You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ud...@apache.org on 2016/02/22 22:42:49 UTC

[001/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917 [Forced Update!]

Repository: incubator-geode
Updated Branches:
  refs/heads/feature/GEODE-870 9cf7ea2c9 -> 0ff942252 (forced update)


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index 545a0ea,0000000..b3f627a
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@@ -1,1910 -1,0 +1,1913 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed;
 +
 +import java.io.File;
 +import java.io.FileReader;
 +import java.io.IOException;
 +import java.io.LineNumberReader;
 +import java.util.ArrayList;
 +import java.util.List;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.ForcedDisconnectException;
 +import com.gemstone.gemfire.GemFireConfigException;
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.SystemConnectException;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.DistributionException;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.InternalLocator;
 +import com.gemstone.gemfire.distributed.internal.MembershipListener;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
 +import com.gemstone.gemfire.distributed.internal.membership.NetView;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.internal.logging.LocalLogWriter;
 +import com.gemstone.gemfire.internal.tcp.Connection;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * Tests the ability of the {@link Locator} API to start and stop
 + * locators running in remote VMs.
 + *
 + * @since 4.0
 + */
 +public class LocatorDUnitTest extends DistributedTestCase {
 +
 +  static TestHook hook;
 +  
 +  /**
 +   * Creates a new <code>LocatorDUnitTest</code>
 +   */
 +  public LocatorDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  private static final String WAIT2_MS_NAME = "LocatorDUnitTest.WAIT2_MS";
 +  private static final int WAIT2_MS_DEFAULT = 5000; // 2000 -- see bug 36470
 +  private static final int WAIT2_MS 
 +      = Integer.getInteger(WAIT2_MS_NAME, WAIT2_MS_DEFAULT).intValue();
 +  
 +  private int port1;
 +  private int port2;
 +  
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    port1 = -1;
 +    port2 = -1;
 +    IgnoredException.addIgnoredException("Removing shunned member");
 +  }
 +  
 +  @Override
 +  protected final void preTearDown() throws Exception {
 +    if (Locator.hasLocator()) {
 +      Locator.getLocator().stop();
 +    }
 +    // delete locator state files so they don't accidentally
 +    // get used by other tests
 +    if (port1 > 0) {
 +      DistributedTestUtils.deleteLocatorStateFile(port1);
 +    }
 +    if (port2 > 0) {
 +      DistributedTestUtils.deleteLocatorStateFile(port2);
 +    }
 +  }
 +  
 +  ////////  Test Methods
 +
 +  
 +  /**
 +   * SQLFire uses a colocated locator in a dm-type=normal VM.  This tests that
 +   * the locator can resume control as coordinator after all locators have been
 +   * shut down and one is restarted.  It's necessary to have a lock service
 +   * start so elder failover is forced to happen.  Prior to fixing how this worked
 +   * it hung with the restarted locator trying to become elder again because
 +   * it put its address at the beginning of the new view it sent out.
 +   */
 +  public void testCollocatedLocatorWithSecurity() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +
 +    final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("start-locator", locators);
 +    properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +    properties.put("security-peer-auth-init","com.gemstone.gemfire.distributed.AuthInitializer.create");
 +    properties.put("security-peer-authenticator","com.gemstone.gemfire.distributed.MyAuthenticator.create");
 +    properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +    properties.put(DistributionConfig.USE_CLUSTER_CONFIGURATION_NAME, "false");
 +    system = (InternalDistributedSystem)DistributedSystem.connect(properties);
 +    InternalDistributedMember mbr = system.getDistributedMember();
 +    assertEquals("expected the VM to have NORMAL vmKind",
 +        DistributionManager.NORMAL_DM_TYPE, system.getDistributedMember().getVmKind());
 +    
 +    properties.remove("start-locator");
 +    properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +    properties.put("locators", locators);
 +    SerializableRunnable startSystem = new SerializableRunnable("start system") {
 +      public void run() {
 +        system = (InternalDistributedSystem)DistributedSystem.connect(properties);
 +      }
 +    };
 +    vm1.invoke(startSystem);
 +    vm2.invoke(startSystem);
 +
 +    // ensure that I, as a collocated locator owner, can create a cache region
 +    Cache cache = CacheFactory.create(system);
 +    Region r = cache.createRegionFactory(RegionShortcut.REPLICATE).create("test region");
 +    assertNotNull("expected to create a region", r);
 +    
 +    // create a lock service and have every vm get a lock
 +    DistributedLockService service = DistributedLockService.create("test service", system);
 +    service.becomeLockGrantor();
 +    service.lock("foo0", 0, 0);
 +    
 +    vm1.invoke(new SerializableRunnable("get the lock service and lock something") {
 +      public void run() {
 +        final DistributedLockService service = DistributedLockService.create("test service", system);
 +        service.lock("foo1", 0, 0);
 +      }
 +    });
 +
 +    vm2.invoke(new SerializableRunnable("get the lock service and lock something") {
 +      public void run() {
 +        final DistributedLockService service = DistributedLockService.create("test service", system);
 +        service.lock("foo2", 0, 0);
 +      }
 +    });
 +      
 +      
 +    // cause elder failover.  vm1 will become the lock grantor
 +    system.disconnect();
 +    
 +    try {
 +      vm1.invoke(new SerializableRunnable("ensure grantor failover") {
 +        public void run() {
 +          final DistributedLockService service = DistributedLockService.getServiceNamed("test service");
 +          service.lock("foo3", 0, 0);
 +          Wait.waitForCriterion(new WaitCriterion() {
 +            @Override
 +            public boolean done() {
 +              return service.isLockGrantor();
 +            }
 +            @Override
 +            public String description() {
 +              return "waiting to become lock grantor after shutting down locator/grantor";
 +            }
 +            
 +          }, DistributionConfig.DEFAULT_MEMBER_TIMEOUT * 2, 1000, true);
 +          assertTrue(service.isLockGrantor());
 +        }
 +      });
 +  
 +      properties.put("start-locator", locators);
 +      properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +      system = (InternalDistributedSystem)DistributedSystem.connect(properties);
 +      System.out.println("done connecting distributed system");
 +      
 +      assertEquals("should be the coordinator", system.getDistributedMember(), MembershipManagerHelper.getCoordinator(system));
 +      NetView view = MembershipManagerHelper.getMembershipManager(system).getView();
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("view after becoming coordinator is " + view);
 +      assertNotSame("should not be the first member in the view ("+view+")", system.getDistributedMember(), view.get(0));
 +      
 +      service = DistributedLockService.create("test service", system);
 +
 +      // now force a non-elder VM to get a lock.  This will hang if the bug is not fixed 
 +      vm2.invoke(new SerializableRunnable("get the lock service and lock something") {
 +        public void run() {
 +          final DistributedLockService service = DistributedLockService.getServiceNamed("test service");
 +          service.lock("foo4", 0, 0);
 +        }
 +      });
 +
 +      assertFalse("should not have become lock grantor", service.isLockGrantor());
 +      
 +      // Now demonstrate that a new member can join and use the lock service
 +      properties.remove("start-locator");
 +      vm3.invoke(startSystem);
 +      vm3.invoke(new SerializableRunnable("get the lock service and lock something(2)") {
 +        public void run() {
 +          final DistributedLockService service = DistributedLockService.create("test service", system);
 +          service.lock("foo5", 0, 0);
 +        }
 +      });
 +      
 +    } finally {
 +      disconnectAllFromDS();
 +    }
 +  }
 +
 +  /**
 +   * Bug 30341 concerns race conditions in JGroups that allow two locators to start up in a
 +   * split-brain configuration.  To work around this we have always told customers that they
 +   * need to stagger the starting of locators.  This test configures two locators to start up
 +   * simultaneously and shows that they find each other and form a single system.
 +   * 
 +   * @throws Exception
 +   */
 +  public void testStartTwoLocators() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM loc1 = host.getVM(1);
 +    VM loc2 = host.getVM(2);
 +    
-     final int port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
++    final int port1 = ports[0];
 +    this.port1 = port1;
-     final int port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    final int port2 = ports[1];
 +    this.port2 = port2; // for cleanup in tearDown2
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    DistributedTestUtils.deleteLocatorStateFile(port2);
 +    final String host0 = NetworkUtils.getServerHostName(host); 
 +    final String locators = host0 + "[" + port1 + "]," +
 +                            host0 + "[" + port2 + "]";
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("locators", locators);
 +    properties.put("enable-network-partition-detection", "false");
 +    properties.put("disable-auto-reconnect", "true");
 +    properties.put("member-timeout", "2000");
 +    properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +    properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +    SerializableCallable startLocator1 = new SerializableCallable("start locator1") {
 +      @Override
 +      public Object call() throws Exception {
 +        try {
 +          System.setProperty("p2p.joinTimeout", "5000"); // set a short join timeout.  default is 17000ms
 +          Locator myLocator = Locator.startLocatorAndDS(port1, new File(""), properties);
 +        } catch (SystemConnectException e) {
 +          return Boolean.FALSE;
 +        } catch (GemFireConfigException e) {
 +          return Boolean.FALSE;
 +        } finally {
 +          System.getProperties().remove("p2p.joinTimeout");
 +        }
 +        return Boolean.TRUE;
 +      }
 +    };
 +    SerializableCallable startLocator2 = new SerializableCallable("start locator2") {
 +      @Override
 +      public Object call() throws Exception {
 +        try {
 +          System.setProperty("p2p.joinTimeout", "5000"); // set a short join timeout.  default is 17000ms
 +          Locator myLocator = Locator.startLocatorAndDS(port2, new File(""), properties);
 +        } catch (SystemConnectException e) {
 +          return Boolean.FALSE;
 +        } finally {
 +          System.getProperties().remove("p2p.joinTimeout");
 +        }
 +        return Boolean.TRUE;
 +      }
 +    };
 +    AsyncInvocation async1 = null;
 +    AsyncInvocation async2 = null;
 +    try {
 +      async2 = loc2.invokeAsync(startLocator2);
 +      Wait.pause(2000);
 +      async1 = loc1.invokeAsync(startLocator1);
 +    } finally {
 +      try {
 +        if (async1 != null) {
 +          async1.join(45000);
 +          if (async1.isAlive()) {
 +            ThreadUtils.dumpAllStacks();
 +          }
 +          if (async2 != null) {
 +            async2.join();
 +            Object result1 = async1.getReturnValue();
 +            if (result1 instanceof Exception) {
 +              throw (Exception)result1;
 +            }
 +            Object result2 = async2.getReturnValue();
 +            if (result2 instanceof Exception) {
 +              throw (Exception)result2;
 +            }
 +            // verify that they found each other
 +            SerializableCallable verify = new SerializableCallable("verify no split-brain") {
 +              public Object call() {
 +                InternalDistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +                if (sys == null) {
 +                  fail("no distributed system found");
 +                }
 +                Assert.assertTrue(sys.getDM().getViewMembers().size() == 2,
 +                    "expected 2 members but found " + sys.getDM().getViewMembers().size()
 +                    );
 +                return true;
 +              }
 +            };
 +            loc2.invoke(verify);
 +            loc1.invoke(verify);
 +          }
 +        }
 +      } finally {
 +        SerializableRunnable r = new SerializableRunnable("stop locator") {
 +          public void run() {
 +            Locator loc = Locator.getLocator();
 +            if (loc != null) {
 +              loc.stop();
 +            }
 +          }
 +        };
 +        loc2.invoke(r);
 +        loc1.invoke(r);
 +      }
 +    }
 +    
 +  }
 +  /**
 +   * test lead member selection
 +   */
 +  public void testLeadMemberSelection() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("locators", locators);
 +    properties.put("enable-network-partition-detection", "true");
 +    properties.put("disable-auto-reconnect", "true");
 +    
 +    File logFile = new File("");
 +    if (logFile.exists()) {
 +      logFile.delete();
 +    }
 +    Locator locator = Locator.startLocatorAndDS(port1, logFile, properties);
 +    try {
 +    DistributedSystem sys = locator.getDistributedSystem();
 +    
 +    Object[] connectArgs = new Object[]{ properties };
 +    
 +    SerializableRunnable disconnect =
 +      new SerializableRunnable("Disconnect from " + locators) {
 +          public void run() {
 +            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +            if (sys != null && sys.isConnected()) {
 +              sys.disconnect();
 +            }
 +          }
 +        };
 +        
 +    assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
 +    
 +    // connect three vms and then watch the lead member selection as they
 +    // are disconnected/reconnected
 +    properties.put("name", "vm1");
 +    DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
 +        "getDistributedMember", connectArgs);
 +    
 +//    assertTrue(MembershipManagerHelper.getLeadMember(sys) != null);
 +    assertLeadMember(mem1, sys, 5000);
 +    
 +    properties.put("name", "vm2");
 +    DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
 +        "getDistributedMember", connectArgs);
 +    assertLeadMember(mem1, sys, 5000);
 +    
 +    properties.put("name", "vm3");
 +    DistributedMember mem3 = (DistributedMember)vm3.invoke(this.getClass(),
 +        "getDistributedMember", connectArgs);
 +    assertLeadMember(mem1, sys, 5000);
 +    
 +    // after disconnecting the first vm, the second one should become the leader
 +    vm1.invoke(disconnect);
 +    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
 +    assertLeadMember(mem2, sys, 5000);
 +    
 +    properties.put("name", "vm1");
 +    mem1 = (DistributedMember)vm1.invoke(this.getClass(),
 +        "getDistributedMember", connectArgs);
 +    assertLeadMember(mem2, sys, 5000);
 +    
 +    vm2.invoke(disconnect);
 +    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem2);
 +    assertLeadMember(mem3, sys, 5000);
 +    
 +    vm1.invoke(disconnect);
 +    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
 +    assertLeadMember(mem3, sys, 5000);
 +
 +    vm3.invoke(disconnect);
 +    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem3);
 +    assertLeadMember(null, sys, 5000);
 +
 +    } finally {
 +      locator.stop();
 +    }
 +  }
 +
 +  private void assertLeadMember(final DistributedMember member,
 +      final DistributedSystem sys, long timeout) {
 +    WaitCriterion ev = new WaitCriterion() {
 +      public boolean done() {
 +        DistributedMember lead = MembershipManagerHelper.getLeadMember(sys);
 +        if (member != null) {
 +          return member.equals(lead);
 +        }
 +        return (lead == null);
 +      }
 +      public String description() {
 +        return null;
 +      }
 +    };
 +    Wait.waitForCriterion(ev, timeout, 200, true);
 +  }
 +  
 +  /**
 +   * test lead member and coordinator failure with network partition detection
 +   * enabled.  It would be nice for this test to have more than two "server"
 +   * vms, to demonstrate that they all exit when the leader and potential-
 +   * coordinator both disappear in the loss-correlation-window, but there
 +   * are only four vms available for dunit testing.
 +   * <p>
 +   * So, we start two locators with admin distributed systems, then start
 +   * two regular distributed members.
 +   * <p>
 +   * We kill the second locator (which is not
 +   * the view coordinator) and then kill the non-lead member.  That should be
 +   * okay - the lead and remaining locator continue to run.
 +   * <p>
 +   * We then kill the lead member and demonstrate that the original locator
 +   * (which is now the sole remaining member) shuts itself down.
 +   */
 +  public void testLeadAndCoordFailure() throws Exception {
 +    IgnoredException.addIgnoredException("Possible loss of quorum due");
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM locvm = host.getVM(3);
 +    Locator locator = null;
 +    
-     final int port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
++    final int port1 = ports[0];
 +    this.port1 = port1;
-     final int port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-     this.port2 = port2; // for cleanup in tearDown2()
++    final int port2 = ports[1];
 +    DistributedTestUtils.deleteLocatorStateFile(port1, port2);
 +    final String host0 = NetworkUtils.getServerHostName(host); 
 +    final String locators = host0 + "[" + port1 + "]," +
 +                            host0 + "[" + port2 + "]";
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("locators", locators);
 +    properties.put("enable-network-partition-detection", "true");
 +    properties.put("disable-auto-reconnect", "true");
 +    properties.put("member-timeout", "2000");
 +    properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +//    properties.put("log-level", "fine");
 +    properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +    
 +    try {
 +      final String uname = getUniqueName();
 +      File logFile = new File("");
 +      locator = Locator.startLocatorAndDS(port1, logFile, properties);
 +      final DistributedSystem sys = locator.getDistributedSystem();
 +      sys.getLogWriter().info("<ExpectedException action=add>java.net.ConnectException</ExpectedException>");
 +      MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
 +      locvm.invoke(new SerializableRunnable() {
 +        public void run() {
 +          File lf = new File("");
 +          try {
 +            Locator.startLocatorAndDS(port2, lf, properties);
 +          }
 +          catch (IOException ios) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
 +          }
 +        }
 +      });
 +      
 +      Object[] connectArgs = new Object[]{ properties };
 +      
 +      SerializableRunnable crashLocator =
 +        new SerializableRunnable("Crash locator") {
 +          public void run() {
 +            Locator loc = Locator.getLocators().iterator().next();
 +            DistributedSystem msys = loc.getDistributedSystem();
 +            MembershipManagerHelper.crashDistributedSystem(msys);
 +            loc.stop();
 +          }
 +      };
 +
 +
 +      assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
 +      
 +//      properties.put("log-level", getDUnitLogLevel());
 +      
 +      DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +      vm2.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +      assertLeadMember(mem1, sys, 5000);
 +      
 +      assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
 +      
 +      // crash the second vm and the locator.  Should be okay
 +      DistributedTestUtils.crashDistributedSystem(vm2);
 +      locvm.invoke(crashLocator);
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm1.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +      
 +      // ensure quorumLost is properly invoked
 +      DistributionManager dm = (DistributionManager)((InternalDistributedSystem)sys).getDistributionManager();
 +      MyMembershipListener listener = new MyMembershipListener();
 +      dm.addMembershipListener(listener);
 +  
 +      // disconnect the first vm and demonstrate that the third vm and the
 +      // locator notice the failure and exit
 +      DistributedTestUtils.crashDistributedSystem(vm1);
 +
 +      /* This vm is watching vm1, which is watching vm2 which is watching locvm.
 +       * It will take 3 * (3 * member-timeout) milliseconds to detect the full
 +       * failure and eject the lost members from the view.
 +       */
 +      
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("waiting for my distributed system to disconnect due to partition detection");
 +      WaitCriterion ev = new WaitCriterion() {
 +        public boolean done() {
 +          return !sys.isConnected();
 +        }
 +        public String description() {
 +          return null;
 +        }
 +      };
 +      Wait.waitForCriterion(ev, 12 * 2000, 200, true);
 +      if (sys.isConnected()) {
 +        fail("Distributed system did not disconnect as expected - network partition detection is broken");
 +      }
 +      // quorumLost should be invoked if we get a ForcedDisconnect in this situation
 +      assertTrue("expected quorumLost to be invoked", listener.quorumLostInvoked);
 +      assertTrue("expected suspect processing initiated by TCPConduit", listener.suspectReasons.contains(Connection.INITIATING_SUSPECT_PROCESSING));
 +    }
 +    finally {
 +      if (locator != null) {
 +        locator.stop();
 +      }
 +      LogWriter bLogger =
 +        new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
 +      bLogger.info("<ExpectedException action=remove>service failure</ExpectedException>");
 +      bLogger.info("<ExpectedException action=remove>java.net.ConnectException</ExpectedException>");
 +      bLogger.info("<ExpectedException action=remove>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +      disconnectAllFromDS();
 +    }
 +  }
 +  
 +
 +  /**
 +   * test lead member failure and normal coordinator shutdown with network partition detection
 +   * enabled.
 +   * <p>
 +   * Start two locators with admin distributed systems, then start
 +   * two regular distributed members.
 +   * <p>
 +   * We kill the lead member and demonstrate that the other members continue
 +   * to operate normally.
 +   * <p>
 +   * We then shut down the group coordinator and observe the second locator
 +   * pick up the job and the remaining member continues to operate normally.
 +   */
 +  public void testLeadFailureAndCoordShutdown() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM locvm = host.getVM(3);
 +    Locator locator = null;
 +    
-     final int port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
++    final int port1 = ports[0];
 +    this.port1 = port1;
-     final int port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    final int port2 = ports[1];
 +    this.port2 = port2;
 +    DistributedTestUtils.deleteLocatorStateFile(port1, port2);
 +    final String host0 = NetworkUtils.getServerHostName(host);
 +    final String locators = host0 + "[" + port1 + "],"
 +          + host0 + "[" + port2 + "]";
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("locators", locators);
 +    properties.put("enable-network-partition-detection", "true");
 +    properties.put("disable-auto-reconnect", "true");
 +    properties.put("member-timeout", "2000");
 +    properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +    SerializableRunnable stopLocator = getStopLocatorRunnable();
 +    
 +    try {
 +      final String uname = getUniqueName();
 +      File logFile = new File("");
 +      locator = Locator.startLocatorAndDS(port1, logFile, properties);
 +      DistributedSystem sys = locator.getDistributedSystem();
 +      locvm.invoke(new SerializableRunnable() {
 +        public void run() {
 +          File lf = new File("");
 +          try {
 +            Locator.startLocatorAndDS(port2, lf, properties);
 +            MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
 +          }
 +          catch (IOException ios) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
 +          }
 +        }
 +      });
 +      
 +      Object[] connectArgs = new Object[]{ properties };
 +      
 +      SerializableRunnable crashSystem =
 +        new SerializableRunnable("Crash system") {
 +          public void run() {
 +            DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
 +            msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +            MembershipManagerHelper.crashDistributedSystem(msys);
 +          }
 +      };
 +
 +      assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
 +      
 +      DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +      DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +
 +      assertEquals(mem1, MembershipManagerHelper.getLeadMember(sys));
 +      
 +      assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
 +      
 +      MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
 +
 +      // crash the lead vm. Should be okay
 +      vm1.invoke(crashSystem);
 +
 +      Wait.pause(4 * 2000); // 4 x the member-timeout
 +      
 +      assertTrue("Distributed system should not have disconnected",
 +          isSystemConnected());
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm2.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           locvm.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +
 +      // stop the locator normally.  This should also be okay
 +      locator.stop();
 +      
 +      if (!Locator.getLocators().isEmpty()) {
 +        // log this for debugging purposes before throwing assertion error
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().warning("found locator " + Locator.getLocators().iterator().next());
 +      }
 +      assertTrue("locator is not stopped", Locator.getLocators().isEmpty());
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm2.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           locvm.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +
 +      // the remaining non-locator member should now be the lead member
 +      assertEquals("This test sometimes fails.  If the log contains " +
 +      		"'failed to collect all ACKs' it is a false failure.",
-       		mem2, vm2.invoke(LocatorDUnitTest.class, "getLeadMember", new Object[]{}));
++      		mem2, vm2.invoke(() -> LocatorDUnitTest.getLeadMember()));
 +      
 +      SerializableRunnable disconnect =
 +        new SerializableRunnable("Disconnect from " + locators) {
 +            public void run() {
 +              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +              if (sys != null && sys.isConnected()) {
 +                sys.disconnect();
 +              }
 +            }
 +          };
 +
 +      // disconnect the first vm and demonstrate that the third vm and the
 +      // locator notice the failure and exit
 +      vm2.invoke(disconnect);
 +      locvm.invoke(stopLocator);
 +    }
 +    finally {
 +      MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
 +      if (locator != null) {
 +        locator.stop();
 +      }
 +      try {
 +        locvm.invoke(stopLocator);
 +      } catch (Exception e) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().severe("failed to stop locator in vm 3", e);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * test lead member failure and normal coordinator shutdown with network partition detection
 +   * enabled.
 +   * <p>
 +   * Start one locators with admin distributed systems, then start
 +   * two regular distributed members.
 +   * <p>
 +   * We kill the lead member and demonstrate that the other members continue
 +   * to operate normally.
 +   * <p>
 +   * We then shut down the group coordinator and observe the second locator
 +   * pick up the job and the remaining member continues to operate normally.
 +   */
 +  // disabled on trunk - should be reenabled on cedar_dev_Oct12
 +  // this test leaves a CloserThread around forever that logs "pausing" messages every 500 ms
 +  public void testForceDisconnectAndPeerShutdownCause() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM locvm = host.getVM(3);
 +    Locator locator = null;
 +    
-     final int port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
++    final int port1 = ports[0];
 +    this.port1 = port1;
-     final int port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-     this.port2 = port2;
++    final int port2 = ports[1];
 +    DistributedTestUtils.deleteLocatorStateFile(port1, port2);
 +    final String host0 = NetworkUtils.getServerHostName(host);
 +    final String locators = host0 + "[" + port1 + "]," + host0 + "[" + port2 + "]";
 +
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("locators", locators);
 +    properties.put("enable-network-partition-detection", "true");
 +    properties.put("disable-auto-reconnect", "true");
 +    properties.put("member-timeout", "2000");
 +    properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +    properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +    SerializableRunnable stopLocator = getStopLocatorRunnable();
 +    
 +    try {
 +      final String uname = getUniqueName();
 +      File logFile = new File("");
 +      locator = Locator.startLocatorAndDS(port1, logFile, properties);
 +      DistributedSystem sys = locator.getDistributedSystem();
 +      locvm.invoke(new SerializableRunnable() {
 +        public void run() {
 +          File lf = new File("");
 +          try {
 +            Locator.startLocatorAndDS(port2, lf, properties);
 +          }
 +          catch (IOException ios) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
 +          }
 +        }
 +      });
 +      
 +      Object[] connectArgs = new Object[]{ properties };
 +      
 +      SerializableRunnable crashSystem =
 +        new SerializableRunnable("Crash system") {
 +          public void run() {
 +            DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
 +            msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>Possible loss of quorum</ExpectedException>");
 +            hook = new TestHook();
 +            MembershipManagerHelper.getMembershipManager(msys).registerTestHook(hook);
 +            try {
 +              MembershipManagerHelper.crashDistributedSystem(msys);
 +            } finally {
 +              hook.reset();
 +            }
 +          }
 +      };
 +
 +      assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
 +      
 +      final DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +      final DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +
 +      assertEquals(mem1, MembershipManagerHelper.getLeadMember(sys));
 +      
 +      assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
 +      
 +      // crash the lead vm. Should be okay. it should hang in test hook thats
 +      // why call is asynchronous.
 +      //vm1.invokeAsync(crashSystem);
 +
 +      assertTrue("Distributed system should not have disconnected",
 +          isSystemConnected());
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm2.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           locvm.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +
 +      vm2.invokeAsync(crashSystem);
 +
 +      Wait.pause(1000); // 4 x the member-timeout
 +      
 +      // request member removal for first peer from second peer.
 +      vm2.invoke(new SerializableRunnable("Request Member Removal") {
 +        
 +        @Override
 +        public void run() {
 +          DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
 +          MembershipManager mmgr = MembershipManagerHelper.getMembershipManager(msys);
 +          
 +          // check for shutdown cause in MembershipManager. Following call should
 +          // throw DistributedSystemDisconnectedException which should have cause as
 +          // ForceDisconnectException.
 +          try {
 +            msys.getLogWriter().info("<ExpectedException action=add>Membership: requesting removal of </ExpectedException>");
 +            mmgr.requestMemberRemoval(mem1, "test reasons");
 +            msys.getLogWriter().info("<ExpectedException action=remove>Membership: requesting removal of </ExpectedException>");
 +            fail("It should have thrown exception in requestMemberRemoval");
 +          } catch (DistributedSystemDisconnectedException e) {
 +            Throwable cause = e.getCause();
 +            assertTrue(
 +                "This should have been ForceDisconnectException but found "
 +                    + cause, cause instanceof ForcedDisconnectException);
 +          } finally {
 +            hook.reset();
 +          }
 +        }
 +      });
 +
 +    }
 +    finally {
 +      if (locator != null) {
 +        locator.stop();
 +      }
 +      locvm.invoke(stopLocator);
 +      assertTrue("locator is not stopped", Locator.getLocators().isEmpty());
 +    }
 +  }
 +
 +  /**
 +   * test lead member shutdown and coordinator crashing with network partition detection
 +   * enabled.
 +   * <p>
 +   * Start two locators with admin distributed systems, then start
 +   * two regular distributed members.
 +   * <p>
 +   * We kill the coordinator and shut down the lead member and observe the second locator
 +   * pick up the job and the remaining member continue to operate normally.
 +   */
 +  public void testLeadShutdownAndCoordFailure() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM locvm = host.getVM(3);
 +    Locator locator = null;
 +    
-     final int port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++    int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
++    final int port1 = ports[0];
 +    this.port1 = port1;
-     final int port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-     this.port2 = port2;
++    final int port2 = ports[1];
 +    DistributedTestUtils.deleteLocatorStateFile(port1, port2);
 +    final String host0 = NetworkUtils.getServerHostName(host);
 +    final String locators = host0 + "[" + port1 + "],"
 +          + host0 + "[" + port2 + "]";
 +    final Properties properties = new Properties();
 +    properties.put("mcast-port", "0");
 +    properties.put("locators", locators);
 +    properties.put("enable-network-partition-detection", "true");
 +    properties.put("disable-auto-reconnect", "true");
 +    properties.put("member-timeout", "2000");
 +    properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +    SerializableRunnable disconnect =
 +      new SerializableRunnable("Disconnect from " + locators) {
 +          public void run() {
 +            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +            if (sys != null && sys.isConnected()) {
 +              sys.disconnect();
 +            }
 +            MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
 +          }
 +        };
 +    SerializableRunnable expectedException =
 +      new SerializableRunnable("Add expected exceptions") {
 +        public void run() {
 +          MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
 +        }
 +    };
 +    try {
 +      final String uname = getUniqueName();
 +      locvm.invoke(new SerializableRunnable() {
 +        public void run() {
 +          File lf = new File("");
 +          try {
 +            Locator.startLocatorAndDS(port2, lf, properties);
 +          }
 +          catch (IOException ios) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator1", ios);
 +          }
 +        }
 +      });
 +
 +      File logFile = new File("");
 +      locator = Locator.startLocatorAndDS(port1, logFile, properties);
 +      DistributedSystem sys = locator.getDistributedSystem();
 +      sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +      Object[] connectArgs = new Object[]{ properties };
 +      
 +      SerializableRunnable crashLocator =
 +        new SerializableRunnable("Crash locator") {
 +          public void run() {
 +            Locator loc = Locator.getLocators().iterator().next();
 +            DistributedSystem msys = loc.getDistributedSystem();
 +            msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
 +            MembershipManagerHelper.crashDistributedSystem(msys);
 +            loc.stop();
 +          }
 +      };
 +
 +      assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
 +      
 +      DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +      vm1.invoke(expectedException);
 +      DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
 +          "getDistributedMember", connectArgs);
 +      
-       DistributedMember loc1Mbr = (DistributedMember)locvm.invoke(this.getClass(),
-           "getLocatorDistributedMember", new Object[]{});
++      DistributedMember loc1Mbr = (DistributedMember)locvm.invoke(() -> this.getLocatorDistributedMember());
 +
 +      assertLeadMember(mem1, sys, 5000);
 +      
 +      assertEquals(loc1Mbr, MembershipManagerHelper.getCoordinator(sys));
 +      
 +      // crash the lead locator.  Should be okay
 +      locvm.invoke(crashLocator);
 +      Wait.pause(10 * 1000);
 +
 +      assertTrue("Distributed system should not have disconnected",
 +          sys.isConnected());
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm1.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm2.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +
 +      // disconnect the first vm and demonstrate that the non-lead vm and the
 +      // locator notice the failure and continue to run
 +      vm1.invoke(disconnect);
 +      Wait.pause(10 * 1000);
 +      
 +      assertTrue("Distributed system should not have disconnected",
-           vm2.invokeBoolean(LocatorDUnitTest.class, "isSystemConnected"));
++          vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 +      
 +      assertEquals(sys.getDistributedMember(),
 +          MembershipManagerHelper.getCoordinator(sys));
 +      assertEquals(mem2, MembershipManagerHelper.getLeadMember(sys));
 +      
 +    }
 +    finally {
 +      vm2.invoke(disconnect);
 +      
 +      if (locator != null) {
 +        locator.stop();
 +      }
 +      locvm.invoke(getStopLocatorRunnable());
 +    }
 +  }
 +
 +  /**
 +   * Tests that attempting to connect to a distributed system in which
 +   * no locator is defined throws an exception.
 +   */
 +  public void testNoLocator() {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    int port =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
 +    Properties props = new Properties();
 +    props.setProperty("mcast-port", "0");
 +    props.setProperty("locators", locators);
 +
 +    final String expected = "java.net.ConnectException";
 +    final String addExpected = 
 +      "<ExpectedException action=add>" + expected + "</ExpectedException>";
 +    final String removeExpected = 
 +      "<ExpectedException action=remove>" + expected + "</ExpectedException>";
 +      
 +    LogWriter bgexecLogger =
 +          new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
 +    bgexecLogger.info(addExpected);
 +    
 +    boolean exceptionOccurred = true;
 +    String oldValue = (String)System.getProperties().put("p2p.joinTimeout", "15000");
 +    try {
 +      DistributedSystem.connect(props);
 +      exceptionOccurred = false;
 +
 +    } catch (DistributionException ex) {
 +      // I guess it can throw this too...
 +
 +    } catch (GemFireConfigException ex) {
 +      String s = ex.getMessage();
 +      assertTrue(s.indexOf("Locator does not exist") >= 0);
 +      
 +    } catch (Exception ex) {
 +      // if you see this fail, determine if unexpected exception is expected
 +      // if expected then add in a catch block for it above this catch
 +      com.gemstone.gemfire.test.dunit.Assert.fail("Failed with unexpected exception", ex);
 +    }
 +    finally {
 +      if (oldValue == null) {
 +        System.getProperties().remove("p2p.joinTimeout");
 +      } else {
 +        System.getProperties().put("p2p.joinTimeout", oldValue);
 +      }
 +      bgexecLogger.info(removeExpected);
 +    }
 +
 +    if (!exceptionOccurred) {
 +      fail("Should have thrown a GemFireConfigException");
 +    }
 +  }
 +
 +  /**
 +   * Tests starting one locator in a remote VM and having multiple
 +   * members of the distributed system join it.  This ensures that
 +   * members start up okay, and that handling of a stopped locator
 +   * is correct.
++   * <p>The locator is then restarted and is shown to take over the
++   * role of membership coordinator.
 +   */
 +  public void testOneLocator() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +
 +    final int port =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    final String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
 +    final String uniqueName = getUniqueName();
 +    
 +    vm0.invoke(new SerializableRunnable("Start locator " + locators) {
 +        public void run() {
 +          File logFile = new File("");
 +          try {
 +            Properties locProps = new Properties();
 +            locProps.setProperty("mcast-port", "0");
 +            locProps.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +            Locator.startLocatorAndDS(port, logFile, locProps);
 +          } catch (IOException ex) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port, ex);
 +          }
 +        }
 +      });
 +    try {
 +
 +    SerializableRunnable connect =
 +      new SerializableRunnable("Connect to " + locators) {
 +          public void run() {
 +            //System.setProperty("p2p.joinTimeout", "5000");
 +            Properties props = new Properties();
 +            props.setProperty("mcast-port", "0");
 +            props.setProperty("locators", locators);
 +            DistributedSystem.connect(props);
 +          }
 +        };
 +    vm1.invoke(connect);
 +    vm2.invoke(connect);
 +
 +    Properties props = new Properties();
 +    props.setProperty("mcast-port", "0");
 +    props.setProperty("locators", locators);
 +
 +    system = (InternalDistributedSystem)DistributedSystem.connect(props);
 +    
 +    final DistributedMember coord = MembershipManagerHelper.getCoordinator(system);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator before termination of locator is " + coord);
 +
 +    vm0.invoke(getStopLocatorRunnable());
 +    
 +    // now ensure that one of the remaining members became the coordinator
 +    WaitCriterion ev = new WaitCriterion() {
 +      public boolean done() {
 +        return !coord.equals(MembershipManagerHelper.getCoordinator(system));
 +      }
 +      public String description() {
-         return "expected the coordinator to be " + coord + " but it is " +
++        return "expected the coordinator to not be " + coord + " but it is " +
 +          MembershipManagerHelper.getCoordinator(system);
 +      }
 +    };
-     Wait.waitForCriterion(ev, 15 * 1000, 200, true);
++    Wait.waitForCriterion(ev, 15 * 1000, 200, false);
 +    DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system); 
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator after shutdown of locator was " +
 +        newCoord);
 +    if (coord.equals(newCoord)) {
 +      fail("another member should have become coordinator after the locator was stopped");
 +    }
 +      
 +
 +    system.disconnect();
 +
 +    SerializableRunnable disconnect =
 +      new SerializableRunnable("Disconnect from " + locators) {
 +          public void run() {
 +            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +            if (sys != null && sys.isConnected()) {
 +              sys.disconnect();
 +            }
 +          }
 +        };
 +    vm1.invoke(disconnect);
 +    vm2.invoke(disconnect);
 +
 +    } finally {
 +      vm0.invoke(getStopLocatorRunnable());
 +    }
 +  }
 +
 +//  public void testRepeat() throws Exception {
 +//    for (int i=0; i<10; i++) {
 +//      System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> run #"+i);
 +//      testLocatorBecomesCoordinator();
 +//      tearDown();
 +//      setUp();
 +//    }
 +//  }
 +  /**
 +   * Tests starting one locator in a remote VM and having multiple
 +   * members of the distributed system join it.  This ensures that
 +   * members start up okay, and that handling of a stopped locator
 +   * is correct.  It then restarts the locator to demonstrate that
 +   * it can connect to and function as the group coordinator
 +   */
 +  public void testLocatorBecomesCoordinator() throws Exception {
 +    disconnectAllFromDS();
 +    final String expected = "java.net.ConnectException";
 +    final String addExpected = 
 +      "<ExpectedException action=add>" + expected + "</ExpectedException>";
 +    final String removeExpected = 
 +      "<ExpectedException action=remove>" + expected + "</ExpectedException>";
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +
 +    final int port =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    final String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
 +    
 +    vm0.invoke(getStartSBLocatorRunnable(port, getUniqueName()+"1"));
 +    try {
 +
 +    final Properties props = new Properties();
 +    props.setProperty("mcast-port", "0");
 +    props.setProperty("locators", locators);
 +    props.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +    SerializableRunnable connect =
 +      new SerializableRunnable("Connect to " + locators) {
 +          public void run() {
 +            //System.setProperty("p2p.joinTimeout", "5000");
 +            DistributedSystem sys = getSystem(props);
 +            sys.getLogWriter().info(addExpected);
 +          }
 +        };
 +    vm1.invoke(connect);
 +    vm2.invoke(connect);
 +
 +    system = (InternalDistributedSystem)getSystem(props);
 +
 +    final DistributedMember coord = MembershipManagerHelper.getCoordinator(system);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator before termination of locator is " + coord);
 +
 +    vm0.invoke(getStopLocatorRunnable());
 +    
 +    // now ensure that one of the remaining members became the coordinator
 +    WaitCriterion ev = new WaitCriterion() {
 +      public boolean done() {
 +        return !coord.equals(MembershipManagerHelper.getCoordinator(system));
 +      }
 +      public String description() {
 +        return "expected the coordinator to be " + coord + " but it is " +
 +          MembershipManagerHelper.getCoordinator(system);
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 15000, 200, true);
 +    DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system); 
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator after shutdown of locator was " +
 +        newCoord);
 +    if (newCoord == null || coord.equals(newCoord)) {
 +      fail("another member should have become coordinator after the locator was stopped: "
 +          + newCoord);
 +    }
 +      
 +
 +    // restart the locator to demonstrate reconnection & make disconnects faster
 +    // it should also regain the role of coordinator, so we check to make sure
 +    // that the coordinator has changed
 +    vm0.invoke(getStartSBLocatorRunnable(port, getUniqueName()+"2"));
 +    
 +    final DistributedMember tempCoord = newCoord;
 +    ev = new WaitCriterion() {
 +      public boolean done() {
 +        return !tempCoord.equals(MembershipManagerHelper.getCoordinator(system));
 +      }
 +      public String description() {
 +        return null;
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 5000, 200, true);
 +    
 +    system.disconnect();
 +    LogWriter bgexecLogger =
 +      new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
 +    bgexecLogger.info(removeExpected);
 +
 +    SerializableRunnable disconnect =
 +      new SerializableRunnable("Disconnect from " + locators) {
 +          public void run() {
 +            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +            if (sys != null && sys.isConnected()) {
 +              sys.disconnect();
 +            }
 +            // connectExceptions occur during disconnect, so we need the
 +            // expectedexception hint to be in effect until this point
 +            LogWriter bLogger =
 +              new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
 +            bLogger.info(removeExpected);
 +          }
 +        };
 +    vm1.invoke(disconnect);
 +    vm2.invoke(disconnect);
 +    vm0.invoke(getStopLocatorRunnable());
 +    } finally {
 +      vm0.invoke(getStopLocatorRunnable());
 +    }
 +
 +  }
 +
 +  
 +  /** set a short locator refresh rate */
 +  public static void setShortRefreshWait() {
 +    System.setProperty("p2p.gossipRefreshRate", "2000");
 +  }
 +  
 +  /** remove shortened locator refresh rate */
 +  public static void resetRefreshWait() {
 +    System.getProperties().remove("p2p.gossipRefreshRate");
 +  }
 +  
 +  public static boolean isSystemConnected() {
 +    DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +    if (sys != null && sys.isConnected()) {
 +      return true;
 +    }
 +    return false;
 +  }
 +  
 +
 +  static boolean beforeFailureNotificationReceived;
 +  static boolean afterFailureNotificationReceived;
 +
 +
 +  /**
 +   * Tests starting multiple locators in multiple VMs.
 +   */
 +  public void testMultipleLocators() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +
 +    int[] freeTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
 +    final int port1 = freeTCPPorts[0];
 +    this.port1 = port1;
 +    final int port2 = freeTCPPorts[1];
 +    this.port2 = port2;
 +    DistributedTestUtils.deleteLocatorStateFile(port1, port2);
 +    final String host0 = NetworkUtils.getServerHostName(host); 
 +    final String locators = host0 + "[" + port1 + "]," +
 +                            host0 + "[" + port2 + "]";
 +
 +    final Properties dsProps = new Properties();
 +    dsProps.setProperty("locators", locators);
 +    dsProps.setProperty("mcast-port", "0");
 +    dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +//    dsProps.setProperty("log-level", "finest");
 +    final String uniqueName = getUniqueName();
 +
 +    vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
 +      public void run() {
 +        File logFile = new File("");
 +        try {
 +          Locator.startLocatorAndDS(port1, logFile, dsProps);
 +        } catch (IOException ex) {
 +          com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port1, ex);
 +        }
 +      }
 +    });
 +    try {
 +
 +      //try { Thread.currentThread().sleep(4000); } catch (InterruptedException ie) { }
 +
 +      vm3.invoke(new SerializableRunnable("Start locator on " + port2) {
 +        public void run() {
 +          File logFile = new File("");
 +          try {
 +            Locator.startLocatorAndDS(port2, logFile, dsProps);
 +
 +          } catch (IOException ex) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port2, ex);
 +          }
 +        }
 +      });
 +      try {
 +
 +        SerializableRunnable connect =
 +          new SerializableRunnable("Connect to " + locators) {
 +          public void run() {
 +            Properties props = new Properties();
 +            props.setProperty("mcast-port", "0");
 +            props.setProperty("locators", locators);
 +            DistributedSystem.connect(props);
 +          }
 +        };
 +        vm1.invoke(connect);
 +        vm2.invoke(connect);
 +
 +        Properties props = new Properties();
 +        props.setProperty("mcast-port", "0");
 +        props.setProperty("locators", locators);
 +
 +        system = (InternalDistributedSystem)DistributedSystem.connect(props);
 +
 +        WaitCriterion ev = new WaitCriterion() {
 +          public boolean done() {
 +            try {
 +              return system.getDM().getViewMembers().size() >= 3;
 +            }
 +            catch (Exception e) {
 +              e.printStackTrace();
 +              fail("unexpected exception");
 +            }
 +            return false; // NOTREACHED
 +          }
 +          public String description() {
 +            return null;
 +          }
 +        };
 +        Wait.waitForCriterion(ev, 10 * 1000, 200, true);
 +
 +        // three applications plus
 +        assertEquals(5, system.getDM().getViewMembers().size());
 +
 +        system.disconnect();
 +
 +        SerializableRunnable disconnect =
 +          new SerializableRunnable("Disconnect from " + locators) {
 +          public void run() {
 +            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +            if (sys != null && sys.isConnected()) {
 +              sys.disconnect();
 +            }
 +          }
 +        };
 +        vm1.invoke(disconnect);
 +        vm2.invoke(disconnect);
 +
 +      } finally {
 +        vm3.invoke(getStopLocatorRunnable());
 +      }
 +    } finally {
 +      vm0.invoke(getStopLocatorRunnable());
 +    }
 +  }
 +  
 +  /**
 +   * Tests starting multiple locators in multiple VMs.
 +   */
 +  public void testMultipleMcastLocators() throws Exception {
 +    disconnectAllFromDS();
 +    IgnoredException.addIgnoredException("Could not stop  Distribution Locator"); // shutdown timing issue in InternalLocator
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +
 +    final int[] freeTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
 +    final int port1 = freeTCPPorts[0];
 +    this.port1 = port1;
 +    final int port2 = freeTCPPorts[1];
 +    this.port2 = port2;
 +    DistributedTestUtils.deleteLocatorStateFile(port1, port2);
 +    final int mcastport = AvailablePort.getRandomAvailablePort(AvailablePort.MULTICAST);
 +    
 +    final String host0 = NetworkUtils.getServerHostName(host); 
 +    final String locators = host0 + "[" + port1 + "]," +
 +                            host0 + "[" + port2 + "]";
 +    final String uniqueName = getUniqueName();
 +    
 +    vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
 +        public void run() {
 +          File logFile = new File("");
 +          try {
 +            Properties props = new Properties();
 +            props.setProperty("mcast-port", String.valueOf(mcastport));
 +            props.setProperty("locators", locators);
 +            props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
 +            props.setProperty("mcast-ttl", "0");
 +            props.setProperty("enable-network-partition-detection", "true");
 +            props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +
 +            Locator.startLocatorAndDS(port1, logFile, null, props);
 +          }
 +          catch (IOException ex) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port1, ex);
 +          }
 +        }
 +      });
 +    vm3.invoke(new SerializableRunnable("Start locator on " + port2) {
 +        public void run() {
 +          File logFile = new File("");
 +          try {
 +            Properties props = new Properties();
 +            props.setProperty("mcast-port", String.valueOf(mcastport));
 +            props.setProperty("locators", locators);
 +            props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
 +            props.setProperty("mcast-ttl", "0");
 +            props.setProperty("enable-network-partition-detection", "true");
 +            props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +            Locator.startLocatorAndDS(port2, logFile, null, props);
 +          }
 +          catch (IOException ex) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port2, ex);
 +          }
 +        }
 +      });
 +
 +    SerializableRunnable connect =
 +      new SerializableRunnable("Connect to " + locators) {
 +          public void run() {
 +            Properties props = new Properties();
 +            props.setProperty("mcast-port", String.valueOf(mcastport));
 +            props.setProperty("locators", locators);
 +            props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
 +            props.setProperty("mcast-ttl", "0");
 +            props.setProperty("enable-network-partition-detection", "true");
 +            DistributedSystem.connect(props);
 +          }
 +        };
 +    try {
 +      vm1.invoke(connect);
 +      vm2.invoke(connect);
 +
 +      Properties props = new Properties();
 +      props.setProperty("mcast-port", String.valueOf(mcastport));
 +      props.setProperty("locators", locators);
 +      props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
 +      props.setProperty("mcast-ttl", "0");
 +      props.setProperty("enable-network-partition-detection", "true");
 +
 +      system = (InternalDistributedSystem)DistributedSystem.connect(props);
 +      WaitCriterion ev = new WaitCriterion() {
 +        public boolean done() {
 +          try {
 +            return system.getDM().getViewMembers().size() == 5;
 +          }
 +          catch (Exception e) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("unexpected exception", e);
 +          }
 +          return false; // NOTREACHED
 +        }
 +        public String description() {
 +          return "waiting for 5 members - have " + system.getDM().getViewMembers().size();
 +        }
 +      };
 +      Wait.waitForCriterion(ev, WAIT2_MS, 200, true);
 +      system.disconnect();
 +
 +      SerializableRunnable disconnect =
 +        new SerializableRunnable("Disconnect from " + locators) {
 +            public void run() {
 +              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +              if (sys != null && sys.isConnected()) {
 +                sys.disconnect();
 +              }
 +            }
 +          };
 +      vm1.invoke(disconnect);
 +      vm2.invoke(disconnect);
 +    }
 +    finally {
 +      SerializableRunnable stop = getStopLocatorRunnable();
 +      vm0.invoke(stop);
 +      vm3.invoke(stop);
 +      if (system != null) {
 +        system.disconnect();
 +      }
 +    }
 +  }
 +
 +
 +  /**
 +   * Tests that a VM can connect to a locator that is hosted in its
 +   * own VM.
 +   */
 +  public void testConnectToOwnLocator() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +
 +    port1 =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    File logFile = new File("");
 +    Locator locator = Locator.startLocator(port1, logFile);
 +    try {
 +
 +    final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
 +
 +    Properties props = new Properties();
 +    props.setProperty("mcast-port", "0");
 +    props.setProperty("locators", locators);
 +    props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +    system = (InternalDistributedSystem)DistributedSystem.connect(props);
 +    system.disconnect();
 +    } finally {
 +    locator.stop();
 +    }
 +  }
 +
 +  /**
 +   * Tests that a VM cannot connect if the locator has a different
 +   * enable-network-partition-detection setting
 +   */
 +  public void testLocatorForcesDetection() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(1);
 +    Locator locator = null;
 +    
 +    try {
 +      port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +      DistributedTestUtils.deleteLocatorStateFile(port1);
 +      final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
 +      final Properties properties = new Properties();
 +      properties.put("mcast-port", "0");
 +      properties.put("locators", locators);
 +      properties.put(DistributionConfig.ENABLE_NETWORK_PARTITION_DETECTION_NAME, "true");
 +      properties.put("disable-auto-reconnect", "true");
 +      properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +      File logFile = new File("");
 +      locator = Locator.startLocatorAndDS(port1, logFile, properties);
 +  
 +      final Properties properties2 = new Properties();
 +      properties2.put("mcast-port", "0");
 +      properties2.put("locators", locators);
 +      properties2.put(DistributionConfig.ENABLE_NETWORK_PARTITION_DETECTION_NAME, "false");
 +      properties2.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +      properties2.put("disable-auto-reconnect", "true");
 +      
 +      vm1.invoke(new SerializableRunnable("try to connect") {
 +        public void run() {
 +          DistributedSystem s = null;
 +          try {
 +            s = DistributedSystem.connect(properties2);
 +            boolean enabled = ((InternalDistributedSystem)s).getConfig().getEnableNetworkPartitionDetection();
 +            s.disconnect();
 +            if (!enabled) {
 +              fail("should not have been able to connect with different enable-network-partition-detection settings");
 +            }
 +          }
 +          catch (GemFireConfigException e) {
 +            fail("should have been able to connect and have enable-network-partion-detection enabled");
 +          }
 +        }
 +      });
 +      
 +      locator.stop();
 +      
 +      // now start the locator with enable-network-partition-detection=false
 +      logFile = new File("");
 +      locator = Locator.startLocatorAndDS(port1, logFile , properties2);
 +  
 +      vm1.invoke(new SerializableRunnable("try to connect") {
 +        public void run() {
 +          DistributedSystem s = null;
 +          try {
 +            s = DistributedSystem.connect(properties);
 +            s.disconnect();
 +            fail("should not have been able to connect with different enable-network-partition-detection settings");
 +          }
 +          catch (GemFireConfigException e) {
 +            // passed
 +          }
 +        }
 +      });
 +      
 +      locator.stop();
 +      locator = null;
 +    }
 +    finally {
 +      if (locator != null) {
 +        locator.stop();
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Tests that a single VM can NOT host multiple locators
 +   */
 +  public void testHostingMultipleLocators() throws Exception {
 +    disconnectAllFromDS();
 +    Host host = Host.getHost(0);
 +    //VM vm = host.getVM(0);
 +    //VM vm1 = host.getVM(1);
 +
 +    port1 =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    File logFile1 = new File("");
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    Locator locator1 = Locator.startLocator(port1, logFile1);
 +    
 +    try {
 +
 +    int port2 =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    File logFile2 = new File("");
 +
 +    DistributedTestUtils.deleteLocatorStateFile(port2);
 +    
 +    try {
 +      Locator locator2 = Locator.startLocator(port2, logFile2);
 +      fail("expected second locator start to fail.");
 +    } catch (IllegalStateException expected) {
 +    }
 +
 +    final String host0 = NetworkUtils.getServerHostName(host);
 +    final String locators = host0 + "[" + port1 + "]," +
 +                            host0 + "[" + port2 + "]";
 +
 +    SerializableRunnable connect =
 +      new SerializableRunnable("Connect to " + locators) {
 +          public void run() {
 +            Properties props = new Properties();
 +            props.setProperty("mcast-port", "0");
 +            props.setProperty("locators", locators);
 +            props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
 +            DistributedSystem.connect(props);
 +          }
 +        };
 +    connect.run();
 +    //vm1.invoke(connect);
 +
 +    SerializableRunnable disconnect =
 +      new SerializableRunnable("Disconnect from " + locators) {
 +          public void run() {
 +            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +            if (sys != null && sys.isConnected()) {
 +              sys.disconnect();
 +            }
 +          }
 +        };
 +
 +    disconnect.run();
 +    //vm1.invoke(disconnect);
 +
 +    } finally {
 +    locator1.stop();
 +    }
 +  }
 +
 +  /**
 +   * Tests starting, stopping, and restarting a locator.  See bug
 +   * 32856.
 +   *
 +   * @since 4.1
 +   */
 +  public void testRestartLocator() throws Exception {
 +    disconnectAllFromDS();
 +    port1 =
 +      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    DistributedTestUtils.deleteLocatorStateFile(port1);
 +    File logFile = new File("");
 +    File stateFile = new File("locator"+port1+"state.dat");
 +    VM vm0 = Host.getHost(0).getVM(0);
 +    final Properties p = new Properties();
 +    p.setProperty(DistributionConfig.LOCATORS_NAME, Host.getHost(0).getHostName() + "["+port1+"]");
 +    p.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    p.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +    if (stateFile.exists()) {
 +      stateFile.delete();
 +    }
 +
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Starting locator");
 +    Locator locator = Locator.startLocatorAndDS(port1, logFile, p);
 +    try {
 +    
 +    SerializableRunnable connect =
 +      new SerializableRunnable("Connect to locator on port " + port1) {
 +          public void run() {
 +            DistributedSystem.connect(p);
 +          }
 +        };
 +    vm0.invoke(connect);
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Stopping locator");
 +    locator.stop();
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Starting locator");
 +    locator = Locator.startLocatorAndDS(port1, logFile, p);
 +    
 +    vm0.invoke(new SerializableRunnable("disconnect") {
 +      public void run() {
 +        DistributedSystem.connect(p).disconnect();
 +      }
 +    });
 +    
 +    } finally {
 +    locator.stop();
 +    }
 +
 +  }
 +  
 +  /** return the distributed member id for the ds on this vm */
 +  public static DistributedMember getDistributedMember(Properties props) {
 +    props.put("name", "vm_"+VM.getCurrentVMNum());
 +    DistributedSystem sys = DistributedSystem.connect(props);
 +    sys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
 +    sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
 +    sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +    return DistributedSystem.connect(props).getDistributedMember();
 +  }
 +  
 +  /** find a running locator and return its distributed member id */
 +  public static DistributedMember getLocatorDistributedMember() {
 +    return (Locator.getLocators().iterator().next())
 +      .getDistributedSystem().getDistributedMember();
 +  }
 +  
 +  /** find the lead member and return its id */
 +  public static DistributedMember getLeadMember() {
 +    DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
 +    return MembershipManagerHelper.getLeadMember(sys);
 +  }
 +
 +  private SerializableRunnable getStopLocatorRunnable() {
 +    return new SerializableRunnable("stop locator") {
 +      public void run() {
 +        MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
 +        Locator loc = Locator.getLocator();
 +        if (loc != null) {
 +          loc.stop();
 +          assertFalse(Locator.hasLocator());
 +        }
 +      }
 +    };
 +  }
 +  
 +  private SerializableRunnable getStartSBLocatorRunnable(final int port, final String name) {
 +    return new SerializableRunnable("Start locator on port " + port) {
 +      public void run() {
 +        File logFile = new File("");
 +        try {
 +          System.setProperty(InternalLocator.LOCATORS_PREFERRED_AS_COORDINATORS, "true");
 +          System.setProperty("p2p.joinTimeout", "1000");
 +          Properties locProps = new Properties();
 +          locProps.put("mcast-port", "0");
 +          locProps.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +          Locator.startLocatorAndDS(port, logFile, locProps);
 +        } catch (IOException ex) {
 +          com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port, ex);
 +        }
 +        finally {
 +          System.getProperties().remove(InternalLocator.LOCATORS_PREFERRED_AS_COORDINATORS);
 +          System.getProperties().remove("p2p.joinTimeout");
 +        }
 +      }
 +    };
 +  }
 +  
 +  protected void nukeJChannel(DistributedSystem sys) {
 +    sys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
 +    sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
 +    sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +    try {
 +      MembershipManagerHelper.crashDistributedSystem(sys);
 +    }
 +    catch (DistributedSystemDisconnectedException se) {
 +      // it's okay for the system to already be shut down
 +    }
 +    sys.getLogWriter().info("<ExpectedException action=remove>service failure</ExpectedException>");
 +    sys.getLogWriter().info("<ExpectedException action=remove>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
 +  }
 +
 +  
 +  //New test hook which blocks before closing channel.
 +  class TestHook implements MembershipTestHook {
 +
 +    volatile boolean unboundedWait = true;
 +    @Override
 +    public void beforeMembershipFailure(String reason, Throwable cause) {
 +      System.out.println("Inside TestHook.beforeMembershipFailure with " + cause);
 +      long giveUp = System.currentTimeMillis() + 30000;
 +      if (cause instanceof ForcedDisconnectException) {
 +        while (unboundedWait && System.currentTimeMillis() < giveUp) {
 +          Wait.pause(1000);
 +        }
 +      } else {
 +        cause.printStackTrace();
 +      }
 +    }
 +
 +    @Override
 +    public void afterMembershipFailure(String reason, Throwable cause) {
 +    }
 +
 +    public void reset() {
 +      unboundedWait = false;
 +    }
 +
 +  }
 +  class MyMembershipListener implements MembershipListener {
 +    boolean quorumLostInvoked;
 +    List<String> suspectReasons = new ArrayList<>(50);
 +    
 +    public void memberJoined(InternalDistributedMember id) {  }
 +    public void memberDeparted(InternalDistributedMember id, boolean crashed) { }
 +    public void memberSuspect(InternalDistributedMember id,
 +        InternalDistributedMember whoSuspected, String reason) {
 +      suspectReasons.add(reason);
 +    }
 +    public void quorumLost(Set<InternalDistributedMember> failures,
 +        List<InternalDistributedMember> remaining) {
 +      quorumLostInvoked = true;
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("quorumLost invoked in test code");
 +    }
 +  }
 +  
 +  
 +}


[058/100] [abbrv] incubator-geode git commit: GEODE-831: unit test FreeListManager

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
index 10e4148..a716f14 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
@@ -32,39 +32,43 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
 import com.gemstone.gemfire.LogWriter;
 import com.gemstone.gemfire.OutOfOffHeapMemoryException;
 import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
-import com.gemstone.gemfire.internal.offheap.MemoryBlock.State;
 
 /**
  * Manages the free lists for a SimpleMemoryAllocatorImpl
  */
 public class FreeListManager {
-  final private AtomicReferenceArray<SyncChunkStack> tinyFreeLists = new AtomicReferenceArray<SyncChunkStack>(SimpleMemoryAllocatorImpl.TINY_FREE_LIST_COUNT);
+  /** The MemoryChunks that this allocator is managing by allocating smaller chunks of them.
+   * The contents of this array never change.
+   */
+  private final AddressableMemoryChunk[] slabs;
+  private final long totalSlabSize;
+  
+  final private AtomicReferenceArray<SyncChunkStack> tinyFreeLists = new AtomicReferenceArray<SyncChunkStack>(TINY_FREE_LIST_COUNT);
   // hugeChunkSet is sorted by chunk size in ascending order. It will only contain chunks larger than MAX_TINY.
-  private final ConcurrentSkipListSet<Chunk> hugeChunkSet = new ConcurrentSkipListSet<Chunk>();
+  private final ConcurrentSkipListSet<ObjectChunk> hugeChunkSet = new ConcurrentSkipListSet<ObjectChunk>();
   private final AtomicLong allocatedSize = new AtomicLong(0L);
 
   private int getNearestTinyMultiple(int size) {
-    return (size-1)/SimpleMemoryAllocatorImpl.TINY_MULTIPLE;
+    return (size-1)/TINY_MULTIPLE;
   }
-  List<Chunk> getLiveChunks() {
-    ArrayList<Chunk> result = new ArrayList<Chunk>();
-    UnsafeMemoryChunk[] slabs = this.ma.getSlabs();
+  List<ObjectChunk> getLiveChunks() {
+    ArrayList<ObjectChunk> result = new ArrayList<ObjectChunk>();
     for (int i=0; i < slabs.length; i++) {
       getLiveChunks(slabs[i], result);
     }
     return result;
   }
-  private void getLiveChunks(UnsafeMemoryChunk slab, List<Chunk> result) {
+  private void getLiveChunks(AddressableMemoryChunk slab, List<ObjectChunk> result) {
     long addr = slab.getMemoryAddress();
-    while (addr <= (slab.getMemoryAddress() + slab.getSize() - Chunk.MIN_CHUNK_SIZE)) {
+    while (addr <= (slab.getMemoryAddress() + slab.getSize() - ObjectChunk.MIN_CHUNK_SIZE)) {
       Fragment f = isAddrInFragmentFreeSpace(addr);
       if (f != null) {
         addr = f.getMemoryAddress() + f.getSize();
       } else {
-        int curChunkSize = Chunk.getSize(addr);
-        int refCount = Chunk.getRefCount(addr);
+        int curChunkSize = ObjectChunk.getSize(addr);
+        int refCount = ObjectChunk.getRefCount(addr);
         if (refCount > 0) {
-          result.add(this.ma.chunkFactory.newChunk(addr));
+          result.add(new ObjectChunk(addr));
         }
         addr += curChunkSize;
       }
@@ -85,13 +89,13 @@ public class FreeListManager {
     return this.allocatedSize.get();
   }
   public long getFreeMemory() {
-    return this.ma.getTotalMemory() - getUsedMemory();
+    return getTotalMemory() - getUsedMemory();
   }
   long getFreeFragmentMemory() {
     long result = 0;
     for (Fragment f: this.fragmentList) {
       int freeSpace = f.freeSpace();
-      if (freeSpace >= Chunk.MIN_CHUNK_SIZE) {
+      if (freeSpace >= ObjectChunk.MIN_CHUNK_SIZE) {
         result += freeSpace;
       }
     }
@@ -109,7 +113,7 @@ public class FreeListManager {
   }
   long getFreeHugeMemory() {
     long hugeFree = 0;
-    for (Chunk c: this.hugeChunkSet) {
+    for (ObjectChunk c: this.hugeChunkSet) {
       hugeFree += c.getSize();
     }
     return hugeFree;
@@ -122,24 +126,37 @@ public class FreeListManager {
   private final CopyOnWriteArrayList<Fragment> fragmentList;
   private final SimpleMemoryAllocatorImpl ma;
 
-  public FreeListManager(SimpleMemoryAllocatorImpl ma) {
+  public FreeListManager(SimpleMemoryAllocatorImpl ma, final AddressableMemoryChunk[] slabs) {
     this.ma = ma;
-    UnsafeMemoryChunk[] slabs = ma.getSlabs();
+    this.slabs = slabs;
+    long total = 0;
     Fragment[] tmp = new Fragment[slabs.length];
     for (int i=0; i < slabs.length; i++) {
-      tmp[i] = new Fragment(slabs[i].getMemoryAddress(), slabs[i].getSize());
+      tmp[i] = createFragment(slabs[i].getMemoryAddress(), slabs[i].getSize());
+      total += slabs[i].getSize();
     }
     this.fragmentList = new CopyOnWriteArrayList<Fragment>(tmp);
+    this.totalSlabSize = total;
 
-    if(ma.validateMemoryWithFill) {
-      fillFragments();
-    }
+    fillFragments();
   }
 
   /**
-   * Fills all fragments with a fill used for data integrity validation.
+   * Create and return a Fragment.
+   * This method exists so that tests can override it.
+   */
+  protected Fragment createFragment(long addr, int size) {
+    return new Fragment(addr, size);
+  }
+  
+  /**
+   * Fills all fragments with a fill used for data integrity validation 
+   * if fill validation is enabled.
    */
   private void fillFragments() {
+    if (!this.validateMemoryWithFill) {
+      return;
+    }
     for(Fragment fragment : this.fragmentList) {
       fragment.fill();
     }
@@ -157,58 +174,48 @@ public class FreeListManager {
    * Maybe it would be better for 3 to look for adjacent free blocks that can be merged together.
    * For now we will just try 1 and 2 and then report out of mem.
    * @param size minimum bytes the returned chunk must have.
-   * @param chunkType TODO
    * @return the allocated chunk
    * @throws IllegalStateException if a chunk can not be allocated.
    */
   @SuppressWarnings("synthetic-access")
-  public Chunk allocate(int size, ChunkType chunkType) {
-    Chunk result = null;
-    {
-      assert size > 0;
-      if (chunkType == null) {
-        chunkType = GemFireChunk.TYPE;
-      }
-      result = basicAllocate(size, true, chunkType);
-      result.setDataSize(size);
-    }
-    this.ma.stats.incObjects(1);
-    int resultSize = result.getSize();
-    this.allocatedSize.addAndGet(resultSize);
-    this.ma.stats.incUsedMemory(resultSize);
-    this.ma.stats.incFreeMemory(-resultSize);
+  public ObjectChunk allocate(int size) {
+    assert size > 0;
+    
+    ObjectChunk result = basicAllocate(size, true);
+
+    result.setDataSize(size);
+    this.allocatedSize.addAndGet(result.getSize());
     result.initializeUseCount();
-    this.ma.notifyListeners();
 
     return result;
   }
 
-  private Chunk basicAllocate(int size, boolean useSlabs, ChunkType chunkType) {
+  private ObjectChunk basicAllocate(int size, boolean useSlabs) {
     if (useSlabs) {
       // Every object stored off heap has a header so we need
       // to adjust the size so that the header gets allocated.
       // If useSlabs is false then the incoming size has already
       // been adjusted.
-      size += Chunk.OFF_HEAP_HEADER_SIZE;
+      size += ObjectChunk.OFF_HEAP_HEADER_SIZE;
     }
-    if (size <= SimpleMemoryAllocatorImpl.MAX_TINY) {
-      return allocateTiny(size, useSlabs, chunkType);
+    if (size <= MAX_TINY) {
+      return allocateTiny(size, useSlabs);
     } else {
-      return allocateHuge(size, useSlabs, chunkType);
+      return allocateHuge(size, useSlabs);
     }
   }
 
-  private Chunk allocateFromFragments(int chunkSize, ChunkType chunkType) {
+  private ObjectChunk allocateFromFragments(int chunkSize) {
     do {
       final int lastAllocationId = this.lastFragmentAllocation.get();
       for (int i=lastAllocationId; i < this.fragmentList.size(); i++) {
-        Chunk result = allocateFromFragment(i, chunkSize, chunkType);
+        ObjectChunk result = allocateFromFragment(i, chunkSize);
         if (result != null) {
           return result;
         }
       }
       for (int i=0; i < lastAllocationId; i++) {
-        Chunk result = allocateFromFragment(i, chunkSize, chunkType);
+        ObjectChunk result = allocateFromFragment(i, chunkSize);
         if (result != null) {
           return result;
         }
@@ -220,22 +227,27 @@ public class FreeListManager {
     try {
       throw failure;
     } finally {
-      this.ma.ooohml.outOfOffHeapMemory(failure);
+      this.ma.getOutOfOffHeapMemoryListener().outOfOffHeapMemory(failure);
     }
   }
 
   private void logOffHeapState(int chunkSize) {
     if (InternalDistributedSystem.getAnyInstance() != null) {
       LogWriter lw = InternalDistributedSystem.getAnyInstance().getLogWriter();
-      lw.info("OutOfOffHeapMemory allocating size of " + chunkSize + ". allocated=" + this.allocatedSize.get() + " compactions=" + this.compactCount.get() + " objects=" + this.ma.stats.getObjects() + " free=" + this.ma.stats.getFreeMemory() + " fragments=" + this.ma.stats.getFragments() + " largestFragment=" + this.ma.stats.getLargestFragment() + " fragmentation=" + this.ma.stats.getFragmentation());
-      logFragmentState(lw);
-      logTinyState(lw);
-      logHugeState(lw);
+      logOffHeapState(lw, chunkSize);
     }
   }
 
+  void logOffHeapState(LogWriter lw, int chunkSize) {
+    OffHeapMemoryStats stats = this.ma.getStats();
+    lw.info("OutOfOffHeapMemory allocating size of " + chunkSize + ". allocated=" + this.allocatedSize.get() + " compactions=" + this.compactCount.get() + " objects=" + stats.getObjects() + " free=" + stats.getFreeMemory() + " fragments=" + stats.getFragments() + " largestFragment=" + stats.getLargestFragment() + " fragmentation=" + stats.getFragmentation());
+    logFragmentState(lw);
+    logTinyState(lw);
+    logHugeState(lw);
+  }
+
   private void logHugeState(LogWriter lw) {
-    for (Chunk c: this.hugeChunkSet) {
+    for (ObjectChunk c: this.hugeChunkSet) {
       lw.info("Free huge of size " + c.getSize());
     }
   }
@@ -256,7 +268,39 @@ public class FreeListManager {
     }
   }
 
-  private final AtomicInteger compactCount = new AtomicInteger();
+  protected final AtomicInteger compactCount = new AtomicInteger();
+  /*
+   * Set this to "true" to perform data integrity checks on allocated and reused Chunks.  This may clobber 
+   * performance so turn on only when necessary.
+   */
+  final boolean validateMemoryWithFill = Boolean.getBoolean("gemfire.validateOffHeapWithFill");
+  /**
+   * Every allocated chunk smaller than TINY_MULTIPLE*TINY_FREE_LIST_COUNT will allocate a chunk of memory that is a multiple of this value.
+   * Sizes are always rounded up to the next multiple of this constant
+   * so internal fragmentation will be limited to TINY_MULTIPLE-1 bytes per allocation
+   * and on average will be TINY_MULTIPLE/2 given a random distribution of size requests.
+   * This does not account for the additional internal fragmentation caused by the off-heap header
+   * which currently is always 8 bytes.
+   */
+  public final static int TINY_MULTIPLE = Integer.getInteger("gemfire.OFF_HEAP_ALIGNMENT", 8);
+  static {
+    verifyOffHeapAlignment(TINY_MULTIPLE);
+  }
+  /**
+   * Number of free lists to keep for tiny allocations.
+   */
+  public final static int TINY_FREE_LIST_COUNT = Integer.getInteger("gemfire.OFF_HEAP_FREE_LIST_COUNT", 16384);
+  static {
+    verifyOffHeapFreeListCount(TINY_FREE_LIST_COUNT);
+  }
+  /**
+   * How many unused bytes are allowed in a huge memory allocation.
+   */
+  public final static int HUGE_MULTIPLE = 256;
+  static {
+    verifyHugeMultiple(HUGE_MULTIPLE);
+  }
+  public final static int MAX_TINY = TINY_MULTIPLE*TINY_FREE_LIST_COUNT;
   /**
    * Compacts memory and returns true if enough memory to allocate chunkSize
    * is freed. Otherwise returns false;
@@ -268,9 +312,10 @@ public class FreeListManager {
    * Or to prevent it from happening we could just check the incoming slabs and throw away a few bytes
    * to keep them from being contiguous.
    */
-  private boolean compact(int chunkSize) {
+  boolean compact(int chunkSize) {
     final long startCompactionTime = this.ma.getStats().startCompaction();
     final int countPreSync = this.compactCount.get();
+    afterCompactCountFetched();
     try {
       synchronized (this) {
         if (this.compactCount.get() != countPreSync) {
@@ -289,10 +334,6 @@ public class FreeListManager {
           long addr = l.poll();
           while (addr != 0) {
             int idx = Arrays.binarySearch(sorted, 0, sortedSize, addr);
-            //System.out.println("DEBUG addr=" + addr + " size=" + Chunk.getSize(addr) + " idx="+idx + " sortedSize=" + sortedSize);
-            if (idx >= 0) {
-              throw new IllegalStateException("duplicate memory address found during compaction!");
-            }
             idx = -idx;
             idx--;
             if (idx == sortedSize) {
@@ -304,10 +345,10 @@ public class FreeListManager {
               } else {
                 // see if we can conflate into sorted[idx]
                 long lowAddr = sorted[idx-1];
-                int lowSize = Chunk.getSize(lowAddr);
+                int lowSize = ObjectChunk.getSize(lowAddr);
                 if (lowAddr + lowSize == addr) {
                   // append the addr chunk to lowAddr
-                  Chunk.setSize(lowAddr, lowSize + Chunk.getSize(addr));
+                  ObjectChunk.setSize(lowAddr, lowSize + ObjectChunk.getSize(addr));
                 } else {
                   if (sortedSize >= sorted.length) {
                     long[] newSorted = new long[sorted.length+SORT_ARRAY_BLOCK_SIZE];
@@ -319,11 +360,11 @@ public class FreeListManager {
                 }
               }
             } else {
-              int addrSize = Chunk.getSize(addr);
+              int addrSize = ObjectChunk.getSize(addr);
               long highAddr = sorted[idx];
               if (addr + addrSize == highAddr) {
                 // append highAddr chunk to addr
-                Chunk.setSize(addr, addrSize + Chunk.getSize(highAddr));
+                ObjectChunk.setSize(addr, addrSize + ObjectChunk.getSize(highAddr));
                 sorted[idx] = addr;
               } else {
                 boolean insert = idx==0;
@@ -333,10 +374,10 @@ public class FreeListManager {
                   //                    long[] tmp = Arrays.copyOf(sorted, sortedSize);
                   //                    throw new IllegalStateException("addr was zero at idx=" + (idx-1) + " sorted="+ Arrays.toString(tmp));
                   //                  }
-                  int lowSize = Chunk.getSize(lowAddr);
+                  int lowSize = ObjectChunk.getSize(lowAddr);
                   if (lowAddr + lowSize == addr) {
                     // append the addr chunk to lowAddr
-                    Chunk.setSize(lowAddr, lowSize + addrSize);
+                    ObjectChunk.setSize(lowAddr, lowSize + addrSize);
                   } else {
                     insert = true;
                   }
@@ -362,10 +403,10 @@ public class FreeListManager {
         for (int i=sortedSize-1; i > 0; i--) {
           long addr = sorted[i];
           long lowAddr = sorted[i-1];
-          int lowSize = Chunk.getSize(lowAddr);
+          int lowSize = ObjectChunk.getSize(lowAddr);
           if (lowAddr + lowSize == addr) {
             // append addr chunk to lowAddr
-            Chunk.setSize(lowAddr, lowSize + Chunk.getSize(addr));
+            ObjectChunk.setSize(lowAddr, lowSize + ObjectChunk.getSize(addr));
             sorted[i] = 0L;
           }
         }
@@ -374,8 +415,8 @@ public class FreeListManager {
         for (int i=sortedSize-1; i >= 0; i--) {
           long addr = sorted[i];
           if (addr == 0L) continue;
-          int addrSize = Chunk.getSize(addr);
-          Fragment f = new Fragment(addr, addrSize);
+          int addrSize = ObjectChunk.getSize(addr);
+          Fragment f = createFragment(addr, addrSize);
           if (addrSize >= chunkSize) {
             result = true;
           }
@@ -389,17 +430,14 @@ public class FreeListManager {
         }
         this.fragmentList.addAll(tmp);
 
-        // Reinitialize fragments with fill pattern data
-        if(this.ma.validateMemoryWithFill) {
-          fillFragments();
-        }
+        fillFragments();
 
         // Signal any waiters that a compaction happened.
         this.compactCount.incrementAndGet();
 
         this.ma.getStats().setLargestFragment(largestFragment);
         this.ma.getStats().setFragments(tmp.size());        
-        updateFragmentation();
+        updateFragmentation(largestFragment);
 
         return result;
       } // sync
@@ -408,12 +446,38 @@ public class FreeListManager {
     }
   }
 
-  private void updateFragmentation() {      
-    long freeSize = this.ma.getStats().getFreeMemory();
+  /**
+   * Unit tests override this method to get better test coverage
+   */
+  protected void afterCompactCountFetched() {
+  }
+  
+  static void verifyOffHeapAlignment(int tinyMultiple) {
+    if (tinyMultiple <= 0 || (tinyMultiple & 3) != 0) {
+      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8.");
+    }
+    if (tinyMultiple > 256) {
+      // this restriction exists because of the dataSize field in the object header.
+      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be <= 256 and a multiple of 8.");
+    }
+  }
+  static void verifyOffHeapFreeListCount(int tinyFreeListCount) {
+    if (tinyFreeListCount <= 0) {
+      throw new IllegalStateException("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
+    }
+  }
+  static void verifyHugeMultiple(int hugeMultiple) {
+    if (hugeMultiple > 256 || hugeMultiple < 0) {
+      // this restriction exists because of the dataSize field in the object header.
+      throw new IllegalStateException("HUGE_MULTIPLE must be >= 0 and <= 256 but it was " + hugeMultiple);
+    }
+  }
+  
+  private void updateFragmentation(long largestFragment) {      
+    long freeSize = getFreeMemory();
 
     // Calculate free space fragmentation only if there is free space available.
     if(freeSize > 0) {
-      long largestFragment = this.ma.getStats().getLargestFragment();
       long numerator = freeSize - largestFragment;
 
       double percentage = (double) numerator / (double) freeSize;
@@ -432,6 +496,9 @@ public class FreeListManager {
     collectFreeHugeChunks(l);
     collectFreeTinyChunks(l);
   }
+  List<Fragment> getFragmentList() {
+    return this.fragmentList;
+  }
   private void collectFreeFragmentChunks(List<SyncChunkStack> l) {
     if (this.fragmentList.size() == 0) return;
     SyncChunkStack result = new SyncChunkStack();
@@ -441,20 +508,17 @@ public class FreeListManager {
       do {
         offset = f.getFreeIndex();
         diff = f.getSize() - offset;
-      } while (diff >= Chunk.MIN_CHUNK_SIZE && !f.allocate(offset, offset+diff));
-      if (diff < Chunk.MIN_CHUNK_SIZE) {
-        if (diff > 0) {
-          SimpleMemoryAllocatorImpl.logger.debug("Lost memory of size {}", diff);
-        }
-        // fragment is too small to turn into a chunk
-        // TODO we need to make sure this never happens
-        // by keeping sizes rounded. I think I did this
-        // by introducing MIN_CHUNK_SIZE and by rounding
-        // the size of huge allocations.
+      } while (diff >= ObjectChunk.MIN_CHUNK_SIZE && !f.allocate(offset, offset+diff));
+      if (diff < ObjectChunk.MIN_CHUNK_SIZE) {
+        // If diff > 0 then that memory will be lost during compaction.
+        // This should never happen since we keep the sizes rounded
+        // based on MIN_CHUNK_SIZE.
+        assert diff == 0;
+        // The current fragment is completely allocated so just skip it.
         continue;
       }
       long chunkAddr = f.getMemoryAddress()+offset;
-      Chunk.setSize(chunkAddr, diff);
+      ObjectChunk.setSize(chunkAddr, diff);
       result.offer(chunkAddr);
     }
     // All the fragments have been turned in to chunks so now clear them
@@ -476,7 +540,7 @@ public class FreeListManager {
     }
   }
   private void collectFreeHugeChunks(List<SyncChunkStack> l) {
-    Chunk c = this.hugeChunkSet.pollFirst();
+    ObjectChunk c = this.hugeChunkSet.pollFirst();
     SyncChunkStack result = null;
     while (c != null) {
       if (result == null) {
@@ -488,7 +552,7 @@ public class FreeListManager {
     }
   }
 
-  private Chunk allocateFromFragment(final int fragIdx, final int chunkSize, ChunkType chunkType) {
+  ObjectChunk allocateFromFragment(final int fragIdx, final int chunkSize) {
     if (fragIdx >= this.fragmentList.size()) return null;
     final Fragment fragment;
     try {
@@ -505,14 +569,9 @@ public class FreeListManager {
       int fragmentFreeSize = fragmentSize - oldOffset;
       if (fragmentFreeSize >= chunkSize) {
         // this fragment has room
-        // Try to allocate up to BATCH_SIZE more chunks from it
-        int allocSize = chunkSize * SimpleMemoryAllocatorImpl.BATCH_SIZE;
-        if (allocSize > fragmentFreeSize) {
-          allocSize = (fragmentFreeSize / chunkSize) * chunkSize;
-        }
-        int newOffset = oldOffset + allocSize;
+        int newOffset = oldOffset + chunkSize;
         int extraSize = fragmentSize - newOffset;
-        if (extraSize < Chunk.MIN_CHUNK_SIZE) {
+        if (extraSize < ObjectChunk.MIN_CHUNK_SIZE) {
           // include these last few bytes of the fragment in the allocation.
           // If we don't then they will be lost forever.
           // The extraSize bytes only apply to the first chunk we allocate (not the batch ones).
@@ -523,28 +582,11 @@ public class FreeListManager {
         if (fragment.allocate(oldOffset, newOffset)) {
           // We did the allocate!
           this.lastFragmentAllocation.set(fragIdx);
-          Chunk result = this.ma.chunkFactory.newChunk(fragment.getMemoryAddress()+oldOffset, chunkSize+extraSize, chunkType);
-          allocSize -= chunkSize+extraSize;
-          oldOffset += extraSize;
-          while (allocSize > 0) {
-            oldOffset += chunkSize;
-            // we add the batch ones immediately to the freelist
-            result.readyForFree();
-            free(result.getMemoryAddress(), false);
-            result = this.ma.chunkFactory.newChunk(fragment.getMemoryAddress()+oldOffset, chunkSize, chunkType);
-            allocSize -= chunkSize;
-          }
-
-          if(this.ma.validateMemoryWithFill) {
-            result.validateFill();
-          }
-
+          ObjectChunk result = new ObjectChunk(fragment.getMemoryAddress()+oldOffset, chunkSize+extraSize);
+          checkDataIntegrity(result);
           return result;
         } else {
-          // TODO OFFHEAP: if batch allocations are disabled should we not call basicAllocate here?
-          // Since we know another thread did a concurrent alloc
-          // that possibly did a batch check the free list again.
-          Chunk result = basicAllocate(chunkSize, false, chunkType);
+          ObjectChunk result = basicAllocate(chunkSize, false);
           if (result != null) {
             return result;
           }
@@ -558,50 +600,36 @@ public class FreeListManager {
   private int round(int multiple, int value) {
     return (int) ((((long)value + (multiple-1)) / multiple) * multiple);
   }
-  private Chunk allocateTiny(int size, boolean useFragments, ChunkType chunkType) {
-    return basicAllocate(getNearestTinyMultiple(size), SimpleMemoryAllocatorImpl.TINY_MULTIPLE, 0, this.tinyFreeLists, useFragments, chunkType);
+  private ObjectChunk allocateTiny(int size, boolean useFragments) {
+    return basicAllocate(getNearestTinyMultiple(size), TINY_MULTIPLE, 0, this.tinyFreeLists, useFragments);
   }
-  private Chunk basicAllocate(int idx, int multiple, int offset, AtomicReferenceArray<SyncChunkStack> freeLists, boolean useFragments, ChunkType chunkType) {
+  private ObjectChunk basicAllocate(int idx, int multiple, int offset, AtomicReferenceArray<SyncChunkStack> freeLists, boolean useFragments) {
     SyncChunkStack clq = freeLists.get(idx);
     if (clq != null) {
       long memAddr = clq.poll();
       if (memAddr != 0) {
-        Chunk result = this.ma.chunkFactory.newChunk(memAddr, chunkType);
-
-        // Data integrity check.
-        if(this.ma.validateMemoryWithFill) {          
-          result.validateFill();
-        }
-
-        result.readyForAllocation(chunkType);
+        ObjectChunk result = new ObjectChunk(memAddr);
+        checkDataIntegrity(result);
+        result.readyForAllocation();
         return result;
       }
     }
     if (useFragments) {
-      return allocateFromFragments(((idx+1)*multiple)+offset, chunkType);
+      return allocateFromFragments(((idx+1)*multiple)+offset);
     } else {
       return null;
     }
   }
-  private Chunk allocateHuge(int size, boolean useFragments, ChunkType chunkType) {
+  private ObjectChunk allocateHuge(int size, boolean useFragments) {
     // sizeHolder is a fake Chunk used to search our sorted hugeChunkSet.
-    Chunk sizeHolder = new FakeChunk(size);
-    NavigableSet<Chunk> ts = this.hugeChunkSet.tailSet(sizeHolder);
-    Chunk result = ts.pollFirst();
+    ObjectChunk sizeHolder = new FakeChunk(size);
+    NavigableSet<ObjectChunk> ts = this.hugeChunkSet.tailSet(sizeHolder);
+    ObjectChunk result = ts.pollFirst();
     if (result != null) {
-      if (result.getSize() - (SimpleMemoryAllocatorImpl.HUGE_MULTIPLE - Chunk.OFF_HEAP_HEADER_SIZE) < size) {
+      if (result.getSize() - (HUGE_MULTIPLE - ObjectChunk.OFF_HEAP_HEADER_SIZE) < size) {
         // close enough to the requested size; just return it.
-
-        // Data integrity check.
-        if(this.ma.validateMemoryWithFill) {          
-          result.validateFill();
-        }
-        if (chunkType.getSrcType() != Chunk.getSrcType(result.getMemoryAddress())) {
-          // The java wrapper class that was cached in the huge chunk list is the wrong type.
-          // So allocate a new one and garbage collect the old one.
-          result = this.ma.chunkFactory.newChunk(result.getMemoryAddress(), chunkType);
-        }
-        result.readyForAllocation(chunkType);
+        checkDataIntegrity(result);
+        result.readyForAllocation();
         return result;
       } else {
         this.hugeChunkSet.add(result);
@@ -610,18 +638,23 @@ public class FreeListManager {
     if (useFragments) {
       // We round it up to the next multiple of TINY_MULTIPLE to make
       // sure we always have chunks allocated on an 8 byte boundary.
-      return allocateFromFragments(round(SimpleMemoryAllocatorImpl.TINY_MULTIPLE, size), chunkType);
+      return allocateFromFragments(round(TINY_MULTIPLE, size));
     } else {
       return null;
     }
   }
   
+  private void checkDataIntegrity(ObjectChunk data) {
+    if (this.validateMemoryWithFill) {
+      data.validateFill();
+    }
+  }
   /**
    * Used by the FreeListManager to easily search its
    * ConcurrentSkipListSet. This is not a real chunk
    * but only used for searching.
    */
-  private static class FakeChunk extends Chunk {
+  private static class FakeChunk extends ObjectChunk {
     private final int size;
     public FakeChunk(int size) {
       super();
@@ -635,19 +668,24 @@ public class FreeListManager {
 
   @SuppressWarnings("synthetic-access")
   public void free(long addr) {
+    if (this.validateMemoryWithFill) {
+      ObjectChunk.fill(addr);
+    }
+    
     free(addr, true);
   }
 
   private void free(long addr, boolean updateStats) {
-    int cSize = Chunk.getSize(addr);
+    int cSize = ObjectChunk.getSize(addr);
     if (updateStats) {
-      this.ma.stats.incObjects(-1);
+      OffHeapMemoryStats stats = this.ma.getStats();
+      stats.incObjects(-1);
       this.allocatedSize.addAndGet(-cSize);
-      this.ma.stats.incUsedMemory(-cSize);
-      this.ma.stats.incFreeMemory(cSize);
+      stats.incUsedMemory(-cSize);
+      stats.incFreeMemory(cSize);
       this.ma.notifyListeners();
     }
-    if (cSize <= SimpleMemoryAllocatorImpl.MAX_TINY) {
+    if (cSize <= MAX_TINY) {
       freeTiny(addr, cSize);
     } else {
       freeHuge(addr, cSize);
@@ -661,17 +699,23 @@ public class FreeListManager {
     if (clq != null) {
       clq.offer(addr);
     } else {
-      clq = new SyncChunkStack();
+      clq = createFreeListForEmptySlot(freeLists, idx);
       clq.offer(addr);
       if (!freeLists.compareAndSet(idx, null, clq)) {
         clq = freeLists.get(idx);
         clq.offer(addr);
       }
     }
-
   }
+  /**
+   * Tests override this method to simulate concurrent modification
+   */
+  protected SyncChunkStack createFreeListForEmptySlot(AtomicReferenceArray<SyncChunkStack> freeLists, int idx) {
+    return new SyncChunkStack();
+  }
+  
   private void freeHuge(long addr, int cSize) {
-    this.hugeChunkSet.add(this.ma.chunkFactory.newChunk(addr)); // TODO make this a collection of longs
+    this.hugeChunkSet.add(new ObjectChunk(addr)); // TODO make this a collection of longs
   }
 
   List<MemoryBlock> getOrderedBlocks() {
@@ -695,8 +739,8 @@ public class FreeListManager {
     }
   }
   
-  private void addBlocksFromChunks(Collection<Chunk> src, List<MemoryBlock> dest) {
-    for (Chunk chunk : src) {
+  private void addBlocksFromChunks(Collection<ObjectChunk> src, List<MemoryBlock> dest) {
+    for (ObjectChunk chunk : src) {
       dest.add(new MemoryBlockNode(this.ma, chunk));
     }
   }
@@ -715,7 +759,7 @@ public class FreeListManager {
       long addr = this.tinyFreeLists.get(i).getTopAddress();
       while (addr != 0L) {
         value.add(new MemoryBlockNode(sma, new TinyMemoryBlock(addr, i)));
-        addr = Chunk.getNext(addr);
+        addr = ObjectChunk.getNext(addr);
       }
     }
     return value;
@@ -756,7 +800,7 @@ public class FreeListManager {
 
     @Override
     public int getBlockSize() {
-      return Chunk.getSize(address);
+      return ObjectChunk.getSize(address);
     }
 
     @Override
@@ -800,11 +844,6 @@ public class FreeListManager {
     }
 
     @Override
-    public ChunkType getChunkType() {
-      return null;
-    }
-    
-    @Override
     public boolean equals(Object o) {
       if (o instanceof TinyMemoryBlock) {
         return getMemoryAddress() == ((TinyMemoryBlock) o).getMemoryAddress();
@@ -818,4 +857,64 @@ public class FreeListManager {
       return (int)(value ^ (value >>> 32));
     }
   }
+
+  long getTotalMemory() {
+    return this.totalSlabSize;
+  }
+  
+  void freeSlabs() {
+    for (int i=0; i < slabs.length; i++) {
+      slabs[i].release();
+    }
+  }
+  /**
+   * newSlabs will be non-null in unit tests.
+   * If the unit test gave us a different array
+   * of slabs then something is wrong because we
+   * are trying to reuse the old already allocated
+   * array which means that the new one will never
+   * be used. Note that this code does not bother
+   * comparing the contents of the arrays.
+   */
+  boolean okToReuse(AddressableMemoryChunk[] newSlabs) {
+    return newSlabs == null || newSlabs == this.slabs;
+  }
+  
+  int getLargestSlabSize() {
+    return this.slabs[0].getSize();
+  }
+  int findSlab(long addr) {
+    for (int i=0; i < this.slabs.length; i++) {
+      AddressableMemoryChunk slab = this.slabs[i];
+      long slabAddr = slab.getMemoryAddress();
+      if (addr >= slabAddr) {
+        if (addr < slabAddr + slab.getSize()) {
+          return i;
+        }
+      }
+    }
+    throw new IllegalStateException("could not find a slab for addr " + addr);
+  }
+  void getSlabDescriptions(StringBuilder sb) {
+    for (int i=0; i < slabs.length; i++) {
+      long startAddr = slabs[i].getMemoryAddress();
+      long endAddr = startAddr + slabs[i].getSize();
+      sb.append("[").append(Long.toString(startAddr, 16)).append("..").append(Long.toString(endAddr, 16)).append("] ");
+    }
+  }
+  boolean validateAddressAndSizeWithinSlab(long addr, int size) {
+    for (int i=0; i < slabs.length; i++) {
+      if (slabs[i].getMemoryAddress() <= addr && addr < (slabs[i].getMemoryAddress() + slabs[i].getSize())) {
+        // validate addr + size is within the same slab
+        if (size != -1) { // skip this check if size is -1
+          if (!(slabs[i].getMemoryAddress() <= (addr+size-1) && (addr+size-1) < (slabs[i].getMemoryAddress() + slabs[i].getSize()))) {
+            throw new IllegalStateException(" address 0x" + Long.toString(addr+size-1, 16) + " does not address the original slab memory");
+          }
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+  
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunk.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunk.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunk.java
deleted file mode 100644
index 20e4a2f..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunk.java
+++ /dev/null
@@ -1,47 +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 com.gemstone.gemfire.internal.offheap;
-
-
-/**
- * A chunk that stores a GemFire object.
- * Currently the object stored in this chunk
- * is always an entry value of a Region.
- */
-public class GemFireChunk extends Chunk {
-  public static final ChunkType TYPE = new ChunkType() {
-    @Override
-    public int getSrcType() {
-      return Chunk.SRC_TYPE_GFE;
-    }
-  };
-  public GemFireChunk(long memoryAddress, int chunkSize) {
-    super(memoryAddress, chunkSize, TYPE);
-  }
-
-  public GemFireChunk(long memoryAddress) {
-    super(memoryAddress);
-    // chunkType may be set by caller when it calls readyForAllocation
-  }
-  public GemFireChunk(GemFireChunk chunk) {
-    super(chunk);
-  }
-  @Override
-  public Chunk slice(int position, int limit) {
-    return new GemFireChunkSlice(this, position, limit);
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactory.java
deleted file mode 100644
index c3f3bcc..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactory.java
+++ /dev/null
@@ -1,52 +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 com.gemstone.gemfire.internal.offheap;
-
-
-/**
- * A ChunkFactory that produces chunks of type GemFireChunk.
- */
-public class GemFireChunkFactory implements ChunkFactory {
-  @Override
-  public Chunk newChunk(long address, int chunkSize, ChunkType chunkType) {
-    assert chunkType.equals(GemFireChunk.TYPE);
-    return new GemFireChunk(address,chunkSize);
-  }
-
-  @Override
-  public Chunk newChunk(long address) {
-    return new GemFireChunk(address);
-  }
-
-  @Override
-  public Chunk newChunk(long address, ChunkType chunkType) {
-    assert chunkType.equals(GemFireChunk.TYPE);
-    return new GemFireChunk(address);
-  }
-
-  @Override
-  public ChunkType getChunkTypeForAddress(long address) {
-    assert Chunk.getSrcType(address) == Chunk.SRC_TYPE_GFE;
-    return GemFireChunk.TYPE;
-  }
-
-  @Override
-  public ChunkType getChunkTypeForRawBits(int bits) {
-    assert Chunk.getSrcTypeFromRawBits(bits) == Chunk.SRC_TYPE_GFE;
-    return GemFireChunk.TYPE;
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSlice.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSlice.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSlice.java
deleted file mode 100644
index 0c27aa3..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSlice.java
+++ /dev/null
@@ -1,44 +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 com.gemstone.gemfire.internal.offheap;
-
-/**
- * Represents a slice of a GemFireChunk.
- * A slice is a subsequence of the bytes stored in a GemFireChunk.
- */
-public class GemFireChunkSlice extends GemFireChunk {
-  private final int offset;
-  private final int capacity;
-  public GemFireChunkSlice(GemFireChunk gemFireChunk, int position, int limit) {
-    super(gemFireChunk);
-    this.offset = gemFireChunk.getBaseDataOffset() + position;
-    this.capacity = limit - position;
-  }
-  @Override
-  public int getDataSize() {
-    return this.capacity;
-  }
-  
-  @Override
-  protected long getBaseDataAddress() {
-    return super.getBaseDataAddress() + this.offset;
-  }
-  @Override
-  protected int getBaseDataOffset() {
-    return this.offset;
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
index 0a014de..0c063ac 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
@@ -26,11 +26,10 @@ package com.gemstone.gemfire.internal.offheap;
 public interface MemoryAllocator {
   /**
    * @param size the size in bytes of the chunk of memory to allocate
-   * @param chunkType TODO
    * @return the allocated chunk of memory.
    * @throws IllegalStateException if the heap does not have enough memory to grant the request
    */
-  public MemoryChunk allocate(int size, ChunkType chunkType);
+  public MemoryChunk allocate(int size);
   
   /**
    * Allocates off heap memory for the given data and returns a MemoryChunk
@@ -38,10 +37,9 @@ public interface MemoryAllocator {
    * @param data the bytes of the data to put in the allocated CachedDeserializable
    * @param isSerialized true if data contains a serialized object; false if it is an actual byte array.
    * @param isCompressed true if data is compressed; false if it is uncompressed.
-   * @param chunkType TODO
    * @throws IllegalStateException if the heap does not have enough memory to grant the request
    */
-  public StoredObject allocateAndInitialize(byte[] data, boolean isSerialized, boolean isCompressed, ChunkType chunkType);
+  public StoredObject allocateAndInitialize(byte[] data, boolean isSerialized, boolean isCompressed);
   
   public long getFreeMemory();
   

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
index 3ad9283..d8cb80a 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
@@ -64,7 +64,6 @@ public interface MemoryBlock {
   
   public int getRefCount();
   public String getDataType();
-  public ChunkType getChunkType();
   public boolean isSerialized();
   public boolean isCompressed();
   public Object getDataValue();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
index 5c6182a..b41d429 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
@@ -65,15 +65,15 @@ public class MemoryBlockNode implements MemoryBlock {
     if (!isSerialized()) {
       // byte array
       if (isCompressed()) {
-        return "compressed byte[" + ((Chunk)this.block).getDataSize() + "]";
+        return "compressed byte[" + ((ObjectChunk)this.block).getDataSize() + "]";
       } else {
-        return "byte[" + ((Chunk)this.block).getDataSize() + "]";
+        return "byte[" + ((ObjectChunk)this.block).getDataSize() + "]";
       }
     } else if (isCompressed()) {
-      return "compressed object of size " + ((Chunk)this.block).getDataSize();
+      return "compressed object of size " + ((ObjectChunk)this.block).getDataSize();
     }
     //Object obj = EntryEventImpl.deserialize(((Chunk)this.block).getRawBytes());
-    byte[] bytes = ((Chunk)this.block).getRawBytes();
+    byte[] bytes = ((ObjectChunk)this.block).getRawBytes();
     return DataType.getDataType(bytes);
   }
   public boolean isSerialized() {
@@ -88,14 +88,14 @@ public class MemoryBlockNode implements MemoryBlock {
     if (dataType == null || dataType.equals("N/A")) {
       return null;
     } else if (isCompressed()) {
-      return ((Chunk)this.block).getCompressedBytes();
+      return ((ObjectChunk)this.block).getCompressedBytes();
     } else if (!isSerialized()) {
       // byte array
       //return "byte[" + ((Chunk)this.block).getDataSize() + "]";
-      return ((Chunk)this.block).getRawBytes();
+      return ((ObjectChunk)this.block).getRawBytes();
     } else {
       try {
-        byte[] bytes = ((Chunk)this.block).getRawBytes();
+        byte[] bytes = ((ObjectChunk)this.block).getRawBytes();
         return DataSerializer.readObject(DataType.getDataInput(bytes));
       } catch (IOException e) {
         e.printStackTrace();
@@ -126,10 +126,6 @@ public class MemoryBlockNode implements MemoryBlock {
       sb.append(getFreeListId());
     }
     sb.append(", RefCount=").append(getRefCount());
-    ChunkType ct = this.getChunkType();
-    if (ct != null) {
-      sb.append(", " + ct);
-    }
     sb.append(", isSerialized=").append(isSerialized());
     sb.append(", isCompressed=").append(isCompressed());
     sb.append(", DataType=").append(getDataType());
@@ -150,10 +146,6 @@ public class MemoryBlockNode implements MemoryBlock {
     sb.append("}");
     return sb.toString();
   }
-  @Override
-  public ChunkType getChunkType() {
-    return this.block.getChunkType();
-  }
   
   @Override
   public boolean equals(Object o) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
new file mode 100644
index 0000000..29e6956
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
@@ -0,0 +1,737 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.DSCODE;
+import com.gemstone.gemfire.internal.HeapDataOutputStream;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.RegionEntry;
+import com.gemstone.gemfire.internal.cache.RegionEntryContext;
+import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+
+/**
+   * A chunk that stores a Java object.
+   * Currently the object stored in this chunk
+   * is always an entry value of a Region.
+   * Note: this class has a natural ordering that is inconsistent with equals.
+   * Instances of this class should have a short lifetime. We do not store references
+   * to it in the cache. Instead the memoryAddress is stored in a primitive field in
+   * the cache and if used it will then, if needed, create an instance of this class.
+   */
+  public class ObjectChunk extends OffHeapCachedDeserializable implements Comparable<ObjectChunk>, MemoryBlock {
+    /**
+     * The unsafe memory address of the first byte of this chunk
+     */
+    private final long memoryAddress;
+    
+    /**
+     * The useCount, chunkSize, dataSizeDelta, isSerialized, and isCompressed
+     * are all stored in off heap memory in a HEADER. This saves heap memory
+     * by using off heap.
+     */
+    public final static int OFF_HEAP_HEADER_SIZE = 4 + 4;
+    /**
+     * We need to smallest chunk to at least have enough room for a hdr
+     * and for an off heap ref (which is a long).
+     */
+    public final static int MIN_CHUNK_SIZE = OFF_HEAP_HEADER_SIZE + 8;
+    /**
+     * int field.
+     * The number of bytes in this chunk.
+     */
+    private final static int CHUNK_SIZE_OFFSET = 0;
+    /**
+     * Volatile int field
+     * The upper two bits are used for the isSerialized
+     * and isCompressed flags.
+     * The next three bits are unused.
+     * The lower 3 bits of the most significant byte contains a magic number to help us detect
+     * if we are changing the ref count of an object that has been released.
+     * The next byte contains the dataSizeDelta.
+     * The number of bytes of logical data in this chunk.
+     * Since the number of bytes of logical data is always <= chunkSize
+     * and since chunkSize never changes, we have dataSize be
+     * a delta whose max value would be HUGE_MULTIPLE-1.
+     * The lower two bytes contains the use count.
+     */
+    final static int REF_COUNT_OFFSET = 4;
+    /**
+     * The upper two bits are used for the isSerialized
+     * and isCompressed flags.
+     */
+    final static int IS_SERIALIZED_BIT =    0x80000000;
+    final static int IS_COMPRESSED_BIT =    0x40000000;
+    // UNUSED 0x38000000
+    final static int MAGIC_MASK = 0x07000000;
+    final static int MAGIC_NUMBER = 0x05000000;
+    final static int DATA_SIZE_DELTA_MASK = 0x00ff0000;
+    final static int DATA_SIZE_SHIFT = 16;
+    final static int REF_COUNT_MASK =       0x0000ffff;
+    final static int MAX_REF_COUNT = 0xFFFF;
+    final static long FILL_PATTERN = 0x3c3c3c3c3c3c3c3cL;
+    final static byte FILL_BYTE = 0x3c;
+    
+    protected ObjectChunk(long memoryAddress, int chunkSize) {
+      SimpleMemoryAllocatorImpl.validateAddressAndSize(memoryAddress, chunkSize);
+      this.memoryAddress = memoryAddress;
+      setSize(chunkSize);
+      UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, MAGIC_NUMBER);
+    }
+    public void readyForFree() {
+      UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0);
+    }
+    public void readyForAllocation() {
+      if (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0, MAGIC_NUMBER)) {
+        throw new IllegalStateException("Expected 0 but found " + Integer.toHexString(UnsafeMemoryChunk.readAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET)));
+      }
+    }
+    /**
+     * Should only be used by FakeChunk subclass
+     */
+    protected ObjectChunk() {
+      this.memoryAddress = 0L;
+    }
+    
+    /**
+     * Used to create a Chunk given an existing, already allocated,
+     * memoryAddress. The off heap header has already been initialized.
+     */
+    protected ObjectChunk(long memoryAddress) {
+      SimpleMemoryAllocatorImpl.validateAddress(memoryAddress);
+      this.memoryAddress = memoryAddress;
+    }
+    
+    protected ObjectChunk(ObjectChunk chunk) {
+      this.memoryAddress = chunk.memoryAddress;
+    }
+    
+    /**
+     * Throw an exception if this chunk is not allocated
+     */
+    public void checkIsAllocated() {
+      int originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
+      if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
+        throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
+      }
+    }
+    
+    public void incSize(int inc) {
+      setSize(getSize()+inc);
+    }
+    
+    protected void beforeReturningToAllocator() {
+      
+    }
+
+    @Override
+    public int getSize() {
+      return getSize(this.memoryAddress);
+    }
+
+    public void setSize(int size) {
+      setSize(this.memoryAddress, size);
+    }
+
+    public long getMemoryAddress() {
+      return this.memoryAddress;
+    }
+    
+    public int getDataSize() {
+      /*int dataSizeDelta = UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET);
+      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
+      dataSizeDelta >>= DATA_SIZE_SHIFT;
+      return getSize() - dataSizeDelta;*/
+      return getDataSize(this.memoryAddress);
+    }
+    
+    protected static int getDataSize(long memoryAdress) {
+      int dataSizeDelta = UnsafeMemoryChunk.readAbsoluteInt(memoryAdress+REF_COUNT_OFFSET);
+      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
+      dataSizeDelta >>= DATA_SIZE_SHIFT;
+      return getSize(memoryAdress) - dataSizeDelta;
+    }
+    
+    protected long getBaseDataAddress() {
+      return this.memoryAddress+OFF_HEAP_HEADER_SIZE;
+    }
+    protected int getBaseDataOffset() {
+      return 0;
+    }
+    
+    /**
+     * Creates and returns a direct ByteBuffer that contains the contents of this Chunk.
+     * Note that the returned ByteBuffer has a reference to this chunk's
+     * off-heap address so it can only be used while this Chunk is retained.
+     * @return the created direct byte buffer or null if it could not be created.
+     */
+    @Unretained
+    public ByteBuffer createDirectByteBuffer() {
+      return basicCreateDirectByteBuffer(getBaseDataAddress(), getDataSize());
+    }
+    @Override
+    public void sendTo(DataOutput out) throws IOException {
+      if (!this.isCompressed() && out instanceof HeapDataOutputStream) {
+        ByteBuffer bb = createDirectByteBuffer();
+        if (bb != null) {
+          HeapDataOutputStream hdos = (HeapDataOutputStream) out;
+          if (this.isSerialized()) {
+            hdos.write(bb);
+          } else {
+            hdos.writeByte(DSCODE.BYTE_ARRAY);
+            InternalDataSerializer.writeArrayLength(bb.remaining(), hdos);
+            hdos.write(bb);
+          }
+          return;
+        }
+      }
+      super.sendTo(out);
+    }
+    
+    @Override
+    public void sendAsByteArray(DataOutput out) throws IOException {
+      if (!isCompressed() && out instanceof HeapDataOutputStream) {
+        ByteBuffer bb = createDirectByteBuffer();
+        if (bb != null) {
+          HeapDataOutputStream hdos = (HeapDataOutputStream) out;
+          InternalDataSerializer.writeArrayLength(bb.remaining(), hdos);
+          hdos.write(bb);
+          return;
+        }
+      }
+      super.sendAsByteArray(out);
+    }
+       
+    private static volatile Class dbbClass = null;
+    private static volatile Constructor dbbCtor = null;
+    private static volatile boolean dbbCreateFailed = false;
+    
+    /**
+     * @return the created direct byte buffer or null if it could not be created.
+     */
+    private static ByteBuffer basicCreateDirectByteBuffer(long baseDataAddress, int dataSize) {
+      if (dbbCreateFailed) {
+        return null;
+      }
+      Constructor ctor = dbbCtor;
+      if (ctor == null) {
+        Class c = dbbClass;
+        if (c == null) {
+          try {
+            c = Class.forName("java.nio.DirectByteBuffer");
+          } catch (ClassNotFoundException e) {
+            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
+            dbbCreateFailed = true;
+            dbbAddressFailed = true;
+            return null;
+          }
+          dbbClass = c;
+        }
+        try {
+          ctor = c.getDeclaredConstructor(long.class, int.class);
+        } catch (NoSuchMethodException | SecurityException e) {
+          //throw new IllegalStateException("Could not get constructor DirectByteBuffer(long, int)", e);
+          dbbClass = null;
+          dbbCreateFailed = true;
+          return null;
+        }
+        ctor.setAccessible(true);
+        dbbCtor = ctor;
+      }
+      try {
+        return (ByteBuffer)ctor.newInstance(baseDataAddress, dataSize);
+      } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+        //throw new IllegalStateException("Could not create an instance using DirectByteBuffer(long, int)", e);
+        dbbClass = null;
+        dbbCtor = null;
+        dbbCreateFailed = true;
+        return null;
+      }
+    }
+    private static volatile Method dbbAddressMethod = null;
+    private static volatile boolean dbbAddressFailed = false;
+    
+    /**
+     * Returns the address of the Unsafe memory for the first byte of a direct ByteBuffer.
+     * If the buffer is not direct or the address can not be obtained return 0.
+     */
+    public static long getDirectByteBufferAddress(ByteBuffer bb) {
+      if (!bb.isDirect()) {
+        return 0L;
+      }
+      if (dbbAddressFailed) {
+        return 0L;
+      }
+      Method m = dbbAddressMethod;
+      if (m == null) {
+        Class c = dbbClass;
+        if (c == null) {
+          try {
+            c = Class.forName("java.nio.DirectByteBuffer");
+          } catch (ClassNotFoundException e) {
+            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
+            dbbCreateFailed = true;
+            dbbAddressFailed = true;
+            return 0L;
+          }
+          dbbClass = c;
+        }
+        try {
+          m = c.getDeclaredMethod("address");
+        } catch (NoSuchMethodException | SecurityException e) {
+          //throw new IllegalStateException("Could not get method DirectByteBuffer.address()", e);
+          dbbClass = null;
+          dbbAddressFailed = true;
+          return 0L;
+        }
+        m.setAccessible(true);
+        dbbAddressMethod = m;
+      }
+      try {
+        return (Long)m.invoke(bb);
+      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+        //throw new IllegalStateException("Could not create an invoke DirectByteBuffer.address()", e);
+        dbbClass = null;
+        dbbAddressMethod = null;
+        dbbAddressFailed = true;
+        return 0L;
+      }
+    }
+    /**
+     * Returns an address that can be used with unsafe apis to access this chunks memory.
+     * @param offset the offset from this chunk's first byte of the byte the returned address should point to. Must be >= 0.
+     * @param size the number of bytes that will be read using the returned address. Assertion will use this to verify that all the memory accessed belongs to this chunk. Must be > 0.
+     * @return a memory address that can be used with unsafe apis
+     */
+    public long getUnsafeAddress(int offset, int size) {
+      assert offset >= 0 && offset + size <= getDataSize(): "Offset=" + offset + ",size=" + size + ",dataSize=" + getDataSize() + ", chunkSize=" + getSize() + ", but offset + size must be <= " + getDataSize();
+      assert size > 0;
+      long result = getBaseDataAddress() + offset;
+      // validateAddressAndSizeWithinSlab(result, size);
+      return result;
+    }
+    
+    @Override
+    public byte readByte(int offset) {
+      assert offset < getDataSize();
+      return UnsafeMemoryChunk.readAbsoluteByte(getBaseDataAddress() + offset);
+    }
+
+    @Override
+    public void writeByte(int offset, byte value) {
+      assert offset < getDataSize();
+      UnsafeMemoryChunk.writeAbsoluteByte(getBaseDataAddress() + offset, value);
+    }
+
+    @Override
+    public void readBytes(int offset, byte[] bytes) {
+      readBytes(offset, bytes, 0, bytes.length);
+    }
+
+    @Override
+    public void writeBytes(int offset, byte[] bytes) {
+      writeBytes(offset, bytes, 0, bytes.length);
+    }
+
+    public long getAddressForReading(int offset, int size) {
+      //delegate to getUnsafeAddress - as both the methods does return the memory address from given offset
+      return getUnsafeAddress(offset, size);
+    }
+    
+    @Override
+    public void readBytes(int offset, byte[] bytes, int bytesOffset, int size) {
+      assert offset+size <= getDataSize();
+      UnsafeMemoryChunk.readAbsoluteBytes(getBaseDataAddress() + offset, bytes, bytesOffset, size);
+    }
+
+    @Override
+    public void writeBytes(int offset, byte[] bytes, int bytesOffset, int size) {
+      assert offset+size <= getDataSize();
+      UnsafeMemoryChunk.writeAbsoluteBytes(getBaseDataAddress() + offset, bytes, bytesOffset, size);
+    }
+    
+    @Override
+    public void release() {
+      release(this.memoryAddress);
+     }
+
+    @Override
+    public int compareTo(ObjectChunk o) {
+      int result = Integer.signum(getSize() - o.getSize());
+      if (result == 0) {
+        // For the same sized chunks we really don't care about their order
+        // but we need compareTo to only return 0 if the two chunks are identical
+        result = Long.signum(getMemoryAddress() - o.getMemoryAddress());
+      }
+      return result;
+    }
+    
+    @Override
+    public boolean equals(Object o) {
+      if (o instanceof ObjectChunk) {
+        return getMemoryAddress() == ((ObjectChunk) o).getMemoryAddress();
+      }
+      return false;
+    }
+    
+    @Override
+    public int hashCode() {
+      long value = this.getMemoryAddress();
+      return (int)(value ^ (value >>> 32));
+    }
+
+    // OffHeapCachedDeserializable methods 
+    
+    @Override
+    public void setSerializedValue(byte[] value) {
+      writeBytes(0, value);
+    }
+    
+    public byte[] getDecompressedBytes(RegionEntryContext context) {
+      byte[] result = getCompressedBytes();
+      long time = context.getCachePerfStats().startDecompression();
+      result = context.getCompressor().decompress(result);
+      context.getCachePerfStats().endDecompression(time);      
+      return result;
+    }
+    
+    /**
+     * Returns the raw possibly compressed bytes of this chunk
+     */
+    public byte[] getCompressedBytes() {
+      byte[] result = new byte[getDataSize()];
+      readBytes(0, result);
+      //debugLog("reading", true);
+      SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+      return result;
+    }
+    protected byte[] getRawBytes() {
+      byte[] result = getCompressedBytes();
+      // TODO OFFHEAP: change the following to assert !isCompressed();
+      if (isCompressed()) {
+        throw new UnsupportedOperationException();
+      }
+      return result;
+    }
+
+    @Override
+    public byte[] getSerializedValue() {
+      byte [] result = getRawBytes();
+      if (!isSerialized()) {
+        // The object is a byte[]. So we need to make it look like a serialized byte[] in our result
+        result = EntryEventImpl.serialize(result);
+      }
+      return result;
+    }
+    
+    @Override
+    public Object getDeserializedValue(Region r, RegionEntry re) {
+      if (isSerialized()) {
+        // TODO OFFHEAP: debug deserializeChunk
+        return EntryEventImpl.deserialize(getRawBytes());
+        //assert !isCompressed();
+        //return EntryEventImpl.deserializeChunk(this);
+      } else {
+        return getRawBytes();
+      }
+    }
+    
+    /**
+     * We want this to include memory overhead so use getSize() instead of getDataSize().
+     */
+    @Override
+    public int getSizeInBytes() {
+      // Calling getSize includes the off heap header size.
+      // We do not add anything to this since the size of the reference belongs to the region entry size
+      // not the size of this object.
+      return getSize();
+    }
+
+    @Override
+    public int getValueSizeInBytes() {
+      return getDataSize();
+    }
+
+    @Override
+    public void copyBytes(int src, int dst, int size) {
+      throw new UnsupportedOperationException("Implement if used");
+//      assert src+size <= getDataSize();
+//      assert dst+size < getDataSize();
+//      getSlabs()[this.getSlabIdx()].copyBytes(getBaseDataAddress()+src, getBaseDataAddress()+dst, size);
+    }
+
+    @Override
+    public boolean isSerialized() {
+      return (UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET) & IS_SERIALIZED_BIT) != 0;
+    }
+
+    @Override
+    public boolean isCompressed() {
+      return (UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET) & IS_COMPRESSED_BIT) != 0;
+    }
+
+    @Override
+    public boolean retain() {
+      return retain(this.memoryAddress);
+    }
+
+    @Override
+    public int getRefCount() {
+      return getRefCount(this.memoryAddress);
+    }
+
+    public static int getSize(long memAddr) {
+      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
+      return UnsafeMemoryChunk.readAbsoluteInt(memAddr+CHUNK_SIZE_OFFSET);
+    }
+    public static void setSize(long memAddr, int size) {
+      SimpleMemoryAllocatorImpl.validateAddressAndSize(memAddr, size);
+      UnsafeMemoryChunk.writeAbsoluteInt(memAddr+CHUNK_SIZE_OFFSET, size);
+    }
+    public static long getNext(long memAddr) {
+      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
+      return UnsafeMemoryChunk.readAbsoluteLong(memAddr+OFF_HEAP_HEADER_SIZE);
+    }
+    public static void setNext(long memAddr, long next) {
+      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
+      UnsafeMemoryChunk.writeAbsoluteLong(memAddr+OFF_HEAP_HEADER_SIZE, next);
+    }
+    
+    /**
+     * Fills the chunk with a repeated byte fill pattern.
+     * @param baseAddress the starting address for a {@link ObjectChunk}.
+     */
+    public static void fill(long baseAddress) {
+      long startAddress = baseAddress + MIN_CHUNK_SIZE;
+      int size = getSize(baseAddress) - MIN_CHUNK_SIZE;
+      
+      UnsafeMemoryChunk.fill(startAddress, size, FILL_BYTE);
+    }
+    
+    /**
+     * Validates that the fill pattern for this chunk has not been disturbed.  This method
+     * assumes the TINY_MULTIPLE is 8 bytes.
+     * @throws IllegalStateException when the pattern has been violated.
+     */
+    public void validateFill() {
+      assert FreeListManager.TINY_MULTIPLE == 8;
+      
+      long startAddress = getMemoryAddress() + MIN_CHUNK_SIZE;
+      int size = getSize() - MIN_CHUNK_SIZE;
+      
+      for(int i = 0;i < size;i += FreeListManager.TINY_MULTIPLE) {
+        if(UnsafeMemoryChunk.readAbsoluteLong(startAddress + i) != FILL_PATTERN) {
+          throw new IllegalStateException("Fill pattern violated for chunk " + getMemoryAddress() + " with size " + getSize());
+        }        
+      }
+    }
+
+    public void setSerialized(boolean isSerialized) {
+      if (isSerialized) {
+        int bits;
+        int originalBits;
+        do {
+          originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
+          if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
+            throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
+          }
+          bits = originalBits | IS_SERIALIZED_BIT;
+        } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
+      }
+    }
+    public void setCompressed(boolean isCompressed) {
+      if (isCompressed) {
+        int bits;
+        int originalBits;
+        do {
+          originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
+          if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
+            throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
+          }
+          bits = originalBits | IS_COMPRESSED_BIT;
+        } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
+      }
+    }
+    public void setDataSize(int dataSize) { // KIRK
+      assert dataSize <= getSize();
+      int delta = getSize() - dataSize;
+      assert delta <= (DATA_SIZE_DELTA_MASK >> DATA_SIZE_SHIFT);
+      delta <<= DATA_SIZE_SHIFT;
+      int bits;
+      int originalBits;
+      do {
+        originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
+        if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
+          throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
+        }
+        bits = originalBits;
+        bits &= ~DATA_SIZE_DELTA_MASK; // clear the old dataSizeDelta bits
+        bits |= delta; // set the dataSizeDelta bits to the new delta value
+      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
+    }
+    
+    public void initializeUseCount() {
+      int rawBits;
+      do {
+        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
+        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
+          throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(rawBits));
+        }
+        int uc = rawBits & REF_COUNT_MASK;
+        if (uc != 0) {
+          throw new IllegalStateException("Expected use count to be zero but it was: " + uc + " rawBits=0x" + Integer.toHexString(rawBits));
+        }
+      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, rawBits, rawBits+1));
+    }
+
+    public static int getRefCount(long memAddr) {
+      return UnsafeMemoryChunk.readAbsoluteInt(memAddr+REF_COUNT_OFFSET) & REF_COUNT_MASK;
+    }
+
+    public static boolean retain(long memAddr) {
+      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
+      int uc;
+      int rawBits;
+      int retryCount = 0;
+      do {
+        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET);
+        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
+          // same as uc == 0
+          // TODO MAGIC_NUMBER rethink its use and interaction with compactor fragments
+          return false;
+        }
+        uc = rawBits & REF_COUNT_MASK;
+        if (uc == MAX_REF_COUNT) {
+          throw new IllegalStateException("Maximum use count exceeded. rawBits=" + Integer.toHexString(rawBits));
+        } else if (uc == 0) {
+          return false;
+        }
+        retryCount++;
+        if (retryCount > 1000) {
+          throw new IllegalStateException("tried to write " + (rawBits+1) + " to @" + Long.toHexString(memAddr) + " 1,000 times.");
+        }
+      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET, rawBits, rawBits+1));
+      //debugLog("use inced ref count " + (uc+1) + " @" + Long.toHexString(memAddr), true);
+      if (ReferenceCountHelper.trackReferenceCounts()) {
+        ReferenceCountHelper.refCountChanged(memAddr, false, uc+1);
+      }
+
+      return true;
+    }
+    public static void release(final long memAddr) {
+      release(memAddr, null);
+    }
+    static void release(final long memAddr, FreeListManager freeListManager) {
+      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
+      int newCount;
+      int rawBits;
+      boolean returnToAllocator;
+      do {
+        returnToAllocator = false;
+        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET);
+        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
+          String msg = "It looks like off heap memory @" + Long.toHexString(memAddr) + " was already freed. rawBits=" + Integer.toHexString(rawBits) + " history=" + ReferenceCountHelper.getFreeRefCountInfo(memAddr);
+          //debugLog(msg, true);
+          throw new IllegalStateException(msg);
+        }
+        int curCount = rawBits&REF_COUNT_MASK;
+        if ((curCount) == 0) {
+          //debugLog("too many frees @" + Long.toHexString(memAddr), true);
+          throw new IllegalStateException("Memory has already been freed." + " history=" + ReferenceCountHelper.getFreeRefCountInfo(memAddr) /*+ System.identityHashCode(this)*/);
+        }
+        if (curCount == 1) {
+          newCount = 0; // clear the use count, bits, and the delta size since it will be freed.
+          returnToAllocator = true;
+        } else {
+          newCount = rawBits-1;
+        }
+      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET, rawBits, newCount));
+      //debugLog("free deced ref count " + (newCount&USE_COUNT_MASK) + " @" + Long.toHexString(memAddr), true);
+      if (returnToAllocator ) {
+       if (ReferenceCountHelper.trackReferenceCounts()) {
+          if (ReferenceCountHelper.trackFreedReferenceCounts()) {
+            ReferenceCountHelper.refCountChanged(memAddr, true, newCount&REF_COUNT_MASK);
+          }
+          ReferenceCountHelper.freeRefCountInfo(memAddr);
+        }
+        if (freeListManager == null) {
+          freeListManager = SimpleMemoryAllocatorImpl.getAllocator().getFreeListManager();
+        }
+        freeListManager.free(memAddr);
+      } else {
+        if (ReferenceCountHelper.trackReferenceCounts()) {
+          ReferenceCountHelper.refCountChanged(memAddr, true, newCount&REF_COUNT_MASK);
+        }
+      }
+    }
+    
+    @Override
+    public String toString() {
+      return toStringForOffHeapByteSource();
+      // This old impl is not safe because it calls getDeserializedForReading and we have code that call toString that does not inc the refcount.
+      // Also if this Chunk is compressed we don't know how to decompress it.
+      //return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + getMemoryAddress() + " storedObject=" + getDeserializedForReading() + ">";
+    }
+    
+    protected String toStringForOffHeapByteSource() {
+      return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + Long.toHexString(getMemoryAddress()) + ">";
+    }
+    
+    @Override
+    public State getState() {
+      if (getRefCount() > 0) {
+        return State.ALLOCATED;
+      } else {
+        return State.DEALLOCATED;
+      }
+    }
+    @Override
+    public MemoryBlock getNextBlock() {
+      throw new UnsupportedOperationException();
+    }
+    @Override
+    public int getBlockSize() {
+      return getSize();
+    }
+    @Override
+    public int getSlabId() {
+      throw new UnsupportedOperationException();
+    }
+    @Override
+    public int getFreeListId() {
+      return -1;
+    }
+    @Override
+    public String getDataType() {
+      return null;
+    }
+    @Override
+    public Object getDataValue() {
+      return null;
+    }
+    public ObjectChunk slice(int position, int limit) {
+      return new ObjectChunkSlice(this, position, limit);
+    }
+  }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.java
new file mode 100644
index 0000000..3d6bf57
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.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 com.gemstone.gemfire.internal.offheap;
+
+/**
+ * Represents a slice of an ObjectChunk.
+ * A slice is a subsequence of the bytes stored in an ObjectChunk.
+ */
+public class ObjectChunkSlice extends ObjectChunk {
+  private final int offset;
+  private final int capacity;
+  public ObjectChunkSlice(ObjectChunk objectChunk, int position, int limit) {
+    super(objectChunk);
+    this.offset = objectChunk.getBaseDataOffset() + position;
+    this.capacity = limit - position;
+  }
+  @Override
+  public int getDataSize() {
+    return this.capacity;
+  }
+  
+  @Override
+  protected long getBaseDataAddress() {
+    return super.getBaseDataAddress() + this.offset;
+  }
+  @Override
+  protected int getBaseDataOffset() {
+    return this.offset;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java
new file mode 100644
index 0000000..5020c7a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java
@@ -0,0 +1,40 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+/**
+ * Used to keep the heapForm around while an operation is still in progress.
+ * This allows the operation to access the serialized heap form instead of copying
+ * it from offheap. See bug 48135.
+ */
+public class ObjectChunkWithHeapForm extends ObjectChunk {
+  private final byte[] heapForm;
+  
+  public ObjectChunkWithHeapForm(ObjectChunk chunk, byte[] heapForm) {
+    super(chunk);
+    this.heapForm = heapForm;
+  }
+
+  @Override
+  protected byte[] getRawBytes() {
+    return this.heapForm;
+  }
+  
+  public ObjectChunk getChunkWithoutHeapForm() {
+    return new ObjectChunk(this);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
index 1ec722d..bd380e2 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
@@ -46,7 +46,7 @@ public abstract class OffHeapCachedDeserializable extends AbstractStoredObject i
     if (isSerialized()) {
       userBits = EntryBits.setSerialized(userBits, true);
     }
-    wrapper.setChunkData((Chunk) this, userBits);
+    wrapper.setChunkData((ObjectChunk) this, userBits);
   }
   
   String getShortClassName() {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
index 84e4218..b62d97a 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
@@ -49,17 +49,6 @@ public class OffHeapRegionEntryHelper {
   protected static final long NOT_AVAILABLE_ADDRESS = 7L<<1;
   protected static final long TOMBSTONE_ADDRESS = 8L<<1;
   public static final int MAX_LENGTH_FOR_DATA_AS_ADDRESS = 8;
- /* private static final ChunkFactory chunkFactory ;
-  static {
-    ChunkFactory factory;
-    try {
-       factory= SimpleMemoryAllocatorImpl.getAllocator().getChunkFactory();
-         
-    }catch(CacheClosedException ce) {
-      factory = null;
-    }
-    chunkFactory = factory;
-  }*/
   
   private static final Token[] addrToObj = new Token[]{
     null,
@@ -74,7 +63,7 @@ public class OffHeapRegionEntryHelper {
   };
   
   private static long objectToAddress(@Unretained Object v) {
-    if (v instanceof Chunk) return ((Chunk) v).getMemoryAddress();
+    if (v instanceof ObjectChunk) return ((ObjectChunk) v).getMemoryAddress();
     if (v instanceof DataAsAddress) return ((DataAsAddress) v).getEncodedAddress();
     if (v == null) return NULL_ADDRESS;
     if (v == Token.TOMBSTONE) return TOMBSTONE_ADDRESS;
@@ -101,8 +90,7 @@ public class OffHeapRegionEntryHelper {
   @Unretained @Retained
   public static Object addressToObject(@Released @Retained long ohAddress, boolean decompress, RegionEntryContext context) {
     if (isOffHeap(ohAddress)) {
-      //Chunk chunk = chunkFactory.newChunk(ohAddress);
-      @Unretained Chunk chunk =  SimpleMemoryAllocatorImpl.getAllocator().getChunkFactory().newChunk(ohAddress);
+      @Unretained ObjectChunk chunk =  new ObjectChunk(ohAddress);
       @Unretained Object result = chunk;
       if (decompress && chunk.isCompressed()) {
         try {
@@ -172,7 +160,7 @@ public class OffHeapRegionEntryHelper {
 
   private static void releaseAddress(@Released long ohAddress) {
     if (isOffHeap(ohAddress)) {
-      Chunk.release(ohAddress, true);
+      ObjectChunk.release(ohAddress);
     }
   }
   
@@ -366,11 +354,11 @@ public class OffHeapRegionEntryHelper {
     int retryCount = 0;
     @Retained long addr = re.getAddress();
     while (isOffHeap(addr)) {
-      if (Chunk.retain(addr)) {
+      if (ObjectChunk.retain(addr)) {
         @Unretained long addr2 = re.getAddress();
         if (addr != addr2) {
           retryCount = 0;
-          Chunk.release(addr, true);
+          ObjectChunk.release(addr);
           // spin around and try again.
           addr = addr2;
         } else {


[030/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
index 52ea6f5,0000000..dd13f19
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
@@@ -1,1625 -1,0 +1,1625 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
 +
 +import java.io.EOFException;
 +import java.io.IOException;
 +import java.io.InterruptedIOException;
 +import java.io.PrintWriter;
 +import java.io.StringWriter;
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.Semaphore;
 +import java.util.regex.Pattern;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.CopyException;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.SerializationException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.InterestResultPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.TransactionException;
 +import com.gemstone.gemfire.cache.persistence.PartitionOfflineException;
 +import com.gemstone.gemfire.cache.query.types.CollectionType;
 +import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 +import com.gemstone.gemfire.distributed.internal.DistributionStats;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.CachedDeserializable;
 +import com.gemstone.gemfire.internal.cache.DistributedRegion;
 +import com.gemstone.gemfire.internal.cache.EntryEventImpl;
 +import com.gemstone.gemfire.internal.cache.EntrySnapshot;
 +import com.gemstone.gemfire.internal.cache.EventID;
 +import com.gemstone.gemfire.internal.cache.FindVersionTagOperation;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.LocalRegion.NonTXEntry;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.TXStateProxy;
 +import com.gemstone.gemfire.internal.cache.Token;
 +import com.gemstone.gemfire.internal.cache.tier.CachedRegionHelper;
 +import com.gemstone.gemfire.internal.cache.tier.Command;
 +import com.gemstone.gemfire.internal.cache.tier.InterestType;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 +import com.gemstone.gemfire.internal.sequencelog.EntryLogger;
 +import com.gemstone.gemfire.security.GemFireSecurityException;
 +
 +/**
 + * @author ashahid
 + *
 + */
 +public abstract class BaseCommand implements Command {
 +  protected static final Logger logger = LogService.getLogger();
 +
 +  /**
 +   * Whether zipped values are being passed to/from the client. Can be modified
 +   * using the system property Message.ZIP_VALUES ? This does not appear to
 +   * happen anywhere
 +   */
 +  protected static final boolean zipValues = false;
 +
 +  protected static final boolean APPLY_RETRIES = Boolean
 +      .getBoolean("gemfire.gateway.ApplyRetries");
 +
 +  public static final byte[] OK_BYTES = new byte[]{0};  
 +
 +  public static final int maximumChunkSize = Integer.getInteger(
 +      "BridgeServer.MAXIMUM_CHUNK_SIZE", 100).intValue();
 +
 +  /** Maximum number of entries in each chunked response chunk */
 +
 +  /** Whether to suppress logging of IOExceptions */
 +  private static boolean suppressIOExceptionLogging = Boolean
 +      .getBoolean("gemfire.bridge.suppressIOExceptionLogging");
 +
 +  /**
 +   * Maximum number of concurrent incoming client message bytes that a bridge
 +   * server will allow. Once a server is working on this number additional
 +   * incoming client messages will wait until one of them completes or fails.
 +   * The bytes are computed based in the size sent in the incoming msg header.
 +   */
 +  private static final int MAX_INCOMING_DATA = Integer.getInteger(
 +      "BridgeServer.MAX_INCOMING_DATA", -1).intValue();
 +
 +  /**
 +   * Maximum number of concurrent incoming client messages that a bridge server
 +   * will allow. Once a server is working on this number additional incoming
 +   * client messages will wait until one of them completes or fails.
 +   */
 +  private static final int MAX_INCOMING_MSGS = Integer.getInteger(
 +      "BridgeServer.MAX_INCOMING_MSGS", -1).intValue();
 +
 +  private static final Semaphore incomingDataLimiter;
 +
 +  private static final Semaphore incomingMsgLimiter;
 +  static {
 +    Semaphore tmp;
 +    if (MAX_INCOMING_DATA > 0) {
 +      // backport requires that this is fair since we inc by values > 1
 +      tmp = new Semaphore(MAX_INCOMING_DATA, true);
 +    }
 +    else {
 +      tmp = null;
 +    }
 +    incomingDataLimiter = tmp;
 +    if (MAX_INCOMING_MSGS > 0) {
 +      tmp = new Semaphore(MAX_INCOMING_MSGS, false); // unfair for best
 +      // performance
 +    }
 +    else {
 +      tmp = null;
 +    }
 +    incomingMsgLimiter = tmp;
 +
 +  }
 +
 +  final public void execute(Message msg, ServerConnection servConn) {
 +    // Read the request and update the statistics
 +    long start = DistributionStats.getStatTime();
 +    //servConn.resetTransientData();
 +    if(EntryLogger.isEnabled() && servConn  != null) {
 +      EntryLogger.setSource(servConn.getMembershipID(), "c2s");
 +    }
 +    boolean shouldMasquerade = shouldMasqueradeForTx(msg, servConn);
 +    try {
 +      if (shouldMasquerade) {
 +        GemFireCacheImpl  cache = (GemFireCacheImpl)servConn.getCache();
 +        InternalDistributedMember member = (InternalDistributedMember)servConn.getProxyID().getDistributedMember();
 +        TXManagerImpl txMgr = cache.getTxManager();
 +        TXStateProxy tx = null;
 +        try {
 +          tx = txMgr.masqueradeAs(msg, member, false);
 +          cmdExecute(msg, servConn, start);
 +        } finally {
 +          txMgr.unmasquerade(tx);
 +        }
 +      } else {
 +        cmdExecute(msg, servConn, start);
 +      }
 +      
 +    }   
 +    catch (EOFException eof) {
 +      BaseCommand.handleEOFException(msg, servConn, eof);
 +      // TODO:Asif: Check if there is any need for explicitly returning
 +      return;
 +    }
 +    catch (InterruptedIOException e) { // Solaris only
 +      BaseCommand.handleInterruptedIOException(msg, servConn, e);
 +      return;
 +    }
 +    catch (IOException e) {
 +      BaseCommand.handleIOException(msg, servConn, e);
 +      return;
 +    }
 +    catch (DistributedSystemDisconnectedException e) {
 +      BaseCommand.handleShutdownException(msg, servConn, e);
 +      return;
 +    }
 +    catch (PartitionOfflineException e) { // fix for bug #42225
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    }
 +    catch (GemFireSecurityException e) {
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    }
 +    catch (CacheLoaderException e) {
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    }
 +    catch (CacheWriterException e) {
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    } catch (SerializationException e) {
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    } catch (CopyException e) {
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    } catch (TransactionException e) {
 +      handleExceptionNoDisconnect(msg, servConn, e);
 +    }
 +    
 +    catch (VirtualMachineError err) {
 +      SystemFailure.initiateFailure(err);
 +      // If this ever returns, rethrow the error.  We're poisoned
 +      // now, so don't let this thread continue.
 +      throw err;
 +    }
 +    catch (Throwable e) {
 +      BaseCommand.handleThrowable(msg, servConn, e);
 +    } finally {
 +      EntryLogger.clearSource();
 +    }
 +    /*
 +     * finally { // Keep track of the fact that a message is no longer being //
 +     * processed. servConn.setNotProcessingMessage();
 +     * servConn.clearRequestMsg(); }
 +     */
 +  }
 +
 +  /**
 +   * checks to see if this thread needs to masquerade as a transactional thread.
 +   * clients after GFE_66 should be able to start a transaction.
 +   * @param msg
 +   * @param servConn
 +   * @return true if thread should masquerade as a transactional thread.
 +   */
 +  protected boolean shouldMasqueradeForTx(Message msg, ServerConnection servConn) {
 +    if (servConn.getClientVersion().compareTo(Version.GFE_66) >= 0
 +        && msg.getTransactionId() > TXManagerImpl.NOTX) {
 +      return true;
 +    }
 +    return false;
 +  }
 +  
 +  /**
 +   * If an operation is retried then some server may have seen it already.
 +   * We cannot apply this operation to the cache without knowing whether a
 +   * version tag has already been created for it.  Otherwise caches that have
 +   * seen the event already will reject it but others will not, but will have
 +   * no version tag with which to perform concurrency checks.
 +   * <p>The client event should have the event identifier from the client and
 +   * the region affected by the operation.
 +   * @param clientEvent
 +   */
 +  public boolean recoverVersionTagForRetriedOperation(EntryEventImpl clientEvent) {
 +    LocalRegion r = clientEvent.getRegion();
 +    VersionTag tag =  null;
 +    if ((clientEvent.getVersionTag() != null) && (clientEvent.getVersionTag().isGatewayTag())) {
 +      tag = r.findVersionTagForGatewayEvent(clientEvent.getEventId());
 +    }
 +    else {
 +      tag = r.findVersionTagForClientEvent(clientEvent.getEventId());
 +    }
 +    if (tag == null) {
 +      if (r instanceof DistributedRegion || r instanceof PartitionedRegion) {
 +        // TODO this could be optimized for partitioned regions by sending the key
 +        // so that the PR could look at an individual bucket for the event
 +        tag = FindVersionTagOperation.findVersionTag(r, clientEvent.getEventId(), false);
 +      }
 +    }
 +    if (tag != null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("recovered version tag {} for replayed operation {}", tag, clientEvent.getEventId());
 +      }
 +      clientEvent.setVersionTag(tag);
 +    }
 +    return (tag != null);
 +  }
 +  
 +  /**
 +   * If an operation is retried then some server may have seen it already.
 +   * We cannot apply this operation to the cache without knowing whether a
 +   * version tag has already been created for it.  Otherwise caches that have
 +   * seen the event already will reject it but others will not, but will have
 +   * no version tag with which to perform concurrency checks.
 +   * <p>The client event should have the event identifier from the client and
 +   * the region affected by the operation.
 +   */
 +  protected VersionTag findVersionTagsForRetriedBulkOp(LocalRegion r, EventID eventID) {
 +    VersionTag tag = r.findVersionTagForClientBulkOp(eventID);
 +    if(tag != null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("recovered version tag {} for replayed bulk operation {}", tag, eventID);
 +      }
 +      return tag;
 +    }
 +    if (r instanceof DistributedRegion || r instanceof PartitionedRegion) {
 +      // TODO this could be optimized for partitioned regions by sending the key
 +      // so that the PR could look at an individual bucket for the event
 +      tag = FindVersionTagOperation.findVersionTag(r, eventID, true);
 +    }
 +    if (tag != null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("recovered version tag {} for replayed bulk operation {}", tag, eventID);
 +      }
 +    }
 +    return tag;
 +  }
 +
 +  abstract public void cmdExecute(Message msg, ServerConnection servConn,
 +      long start) throws IOException, ClassNotFoundException, InterruptedException;
 +
 +  protected void writeReply(Message origMsg, ServerConnection servConn)
 +      throws IOException {
 +    Message replyMsg = servConn.getReplyMessage();
 +    servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
 +    replyMsg.setMessageType(MessageType.REPLY);
 +    replyMsg.setNumberOfParts(1);
 +    replyMsg.setTransactionId(origMsg.getTransactionId());
 +    replyMsg.addBytesPart(OK_BYTES);
 +    replyMsg.send(servConn);
 +    if (logger.isTraceEnabled()) {
 +      logger.trace("{}: rpl tx: {}", servConn.getName(), origMsg.getTransactionId());
 +    }
 +  }
 +  protected void writeReplyWithRefreshMetadata(Message origMsg,
 +      ServerConnection servConn, PartitionedRegion pr, byte nwHop) throws IOException {
 +    Message replyMsg = servConn.getReplyMessage();
 +    servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
 +    replyMsg.setMessageType(MessageType.REPLY);
 +    replyMsg.setNumberOfParts(1);
 +    replyMsg.setTransactionId(origMsg.getTransactionId());
 +    replyMsg.addBytesPart(new byte[]{pr.getMetadataVersion().byteValue(), nwHop});
 +    replyMsg.send(servConn);
 +    pr.getPrStats().incPRMetaDataSentCount();
 +    if (logger.isTraceEnabled()) {
 +      logger.trace("{}: rpl with REFRESH_METADAT tx: {}", servConn.getName(), origMsg.getTransactionId());
 +    }
 +  }
 +
 +  private static void handleEOFException(Message msg,
 +      ServerConnection servConn, Exception eof) {
 +    CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
 +    CacheServerStats stats = servConn.getCacheServerStats();
 +    boolean potentialModification = servConn.getPotentialModification();
 +    if (!crHelper.isShutdown()) {
 +      if (potentialModification) {
 +        stats.incAbandonedWriteRequests();
 +      }
 +      else {
 +        stats.incAbandonedReadRequests();
 +      }
 +      if (!suppressIOExceptionLogging) {
 +        if (potentialModification) {
 +          int transId = (msg != null) ? msg.getTransactionId()
 +              : Integer.MIN_VALUE;
 +          logger.warn(LocalizedMessage.create(
 +            LocalizedStrings.BaseCommand_0_EOFEXCEPTION_DURING_A_WRITE_OPERATION_ON_REGION__1_KEY_2_MESSAGEID_3,
 +            new Object[] {servConn.getName(), servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}));
 +        }
 +        else {
 +          logger.debug("EOF exception", eof);
 +          logger.info(LocalizedMessage.create(
 +            LocalizedStrings.BaseCommand_0_CONNECTION_DISCONNECT_DETECTED_BY_EOF,
 +            servConn.getName()));
 +        }
 +      }
 +    }
 +    servConn.setFlagProcessMessagesAsFalse();
 +  }
 +
 +  private static void handleInterruptedIOException(Message msg,
 +      ServerConnection servConn, Exception e) {
 +    CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
 +    if (!crHelper.isShutdown() && servConn.isOpen()) {
 +      if (!suppressIOExceptionLogging) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("Aborted message due to interrupt: {}", e.getMessage(), e);
 +      }
 +    }
 +    servConn.setFlagProcessMessagesAsFalse();
 +  }
 +
 +  private static void handleIOException(Message msg, ServerConnection servConn,
 +      Exception e) {
 +    CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
 +    boolean potentialModification = servConn.getPotentialModification();
 +
 +    if (!crHelper.isShutdown() && servConn.isOpen()) {
 +      if (!suppressIOExceptionLogging) {
 +        if (potentialModification) {
 +          int transId = (msg != null) ? msg.getTransactionId()
 +              : Integer.MIN_VALUE;
 +          logger.warn(LocalizedMessage.create(
 +            LocalizedStrings.BaseCommand_0_UNEXPECTED_IOEXCEPTION_DURING_OPERATION_FOR_REGION_1_KEY_2_MESSID_3,
 +            new Object[] {servConn.getName(), servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), e);
 +        }
 +        else {
 +          logger.warn(LocalizedMessage.create(
 +            LocalizedStrings.BaseCommand_0_UNEXPECTED_IOEXCEPTION,
 +            servConn.getName()), e);
 +        }
 +      }
 +    }
 +    servConn.setFlagProcessMessagesAsFalse();
 +  }
 +
 +  private static void handleShutdownException(Message msg,
 +      ServerConnection servConn, Exception e) {
 +    CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
 +    boolean potentialModification = servConn.getPotentialModification();
 +
 +    if (!crHelper.isShutdown()) {
 +      if (potentialModification) {
 +        int transId = (msg != null) ? msg.getTransactionId()
 +            : Integer.MIN_VALUE;
 +        logger.warn(LocalizedMessage.create(
 +          LocalizedStrings.BaseCommand_0_UNEXPECTED_SHUTDOWNEXCEPTION_DURING_OPERATION_ON_REGION_1_KEY_2_MESSAGEID_3,
 +          new Object[] {servConn.getName(), servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), e);
 +      }
 +      else {
 +        logger.warn(LocalizedMessage.create(
 +          LocalizedStrings.BaseCommand_0_UNEXPECTED_SHUTDOWNEXCEPTION,
 +          servConn.getName()),e);
 +        }
 +    }
 +    servConn.setFlagProcessMessagesAsFalse();
 +  }
 +
 +  // Handle GemfireSecurityExceptions separately since the connection should not
 +  // be terminated (by setting processMessages to false) unlike in
 +  // handleThrowable. Fixes bugs #38384 and #39392.
 +//  private static void handleGemfireSecurityException(Message msg,
 +//      ServerConnection servConn, GemFireSecurityException e) {
 +//
 +//    boolean requiresResponse = servConn.getTransientFlag(REQUIRES_RESPONSE);
 +//    boolean responded = servConn.getTransientFlag(RESPONDED);
 +//    boolean requiresChunkedResponse = servConn
 +//        .getTransientFlag(REQUIRES_CHUNKED_RESPONSE);
 +//    boolean potentialModification = servConn.getPotentialModification();
 +//
 +//    try {
 +//      try {
 +//        if (requiresResponse && !responded) {
 +//          if (requiresChunkedResponse) {
 +//            writeChunkedException(msg, e, false, servConn);
 +//          }
 +//          else {
 +//            writeException(msg, e, false, servConn);
 +//          }
 +//          servConn.setAsTrue(RESPONDED);
 +//        }
 +//      }
 +//      finally { // inner try-finally to ensure proper ordering of logging
 +//        if (potentialModification) {
 +//          int transId = (msg != null) ? msg.getTransactionId()
 +//              : Integer.MIN_VALUE;
 +//        }
 +//      }
 +//    }
 +//    catch (IOException ioe) {
 +//      if (logger.isDebugEnabled()) {
 +//        logger.fine(servConn.getName()
 +//            + ": Unexpected IOException writing security exception: ", ioe);
 +//      }
 +//    }
 +//  }
 +
 +  private static void handleExceptionNoDisconnect(Message msg,
 +      ServerConnection servConn, Exception e) {
 +    boolean requiresResponse = servConn.getTransientFlag(REQUIRES_RESPONSE);
 +    boolean responded = servConn.getTransientFlag(RESPONDED);
 +    boolean requiresChunkedResponse = servConn
 +        .getTransientFlag(REQUIRES_CHUNKED_RESPONSE);
 +    boolean potentialModification = servConn.getPotentialModification();
 +    boolean wroteExceptionResponse = false;
 +
 +    try {
 +      try {
 +        if (requiresResponse && !responded) {
 +          if (requiresChunkedResponse) {
 +            writeChunkedException(msg, e, false, servConn);
 +          }
 +          else {
 +            writeException(msg, e, false, servConn);
 +          }
 +          wroteExceptionResponse = true;
 +          servConn.setAsTrue(RESPONDED);
 +        }
 +      }
 +      finally { // inner try-finally to ensure proper ordering of logging
 +        if (potentialModification) {
 +          int transId = (msg != null) ? msg.getTransactionId()
 +              : Integer.MIN_VALUE;
 +          if (!wroteExceptionResponse) {
 +            logger.warn(LocalizedMessage.create(
 +                LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION_DURING_OPERATION_ON_REGION_1_KEY_2_MESSAGEID_3,
 +                new Object[] {servConn.getName(),servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), e);
 +          } else {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}: Exception during operation on region: {} key: {} messageId: {}", servConn.getName(),
 +                  servConn.getModRegion(), servConn.getModKey(), transId, e);
 +            }
 +          }
 +        }
 +        else {
 +          if (!wroteExceptionResponse) {
 +            logger.warn(LocalizedMessage.create(
 +                LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION,
 +                servConn.getName()), e);
 +          } else {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}: Exception: {}", servConn.getName(), e.getMessage(), e);
 +            }
 +          }
 +        }
 +      }
 +    }
 +    catch (IOException ioe) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Unexpected IOException writing exception: {}", servConn.getName(), ioe.getMessage(), ioe);
 +      }
 +    }
 +  }
 +
 +  private static void handleThrowable(Message msg, ServerConnection servConn,
 +      Throwable th) {
 +    boolean requiresResponse = servConn.getTransientFlag(REQUIRES_RESPONSE);
 +    boolean responded = servConn.getTransientFlag(RESPONDED);
 +    boolean requiresChunkedResponse = servConn
 +        .getTransientFlag(REQUIRES_CHUNKED_RESPONSE);
 +    boolean potentialModification = servConn.getPotentialModification();
 +
 +    try {
 +      try {
 +        if (th instanceof Error) {
 +          logger.fatal(LocalizedMessage.create(LocalizedStrings.BaseCommand_0_UNEXPECTED_ERROR_ON_SERVER,
 +              servConn.getName()), th);
 +        }
 +        if (requiresResponse && !responded) {
 +          if (requiresChunkedResponse) {
 +            writeChunkedException(msg, th, false, servConn);
 +          }
 +          else {
 +            writeException(msg, th, false, servConn);
 +          }
 +          servConn.setAsTrue(RESPONDED);
 +        }
 +      }
 +      finally { // inner try-finally to ensure proper ordering of logging
 +        if (th instanceof Error) {
 +          // log nothing
 +        } else if (th instanceof CancelException) {
 +          // log nothing
 +        } else {
 +          if (potentialModification) {
 +            int transId = (msg != null) ? msg.getTransactionId()
 +                : Integer.MIN_VALUE;
 +            logger.warn(LocalizedMessage.create(
 +              LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION_DURING_OPERATION_ON_REGION_1_KEY_2_MESSAGEID_3,
 +              new Object[] {servConn.getName(),servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), th);
 +          }
 +          else {
 +            logger.warn(LocalizedMessage.create(
 +              LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION,
 +              servConn.getName()), th);
 +          }
 +        }
 +      }
 +    } catch (IOException ioe) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Unexpected IOException writing exception: {}", servConn.getName(), ioe.getMessage(), ioe);
 +      }
 +    } finally {
 +      servConn.setFlagProcessMessagesAsFalse();
 +    }
 +  }
 +  
 +  protected static void writeChunkedException(Message origMsg, Throwable e,
 +      boolean isSevere, ServerConnection servConn) throws IOException {
 +    writeChunkedException(origMsg, e, isSevere, servConn, servConn.getChunkedResponseMessage());
 +  }
 +
 +  protected static void writeChunkedException(Message origMsg, Throwable e,
 +      boolean isSevere, ServerConnection servConn, ChunkedMessage originalReponse) throws IOException {
 +    writeChunkedException(origMsg, e, isSevere, servConn, originalReponse, 2);
 +  }
 +
 +  protected static void writeChunkedException(Message origMsg, Throwable e,
 +      boolean isSevere, ServerConnection servConn, ChunkedMessage originalReponse, int numOfParts) throws IOException {
 +    ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
 +    chunkedResponseMsg.setServerConnection(servConn);
 +    if (originalReponse.headerHasBeenSent()) {
 +      //chunkedResponseMsg = originalReponse;
 +      // fix for bug 35442
 +      chunkedResponseMsg.setNumberOfParts(numOfParts);
 +      chunkedResponseMsg.setLastChunkAndNumParts(true, numOfParts);
 +      chunkedResponseMsg.addObjPart(e); 
 +      if (numOfParts == 2) {
 +        chunkedResponseMsg.addStringPart(getExceptionTrace(e));
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk while reply in progress: {}", servConn.getName(), e.getMessage(), e);
 +      }
 +    }
 +    else {
 +      chunkedResponseMsg.setMessageType(MessageType.EXCEPTION);
 +      chunkedResponseMsg.setNumberOfParts(numOfParts);
 +      chunkedResponseMsg.setLastChunkAndNumParts(true, numOfParts);
 +      chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +      chunkedResponseMsg.sendHeader();
 +      chunkedResponseMsg.addObjPart(e);
 +      if (numOfParts == 2) {
 +        chunkedResponseMsg.addStringPart(getExceptionTrace(e));
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk: {}", servConn.getName(), e.getMessage(), e);
 +      }
 +    }
 +    chunkedResponseMsg.sendChunk(servConn);
 +  }
 +
 +  // Get the exception stacktrace for native clients
 +  public static String getExceptionTrace(Throwable ex) {
 +    StringWriter sw = new StringWriter();
 +    PrintWriter pw = new PrintWriter(sw);
 +    ex.printStackTrace(pw);
 +    pw.close();
 +    return sw.toString();
 +  }
 +
 +  protected static void writeException(Message origMsg, Throwable e,
 +      boolean isSevere, ServerConnection servConn) throws IOException {
 +    writeException(origMsg, MessageType.EXCEPTION, e, isSevere, servConn);
 +  }
 +
 +  protected static void writeException(Message origMsg, int msgType, Throwable e,
 +      boolean isSevere, ServerConnection servConn) throws IOException {
 +    Message errorMsg = servConn.getErrorResponseMessage();
 +    errorMsg.setMessageType(msgType);
 +    errorMsg.setNumberOfParts(2);
 +    errorMsg.setTransactionId(origMsg.getTransactionId());
 +    if (isSevere) {
 +      String msg = e.getMessage();
 +      if (msg == null) {
 +        msg = e.toString();
 +      }
 +      logger.fatal(LocalizedMessage.create(LocalizedStrings.BaseCommand_SEVERE_CACHE_EXCEPTION_0, msg));
 +    }
 +    errorMsg.addObjPart(e);
 +    errorMsg.addStringPart(getExceptionTrace(e));
 +    errorMsg.send(servConn);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Wrote exception: {}", servConn.getName(), e.getMessage(), e);
 +    }
 +  }
 +
 +  protected static void writeErrorResponse(Message origMsg, int messageType,
 +      ServerConnection servConn) throws IOException {
 +    Message errorMsg = servConn.getErrorResponseMessage();
 +    errorMsg.setMessageType(messageType);
 +    errorMsg.setNumberOfParts(1);
 +    errorMsg.setTransactionId(origMsg.getTransactionId());
 +    errorMsg
 +        .addStringPart(LocalizedStrings.BaseCommand_INVALID_DATA_RECEIVED_PLEASE_SEE_THE_CACHE_SERVER_LOG_FILE_FOR_ADDITIONAL_DETAILS.toLocalizedString());
 +    errorMsg.send(servConn);
 +  }
 +
 +  protected static void writeErrorResponse(Message origMsg, int messageType,
 +      String msg, ServerConnection servConn) throws IOException {
 +    Message errorMsg = servConn.getErrorResponseMessage();
 +    errorMsg.setMessageType(messageType);
 +    errorMsg.setNumberOfParts(1);
 +    errorMsg.setTransactionId(origMsg.getTransactionId());
 +    errorMsg.addStringPart(msg);
 +    errorMsg.send(servConn);
 +  }
 +
 +  protected static void writeRegionDestroyedEx(Message msg, String regionName,
 +      String title, ServerConnection servConn) throws IOException {
 +    String reason = servConn.getName() + ": Region named " + regionName + title;
 +    RegionDestroyedException ex = new RegionDestroyedException(reason,
 +        regionName);
 +    if (servConn.getTransientFlag(REQUIRES_CHUNKED_RESPONSE)) {
 +      writeChunkedException(msg, ex, false, servConn);
 +    }
 +    else {
 +      writeException(msg, ex, false, servConn);
 +    }
 +  }
 +
 +  protected static void writeResponse(Object data, Object callbackArg,
 +      Message origMsg, boolean isObject, ServerConnection servConn)
 +      throws IOException {
 +    Message responseMsg = servConn.getResponseMessage();
 +    responseMsg.setMessageType(MessageType.RESPONSE);
 +    responseMsg.setTransactionId(origMsg.getTransactionId());
 +
 +    
 +    if (callbackArg == null) {
 +      responseMsg.setNumberOfParts(1);
 +    }
 +    else {
 +      responseMsg.setNumberOfParts(2);
 +    }
 +    if (data instanceof byte[]) {
 +      responseMsg.addRawPart((byte[])data, isObject);
 +    }
 +    else {
 +      Assert.assertTrue(isObject,
 +          "isObject should be true when value is not a byte[]");
 +      responseMsg.addObjPart(data, zipValues);
 +    }
 +    if (callbackArg != null) {
 +      responseMsg.addObjPart(callbackArg);
 +    }
 +    servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
 +    responseMsg.send(servConn);
 +    origMsg.clearParts();
 +  }
 +  
 +  protected static void writeResponseWithRefreshMetadata(Object data,
 +      Object callbackArg, Message origMsg, boolean isObject,
 +      ServerConnection servConn, PartitionedRegion pr, byte nwHop) throws IOException {
 +    Message responseMsg = servConn.getResponseMessage();
 +    responseMsg.setMessageType(MessageType.RESPONSE);
 +    responseMsg.setTransactionId(origMsg.getTransactionId());
 +
 +    if (callbackArg == null) {
 +      responseMsg.setNumberOfParts(2);
 +    }
 +    else {
 +      responseMsg.setNumberOfParts(3);
 +    }
 +
 +    if (data instanceof byte[]) {
 +      responseMsg.addRawPart((byte[])data, isObject);
 +    }
 +    else {
 +      Assert.assertTrue(isObject,
 +          "isObject should be true when value is not a byte[]");
 +      responseMsg.addObjPart(data, zipValues);
 +    }
 +    if (callbackArg != null) {
 +      responseMsg.addObjPart(callbackArg);
 +    }
 +    responseMsg.addBytesPart(new byte[]{pr.getMetadataVersion().byteValue(),nwHop});
 +    servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
 +    responseMsg.send(servConn);
 +    origMsg.clearParts();
 +  }
 +
 +  protected static void writeResponseWithFunctionAttribute(byte[] data,
 +      Message origMsg, ServerConnection servConn) throws IOException {
 +    Message responseMsg = servConn.getResponseMessage();
 +    responseMsg.setMessageType(MessageType.RESPONSE);
 +    responseMsg.setTransactionId(origMsg.getTransactionId());
 +    responseMsg.setNumberOfParts(1);
 +    responseMsg.addBytesPart(data);
 +    servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
 +    responseMsg.send(servConn);
 +    origMsg.clearParts();
 +  }
 +  
 +  static protected void checkForInterrupt(ServerConnection servConn, Exception e) 
 +      throws InterruptedException, InterruptedIOException {
 +    servConn.getCachedRegionHelper().checkCancelInProgress(e);
 +    if (e instanceof InterruptedException) {
 +      throw (InterruptedException)e;
 +    }
 +    if (e instanceof InterruptedIOException) {
 +      throw (InterruptedIOException)e;
 +    }
 +  }
 +
 +  protected static void writeQueryResponseChunk(Object queryResponseChunk,
 +      CollectionType collectionType, boolean lastChunk,
 +      ServerConnection servConn) throws IOException {
 +    ChunkedMessage queryResponseMsg = servConn.getQueryResponseMessage();
 +    queryResponseMsg.setNumberOfParts(2);
 +    queryResponseMsg.setLastChunk(lastChunk);
 +    queryResponseMsg.addObjPart(collectionType, zipValues);
 +    queryResponseMsg.addObjPart(queryResponseChunk, zipValues);
 +    queryResponseMsg.sendChunk(servConn);
 +  }
 +
 +  protected static void writeQueryResponseException(Message origMsg,
 +      Throwable e, boolean isSevere, ServerConnection servConn)
 +      throws IOException {
 +    ChunkedMessage queryResponseMsg = servConn.getQueryResponseMessage();
 +    ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
 +    if (queryResponseMsg.headerHasBeenSent()) {
 +      // fix for bug 35442
 +      // This client is expecting 2 parts in this message so send 2 parts
 +      queryResponseMsg.setServerConnection(servConn);
 +      queryResponseMsg.setNumberOfParts(2);
 +      queryResponseMsg.setLastChunkAndNumParts(true, 2);
 +      queryResponseMsg.addObjPart(e);
 +      queryResponseMsg.addStringPart(getExceptionTrace(e));
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk while reply in progress: {}", servConn.getName(), e.getMessage(), e);
 +      }
 +      queryResponseMsg.sendChunk(servConn);
 +    }
 +    else {
 +      chunkedResponseMsg.setServerConnection(servConn);
 +      chunkedResponseMsg.setMessageType(MessageType.EXCEPTION);
 +      chunkedResponseMsg.setNumberOfParts(2);
 +      chunkedResponseMsg.setLastChunkAndNumParts(true, 2);
 +      chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +      chunkedResponseMsg.sendHeader();
 +      chunkedResponseMsg.addObjPart(e);
 +      chunkedResponseMsg.addStringPart(getExceptionTrace(e));
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk: {}", servConn.getName(), e.getMessage(), e);
 +      }
 +      chunkedResponseMsg.sendChunk(servConn);
 +    }
 +  }
 +
 +  protected static void writeChunkedErrorResponse(Message origMsg,
 +      int messageType, String message, ServerConnection servConn)
 +      throws IOException {
 +    // Send chunked response header identifying error message
 +    ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
 +    if (logger.isDebugEnabled()) {
 +      logger.debug(servConn.getName() + ": Sending error message header type: "
 +          + messageType + " transaction: " + origMsg.getTransactionId());
 +    }
 +    chunkedResponseMsg.setMessageType(messageType);
 +    chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +    chunkedResponseMsg.sendHeader();
 +
 +    // Send actual error
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Sending error message chunk: {}", servConn.getName(), message);
 +    }
 +    chunkedResponseMsg.setNumberOfParts(1);
 +    chunkedResponseMsg.setLastChunk(true);
 +    chunkedResponseMsg.addStringPart(message);
 +    chunkedResponseMsg.sendChunk(servConn);
 +  }
 +  
 +  protected static void writeFunctionResponseException(Message origMsg,
 +      int messageType, String message, ServerConnection servConn, Throwable e)
 +      throws IOException {
 +    ChunkedMessage functionResponseMsg = servConn.getFunctionResponseMessage();
 +    ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
 +    if (functionResponseMsg.headerHasBeenSent()) {
 +      functionResponseMsg.setServerConnection(servConn);
 +      functionResponseMsg.setNumberOfParts(2);
 +      functionResponseMsg.setLastChunkAndNumParts(true,2);
 +      functionResponseMsg.addObjPart(e);
 +      functionResponseMsg.addStringPart(getExceptionTrace(e));
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk while reply in progress: {}", servConn.getName(), e.getMessage(), e);
 +      }
 +      functionResponseMsg.sendChunk(servConn);
 +    }
 +    else {
 +      chunkedResponseMsg.setServerConnection(servConn);
 +      chunkedResponseMsg.setMessageType(messageType);
 +      chunkedResponseMsg.setNumberOfParts(2);
 +      chunkedResponseMsg.setLastChunkAndNumParts(true,2);
 +      chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +      chunkedResponseMsg.sendHeader();
 +      chunkedResponseMsg.addObjPart(e);
 +      chunkedResponseMsg.addStringPart(getExceptionTrace(e));
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk: {}", servConn.getName(), e.getMessage(), e);
 +      }
 +      chunkedResponseMsg.sendChunk(servConn);
 +    }
 +  }
 +  
 +  protected static void writeFunctionResponseError(Message origMsg,
 +      int messageType, String message, ServerConnection servConn)
 +      throws IOException {
 +    ChunkedMessage functionResponseMsg = servConn.getFunctionResponseMessage();
 +    ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
 +    if (functionResponseMsg.headerHasBeenSent()) {
 +      functionResponseMsg.setNumberOfParts(1);
 +      functionResponseMsg.setLastChunk(true);
 +      functionResponseMsg.addStringPart(message);
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending Error chunk while reply in progress: {}", servConn.getName(), message);
 +      }
 +      functionResponseMsg.sendChunk(servConn);
 +    }
 +    else {
 +      chunkedResponseMsg.setMessageType(messageType);
 +      chunkedResponseMsg.setNumberOfParts(1);
 +      chunkedResponseMsg.setLastChunk(true);
 +      chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +      chunkedResponseMsg.sendHeader();
 +      chunkedResponseMsg.addStringPart(message);
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending Error chunk: {}", servConn.getName(), message);
 +      }
 +      chunkedResponseMsg.sendChunk(servConn);
 +    }
 +  }
 +
 +  protected static void writeKeySetErrorResponse(Message origMsg,
 +      int messageType, String message, ServerConnection servConn)
 +      throws IOException {
 +    // Send chunked response header identifying error message
 +    ChunkedMessage chunkedResponseMsg = servConn.getKeySetResponseMessage();
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Sending error message header type: {} transaction: {}",
 +          servConn.getName(), messageType, origMsg.getTransactionId());
 +    }
 +    chunkedResponseMsg.setMessageType(messageType);
 +    chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +    chunkedResponseMsg.sendHeader();
 +    // Send actual error
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Sending error message chunk: {}", servConn.getName(), message);
 +    }
 +    chunkedResponseMsg.setNumberOfParts(1);
 +    chunkedResponseMsg.setLastChunk(true);
 +    chunkedResponseMsg.addStringPart(message);
 +    chunkedResponseMsg.sendChunk(servConn);
 +  }
 +  
 +  static Message readRequest(ServerConnection servConn) {
 +    Message requestMsg = null;
 +    try {
 +      requestMsg = servConn.getRequestMessage();
 +      requestMsg.recv(servConn, MAX_INCOMING_DATA, incomingDataLimiter,
-           MAX_INCOMING_MSGS, incomingMsgLimiter);
++          incomingMsgLimiter);
 +      return requestMsg;
 +    }
 +    catch (EOFException eof) {
 +      handleEOFException(null, servConn, eof);
 +      // TODO:Asif: Check if there is any need for explicitly returning
 +
 +    }
 +    catch (InterruptedIOException e) { // Solaris only
 +      handleInterruptedIOException(null, servConn, e);
 +
 +    }
 +    catch (IOException e) {
 +      handleIOException(null, servConn, e);
 +
 +    }
 +    catch (DistributedSystemDisconnectedException e) {
 +      handleShutdownException(null, servConn, e);
 +
 +    }
 +    catch (VirtualMachineError err) {
 +      SystemFailure.initiateFailure(err);
 +      // If this ever returns, rethrow the error.  We're poisoned
 +      // now, so don't let this thread continue.
 +      throw err;
 +    }
 +    catch (Throwable e) {
 +      SystemFailure.checkFailure();
 +      handleThrowable(null, servConn, e);
 +    }
 +    return requestMsg;
 +  }
 +
 +  protected static void fillAndSendRegisterInterestResponseChunks(
 +      LocalRegion region, Object riKey, int interestType,
 +      InterestResultPolicy policy, ServerConnection servConn)
 +      throws IOException {
 +    fillAndSendRegisterInterestResponseChunks(region, riKey, interestType,
 +        false, policy, servConn);
 +  }
 +
 +  /*
 +   * serializeValues is unused for clients < GFE_80
 +   */
 +  protected static void fillAndSendRegisterInterestResponseChunks(
 +      LocalRegion region, Object riKey, int interestType, boolean serializeValues,
 +      InterestResultPolicy policy, ServerConnection servConn)
 +      throws IOException {
 +    // Client is not interested.
 +    if (policy.isNone()) {
 +      sendRegisterInterestResponseChunk(region, riKey, new ArrayList(), true,
 +          servConn);
 +      return;
 +    }
 +    if (policy.isKeysValues()
 +        && servConn.getClientVersion().compareTo(Version.GFE_80) >= 0) {
 +        handleKeysValuesPolicy(region, riKey, interestType, serializeValues, servConn);
 +        return;
 +    }
 +    if (riKey instanceof List) {
 +      handleList(region, (List)riKey, policy, servConn);
 +      return;
 +    }
 +    if (!(riKey instanceof String)) {
 +      handleSingleton(region, riKey, policy, servConn);
 +      return;
 +    }
 +
 +    switch (interestType) {
 +    case InterestType.OQL_QUERY:
 +      // Not supported yet
 +      throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
 +    case InterestType.FILTER_CLASS:
 +      throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
 +      // handleFilter(region, (String)riKey, policy);
 +      // break;
 +    case InterestType.REGULAR_EXPRESSION: {
 +      String regEx = (String)riKey;
 +      if (regEx.equals(".*")) {
 +        handleAllKeys(region, policy, servConn);
 +      }
 +      else {
 +        handleRegEx(region, regEx, policy, servConn);
 +      }
 +    }
 +      break;
 +    case InterestType.KEY:
 +      if (riKey.equals("ALL_KEYS")) {
 +        handleAllKeys(region, policy, servConn);
 +      }
 +      else {
 +        handleSingleton(region, riKey, policy, servConn);
 +      }
 +      break;
 +    default:
 +      throw new InternalGemFireError(LocalizedStrings.BaseCommand_UNKNOWN_INTEREST_TYPE.toLocalizedString());
 +    }
 +  }
 +
 +  @SuppressWarnings("rawtypes")
 +  private static void handleKeysValuesPolicy(LocalRegion region, Object riKey,
 +      int interestType, boolean serializeValues, ServerConnection servConn)
 +      throws IOException {
 +    if (riKey instanceof List) {
 +      handleKVList(region, (List)riKey, serializeValues, servConn);
 +      return;
 +    }
 +    if (!(riKey instanceof String)) {
 +      handleKVSingleton(region, riKey, serializeValues, servConn);
 +      return;
 +    }
 +
 +    switch (interestType) {
 +    case InterestType.OQL_QUERY:
 +      throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
 +    case InterestType.FILTER_CLASS:
 +      throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
 +    case InterestType.REGULAR_EXPRESSION:
 +      String regEx = (String)riKey;
 +      if (regEx.equals(".*")) {
 +        handleKVAllKeys(region, null, serializeValues, servConn);
 +      } else {
 +        handleKVAllKeys(region, regEx, serializeValues, servConn);
 +      }
 +      break;
 +    case InterestType.KEY:
 +      if (riKey.equals("ALL_KEYS")) {
 +        handleKVAllKeys(region, null, serializeValues, servConn);
 +      } else {
 +        handleKVSingleton(region, riKey, serializeValues, servConn);
 +      }
 +      break;
 +    default:
 +      throw new InternalGemFireError(LocalizedStrings.BaseCommand_UNKNOWN_INTEREST_TYPE.toLocalizedString());
 +    }
 +  }
 +
 +  /**
 +   * @param list
 +   *                is a List of entry keys
 +   */
 +  protected static void sendRegisterInterestResponseChunk(Region region,
 +      Object riKey, ArrayList list, boolean lastChunk, ServerConnection servConn)
 +      throws IOException {
 +    ChunkedMessage chunkedResponseMsg = servConn.getRegisterInterestResponseMessage();
 +    chunkedResponseMsg.setNumberOfParts(1);
 +    chunkedResponseMsg.setLastChunk(lastChunk);
 +    chunkedResponseMsg.addObjPart(list, zipValues);
 +    String regionName = (region == null) ? " null " : region.getFullPath();
 +    if (logger.isDebugEnabled()) {
 +      String str = servConn.getName() + ": Sending"
 +          + (lastChunk ? " last " : " ")
 +          + "register interest response chunk for region: " + regionName
 +          + " for keys: " + riKey + " chunk=<" + chunkedResponseMsg + ">";
 +      logger.debug(str);
 +    }
 +
 +    chunkedResponseMsg.sendChunk(servConn);
 +  }
 +  
 +  /**
 +   * Determines whether keys for destroyed entries (tombstones) should be sent
 +   * to clients in register-interest results.
 +   * 
 +   * @param servConn
 +   * @param policy
 +   * @return true if tombstones should be sent to the client
 +   */
 +  private static boolean sendTombstonesInRIResults(ServerConnection servConn, InterestResultPolicy policy) {
 +    return (policy == InterestResultPolicy.KEYS_VALUES)
 +         && (servConn.getClientVersion().compareTo(Version.GFE_80) >= 0);
 +  }
 +
 +  /**
 +   * Process an interest request involving a list of keys
 +   *
 +   * @param region
 +   *                the region
 +   * @param keyList
 +   *                the list of keys
 +   * @param policy
 +   *                the policy
 +   * @throws IOException
 +   */
 +  private static void handleList(LocalRegion region, List keyList,
 +      InterestResultPolicy policy, ServerConnection servConn)
 +      throws IOException {
 +    if (region instanceof PartitionedRegion) {
 +      // too bad java doesn't provide another way to do this...
 +      handleListPR((PartitionedRegion)region, keyList, policy, servConn);
 +      return;
 +    }
 +    ArrayList newKeyList = new ArrayList(maximumChunkSize);
 +    // Handle list of keys
 +    if (region != null) {
 +      for (Iterator it = keyList.iterator(); it.hasNext();) {
 +        Object entryKey = it.next();
 +        if (region.containsKey(entryKey)
 +            || (sendTombstonesInRIResults(servConn, policy) && region.containsTombstone(entryKey))) {
 +          
 +          appendInterestResponseKey(region, keyList, entryKey, newKeyList,
 +              "list", servConn);
 +        }
 +      }
 +    }
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendRegisterInterestResponseChunk(region, keyList, newKeyList, true,
 +        servConn);
 +  }
 +
 +  /**
 +   * Handles both RR and PR cases
 +   */
 +  @SuppressWarnings("rawtypes")
 +  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="NP_NULL_PARAM_DEREF", justification="Null value handled in sendNewRegisterInterestResponseChunk()")
 +  private static void handleKVSingleton(LocalRegion region, Object entryKey,
 +      boolean serializeValues, ServerConnection servConn)
 +      throws IOException {
 +    VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
 +        true, region == null ? true : region.getAttributes()
 +            .getConcurrencyChecksEnabled(), serializeValues);
 +
 +    if (region != null) {
 +      if (region.containsKey(entryKey) || region.containsTombstone(entryKey)) {
 +        EntryEventImpl versionHolder = EntryEventImpl.createVersionTagHolder();
 +        ClientProxyMembershipID id = servConn == null ? null : servConn.getProxyID();
 +        // From Get70.getValueAndIsObject()
 +        Object data = region.get(entryKey, null, true, true, true, id, versionHolder, true, false);
 +        VersionTag vt = versionHolder.getVersionTag();
 +
 +        updateValues(values, entryKey, data, vt);
 +      }
 +    }
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendNewRegisterInterestResponseChunk(region, entryKey, values, true, servConn);
 +  }
 +
 +  /**
 +   * Process an interest request consisting of a single key
 +   *
 +   * @param region
 +   *                the region
 +   * @param entryKey
 +   *                the key
 +   * @param policy
 +   *                the policy
 +   * @throws IOException
 +   */
 +  private static void handleSingleton(LocalRegion region, Object entryKey,
 +      InterestResultPolicy policy, ServerConnection servConn)
 +      throws IOException {
 +    ArrayList keyList = new ArrayList(1);
 +    if (region != null) {
 +      if (region.containsKey(entryKey) ||
 +          (sendTombstonesInRIResults(servConn, policy) && region.containsTombstone(entryKey))) {
 +        appendInterestResponseKey(region, entryKey, entryKey, keyList,
 +            "individual", servConn);
 +      }
 +    }
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendRegisterInterestResponseChunk(region, entryKey, keyList, true, servConn);
 +  }
 +
 +  /**
 +   * Process an interest request of type ALL_KEYS
 +   *
 +   * @param region
 +   *                the region
 +   * @param policy
 +   *                the policy
 +   * @throws IOException
 +   */
 +  private static void handleAllKeys(LocalRegion region,
 +      InterestResultPolicy policy, ServerConnection servConn)
 +      throws IOException {
 +    ArrayList keyList = new ArrayList(maximumChunkSize);
 +    if (region != null) {
 +      for (Iterator it = region.keySet(sendTombstonesInRIResults(servConn, policy)).iterator(); it.hasNext();) {
 +        appendInterestResponseKey(region, "ALL_KEYS", it.next(), keyList,
 +            "ALL_KEYS", servConn);
 +      }
 +    }
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendRegisterInterestResponseChunk(region, "ALL_KEYS", keyList, true,
 +        servConn);
 +  }
 +
 +  /**
 +   * @param region
 +   * @param regex
 +   * @param serializeValues
 +   * @param servConn
 +   * @throws IOException
 +   */
 +  private static void handleKVAllKeys(LocalRegion region, String regex,
 +      boolean serializeValues, ServerConnection servConn) throws IOException {
 +
 +    if (region != null && region instanceof PartitionedRegion) {
 +      handleKVKeysPR((PartitionedRegion) region, regex, serializeValues, servConn);
 +      return;
 +    }
 +
 +    VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
 +        true, region == null ? true : region.getAttributes()
 +            .getConcurrencyChecksEnabled(), serializeValues);
 +
 +    if (region != null) {
 +
 +      VersionTag versionTag = null;
 +      Object data = null;
 +
 +      Pattern keyPattern = null;
 +      if (regex != null) {
 +        keyPattern = Pattern.compile(regex);
 +      }
 +
 +      for (Object key : region.keySet(true)) {
 +        EntryEventImpl versionHolder = EntryEventImpl.createVersionTagHolder();
 +        if (keyPattern != null) {
 +          if (!(key instanceof String)) {
 +            // key is not a String, cannot apply regex to this entry
 +            continue;
 +          }
 +          if (!keyPattern.matcher((String) key).matches()) {
 +            // key does not match the regex, this entry should not be
 +            // returned.
 +            continue;
 +          }
 +        }
 +
 +        ClientProxyMembershipID id = servConn == null ? null : servConn.getProxyID();
 +        data = region.get(key, null, true, true, true, id, versionHolder, true, false);
 +        versionTag = versionHolder.getVersionTag();
 +        updateValues(values, key, data, versionTag);
 +
 +        if (values.size() == maximumChunkSize) {
 +          sendNewRegisterInterestResponseChunk(region, regex != null ? regex : "ALL_KEYS", values, false, servConn);
 +          values.clear();
 +        }
 +      } // for
 +    } // if
 +
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendNewRegisterInterestResponseChunk(region, regex != null ? regex : "ALL_KEYS", values, true, servConn);
 +  }
 +
 +  private static void handleKVKeysPR(PartitionedRegion region, Object keyInfo,
 +      boolean serializeValues, ServerConnection servConn) throws IOException {
 +    int id = 0;
 +    HashMap<Integer, HashSet> bucketKeys = null;
 +
 +    VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
 +        true, region.getConcurrencyChecksEnabled(), serializeValues);
 +
 +    if (keyInfo != null && keyInfo instanceof List) {
 +      bucketKeys = new HashMap<Integer, HashSet>();
 +      for (Object key : (List) keyInfo) {
 +        id = PartitionedRegionHelper.getHashKey(region, null, key, null, null);
 +        if (bucketKeys.containsKey(id)) {
 +          bucketKeys.get(id).add(key);
 +        } else {
 +          HashSet<Object> keys = new HashSet<Object>();
 +          keys.add(key);
 +          bucketKeys.put(id, keys);
 +        }
 +      }
 +      region.fetchEntries(bucketKeys, values, servConn);
 +    } else { // keyInfo is a String
 +      region.fetchEntries((String)keyInfo, values, servConn);
 +    }
 +
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendNewRegisterInterestResponseChunk(region, keyInfo != null ? keyInfo : "ALL_KEYS", values, true, servConn);
 +  }
 +
 +  /**
 +   * Copied from Get70.getValueAndIsObject(), except a minor change. (Make the
 +   * method static instead of copying it here?)
 +   * 
 +   * @param value
 +   */
 +  private static void updateValues(VersionedObjectList values, Object key, Object value, VersionTag versionTag) {
 +    boolean isObject = true;
 +
 +    // If the value in the VM is a CachedDeserializable,
 +    // get its value. If it is Token.REMOVED, Token.DESTROYED,
 +    // Token.INVALID, or Token.LOCAL_INVALID
 +    // set it to null. If it is NOT_AVAILABLE, get the value from
 +    // disk. If it is already a byte[], set isObject to false.
 +    boolean wasInvalid = false;
 +    if (value instanceof CachedDeserializable) {
 +      value = ((CachedDeserializable)value).getValue();
 +    }
 +    else if (value == Token.REMOVED_PHASE1 || value == Token.REMOVED_PHASE2 || value == Token.DESTROYED || value == Token.TOMBSTONE) {
 +      value = null;
 +    }
 +    else if (value == Token.INVALID || value == Token.LOCAL_INVALID) {
 +      value = null; // fix for bug 35884
 +      wasInvalid = true;
 +    }
 +    else if (value instanceof byte[]) {
 +      isObject = false;
 +    }
 +    boolean keyNotPresent = !wasInvalid && (value == null || value == Token.TOMBSTONE);
 +
 +    if (keyNotPresent) {
 +      values.addObjectPartForAbsentKey(key, value, versionTag);
 +    } else {
 +      values.addObjectPart(key, value, isObject, versionTag);
 +    }
 +  }
 +
 +  public static void appendNewRegisterInterestResponseChunkFromLocal(LocalRegion region,
 +      VersionedObjectList values, Object riKeys, Set keySet, ServerConnection servConn)
 +      throws IOException {
 +    Object key = null;
 +    EntryEventImpl versionHolder = null;
 +    ClientProxyMembershipID requestingClient = servConn == null ? null : servConn.getProxyID();
 +    for (Iterator it = keySet.iterator(); it.hasNext();) {
 +      key = it.next();
 +      versionHolder = EntryEventImpl.createVersionTagHolder();
 +
 +      Object value = region.get(key, null, true, true, true, requestingClient, versionHolder, true, false);
 +      
 +      updateValues(values, key, value, versionHolder.getVersionTag());
 +
 +      if (values.size() == maximumChunkSize) {
 +        // Send the chunk and clear the list
 +        // values.setKeys(null); // Now we need to send keys too.
 +        sendNewRegisterInterestResponseChunk(region, riKeys != null ? riKeys : "ALL_KEYS", values, false, servConn);
 +        values.clear();
 +      }
 +    } // for
 +  }
 +
 +  /**
 +   * 
 +   * @param region
 +   * @param values {@link VersionedObjectList}
 +   * @param riKeys
 +   * @param set set of entries
 +   * @param servConn
 +   * @throws IOException
 +   */
 +  public static void appendNewRegisterInterestResponseChunk(LocalRegion region,
 +      VersionedObjectList values, Object riKeys, Set set, ServerConnection servConn)
 +      throws IOException {
 +    for (Iterator<Map.Entry> it = set.iterator(); it.hasNext();) {
 +      Map.Entry entry = it.next(); // Region.Entry or Map.Entry
 +      if (entry instanceof Region.Entry) { // local entries
 +        VersionTag vt = null;
 +        Object key = null;
 +        Object value = null;
 +        if (entry instanceof EntrySnapshot) {
 +          vt = ((EntrySnapshot) entry).getVersionTag();
 +          key = ((EntrySnapshot) entry).getRegionEntry().getKey();
 +          value = ((EntrySnapshot) entry).getRegionEntry().getValue(null);
 +          updateValues(values, key, value, vt);
 +        } else {
 +          VersionStamp vs = ((NonTXEntry)entry).getRegionEntry().getVersionStamp();
 +          vt = vs == null ? null : vs.asVersionTag();
 +          key = entry.getKey();
 +          value = ((NonTXEntry)entry).getRegionEntry()._getValueRetain(region, true);
 +          try {
 +            updateValues(values, key, value, vt);
 +          } finally {
 +            // TODO OFFHEAP: in the future we might want to delay this release
 +            // until the "values" VersionedObjectList is released.
 +            // But for now "updateValues" copies the off-heap value to the heap.
 +            OffHeapHelper.release(value);
 +          }
 +        }
 +      } else { // Map.Entry (remote entries)
 +        ArrayList list = (ArrayList)entry.getValue();
 +        Object value = list.get(0);
 +        VersionTag tag = (VersionTag)list.get(1);
 +        updateValues(values, entry.getKey(), value, tag);
 +      }
 +      if (values.size() == maximumChunkSize) {
 +        // Send the chunk and clear the list
 +        // values.setKeys(null); // Now we need to send keys too.
 +        sendNewRegisterInterestResponseChunk(region, riKeys != null ? riKeys : "ALL_KEYS", values, false, servConn);
 +        values.clear();
 +      }
 +    } // for
 +  }
 +
 +  public static void sendNewRegisterInterestResponseChunk(LocalRegion region,
 +      Object riKey, VersionedObjectList list, boolean lastChunk, ServerConnection servConn)
 +      throws IOException {
 +    ChunkedMessage chunkedResponseMsg = servConn.getRegisterInterestResponseMessage();
 +    chunkedResponseMsg.setNumberOfParts(1);
 +    chunkedResponseMsg.setLastChunk(lastChunk);
 +    chunkedResponseMsg.addObjPart(list, zipValues);
 +    String regionName = (region == null) ? " null " : region.getFullPath();
 +    if (logger.isDebugEnabled()) {
 +      String str = servConn.getName() + ": Sending"
 +          + (lastChunk ? " last " : " ")
 +          + "register interest response chunk for region: " + regionName
 +          + " for keys: " + riKey + " chunk=<" + chunkedResponseMsg + ">";
 +      logger.debug(str);
 +    }
 +
 +    chunkedResponseMsg.sendChunk(servConn);
 +  }
 +
 +  /**
 +   * Process an interest request of type {@link InterestType#REGULAR_EXPRESSION}
 +   *
 +   * @param region
 +   *                the region
 +   * @param regex
 +   *                the regex
 +   * @param policy
 +   *                the policy
 +   * @throws IOException
 +   */
 +  private static void handleRegEx(LocalRegion region, String regex,
 +      InterestResultPolicy policy, ServerConnection servConn)
 +      throws IOException {
 +    if (region instanceof PartitionedRegion) {
 +      // too bad java doesn't provide another way to do this...
 +      handleRegExPR((PartitionedRegion)region, regex, policy, servConn);
 +      return;
 +    }
 +    ArrayList keyList = new ArrayList(maximumChunkSize);
 +    // Handle the regex pattern
 +    Pattern keyPattern = Pattern.compile(regex);
 +    if (region != null) {
 +      for (Iterator it = region.keySet(sendTombstonesInRIResults(servConn, policy)).iterator(); it.hasNext();) {
 +        Object entryKey = it.next();
 +        if (!(entryKey instanceof String)) {
 +          // key is not a String, cannot apply regex to this entry
 +          continue;
 +        }
 +        if (!keyPattern.matcher((String)entryKey).matches()) {
 +          // key does not match the regex, this entry should not be returned.
 +          continue;
 +        }
 +
 +        appendInterestResponseKey(region, regex, entryKey, keyList, "regex",
 +            servConn);
 +      }
 +    }
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendRegisterInterestResponseChunk(region, regex, keyList, true, servConn);
 +  }
 +
 +  /**
 +   * Process an interest request of type {@link InterestType#REGULAR_EXPRESSION}
 +   *
 +   * @param region
 +   *                the region
 +   * @param regex
 +   *                the regex
 +   * @param policy
 +   *                the policy
 +   * @throws IOException
 +   */
 +  private static void handleRegExPR(final PartitionedRegion region,
 +      final String regex, final InterestResultPolicy policy,
 +      final ServerConnection servConn) throws IOException {
 +    final ArrayList keyList = new ArrayList(maximumChunkSize);
 +    region.getKeysWithRegEx(regex, sendTombstonesInRIResults(servConn, policy), new PartitionedRegion.SetCollector() {
 +      public void receiveSet(Set theSet) throws IOException {
 +        appendInterestResponseKeys(region, regex, theSet, keyList, "regex",
 +            servConn);
 +      }
 +    });
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendRegisterInterestResponseChunk(region, regex, keyList, true, servConn);
 +  }
 +
 +  /**
 +   * Process an interest request involving a list of keys
 +   *
 +   * @param region
 +   *                the region
 +   * @param keyList
 +   *                the list of keys
 +   * @param policy
 +   *                the policy
 +   * @throws IOException
 +   */
 +  private static void handleListPR(final PartitionedRegion region,
 +      final List keyList, final InterestResultPolicy policy,
 +      final ServerConnection servConn) throws IOException {
 +    final ArrayList newKeyList = new ArrayList(maximumChunkSize);
 +    region.getKeysWithList(keyList, sendTombstonesInRIResults(servConn, policy), new PartitionedRegion.SetCollector() {
 +      public void receiveSet(Set theSet) throws IOException {
 +        appendInterestResponseKeys(region, keyList, theSet, newKeyList, "list",
 +            servConn);
 +      }
 +    });
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendRegisterInterestResponseChunk(region, keyList, newKeyList, true,
 +        servConn);
 +  }
 +
 +  @SuppressWarnings("rawtypes")
 +  private static void handleKVList(final LocalRegion region,
 +      final List keyList, boolean serializeValues,
 +      final ServerConnection servConn) throws IOException {
 +
 +    if (region != null && region instanceof PartitionedRegion) {
 +      handleKVKeysPR((PartitionedRegion)region, keyList, serializeValues, servConn);
 +      return;
 +    }
 +    VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
 +        true, region == null ? true : region.getAttributes()
 +            .getConcurrencyChecksEnabled(), serializeValues);
 +
 +    // Handle list of keys
 +    if (region != null) {
 +      VersionTag versionTag = null;
 +      Object data = null;
 +
 +      for (Iterator it = keyList.iterator(); it.hasNext();) {
 +        Object key = it.next();
 +        if (region.containsKey(key) || region.containsTombstone(key)) {
 +          EntryEventImpl versionHolder = EntryEventImpl
 +              .createVersionTagHolder();
 +
 +          ClientProxyMembershipID id = servConn == null ? null : servConn
 +              .getProxyID();
 +          data = region.get(key, null, true, true, true, id, versionHolder,
 +              true, false);
 +          versionTag = versionHolder.getVersionTag();
 +          updateValues(values, key, data, versionTag);
 +
 +          if (values.size() == maximumChunkSize) {
 +            // Send the chunk and clear the list
 +            // values.setKeys(null); // Now we need to send keys too.
 +            sendNewRegisterInterestResponseChunk(region, keyList, values, false, servConn);
 +            values.clear();
 +          }
 +        }
 +      }
 +    }
 +    // Send the last chunk (the only chunk for individual and list keys)
 +    // always send it back, even if the list is of zero size.
 +    sendNewRegisterInterestResponseChunk(region, keyList, values, true, servConn);
 +  }
 +
 +  /**
 +   * Append an interest response
 +   *
 +   * @param region
 +   *                the region (for debugging)
 +   * @param riKey
 +   *                the registerInterest "key" (what the client is interested
 +   *                in)
 +   * @param entryKey
 +   *                key we're responding to
 +   * @param list
 +   *                list to append to
 +   * @param kind
 +   *                for debugging
 +   */
 +  private static void appendInterestResponseKey(LocalRegion region,
 +      Object riKey, Object entryKey, ArrayList list, String kind,
 +      ServerConnection servConn) throws IOException {
 +    list.add(entryKey);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: appendInterestResponseKey <{}>; list size was {}; region: {}",
 +          servConn.getName(), entryKey, list.size(), region.getFullPath());
 +    }
 +    if (list.size() == maximumChunkSize) {
 +      // Send the chunk and clear the list
 +      sendRegisterInterestResponseChunk(region, riKey, list, false, servConn);
 +      list.clear();
 +    }
 +  }
 +
 +  protected static void appendInterestResponseKeys(LocalRegion region,
 +      Object riKey, Collection entryKeys, ArrayList collector, String riDescr,
 +      ServerConnection servConn) throws IOException {
 +    for (Iterator it = entryKeys.iterator(); it.hasNext();) {
 +      appendInterestResponseKey(region, riKey, it.next(), collector, riDescr,
 +          servConn);
 +    }
 +  }
 +}


[039/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/LonerDistributionManager.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/LonerDistributionManager.java
index 419c096,0000000..c958028
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/LonerDistributionManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/LonerDistributionManager.java
@@@ -1,997 -1,0 +1,1001 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal;
 +
 +import java.io.Serializable;
 +import java.net.InetAddress;
 +import java.net.UnknownHostException;
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.NoSuchElementException;
 +import java.util.Set;
 +import java.util.Vector;
 +import java.util.concurrent.Callable;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentMap;
 +import java.util.concurrent.ExecutionException;
 +import java.util.concurrent.ExecutorService;
 +import java.util.concurrent.Future;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.TimeoutException;
 +
 +import com.gemstone.gemfire.CancelCriterion;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DurableClientAttributes;
 +import com.gemstone.gemfire.distributed.Role;
 +import com.gemstone.gemfire.distributed.internal.locks.ElderState;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.MemberAttributes;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 +import com.gemstone.gemfire.i18n.LogWriterI18n;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +
 +/**
 + * A <code>LonerDistributionManager</code> is a dm that never communicates
 + * with anyone else.
 + *
 + * @author Darrel
 + *
 + *
 + * @since 3.5
 + */
 +public class LonerDistributionManager implements DM {
 +  private final InternalDistributedSystem system;
 +  private final InternalLogWriter logger;
 +  private ElderState elderState;
 +  
 +  
 +  ////////////////////////  Constructors  ////////////////////////
 +
 +  /**
 +   * Creates a new local distribution manager
 +   *
 +   * @param system
 +   *        The distributed system to which this distribution manager
 +   *        will send messages.
 +   *
 +   */
 +  public LonerDistributionManager(InternalDistributedSystem system,
 +                                  InternalLogWriter logger) {
 +    this.system = system;
 +    this.logger = logger;
 +    this.id = generateMemberId();
 +    this.allIds = Collections.singleton(id);
 +    this.viewMembers = new ArrayList<InternalDistributedMember>(allIds);
 +    DistributionStats.enableClockStats = this.system.getConfig().getEnableTimeStatistics();
 +  }
 +
 +  //////////////////////  Instance Methods  //////////////////////
 +
 +  protected void startThreads() {
 +    // no threads needed
 +  }
 +
 +  protected void shutdown() {
 +  }
 +
 +  private final InternalDistributedMember id;
 +
 +  /*static {
 +    // Make the id a little unique
 +    String host;
 +    try {
 +      host = InetAddress.getLocalHost().getCanonicalHostName();
 +      MemberAttributes.setDefaults(65535,
 +              com.gemstone.gemfire.internal.OSProcess.getId(),
 +              DistributionManager.LONER_DM_TYPE,
 +              MemberAttributes.parseRoles(system.getConfig().getRoles()));
 +      id = new InternalDistributedMember(host, 65535); // noise value for port number
 +
 +    } catch (UnknownHostException ex) {
 +      throw new InternalError(LocalizedStrings.LonerDistributionManager_CANNOT_RESOLVE_LOCAL_HOST_NAME_TO_AN_IP_ADDRESS.toLocalizedString());
 +    }
 +
 +  }*/
 +
 +  private final Set<InternalDistributedMember> allIds;// = Collections.singleton(id);
 +  private final List<InternalDistributedMember> viewMembers;
 +  private ConcurrentMap<InternalDistributedMember, InternalDistributedMember> canonicalIds = new ConcurrentHashMap();
 +  static private final DummyDMStats stats = new DummyDMStats();
 +  static private final DummyExecutor executor = new DummyExecutor();
 +
 +  @Override
 +  public long cacheTimeMillis() {
 +    return this.system.getClock().cacheTimeMillis();
 +  }
 +  public InternalDistributedMember getDistributionManagerId() {
 +    return id;
 +  }
 +
 +  public Set getDistributionManagerIds() {
 +    return allIds;
 +  }
 +
 +  public Set getDistributionManagerIdsIncludingAdmin() {
 +    return allIds;
 +  }
 +  public Serializable[] getDirectChannels(InternalDistributedMember[] ids) {
 +    return ids;
 +  }
 +  
 +  public InternalDistributedMember getCanonicalId(DistributedMember dmid) {
 +    InternalDistributedMember iid = (InternalDistributedMember)dmid;
 +    InternalDistributedMember result = this.canonicalIds.putIfAbsent(iid,iid);
 +    if (result != null) {
 +      return result;
 +    }
 +    return iid;
 +  }
 +
 +  public Set getOtherDistributionManagerIds() {
 +    return Collections.EMPTY_SET;
 +  }
 +  @Override
 +  public Set getOtherNormalDistributionManagerIds() {
 +    return Collections.EMPTY_SET;
 +  }
 +  public Set getAllOtherMembers() {
 +    return Collections.EMPTY_SET;
 +  }
 +  
 +  @Override // DM method
 +  public void retainMembersWithSameOrNewerVersion(Collection<InternalDistributedMember> members, Version version) {
 +    for (Iterator<InternalDistributedMember> it = members.iterator(); it.hasNext(); ) {
 +      InternalDistributedMember id = it.next();
 +      if (id.getVersionObject().compareTo(version) < 0) {
 +        it.remove();
 +      }
 +    }
 +  }
 +  
 +  @Override // DM method
 +  public void removeMembersWithSameOrNewerVersion(Collection<InternalDistributedMember> members, Version version) {
 +    for (Iterator<InternalDistributedMember> it = members.iterator(); it.hasNext(); ) {
 +      InternalDistributedMember id = it.next();
 +      if (id.getVersionObject().compareTo(version) >= 0) {
 +        it.remove();
 +      }
 +    }
 +  }
 +  
 +
 +  public Set addMembershipListenerAndGetDistributionManagerIds(MembershipListener l) {
 +    //return getOtherDistributionManagerIds();
 +    return allIds;
 +  }
 +  public Set addAllMembershipListenerAndGetAllIds(MembershipListener l) {
 +    return allIds;
 +  }
 +  public int getDistributionManagerCount() {
 +    return 0;
 +  }
 +  public InternalDistributedMember getId() {
 +    return getDistributionManagerId();
 +  }
 +  public boolean isAdam() {
 +    return true;
 +  }
 +  public InternalDistributedMember getElderId() {
 +    return getId();
 +  }
 +  public boolean isElder() {
 +    return true;
 +  }
 +  public boolean isLoner() {
 +    return true;
 +  }
 +
 +  public synchronized ElderState getElderState(boolean force, boolean useTryLock) {
 +    // loners are always the elder
 +    if (this.elderState == null) {
 +      this.elderState = new ElderState(this);
 +    }
 +    return this.elderState;
 +  }
 +
 +  public long getChannelId() {
 +    return 0;
 +  }
 +
 +  public Set putOutgoingUserData(final DistributionMessage message) {
 +    if (message.forAll() || message.getRecipients().length == 0) {
 +      // do nothing
 +      return null;
 +    } else {
 +      throw new RuntimeException(LocalizedStrings.LonerDistributionManager_LONER_TRIED_TO_SEND_MESSAGE_TO_0.toLocalizedString(message.getRecipientsDescription()));
 +    }
 +  }
 +  public InternalDistributedSystem getSystem() {
 +    return this.system;
 +  }
 +  public void addMembershipListener(MembershipListener l) {}
 +
 +  public void removeMembershipListener(MembershipListener l) {}
 +  public void removeAllMembershipListener(MembershipListener l) {}
 +
 +  public void addAdminConsole(InternalDistributedMember p_id) {}
 +
 +  public DMStats getStats() {
 +    return stats;
 +  }
 +  public DistributionConfig getConfig() {
 +    DistributionConfig result = null;
 +    if (getSystem() != null) {
 +      result = getSystem().getConfig();
 +    }
 +    return result;
 +  }
 +
 +  public void handleManagerDeparture(InternalDistributedMember p_id, 
 +      boolean crashed, String reason) {}
 +
 +  public LogWriterI18n getLoggerI18n() {
 +    return this.logger;
 +  }
 +  public InternalLogWriter getInternalLogWriter() {
 +    return this.logger;
 +  }
 +  public ExecutorService getThreadPool() {
 +    return executor;
 +  }
 +  public ExecutorService getHighPriorityThreadPool() {
 +    return executor;
 +  }
 +  public ExecutorService getWaitingThreadPool() {
 +    return executor;
 +  }
 +  public ExecutorService getPrMetaDataCleanupThreadPool() {
 +    return executor;
 +  }
 +  public Map getChannelMap() {
 +    return null;
 +  }
 +  public Map getMemberMap() {
 +    return null;
 +  }
 +  public void close() {
 +  }
 +  public void restartCommunications() {
 +
 +  }
 +  
 +  @Override
 +  public List<InternalDistributedMember> getViewMembers() {
 +    return viewMembers;
 +  }
 +
 +  public DistributedMember getOldestMember(Collection members) throws NoSuchElementException {
 +    if (members.size() == 1) {
 +      DistributedMember member = (DistributedMember)members.iterator().next();
 +      if (member.equals(viewMembers.get(0))) {
 +        return member;
 +      }
 +    }
 +    throw new NoSuchElementException(LocalizedStrings.LonerDistributionManager_MEMBER_NOT_FOUND_IN_MEMBERSHIP_SET.toLocalizedString());
 +  }
 +
 +  public Set getAdminMemberSet(){ return Collections.EMPTY_SET; }
 +
 +  public static class DummyDMStats implements DMStats {
 +    @Override
 +    public long getSentMessages() {return 0;}
 +    @Override
 +    public void incSentMessages(long messages) {}
 +    @Override
 +    public void incTOSentMsg() {}
 +    @Override
 +    public long getSentCommitMessages() {return 0;}
 +    @Override
 +    public void incSentCommitMessages(long messages) {}
 +    @Override
 +    public long getCommitWaits() {return 0;}
 +    @Override
 +    public void incCommitWaits() {}
 +    @Override
 +    public long getSentMessagesTime() {return 0;}
 +    @Override
 +    public void incSentMessagesTime(long nanos) {}
 +    @Override
 +    public long getBroadcastMessages() {return 0;}
 +    @Override
 +    public void incBroadcastMessages(long messages) {}
 +    @Override
 +    public long getBroadcastMessagesTime() {return 0;}
 +    @Override
 +    public void incBroadcastMessagesTime(long nanos) {}
 +    @Override
 +    public long getReceivedMessages() {return 0;}
 +    @Override
 +    public void incReceivedMessages(long messages) {}
 +    @Override
 +    public long getReceivedBytes() {return 0;}
 +    @Override
 +    public void incReceivedBytes(long bytes) {}
 +    @Override
 +    public void incSentBytes(long bytes) {}
 +    @Override
 +    public long getProcessedMessages() {return 0;}
 +    @Override
 +    public void incProcessedMessages(long messages) {}
 +    @Override
 +    public long getProcessedMessagesTime() {return 0;}
 +    @Override
 +    public void incProcessedMessagesTime(long nanos) {}
 +    @Override
 +    public long getMessageProcessingScheduleTime() {return 0;}
 +    @Override
 +    public void incMessageProcessingScheduleTime(long nanos) {}
 +    @Override
 +    public int getOverflowQueueSize() {return 0;}
 +    @Override
 +    public void incOverflowQueueSize(int messages) {}
 +    @Override
 +    public int getNumProcessingThreads() {return 0;}
 +    @Override
 +    public void incNumProcessingThreads(int threads) {}
 +    @Override
 +    public int getNumSerialThreads() {return 0;}
 +    @Override
 +    public void incNumSerialThreads(int threads) {}
 +    @Override
 +    public void incMessageChannelTime(long val) {}
 +    @Override
++    public void incUDPDispatchRequestTime(long val) {};
++    @Override
++    public long getUDPDispatchRequestTime() {return 0;};
++    @Override
 +    public long getReplyMessageTime() {return 0;}
 +    @Override
 +    public void incReplyMessageTime(long val) {}
 +    @Override
 +    public long getDistributeMessageTime() {return 0;}
 +    @Override
 +    public void incDistributeMessageTime(long val) {}
 +    @Override
 +    public int getNodes() {return 0;}
 +    @Override
 +    public void setNodes(int val) {}
 +    @Override
 +    public void incNodes(int val) {}
 +    @Override
 +    public int getReplyWaitsInProgress() {return 0;}
 +    @Override
 +    public int getReplyWaitsCompleted() {return 0;}
 +    @Override
 +    public long getReplyWaitTime() {return 0;}
 +    @Override
 +    public long startReplyWait() {return 0;}
 +    @Override
 +    public void endReplyWait(long startNanos, long startMillis) {}
 +    @Override
 +    public void incReplyTimeouts() { }
 +    @Override
 +    public long getReplyTimeouts() { return 0; }
 +    @Override
 +    public void incReceivers() {}
 +    @Override
 +    public void decReceivers() {}
 +    @Override
 +    public void incFailedAccept() {}
 +    @Override
 +    public void incFailedConnect() {}
 +    @Override
 +    public void incReconnectAttempts() {}
 +    @Override
 +    public void incLostLease() {}
 +    @Override
 +    public void incSenders(boolean shared, boolean preserveOrder) {}
 +    @Override
 +    public void decSenders(boolean shared, boolean preserveOrder) {}
 +    @Override
 +    public int getSendersSU() { return 0; }
 +    @Override
 +    public long startSocketWrite(boolean sync) {return 0; }
 +    @Override
 +    public void endSocketWrite(boolean sync, long start, int bytesWritten, int retries) {}
 +    @Override
 +    public long startSerialization() {return 0;}
 +    @Override
 +    public void endSerialization(long start, int bytes) {}
 +    @Override
 +    public long startDeserialization() {return 0;}
 +    @Override
 +    public void endDeserialization(long start, int bytes) {}
 +    @Override
 +    public long startMsgSerialization() {return 0;}
 +    @Override
 +    public void endMsgSerialization(long start) {}
 +    @Override
 +    public long startMsgDeserialization() {return 0;}
 +    @Override
 +    public void endMsgDeserialization(long start) {}
 +    @Override
 +    public void incBatchSendTime(long start) {}
 +    @Override
 +    public void incBatchCopyTime(long start) {}
 +    @Override
 +    public void incBatchWaitTime(long start) {}
 +    @Override
 +    public void incBatchFlushTime(long start) {}
 +    @Override
 +    public void incUcastWriteBytes(int bytesWritten) {}
 +    @Override
 +    public void incMcastWriteBytes(int bytesWritten) {}
 +    @Override
 +    public void incUcastRetransmits() {}
 +    @Override
 +    public void incMcastRetransmits() {}
 +    @Override
 +    public void incMcastRetransmitRequests() {}
 +    @Override
 +    public int getMcastRetransmits() { return 0; }
 +    @Override
 +    public int getMcastWrites() { return 0; }
 +    @Override
 +    public int getMcastReads() { return 0; }
 +    @Override
 +    public void incUcastReadBytes(int amount) {}
 +    @Override
 +    public void incMcastReadBytes(int amount) {}
 +    @Override
 +    public int getAsyncSocketWritesInProgress() {return 0;}
 +    @Override
 +    public int getAsyncSocketWrites() {return 0;}
 +    @Override
 +    public int getAsyncSocketWriteRetries() {return 0;}
 +    @Override
 +    public long getAsyncSocketWriteBytes() {return 0;}
 +    @Override
 +    public long getAsyncSocketWriteTime() {return 0;}
 +    @Override
 +    public int getAsyncQueues() {return 0;}
 +    @Override
 +    public void incAsyncQueues(int inc) {}
 +    @Override
 +    public int getAsyncQueueFlushesInProgress() {return 0;}
 +    @Override
 +    public int getAsyncQueueFlushesCompleted() {return 0;}
 +    @Override
 +    public long getAsyncQueueFlushTime() {return 0;}
 +    @Override
 +    public long startAsyncQueueFlush() {return 0;}
 +    @Override
 +    public void endAsyncQueueFlush(long start) {}
 +    @Override
 +    public int getAsyncQueueTimeouts() {return 0;}
 +    @Override
 +    public void incAsyncQueueTimeouts(int inc) {}
 +    @Override
 +    public int getAsyncQueueSizeExceeded() {return 0;}
 +    @Override
 +    public void incAsyncQueueSizeExceeded(int inc) {}
 +    @Override
 +    public int getAsyncDistributionTimeoutExceeded() {return 0;}
 +    @Override
 +    public void incAsyncDistributionTimeoutExceeded() {}
 +    @Override
 +    public long getAsyncQueueSize() {return 0;}
 +    @Override
 +    public void incAsyncQueueSize(long inc) {}
 +    @Override
 +    public long getAsyncQueuedMsgs() {return 0;}
 +    @Override
 +    public void incAsyncQueuedMsgs() {}
 +    @Override
 +    public long getAsyncDequeuedMsgs() {return 0;}
 +    @Override
 +    public void incAsyncDequeuedMsgs() {}
 +    @Override
 +    public long getAsyncConflatedMsgs() {return 0;}
 +    @Override
 +    public void incAsyncConflatedMsgs() {}
 +    @Override
 +    public int getAsyncThreads() {return 0;}
 +    @Override
 +    public void incAsyncThreads(int inc) {}
 +    @Override
 +    public int getAsyncThreadInProgress() {return 0;}
 +    @Override
 +    public int getAsyncThreadCompleted() {return 0;}
 +    @Override
 +    public long getAsyncThreadTime() {return 0;}
 +    @Override
 +    public long startAsyncThread() {return 0;}
 +    @Override
 +    public void endAsyncThread(long start) {}
 +    @Override
 +    public long getAsyncQueueAddTime() {return 0;}
 +    @Override
 +    public void incAsyncQueueAddTime(long inc) {}
 +    @Override
 +    public long getAsyncQueueRemoveTime() {return 0;}
 +    @Override
 +    public void incAsyncQueueRemoveTime(long inc) {}
 +    @Override
 +    public void incReceiverBufferSize(int inc, boolean direct) {}
 +    @Override
 +    public void incSenderBufferSize(int inc, boolean direct) {}
 +    @Override
 +    public long startSocketLock() {return 0;}
 +    @Override
 +    public void endSocketLock(long start) {}
 +    @Override
 +    public long startBufferAcquire() {return 0;}
 +    @Override
 +    public void endBufferAcquire(long start) {}
 +    @Override
 +    public void incMessagesBeingReceived(boolean newMsg, int bytes) {}
 +    @Override
 +    public void decMessagesBeingReceived(int bytes) {}
 +    @Override
 +    public void incReplyHandOffTime(long start) {}
 +    @Override
 +    public int getElders() {return 0;}
 +    @Override
 +    public void incElders(int val) {}
 +    @Override
 +    public int getInitialImageMessagesInFlight() {return 0;}
 +    @Override
 +    public void incInitialImageMessagesInFlight(int val) {}
 +    @Override
 +    public int getInitialImageRequestsInProgress() {return 0;}
 +    @Override
 +    public void incInitialImageRequestsInProgress(int val) {}
 +    @Override
 +    public void incPdxSerialization(int bytesWritten) {}
 +    @Override
 +    public void incPdxDeserialization(int i) {}
 +    @Override
 +    public long startPdxInstanceDeserialization() {return 0;}
 +    @Override
 +    public void endPdxInstanceDeserialization(long start) {}
 +    @Override
 +    public void incPdxInstanceCreations() {}
 +    @Override
 +    public void incThreadOwnedReceivers(long value, int dominoCount) {
 +    }
 +    @Override
 +    public long getHeartbeatRequestsSent() {return 0;}
 +    @Override
 +    public void incHeartbeatRequestsSent() {}
 +    @Override
 +    public long getHeartbeatRequestsReceived() {return 0;}
 +    @Override
 +    public void incHeartbeatRequestsReceived() {}
 +    @Override
 +    public long getHeartbeatsSent() {return 0;}
 +    @Override
 +    public void incHeartbeatsSent() {}
 +    @Override
 +    public long getHeartbeatsReceived() {return 0;}
 +    @Override
 +    public void incHeartbeatsReceived() {}
 +    @Override
 +    public long getSuspectsSent() {return 0;}
 +    @Override
 +    public void incSuspectsSent() {}
 +    @Override
 +    public long getSuspectsReceived() {return 0;}
 +    @Override
 +    public void incSuspectsReceived() {}
 +    @Override
 +    public long getFinalCheckRequestsSent() {return 0;}
 +    @Override
 +    public void incFinalCheckRequestsSent() {}
 +    @Override
 +    public long getFinalCheckRequestsReceived() {return 0;}
 +    @Override
 +    public void incFinalCheckRequestsReceived() {}
 +    @Override
 +    public long getFinalCheckResponsesSent() {return 0;}
 +    @Override
 +    public void incFinalCheckResponsesSent() {}
 +    @Override
 +    public long getFinalCheckResponsesReceived() {return 0;}
 +    @Override
 +    public void incFinalCheckResponsesReceived() {}
 +    @Override    
 +    public long getTcpFinalCheckRequestsSent() {return 0;}
 +    @Override
 +    public void incTcpFinalCheckRequestsSent() {}
 +    @Override
 +    public long getTcpFinalCheckRequestsReceived() {return 0;}
 +    @Override
 +    public void incTcpFinalCheckRequestsReceived() {}
 +    @Override
 +    public long getTcpFinalCheckResponsesSent() {return 0;}
 +    @Override
 +    public void incTcpFinalCheckResponsesSent() {}
 +    @Override
 +    public long getTcpFinalCheckResponsesReceived() {return 0;}
 +    @Override
 +    public void incTcpFinalCheckResponsesReceived() {}
 +    @Override
 +    public long getUdpFinalCheckRequestsSent() {return 0;}
 +    @Override
 +    public void incUdpFinalCheckRequestsSent() {}
 +    @Override
 +    public long getUdpFinalCheckResponsesReceived() {return 0;}
 +    @Override
 +    public void incUdpFinalCheckResponsesReceived() {}
 +  }
 +  protected static class DummyExecutor implements ExecutorService {
 +    @Override
 +    public void execute(Runnable command) {
 +      command.run();
 +    }
 +
 +    @Override
 +    public void shutdown() {
 +    }
 +
 +    @Override
 +    public List<Runnable> shutdownNow() {
 +      return Collections.emptyList();
 +    }
 +
 +    @Override
 +    public boolean isShutdown() {
 +      return false;
 +    }
 +
 +    @Override
 +    public boolean isTerminated() {
 +      return false;
 +    }
 +
 +    @Override
 +    public boolean awaitTermination(long timeout, TimeUnit unit)
 +        throws InterruptedException {
 +      return true;
 +    }
 +
 +    @Override
 +    public <T> Future<T> submit(final Callable<T> task) {
 +      Exception ex = null;
 +      T result = null;
 +      try {
 +        result = task.call();
 +      } catch (Exception e) {
 +        ex = e;
 +      }
 +      return new CompletedFuture<T>(result, ex);
 +    }
 +
 +    @Override
 +    public <T> Future<T> submit(final Runnable task, final T result) {
 +      return submit(new Callable<T>() {
 +        @Override
 +        public T call() throws Exception {
 +          task.run();
 +          return result;
 +        }
 +      });
 +    }
 +
 +    @Override
 +    public Future<?> submit(Runnable task) {
 +      return submit(task, null);
 +    }
 +
 +    @Override
 +    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
 +        throws InterruptedException {
 +      List<Future<T>> results = new ArrayList<Future<T>>();
 +      for (Callable<T> task : tasks) {
 +        results.add(submit(task));
 +      }
 +      return results;
 +    }
 +
 +    @Override
 +    public <T> List<Future<T>> invokeAll(
 +        Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
 +        throws InterruptedException {
 +      return invokeAll(tasks);
 +    }
 +
 +    @Override
 +    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
 +        throws InterruptedException, ExecutionException {
 +
 +      ExecutionException ex = null;
 +      for (Callable<T> task : tasks) {
 +        try {
 +          return submit(task).get();
 +        } catch (ExecutionException e) {
 +          ex = e;
 +        }
 +      }
 +      throw (ExecutionException) ex.fillInStackTrace();
 +    }
 +
 +    @Override
 +    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
 +        long timeout, TimeUnit unit) throws InterruptedException,
 +        ExecutionException, TimeoutException {
 +      return invokeAny(tasks);
 +    }
 +  }
 +  
 +  private static class CompletedFuture<T> implements Future<T> {
 +    private final T result;
 +    private final Exception ex;
 +    
 +    public CompletedFuture(T result, Exception ex) {
 +      this.result = result;
 +      this.ex = ex;
 +    }
 +    
 +    @Override
 +    public boolean cancel(boolean mayInterruptIfRunning) {
 +      return false;
 +    }
 +
 +    @Override
 +    public boolean isCancelled() {
 +      return false;
 +    }
 +
 +    @Override
 +    public boolean isDone() {
 +      return true;
 +    }
 +
 +    @Override
 +    public T get() throws InterruptedException, ExecutionException {
 +      if (ex != null) {
 +        throw new ExecutionException(ex);
 +      }
 +      return result;
 +    }
 +
 +    @Override
 +    public T get(long timeout, TimeUnit unit) throws InterruptedException,
 +        ExecutionException, TimeoutException {
 +      return get();
 +    }
 +  }
 +  
 +  public void throwIfDistributionStopped() {
 +    stopper.checkCancelInProgress(null);
 +  }
 +
 +  /** Returns count of members filling the specified role */
 +  public int getRoleCount(Role role) {
 +    return id.getRoles().contains(role) ? 1 : 0;
 +  }
 +
 +  /** Returns true if at least one member is filling the specified role */
 +  public boolean isRolePresent(Role role) {
 +    return id.getRoles().contains(role);
 +  }
 +
 +  /** Returns a set of all roles currently in the distributed system. */
 +  public Set getAllRoles() {
 +    return id.getRoles();
 +  }
 +
 +  private int lonerPort = 0;
 +
 +  //private static final int CHARS_32KB = 16384;
 +  private InternalDistributedMember generateMemberId() {
 +    InternalDistributedMember result = null;
 +    String host;
 +    try {
 +      // create string of the current millisecond clock time
 +      StringBuffer sb = new StringBuffer();
 +      // use low four bytes for backward compatibility
 +      long time = System.currentTimeMillis() & 0xffffffffL;
 +      for (int i = 0; i < 4; i++) {
 +        String hex = Integer.toHexString((int)(time & 0xff));
 +        if (hex.length() < 2) {
 +          sb.append('0');
 +        }
 +        sb.append(hex);
 +        time = time / 0x100;
 +      }
 +      String uniqueString = sb.toString();
 +
 +      String name = this.system.getName();
 +
 +      host = SocketCreator.getLocalHost().getCanonicalHostName();
 +      DistributionConfig config = system.getConfig();
 +      DurableClientAttributes dac = null;
 +      if (config.getDurableClientId() != null) {
 +        dac = new DurableClientAttributes(config.getDurableClientId(), config
 +            .getDurableClientTimeout());
 +      }
 +      result = new InternalDistributedMember(host, lonerPort, name, uniqueString, DistributionManager.LONER_DM_TYPE,
 +          MemberAttributes.parseGroups(config.getRoles(), config.getGroups()), dac);
 +
 +    } catch (UnknownHostException ex) {
 +      throw new InternalGemFireError(LocalizedStrings.LonerDistributionManager_CANNOT_RESOLVE_LOCAL_HOST_NAME_TO_AN_IP_ADDRESS.toLocalizedString());
 +    }
 +    return result;
 +  }
 +
 +  /**
 +   * update the loner port with an integer that may be more unique than the 
 +   * default port (zero).  This updates the ID in place and establishes new
 +   * default settings for the manufacture of new IDs.
 +   * 
 +   * @param newPort the new port to use
 +   */
 +  public void updateLonerPort(int newPort) {
 +    this.lonerPort = newPort;
 +    this.getId().setPort(this.lonerPort);
 +    this.logger.config(LocalizedStrings.LonerDistributionmanager_CHANGING_PORT_FROM_TO,
 +        new Object[]{this.lonerPort, newPort, getId()});
 +  }
 +  public boolean isCurrentMember(InternalDistributedMember p_id) {
 +    return getId().equals(p_id);
 +  }
 +
 +  public Set putOutgoing(DistributionMessage msg)
 +  {
 +    return null;
 +  }
 +
 +  public boolean shutdownInProgress() {
 +    return false;
 +  }
 +
 +  public void removeUnfinishedStartup(InternalDistributedMember m, boolean departed) {
 +  }
 +
 +  public void setUnfinishedStartups(Collection s) {
 +  }
 +
 +  protected static class Stopper extends CancelCriterion {
 +
 +    @Override
 +    public String cancelInProgress() {
 +      checkFailure();
 +      return null;
 +    }
 +
 +    @Override
 +    public RuntimeException generateCancelledException(Throwable e) {
 +      return null;
 +    }
 +  }
 +  private final Stopper stopper = new Stopper();
 +
 +  public CancelCriterion getCancelCriterion() {
 +    return stopper;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.distributed.internal.DM#getMembershipManager()
 +   */
 +  public MembershipManager getMembershipManager() {
 +    // no membership manager
 +    return null;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.distributed.internal.DM#getRootCause()
 +   */
 +  public Throwable getRootCause() {
 +    return null;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.distributed.internal.DM#setRootCause(java.lang.Throwable)
 +   */
 +  public void setRootCause(Throwable t) {
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.distributed.internal.DM#getMembersOnThisHost()
 +   * @since gemfire59poc
 +   */
 +  public Set<InternalDistributedMember> getMembersInThisZone() {
 +    return this.allIds;
 +  }
 +
 +  public void acquireGIIPermitUninterruptibly() {
 +  }
 +
 +  public void releaseGIIPermit() {
 +  }
 +
 +  public int getDistributedSystemId() {
 +    return getSystem().getConfig().getDistributedSystemId();
 +  }
 +
 +  public boolean enforceUniqueZone() {
 +    return system.getConfig().getEnforceUniqueHost() || system.getConfig().getRedundancyZone() != null;
 +  }
 +
 +  public boolean areInSameZone(InternalDistributedMember member1,
 +      InternalDistributedMember member2) {
 +    return false;
 +  }
 +
 +  public boolean areOnEquivalentHost(InternalDistributedMember member1,
 +                                     InternalDistributedMember member2) {
 +    return member1 == member2;
 +  }
 +  
 +  public Set<InternalDistributedMember> getMembersInSameZone(
 +      InternalDistributedMember acceptedMember) {
 +    return Collections.singleton(acceptedMember);
 +  }
 +  
 +  public Set<InetAddress> getEquivalents(InetAddress in) {
 +    Set<InetAddress> value = new HashSet<InetAddress>();
 +    value.add(this.getId().getInetAddress());
 +    return value;
 +  }
 +
 +  public Set<DistributedMember> getGroupMembers(String group) {
 +    if (getDistributionManagerId().getGroups().contains(group)) {
 +      return Collections.singleton((DistributedMember)getDistributionManagerId());
 +    } else {
 +      return Collections.emptySet();
 +    }
 +  }
 +
 +  public void addHostedLocators(InternalDistributedMember member, Collection<String> locators, boolean isSharedConfigurationEnabled) {
 +    // no-op
 +  }
 +  
 +  public Collection<String> getHostedLocators(InternalDistributedMember member) {
 +    return Collections.<String>emptyList();
 +  }
 +  
 +  public Map<InternalDistributedMember, Collection<String>> getAllHostedLocators() {
 +    return Collections.<InternalDistributedMember, Collection<String>>emptyMap();
 +  }
 +
 +  @Override
 +  public Set getNormalDistributionManagerIds() {
 +    return getDistributionManagerIds();
 +  }
 +
 +  @Override
 +  public Map<InternalDistributedMember, Collection<String>> getAllHostedLocatorsWithSharedConfiguration() {
 +    return Collections.<InternalDistributedMember, Collection<String>>emptyMap();
 +  }
 +
 +  @Override
 +  public void forceUDPMessagingForCurrentThread() {
 +    // no-op for loners
 +  }
 +
 +  @Override
 +  public void releaseUDPMessagingForCurrentThread() {
 +    // no-op for loners
 +  }
 +
 +  @Override
 +  public boolean isSharedConfigurationServiceEnabledForDS() {
 +    //return false for loner
 +    return false;
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/InternalDistributedMember.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/InternalDistributedMember.java
index 8b5c279,0000000..81058f8
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/InternalDistributedMember.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/InternalDistributedMember.java
@@@ -1,1304 -1,0 +1,1304 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal.membership;
 +
 +import java.io.DataInput;
 +import java.io.DataOutput;
 +import java.io.EOFException;
 +import java.io.Externalizable;
 +import java.io.IOException;
 +import java.io.ObjectInput;
 +import java.io.ObjectOutput;
 +import java.net.Inet4Address;
 +import java.net.InetAddress;
 +import java.net.UnknownHostException;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.UnsupportedVersionException;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DurableClientAttributes;
 +import com.gemstone.gemfire.distributed.Role;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.ProfileId;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.DataSerializableFixedID;
 +import com.gemstone.gemfire.internal.InternalDataSerializer;
 +import com.gemstone.gemfire.internal.OSProcess;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.versions.VersionSource;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +
 +/**
 + * This is the fundamental representation of a member of a GemFire distributed
 + * system.
 + */
- public final class InternalDistributedMember
++public class InternalDistributedMember
 + implements DistributedMember,
 +    Externalizable, DataSerializableFixedID, ProfileId,
 +    VersionSource<DistributedMember>
 +{
 +  private final static long serialVersionUID = -2785249969777296507L;
 +  
 +  // whether to show NetMember components in toString()
 +  private final boolean SHOW_NETMEMBER = Boolean.getBoolean("gemfire.show_netmembers");
 +  
 +  protected NetMember netMbr; // the underlying member object, e.g. from JGroups
 +
 +  /**
 +   * This is the direct channel port. The underlying NetMember must be able to
 +   * serialize and deliver this value.
 +   */
 +  private int dcPort = -1;
 +
 +  /**
 +   * This is the process id of this member on its machine. The underlying
 +   * NetMember must be able to serialize and deliver this value.
 +   */
 +  private int vmPid = -1;
 +
 +  /**
 +   * This is a representation of the type of VM. The underlying NetMember must
 +   * be able to serialize and deliver this value.
 +   */
 +  private int vmKind = DistributionManager.NORMAL_DM_TYPE;
 +  
 +  /**
 +   * This is the view identifier where this ID was born, or zero if this is
 +   * a loner member
 +   */
 +  private int vmViewId = -1;
 +  
 +  /**
 +   * whether this is a partial member ID (without roles, durable attributes).
 +   * We use partial IDs in EventID objects to reduce their size.  It would be
 +   * better to use canonical IDs but there is currently no central mechanism
 +   * that would allow that for both server and client identifiers
 +   */
 +  private boolean isPartial;
 +
 +  /** Internal list of group/role names for this member. */
 +  private String[] groups;
 +
 +  /**
 +   * The roles, if any, of this member. Lazily created first time getRoles()
 +   * is called.
 +   */
 +  private volatile Set<Role> rolesSet = null;
 +
 +  /** lock object used when getting/setting roles/rolesSet fields */
 +  private final Object rolesLock = new Object();
 +
 +  /**
 +   * The name of this member's distributed system connection.
 +   * @see com.gemstone.gemfire.distributed.DistributedSystem#getName
 +   */
 +  private String name = null;
 +
 +  /**
 +   * Unique tag (such as randomly generated bytes) to help enforce uniqueness.
 +   * Note: this should be displayable.
 +   */
 +  private String uniqueTag = null;
 +
 +  /** serialization bit mask */
 +  private static final int SB_ENABLED_MASK = 0x1;
 +
 +  /** serialization bit mask */
 +  private static final int COORD_ENABLED_MASK = 0x2;
 +
 +  /** partial ID bit mask */
 +  private static final int PARTIAL_ID_MASK = 0x4;
 +
 +  /** product version bit mask */
 +  private static final int VERSION_MASK = 0x8;
 +
 +  /**
 +   * Representing the host name of this member.
 +   */
 +  private String hostName = null;
 +
 +  private transient short version = Version.CURRENT_ORDINAL;
 +  private transient Version versionObj = Version.CURRENT;
 +
 +  /**
 +   * User-defined attributes (id and timeout) used by durable clients.
 +   */
 +  private DurableClientAttributes durableClientAttributes = null;
 +
 +  /** The versions in which this message was modified */
 +  private static final Version[] dsfidVersions = new Version[] {
 +        Version.GFE_71, Version.GFE_90 };
 +
 +  private void defaultToCurrentHost() {
 +    this.vmPid = OSProcess.getId();
 +    try {
 +      if (SocketCreator.resolve_dns) {
 +        this.hostName = SocketCreator.getHostName(SocketCreator.getLocalHost());
 +      }
 +      else {
 +        this.hostName = SocketCreator.getLocalHost().getHostAddress();
 +      }
 +    }
 +    catch(UnknownHostException ee){
 +      throw new InternalGemFireError(ee);
 +    }
 +    synchPayload();
 +  }
 +
 +
 +  // Used only by Externalization
 +  public InternalDistributedMember() {
 +    this.groups = new String[0];
 +  }
 +
 +  /**
 +   * Construct a InternalDistributedMember.  All fields are specified.<p>
 +   *
 +   * This, and the following constructor are the only valid ways to create an ID
 +   * for a distributed member for use
 +   * in the P2P cache.  Use of other constructors can break network-partition-detection.
 +   *
 +   * @param i
 +   * @param p
 +   *        the membership port
 +   * @param splitBrainEnabled whether this feature is enabled for the member
 +   * @param canBeCoordinator whether the member is eligible to be the membership coordinator
 +   * @param attr
 +   *        the member's attributes
 +   */
 +  public InternalDistributedMember(InetAddress i, int p, 
 +      boolean splitBrainEnabled, boolean canBeCoordinator, MemberAttributes attr) {
 +    this.dcPort = attr.getPort();
 +    this.vmPid = attr.getVmPid();
 +    this.vmKind = attr.getVmKind();
 +    this.vmViewId = attr.getVmViewId();
 +    this.name = attr.getName();
 +    this.groups = attr.getGroups();
 +    this.durableClientAttributes = attr.getDurableClientAttributes();
 +    this.netMbr = MemberFactory.newNetMember(i, p, splitBrainEnabled, canBeCoordinator, Version.CURRENT_ORDINAL, attr);
 +    this.hostName = SocketCreator.resolve_dns? SocketCreator.getHostName(i) : i.getHostAddress();
 +    this.version = netMbr.getVersionOrdinal();
 +    try {
 +      this.versionObj = Version.fromOrdinal(version, false);
 +    } catch (UnsupportedVersionException e) {
 +      this.versionObj = Version.CURRENT;
 +    }
 +//    checkHostName();
 +  }
 +
 +  
 +  /**
 +   * Construct a InternalDistributedMember based on the given NetMember.<p>
 +   * This is not the preferred way of creating an instance since the NetMember
 +   * may not have all required information (e.g., a JGroups address without
 +   * direct-port and other information).
 +   * @param m
 +   */
 +  public InternalDistributedMember(NetMember m) {
 +    netMbr = m;
 +
 +    MemberAttributes attr = m.getAttributes();
 +    this.hostName = SocketCreator.resolve_dns? SocketCreator.getHostName(m.getInetAddress()) :
 +      m.getInetAddress().getHostAddress();
 +//    checkHostName();
 +    if (attr == null) {
 +      // no extended information available, so this address is crippled
 +    }
 +    else {
 +      this.dcPort = attr.getPort();
 +      this.vmPid = attr.getVmPid();
 +      this.vmKind = attr.getVmKind();
 +      this.vmViewId = attr.getVmViewId();
 +      this.name = attr.getName();
 +      this.groups = attr.getGroups();
 +      this.durableClientAttributes = attr.getDurableClientAttributes();
 +    }
 +    this.version = m.getVersionOrdinal();
 +    try {
 +      this.versionObj = Version.fromOrdinal(version, false);
 +    } catch (UnsupportedVersionException e) {
 +      this.versionObj = Version.CURRENT;
 +    }
 +    cachedToString = null;
 +  }
 +
 +  //  private void checkHostName() {
 +//    // bug #44858: debug method to find who is putting a host name instead of addr into an ID
 +//    if (!SocketCreator.resolve_dns
 +//        && this.hostName != null && this.hostName.length() > 0
 +//        && !Character.isDigit(this.hostName.charAt(0))) {
 +//      throw new RuntimeException("found hostname that doesn't start with a digit: " + this.hostName);
 +//    }
 +//  }
 +
 +  /**
 +   * Create a InternalDistributedMember referring to the current host (as defined by the given
 +   * string).<p>
 +   *
 +   * <b>
 +   * [bruce]THIS METHOD IS FOR TESTING ONLY.  DO NOT USE IT TO CREATE IDs FOR
 +   * USE IN THE PRODUCT.  IT DOES NOT PROPERLY INITIALIZE ATTRIBUTES NEEDED
 +   * FOR P2P FUNCTIONALITY.
 +   * </b>
 +   *
 +   * 
 +   * @param i
 +   *          the hostname, must be for the current host
 +   * @param p
 +   *          the membership listening port
 +   * @throws UnknownHostException if the given hostname cannot be resolved
 +   */
 +  public InternalDistributedMember(String i, int p) throws UnknownHostException {
 +    this(i, p, Version.CURRENT);
 +  }
 +  
 +  /**
 +   * Create a InternalDistributedMember referring to the current host (as defined by the given
 +   * string).<p>
 +   *
 +   * <b>
 +   * [bruce]THIS METHOD IS FOR TESTING ONLY.  DO NOT USE IT TO CREATE IDs FOR
 +   * USE IN THE PRODUCT.  IT DOES NOT PROPERLY INITIALIZE ATTRIBUTES NEEDED
 +   * FOR P2P FUNCTIONALITY.
 +   * </b>
 +   *
 +   * 
 +   * @param i
 +   *          the hostname, must be for the current host
 +   * @param p
 +   *          the membership listening port
 +   * @param version
 +   *          the version of this member
 +   * @throws UnknownHostException if the given hostname cannot be resolved
 +   */
 +  public InternalDistributedMember(String i, int p, Version version) throws UnknownHostException {
 +    this (i, p, version, MemberFactory.newNetMember(i, p));
 +  }
 +  
 +  /**
 +   * Create a InternalDistributedMember referring to the current host (as defined by the given
 +   * string).<p>
 +   *
 +   * <b>
 +   * THIS METHOD IS FOR TESTING ONLY.  DO NOT USE IT TO CREATE IDs FOR
 +   * USE IN THE PRODUCT.  IT DOES NOT PROPERLY INITIALIZE ATTRIBUTES NEEDED
 +   * FOR P2P FUNCTIONALITY.
 +   * </b>
 +   **/
 +  public InternalDistributedMember(String i, int p, Version version, NetMember netMember) throws UnknownHostException {
 +    netMbr = netMember;
 +    defaultToCurrentHost();
 +    this.vmKind = DistributionManager.NORMAL_DM_TYPE;
 +    this.versionObj = version;
 +  }
 +
 +  /**
 +   * Create a InternalDistributedMember referring to the current host
 +   * (as defined by the given string) with additional info including optional
 +   * connection name and an optional unique string. Currently these two
 +   * optional fields (and this constructor) are only used by the
 +   * LonerDistributionManager.<p>
 +   *
 +   * < b>
 +   * [bruce]DO NOT USE THIS METHOD TO CREATE ANYTHING OTHER THAN A LONER ID
 +   * WITHOUT TALKING TO ME FIRST.  IT DOES NOT PROPERLY INITIALIZE THE ID.
 +   * </b>
 +   *
 +   * @param host
 +   *          the hostname, must be for the current host
 +   * @param p
 +   *          the membership listening port
 +   * @param n
 +   *          gemfire properties connection name
 +   * @param u
 +   *          unique string used make the member more unique
 +   * @param vmKind the dmType
 +   * @param groups the server groups / roles
 +   * @param attr durable client attributes, if any
 +   * 
 +   * @throws UnknownHostException if the given hostname cannot be resolved
 +   */
 +  public InternalDistributedMember(String host, int p, String n, String u,
 +      int vmKind, String[] groups, DurableClientAttributes attr) throws UnknownHostException {
 +    MemberAttributes mattr = new MemberAttributes(p,
 +        com.gemstone.gemfire.internal.OSProcess.getId(),
 +        vmKind, -1,
 +        n,
 +        groups, attr);
 +    InetAddress addr = SocketCreator.toInetAddress(host);
 +    netMbr = MemberFactory.newNetMember(addr, p, false, true, Version.CURRENT_ORDINAL, mattr);
 +    defaultToCurrentHost();
 +    this.name = n;
 +    this.uniqueTag = u;
 +    this.vmKind = vmKind;
 +    this.dcPort = p;
 +    this.durableClientAttributes = attr;
 +    this.hostName = host;
 +    this.vmPid = OSProcess.getId();
 +    this.groups = groups;
 +  }
 +
 +  /**
 +   * Create a InternalDistributedMember  referring to the current host (as defined by the given
 +   * address).<p>
 +   *
 +   * <b>
 +   * [bruce]THIS METHOD IS FOR TESTING ONLY.  DO NOT USE IT TO CREATE IDs FOR
 +   * USE IN THE PRODUCT.  IT DOES NOT PROPERLY INITIALIZE ATTRIBUTES NEEDED
 +   * FOR P2P FUNCTIONALITY.
 +   * </b>
 +   *
 +   * 
 +   * @param i
 +   *          the hostname, must be for the current host
 +   * @param p
 +   *          the membership listening port
 +   */
 +  public InternalDistributedMember(InetAddress i, int p) {
 +    netMbr = MemberFactory.newNetMember(i, p);
 +    defaultToCurrentHost();
 +  }
 +
 +  /**
 +   * Create a InternalDistributedMember as defined by the given address.
 +   * <p>
 +   * 
 +   * <b>
 +   * [bruce]THIS METHOD IS FOR TESTING ONLY.  DO NOT USE IT TO CREATE IDs FOR
 +   * USE IN THE PRODUCT.  IT DOES NOT PROPERLY INITIALIZE ATTRIBUTES NEEDED
 +   * FOR P2P FUNCTIONALITY.
 +   * </b>
 +   * 
 +   * @param addr 
 +   *        address of the server
 +   * @param p
 +   *        the listening port of the server
 +   * @param isCurrentHost
 +   *        true if the given host refers to the current host (bridge and
 +   *        gateway use false to create a temporary id for the OTHER side of a
 +   *        connection)
 +   */
 +  public InternalDistributedMember(InetAddress addr,
 +                                   int p,
 +                                   boolean isCurrentHost) {
 +    netMbr = MemberFactory.newNetMember(addr, p);
 +    if (isCurrentHost) {
 +      defaultToCurrentHost();
 +    }
 +  }
 +
 +  /**
 +   * Return the underlying host address
 +   *
 +   * @return the underlying host address
 +   */
 +  public InetAddress getInetAddress()
 +  {
 +    return netMbr.getInetAddress();
 +  }
 +
 +  public NetMember getNetMember() {
 +    return netMbr;
 +  }
 +
 +  /**
 +   * Return the underlying port (membership port)
 +   * @return the underlying membership port
 +   */
 +  public int getPort()
 +  {
 +    return netMbr.getPort();
 +  }
 +
 +
 +  /**
 +   * Returns the port on which the direct channel runs
 +   */
 +  public int getDirectChannelPort()
 +  {
 +    assert !this.isPartial;
 +    return dcPort;
 +  }
 +
 +  /**
 +   * [GemStone] Returns the kind of VM that hosts the distribution manager with
 +   * this address.
 +   *
 +   * @see com.gemstone.gemfire.distributed.internal.DistributionManager#getDMType()
 +   * @see com.gemstone.gemfire.distributed.internal.DistributionManager#NORMAL_DM_TYPE
 +   */
 +  public int getVmKind()
 +  {
 +    return vmKind;
 +  }
 +  
 +  /**
 +   * Returns the membership view ID that this member was born in. For
 +   * backward compatibility reasons this is limited to 16 bits.
 +   */
 +  public int getVmViewId() {
 +    return this.vmViewId;
 +  }
 +
 +  /**
 +   * Returns an unmodifiable Set of this member's Roles.
 +   */
 +  public Set<Role> getRoles() {
 +    Set<Role> tmpRolesSet = this.rolesSet;
 +    if (tmpRolesSet != null) {
 +      return tmpRolesSet;
 +    }
 +    assert !this.isPartial;
 +    synchronized (this.rolesLock) {
 +      tmpRolesSet = this.rolesSet;
 +      if (tmpRolesSet == null) {
 +        final String[] tmpRoles = this.groups;
 +        // convert array of string role names to array of Roles...
 +        if (tmpRoles == null  ||  tmpRoles.length == 0) {
 +          tmpRolesSet = Collections.emptySet();
 +        }
 +        else {
 +          tmpRolesSet = new HashSet<Role>(tmpRoles.length);
 +          for (int i = 0; i < tmpRoles.length; i++) {
 +            tmpRolesSet.add(InternalRole.getRole(tmpRoles[i]));
 +          }
 +          tmpRolesSet = Collections.unmodifiableSet(tmpRolesSet);
 +        }
 +        this.rolesSet = tmpRolesSet;
 +      }
 +    }
 +    Assert.assertTrue(tmpRolesSet != null);
 +    return tmpRolesSet;
 +  }
 +  public List<String> getGroups() {
 +    return Collections.unmodifiableList(Arrays.asList(this.groups));
 +  }
 +
 +  public void setGroups(String[] newGroups) {
 +    assert !this.isPartial;
 +    assert newGroups != null;
 +    synchronized (this.rolesLock) {
 +      this.groups = newGroups;
 +      synchPayload();
 +      this.rolesSet = null;
 +      this.cachedToString = null;
 +    }
 +  }
 +
 +  private void synchPayload() {
 +    netMbr.setAttributes(new MemberAttributes(dcPort, vmPid, vmKind, 
 +        vmViewId, name, groups, durableClientAttributes));
 +  }
 +
 +  public void setVmKind(int p)
 +  {
 +    vmKind = p;
 +    synchPayload();
 +    cachedToString = null;
 +  }
 +  
 +  public void setVmViewId(int p) {
 +    this.vmViewId = p;
 +    synchPayload();
 +    cachedToString = null;
 +  }
 +
 +  /**
 +   * [GemStone] Returns the process id of the VM that hosts the distribution
 +   * manager with this address.
 +   *
 +   * @since 4.0
 +   */
 +  public int getVmPid()
 +  {
 +    return vmPid;
 +  }
 +
 +  /**
 +   * [GemStone] Sets the process id of the VM that hosts the distribution
 +   * manager with this address.
 +   *
 +   * @since 4.0
 +   */
 +  public void setVmPid(int p)
 +  {
 +    this.vmPid = p;
 +    synchPayload();
 +    cachedToString = null;
 +  }
 +
 +  /**
 +   * Returns the name of this member's distributed system connection or null
 +   * if no name was specified.
 +   * @see com.gemstone.gemfire.distributed.DistributedSystem#getName
 +   */
 +  public String getName() {
 +    String result = this.name;
 +    if (result == null) {
 +      result = "";
 +    }
 +    return result;
 +  }
 +
 +  /**
 +   * Returns this member's unique tag (such as randomly generated bytes) or
 +   * null if no unique tag was created.
 +   */
 +  public String getUniqueTag() {
 +    return this.uniqueTag;
 +  }
 +
 +  /**
 +   * Returns this client member's durable attributes or null if no durable
 +   * attributes were created.
 +   */
 +  public DurableClientAttributes getDurableClientAttributes() {
 +    assert !this.isPartial;
 +    return this.durableClientAttributes;
 +  }
 +
 +  /**
 +   * implements the java.lang.Comparable interface
 +   *
 +   * @see java.lang.Comparable
 +   * @param o -
 +   *          the Object to be compared
 +   * @return a negative integer, zero, or a positive integer as this object is
 +   *         less than, equal to, or greater than the specified object.
 +   * @exception java.lang.ClassCastException -
 +   *              if the specified object's type prevents it from being compared
 +   *              to this Object.
 +   */
 +  public int compareTo(DistributedMember o) {
 +    return compareTo(o, true);
 +  }
 +  
 +  public int compareTo(DistributedMember o, boolean checkNetMembersIfEqual) {
 +    if (this == o) {
 +      return 0;
 +    }
 +    // obligatory type check
 +    if ((o == null) || !(o instanceof InternalDistributedMember))
 +      throw new ClassCastException(LocalizedStrings.InternalDistributedMember_INTERNALDISTRIBUTEDMEMBERCOMPARETO_COMPARISON_BETWEEN_DIFFERENT_CLASSES.toLocalizedString());
 +    InternalDistributedMember other = (InternalDistributedMember)o;
 +
 +    int myPort = getPort();
 +    int otherPort = other.getPort();
 +    if (myPort < otherPort)
 +      return -1;
 +    if (myPort > otherPort)
 +      return 1;
 +
 +
 +    InetAddress myAddr = getInetAddress();
 +    InetAddress otherAddr = other.getInetAddress();
 +
 +    // Discard null cases
 +    if (myAddr == null && otherAddr == null) {
 +      if (myPort < otherPort)
 +        return -1;
 +      else if (myPort > otherPort)
 +        return 1;
 +      else
 +        return 0;
 +    }
 +    else if (myAddr == null) {
 +      return -1;
 +    }
 +    else if (otherAddr == null)
 +      return 1;
 +
 +    byte[] myBytes = myAddr.getAddress();
 +    byte[] otherBytes = otherAddr.getAddress();
 +
 +    if (myBytes != otherBytes) {
 +      for (int i = 0; i < myBytes.length; i++) {
 +        if (i >= otherBytes.length)
 +          return -1; // same as far as they go, but shorter...
 +        if (myBytes[i] < otherBytes[i])
 +          return -1;
 +        if (myBytes[i] > otherBytes[i])
 +          return 1;
 +      }
 +      if (myBytes.length > otherBytes.length)
 +        return 1; // same as far as they go, but longer...
 +    }
 +
 +    if (this.name == null && other.name == null) {
 +      // do nothing
 +    } else if (this.name == null) {
 +      return -1;
 +    }
 +    else if (other.name == null) {
 +      return 1;
 +    }
 +    else {
 +      int i = this.name.compareTo(other.name);
 +      if (i != 0) {
 +        return i;
 +      }
 +    }
 +
 +    if (this.uniqueTag == null && other.uniqueTag == null) {
 +      // not loners, so look at P2P view ID
 +      if (this.vmViewId >= 0 && other.vmViewId >= 0) {
 +        if (this.vmViewId < other.vmViewId) {
 +          return -1;
 +        } else if (this.vmViewId > other.vmViewId) {
 +          return 1;
 +        } // else they're the same, so continue
 +      }
 +    } else if (this.uniqueTag == null) {
 +      return -1;
 +    }
 +    else if (other.uniqueTag == null) {
 +      return 1;
 +    }
 +    else {
 +      int i = this.uniqueTag.compareTo(other.uniqueTag);
 +      if (i != 0) {
 +        return i;
 +      }
 +    }
 +    
 +    if (checkNetMembersIfEqual
 +        && this.netMbr != null && other.netMbr != null) {
 +      return this.netMbr.compareTo(other.netMbr);
 +    } else {
 +      return 0;
 +    }
 +    
 +    // purposely avoid comparing roles
 +    // @todo Add durableClientAttributes to compare
 +  }
 +
 +  @Override
 +  public boolean equals(Object obj)
 +  {
 +    if (this == obj) {
 +      return true;
 +    }
 +    // GemStone fix for 29125
 +    if ((obj == null) || !(obj instanceof InternalDistributedMember)) {
 +      return false;
 +    }
 +    return compareTo((InternalDistributedMember)obj) == 0;
 +  }
 +
 +  @Override
 +  public int hashCode()
 +  {
 +    int result = 0;
 +     result = result + netMbr.getInetAddress().hashCode();
 +    result = result + getPort();
 +    return result;
 +  }
 +
 +  private String shortName(String hostname)
 +  {
 +    if (hostname == null)
 +      return "<null inet_addr hostname>";
 +    int index = hostname.indexOf('.');
 +
 +    if (index > 0 && !Character.isDigit(hostname.charAt(0)))
 +      return hostname.substring(0, index);
 +    else
 +      return hostname;
 +  }
 +
 +
 +  /** the cached string description of this object */
 +  private transient String cachedToString;
 +
 +  @Override
 +  public String toString()
 +  {
 +    String result = cachedToString;
 +    if (result == null) {
 +      String host;
 +
 +      InetAddress add = getInetAddress();
 +        if (add.isMulticastAddress())
 +          host = add.getHostAddress();
 +        else {
 +         // host = shortName(add.getHostName());
 +          host = SocketCreator.resolve_dns? shortName(this.hostName) : this.hostName;
 +        }
 +      final StringBuilder sb = new StringBuilder();
 +
 +      sb.append(host);
 +
 +      String myName = getName();
 +      if (vmPid > 0 || vmKind != DistributionManager.NORMAL_DM_TYPE || !"".equals(myName)) {
 +        sb.append("(");
 +
 +        if (!"".equals(myName)) {
 +          sb.append(myName);
 +          if (vmPid > 0) {
 +            sb.append(':');
 +          }
 +        }
 +
 +        if (vmPid > 0)
 +          sb.append(Integer.toString(vmPid));
 +
 +        String vmStr = "";
 +        switch (vmKind) {
 +        case DistributionManager.NORMAL_DM_TYPE:
 +  //        vmStr = ":local"; // let this be silent
 +          break;
 +        case DistributionManager.LOCATOR_DM_TYPE:
 +          vmStr = ":locator";
 +          break;
 +        case DistributionManager.ADMIN_ONLY_DM_TYPE:
 +          vmStr = ":admin";
 +          break;
 +        case DistributionManager.LONER_DM_TYPE:
 +          vmStr = ":loner";
 +          break;
 +        default:
 +          vmStr = ":<unknown:" + vmKind + ">";
 +          break;
 +        }
 +        sb.append(vmStr);
 +        sb.append(")");
 +      }
 +      if (vmKind != DistributionManager.LONER_DM_TYPE && netMbr.preferredForCoordinator()) {
 +        sb.append("<ec>");
 +      }
 +      if (this.vmViewId >= 0) {
 +        sb.append("<v" + this.vmViewId + ">");
 +      }
 +      sb.append(":");
 +      sb.append(getPort());
 +
 +//      if (dcPort > 0 && vmKind != DistributionManager.LONER_DM_TYPE) {
 +//        sb.append("/");
 +//        sb.append(Integer.toString(dcPort));
 +//      }
 +
 +      if (vmKind == DistributionManager.LONER_DM_TYPE) {
 +        // add some more info that was added in 4.2.1 for loner bridge clients
 +        // impact on non-bridge loners is ok
 +        if (this.uniqueTag != null && this.uniqueTag.length() != 0) {
 +          sb.append(":").append(this.uniqueTag);
 +        }
 +        if (this.name != null && this.name.length() != 0) {
 +          sb.append(":").append(this.name);
 +        }
 +      }
 +
 +      // add version if not current
 +      if (this.version != Version.CURRENT.ordinal()) {
 +        sb.append("(version:").append(Version.toString(this.version))
 +            .append(')');
 +      }
 +
 +      if (SHOW_NETMEMBER) {
 +        sb.append("[[").append(this.netMbr).append("]]");
 +      }
 +
 +      // leave out Roles on purpose
 +      
 +//      if (netMbr instanceof GMSMember) {
 +//        sb.append("(UUID=").append(((GMSMember)netMbr).getUUID()).append(")");
 +//      }
 +
 +      result = sb.toString();
 +      cachedToString = result;
 +    }
 +    return result;
 +  }
 +
 +  private void readVersion(int flags, DataInput in) throws IOException {
 +    if ((flags & VERSION_MASK) != 0) {
 +      this.version = Version.readOrdinal(in);
 +      this.versionObj = Version.fromOrdinalNoThrow(this.version, false);
 +    } else {
 +      // prior to 7.1 member IDs did not serialize their version information
 +      Version v = InternalDataSerializer.getVersionForDataStreamOrNull(in);
 +      if (v != null) {
 +        this.versionObj = v;
 +        this.version = v.ordinal();
 +      }
 +    }
 +  }
 +
 +  /**
 +   * For Externalizable
 +   *
 +   * @see Externalizable
 +   */
 +  public void writeExternal(ObjectOutput out) throws IOException {
 +    Assert.assertTrue(vmKind > 0);
 +
 +    // do it the way we like
 +    byte[] address = getInetAddress().getAddress();
 +
 +    out.writeInt(address.length); // IPv6 compatible
 +    out.write(address);
 +    out.writeInt(getPort());
 +
 +    DataSerializer.writeString(this.hostName, out);
 +    
 +    int flags = 0;
 +    if (netMbr.splitBrainEnabled()) flags |= SB_ENABLED_MASK;
 +    if (netMbr.preferredForCoordinator()) flags |= COORD_ENABLED_MASK;
 +    if (this.isPartial) flags |= PARTIAL_ID_MASK;
 +    // always write product version but enable reading from older versions
 +    // that do not have it
 +    flags |= VERSION_MASK;
 +    out.writeByte((byte)(flags & 0xff));
 +
 +    out.writeInt(dcPort);
 +    out.writeInt(vmPid);
 +    out.writeInt(vmKind);
 +    out.writeInt(vmViewId);
 +    DataSerializer.writeStringArray(this.groups, out);
 +
 +    DataSerializer.writeString(this.name, out);
 +    DataSerializer.writeString(this.uniqueTag, out);
 +    DataSerializer.writeString(this.durableClientAttributes==null ? "" : this.durableClientAttributes.getId(), out);
 +    DataSerializer.writeInteger(Integer.valueOf(this.durableClientAttributes==null ? 300 : this.durableClientAttributes.getTimeout()), out);
 +    Version.writeOrdinal(out, this.version, true);
 +    netMbr.writeAdditionalData(out);
 +  }
 +
 +  /**
 +    * For Externalizable
 +    *
 +    * @see Externalizable
 +    */
 +   public void readExternal(ObjectInput in)
 +   throws IOException, ClassNotFoundException {
 +     int len = in.readInt(); // IPv6 compatible
 +     byte addr[] = new byte[len];
 +     in.readFully(addr);
 +     InetAddress inetAddr = InetAddress.getByAddress(addr);
 +     int port = in.readInt();
 +     
 +     this.hostName = DataSerializer.readString(in);
 +
 +     int flags = in.readUnsignedByte();
 +     boolean sbEnabled = (flags & SB_ENABLED_MASK) != 0;
 +     boolean elCoord = (flags & COORD_ENABLED_MASK) != 0;
 +     this.isPartial = (flags & PARTIAL_ID_MASK) != 0;
 +     
 +     this.dcPort = in.readInt();
 +     this.vmPid = in.readInt();
 +     this.vmKind = in.readInt();
 +     this.vmViewId = in.readInt();
 +     this.groups = DataSerializer.readStringArray(in);
 +
 +     this.name = DataSerializer.readString(in);
 +     this.uniqueTag = DataSerializer.readString(in);
 +     String durableId = DataSerializer.readString(in);
 +     int durableTimeout = DataSerializer.readInteger(in).intValue();
 +     this.durableClientAttributes = new DurableClientAttributes(durableId, durableTimeout);
 +
 +     readVersion(flags, in);
 +
 +     netMbr = MemberFactory.newNetMember(inetAddr, port, sbEnabled, elCoord, version,
 +         new MemberAttributes(dcPort, vmPid, vmKind, vmViewId, name, groups, durableClientAttributes));
 +     if (this.version >= Version.GFE_90.ordinal()) {
 +       try {
 +         netMbr.readAdditionalData(in);
 +       } catch (java.io.EOFException e) {
 +         // old version quand-meme
 +       }
 +     }
 +
 +     Assert.assertTrue(this.vmKind > 0);
 +   }
 +
 +  public int getDSFID() {
 +    return DISTRIBUTED_MEMBER;
 +  }
 +
 +  public void toData(DataOutput out) throws IOException {
 +    toDataPre_GFE_9_0_0_0(out);
 +    if (this.version >= Version.GFE_90.ordinal()) {
 +      getNetMember().writeAdditionalData(out);
 +    }
 +  }
 +  
 +  
 +  public void toDataPre_GFE_9_0_0_0(DataOutput out) throws IOException {
 +    Assert.assertTrue(vmKind > 0);
 +    // NOTE: If you change the serialized format of this class
 +    //       then bump Connection.HANDSHAKE_VERSION since an
 +    //       instance of this class is sent during Connection handshake.
 +    DataSerializer.writeInetAddress(getInetAddress(), out);
 +    out.writeInt(getPort());
 +
 +    DataSerializer.writeString(this.hostName, out);
 +
 +    int flags = 0;
 +    if (netMbr.splitBrainEnabled()) flags |= SB_ENABLED_MASK;
 +    if (netMbr.preferredForCoordinator()) flags |= COORD_ENABLED_MASK;
 +    if (this.isPartial) flags |= PARTIAL_ID_MASK;
 +    // always write product version but enable reading from older versions
 +    // that do not have it
 +    flags |= VERSION_MASK;
 +    out.writeByte((byte)(flags & 0xff));
 +    
 +    out.writeInt(dcPort);
 +    out.writeInt(vmPid);
 +    out.writeByte(vmKind);
 +    DataSerializer.writeStringArray(this.groups, out);
 +
 +    DataSerializer.writeString(this.name, out);
 +    if (this.vmKind == DistributionManager.LONER_DM_TYPE) {
 +      DataSerializer.writeString(this.uniqueTag, out);
 +    } else {  // added in 6.5 for unique identifiers in P2P
 +      DataSerializer.writeString(String.valueOf(this.vmViewId), out);
 +    }
 +    DataSerializer.writeString(this.durableClientAttributes==null ? "" : this.durableClientAttributes.getId(), out);
 +    DataSerializer.writeInteger(Integer.valueOf(this.durableClientAttributes==null ? 300 : this.durableClientAttributes.getTimeout()), out);
 +    Version.writeOrdinal(out, this.version, true);
 +  }
 +
 +  public void toDataPre_GFE_7_1_0_0(DataOutput out) throws IOException {
 +      Assert.assertTrue(vmKind > 0);
 +    // [bruce] disabled to allow post-connect setting of the port for loner systems
 +//    Assert.assertTrue(getPort() > 0);
 +//    if (this.getPort() == 0) {
 +//      InternalDistributedSystem.getLoggerI18n().warning(LocalizedStrings.DEBUG,
 +//          "Serializing ID with zero port", new Exception("Stack trace"));
 +//    }
 +
 +    // NOTE: If you change the serialized format of this class
 +    //       then bump Connection.HANDSHAKE_VERSION since an
 +    //       instance of this class is sent during Connection handshake.
 +    DataSerializer.writeInetAddress(getInetAddress(), out);
 +    out.writeInt(getPort());
 +
 +    DataSerializer.writeString(this.hostName, out);
 +
 +    int flags = 0;
 +    if (netMbr.splitBrainEnabled()) flags |= SB_ENABLED_MASK;
 +    if (netMbr.preferredForCoordinator()) flags |= COORD_ENABLED_MASK;
 +    if (this.isPartial) flags |= PARTIAL_ID_MASK;
 +    out.writeByte((byte)(flags & 0xff));
 +    
 +    out.writeInt(dcPort);
 +    out.writeInt(vmPid);
 +    out.writeByte(vmKind);
 +    DataSerializer.writeStringArray(this.groups, out);
 +
 +    DataSerializer.writeString(this.name, out);
 +    if (this.vmKind == DistributionManager.LONER_DM_TYPE) {
 +      DataSerializer.writeString(this.uniqueTag, out);
 +    } else {  // added in 6.5 for unique identifiers in P2P
 +      DataSerializer.writeString(String.valueOf(this.vmViewId), out);
 +    }
 +    DataSerializer.writeString(this.durableClientAttributes==null ? "" : this.durableClientAttributes.getId(), out);
 +    DataSerializer.writeInteger(Integer.valueOf(this.durableClientAttributes==null ? 300 : this.durableClientAttributes.getTimeout()), out);
 + 
 +  }
 +  
 +  public void fromData(DataInput in)
 +  throws IOException, ClassNotFoundException {
 +    fromDataPre_GFE_9_0_0_0(in);
 +    // just in case this is just a non-versioned read
 +    // from a file we ought to check the version
 +    if (this.version >= Version.GFE_90.ordinal()) {
 +      try {
 +        netMbr.readAdditionalData(in);
 +      } catch (EOFException e) {
 +        // nope - it's from a pre-GEODE client or WAN site
 +      }
 +    }
 +  }
 +  
 +  public void fromDataPre_GFE_9_0_0_0(DataInput in)
 +  throws IOException, ClassNotFoundException {
 +    InetAddress inetAddr = DataSerializer.readInetAddress(in);
 +    int port = in.readInt();
 +
 +    this.hostName = DataSerializer.readString(in);
 +    this.hostName = SocketCreator.resolve_dns? SocketCreator.getCanonicalHostName(inetAddr, hostName) : inetAddr.getHostAddress();
 +
 +    int flags = in.readUnsignedByte();
 +    boolean sbEnabled = (flags & SB_ENABLED_MASK) != 0;
 +    boolean elCoord = (flags & COORD_ENABLED_MASK) != 0;
 +    this.isPartial = (flags & PARTIAL_ID_MASK) != 0;
 +
 +    this.dcPort = in.readInt();
 +    this.vmPid = in.readInt();
 +    this.vmKind = in.readUnsignedByte();
 +    this.groups = DataSerializer.readStringArray(in);
 +
 +    this.name = DataSerializer.readString(in);
 +    if (this.vmKind == DistributionManager.LONER_DM_TYPE) {
 +      this.uniqueTag = DataSerializer.readString(in);
 +    } else {
 +      String str = DataSerializer.readString(in);
 +      if (str != null) { // backward compatibility from earlier than 6.5
 +        this.vmViewId = Integer.parseInt(str);
 +      }
 +    }
 +
 +    String durableId = DataSerializer.readString(in);
 +    int durableTimeout = DataSerializer.readInteger(in).intValue();
 +    this.durableClientAttributes = new DurableClientAttributes(durableId, durableTimeout);
 +
 +    readVersion(flags, in);
 +
 +    MemberAttributes attr = new MemberAttributes(this.dcPort, this.vmPid,
 +        this.vmKind, this.vmViewId, this.name, this.groups, this.durableClientAttributes);
 +    netMbr = MemberFactory.newNetMember(inetAddr, port, sbEnabled, elCoord, version, attr);
 +
 +    synchPayload();
 +
 +    Assert.assertTrue(this.vmKind > 0);
 +//    Assert.assertTrue(getPort() > 0);
 +  }
 +
 +  public void fromDataPre_GFE_7_1_0_0(DataInput in)  throws IOException, ClassNotFoundException {
 +    InetAddress inetAddr = DataSerializer.readInetAddress(in);
 +    int port = in.readInt();
 +
 +    this.hostName = DataSerializer.readString(in);
 +    this.hostName = SocketCreator.resolve_dns? SocketCreator.getCanonicalHostName(inetAddr, hostName) : inetAddr.getHostAddress();
 +
 +    int flags = in.readUnsignedByte();
 +    boolean sbEnabled = (flags & SB_ENABLED_MASK) != 0;
 +    boolean elCoord = (flags & COORD_ENABLED_MASK) != 0;
 +    this.isPartial = (flags & PARTIAL_ID_MASK) != 0;
 +
 +    this.dcPort = in.readInt();
 +    this.vmPid = in.readInt();
 +    this.vmKind = in.readUnsignedByte();
 +    this.groups = DataSerializer.readStringArray(in);
 +
 +    this.name = DataSerializer.readString(in);
 +    if (this.vmKind == DistributionManager.LONER_DM_TYPE) {
 +      this.uniqueTag = DataSerializer.readString(in);
 +    } else {
 +      String str = DataSerializer.readString(in);
 +      if (str != null) { // backward compatibility from earlier than 6.5
 +        this.vmViewId = Integer.parseInt(str);
 +      }
 +    }
 +
 +    String durableId = DataSerializer.readString(in);
 +    int durableTimeout = DataSerializer.readInteger(in).intValue();
 +    this.durableClientAttributes = new DurableClientAttributes(durableId, durableTimeout);
 +
 +    MemberAttributes attr = new MemberAttributes(this.dcPort, this.vmPid,
 +        this.vmKind, this.vmViewId, this.name, this.groups, this.durableClientAttributes);
 +    netMbr = MemberFactory.newNetMember(inetAddr, port, sbEnabled, elCoord, 
 +        InternalDataSerializer.getVersionForDataStream(in).ordinal(), attr);
 +
 +    synchPayload();
 +
 +    Assert.assertTrue(this.vmKind > 0);
 +  }
 +
 +  /** this writes just the parts of the ID that are needed for comparisons and communications */
 +   public static InternalDistributedMember readEssentialData(DataInput in)
 +     throws IOException, ClassNotFoundException {
 +     final InternalDistributedMember mbr = new InternalDistributedMember();
 +     mbr._readEssentialData(in);
 +     return mbr;
 +   }
 +   
 +   private void _readEssentialData(DataInput in)
 +     throws IOException, ClassNotFoundException {
 +     this.isPartial = true;
 +     InetAddress inetAddr = DataSerializer.readInetAddress(in);
 +     int port = in.readInt();
 +
 +     this.hostName = SocketCreator.resolve_dns? SocketCreator.getHostName(inetAddr) : inetAddr.getHostAddress();
 +
 +     int flags = in.readUnsignedByte();
 +     boolean sbEnabled = (flags & SB_ENABLED_MASK) != 0;
 +     boolean elCoord = (flags & COORD_ENABLED_MASK) != 0;
 +
 +     this.vmKind = in.readUnsignedByte();
 +     
 +
 +     if (this.vmKind == DistributionManager.LONER_DM_TYPE) {
 +       this.uniqueTag = DataSerializer.readString(in);
 +     } else {
 +       String str = DataSerializer.readString(in);
 +       if (str != null) { // backward compatibility from earlier than 6.5
 +         this.vmViewId = Integer.parseInt(str);
 +       }
 +     }
 +
 +     this.name = DataSerializer.readString(in);
 +
 +     MemberAttributes attr = new MemberAttributes(this.dcPort, this.vmPid,
 +         this.vmKind, this.vmViewId, this.name, this.groups, this.durableClientAttributes);
 +     netMbr = MemberFactory.newNetMember(inetAddr, port, sbEnabled, elCoord, 
 +         InternalDataSerializer.getVersionForDataStream(in).ordinal(), attr);
 +
 +     synchPayload();
 +
 +     if (InternalDataSerializer.getVersionForDataStream(in).compareTo(Version.GFE_90)>=0) {
 +       netMbr.readAdditionalData(in);
 +     }
 +   }
 +
 +
 +   public void writeEssentialData(DataOutput out) throws IOException {
 +     Assert.assertTrue(vmKind > 0);
 +     DataSerializer.writeInetAddress(getInetAddress(), out);
 +     out.writeInt(getPort());
 +
 +     int flags = 0;
 +     if (netMbr.splitBrainEnabled()) flags |= SB_ENABLED_MASK;
 +     if (netMbr.preferredForCoordinator()) flags |= COORD_ENABLED_MASK;
 +     flags |= PARTIAL_ID_MASK;
 +     out.writeByte((byte)(flags & 0xff));
 +     
 +//     out.writeInt(dcPort);
 +     out.writeByte(vmKind);
 +
 +     if (this.vmKind == DistributionManager.LONER_DM_TYPE) {
 +       DataSerializer.writeString(this.uniqueTag, out);
 +     } else {  // added in 6.5 for unique identifiers in P2P
 +       DataSerializer.writeString(String.valueOf(this.vmViewId), out);
 +     }
 +     // write name last to fix bug 45160
 +     DataSerializer.writeString(this.name, out);
 +
 +     if (InternalDataSerializer.getVersionForDataStream(out).compareTo(Version.GFE_90)>=0) {
 +       netMbr.writeAdditionalData(out);
 +     }
 +   }
 +
 +  /**
 +   * [GemStone] Set the direct channel port
 +   */
 +  public void setDirectChannelPort(int p)
 +  {
 +    dcPort = p;
 +    synchPayload();
 +  }
 +  
 +  /**
 +   * Set the membership port.  This is done in loner systems using
 +   * client/server connection information to help form a unique ID
 +   */
 +  public void setPort(int p) {
 +    assert this.vmKind == DistributionManager.LONER_DM_TYPE;
 +    this.netMbr.setPort(p);
 +    synchPayload();
 +    cachedToString = null;
 +  }
 +  
 +  /** drop the cached toString rep of this ID */
 +  public void dropCachedString() {
 +    this.cachedToString = null;
 +  }
 +
 +  public String getHost() {
 +    return this.netMbr.getInetAddress().getCanonicalHostName();
 +  }
 +
 +  public int getProcessId() {
 +    return this.vmPid;
 +  }
 +
 +  public String getId() {
 +    return toString();
 +  }
 +    /*if (this.ipAddr == null) {
 +      return "<null>";
 +    }
 +    else {
 +      StringBuffer sb = new StringBuffer();
 +      InetAddress addr = this.ipAddr.getIpAddress();
 +      if(addr.isMulticastAddress()) {
 +        sb.append(addr.getHostAddress());
 +      } else {
 +        appendShortName(addr.getHostName(), sb);
 +      }
 +      if (this.vmPid != 0) {
 +        sb.append("(");
 +        sb.append(this.vmPid);
 +        sb.append(")");
 +      }
 +      sb.append(":");
 +      sb.append(this.ipAddr.getPort());
 +      return sb.toString();
 +    }
 +  }
 +
 +  // Helper method for getId()... copied from IpAddress.
 +  private void appendShortName(String hostname, StringBuffer sb) {
 +    if (hostname == null) return;
 +    int index = hostname.indexOf('.');
 +    if(index > 0 && !Character.isDigit(hostname.charAt(0))) {
 +      sb.append(hostname.substring(0, index));
 +    } else {
 +      sb.append(hostname);
 +    }
 +  }*/
 +  
 +  public final void setVersionObjectForTest(Version v) {
 +    this.version = v.ordinal();
 +    this.versionObj = v;
 +    netMbr.setVersion(v);
 +  }
 +
 +  public final Version getVersionObject() {
 +    return this.versionObj;
 +  }
 +  
 +  @Override
 +  public Version[] getSerializationVersions() {
 +    return dsfidVersions;
 +  }
 +
 +
 +  @Override
 +  public int getSizeInBytes() {
 +  
 +    int size = 0;
 +  
 +    // ipaddr:  1 byte length + 4 bytes (IPv4) or 16 bytes (IPv6)
 +    if (netMbr.getInetAddress() instanceof Inet4Address){
 +      size += 5;
 +    } else {
 +      size += 17;
 +    }
 +    
 +    // port:  4 bytes
 +    // flags: 1 byte
 +    //vmKind: 1 byte
 +    size += 6;
 +    
 +    // viewID:  String(1+1+numchars)
 +    size += (2+ String.valueOf(this.vmViewId).length());
 +    
 +    // empty name: String(1+1)
 +    size += 2;
 +    
 +    return size;
 +  }
 +}


[088/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
index 0000000,edfee10..3d554fa
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
@@@ -1,0 -1,2655 +1,2652 @@@
+ /*
+  * 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 com.gemstone.gemfire.distributed.internal.membership.gms.mgr;
+ 
+ import java.io.IOException;
+ import java.io.NotSerializableException;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.LinkedHashMap;
+ import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.CountDownLatch;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.TimeoutException;
+ import java.util.concurrent.locks.ReadWriteLock;
+ import java.util.concurrent.locks.ReentrantReadWriteLock;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.ForcedDisconnectException;
+ import com.gemstone.gemfire.GemFireConfigException;
+ import com.gemstone.gemfire.InternalGemFireError;
+ import com.gemstone.gemfire.SystemConnectException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.ToDataException;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.server.CacheServer;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
+ import com.gemstone.gemfire.distributed.Locator;
+ import com.gemstone.gemfire.distributed.internal.AdminMessageType;
+ import com.gemstone.gemfire.distributed.internal.DMStats;
+ import com.gemstone.gemfire.distributed.internal.DSClock;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.distributed.internal.DistributionException;
+ import com.gemstone.gemfire.distributed.internal.DistributionManager;
+ import com.gemstone.gemfire.distributed.internal.DistributionMessage;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.InternalLocator;
+ import com.gemstone.gemfire.distributed.internal.OverflowQueueWithDMStats;
+ import com.gemstone.gemfire.distributed.internal.SizeableRunnable;
+ import com.gemstone.gemfire.distributed.internal.StartupMessage;
+ import com.gemstone.gemfire.distributed.internal.direct.DirectChannel;
+ import com.gemstone.gemfire.distributed.internal.direct.DirectChannelListener;
+ import com.gemstone.gemfire.distributed.internal.direct.ShunnedMemberException;
+ import com.gemstone.gemfire.distributed.internal.membership.DistributedMembershipListener;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
+ import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
+ import com.gemstone.gemfire.distributed.internal.membership.NetView;
+ import com.gemstone.gemfire.distributed.internal.membership.QuorumChecker;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.GMSMember;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.SuspectMember;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.fd.GMSHealthMonitor;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.Manager;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeave;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.messenger.GMSQuorumChecker;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.SystemTimer;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.admin.remote.RemoteTransportConfig;
+ import com.gemstone.gemfire.internal.cache.CacheServerImpl;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.xmlcache.CacheServerCreation;
+ import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.log4j.AlertAppender;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+ import com.gemstone.gemfire.internal.shared.StringPrintWriter;
+ import com.gemstone.gemfire.internal.tcp.ConnectExceptions;
+ import com.gemstone.gemfire.internal.tcp.MemberShunnedException;
+ import com.gemstone.gemfire.internal.util.Breadcrumbs;
+ 
+ public class GMSMembershipManager implements MembershipManager, Manager
+ {
+   private static final Logger logger = Services.getLogger();
+   
+   /** product version to use for multicast serialization */
+   volatile boolean disableMulticastForRollingUpgrade;
+   
+   /**
+    * set to true if the distributed system that created this manager was
+    * auto-reconnecting when it was created.
+    */
+   boolean wasReconnectingSystem;
+   
+   /**
+    * A quorum checker is created during reconnect and is held
+    * here so it is available to the UDP protocol for passing off
+    * the ping-pong responses used in the quorum-checking algorithm. 
+    */
+   private volatile QuorumChecker quorumChecker;
+   
+   /**
+    * thread-local used to force use of Messenger for communications, usually to
+    * avoid deadlock when conserve-sockets=true.  Use of this should be removed
+    * when connection pools are implemented in the direct-channel 
+    */
+   private ThreadLocal<Boolean> forceUseUDPMessaging = new ThreadLocal<Boolean>();
+   
+   /**
+    * Trick class to make the startup synch more
+    * visible in stack traces
+    * 
+    * @see GMSMembershipManager#startupLock
+    */
+   static class EventProcessingLock  {
+     public EventProcessingLock() {
+     }
+   }
+   
+   static class StartupEvent  {
+     static final int SURPRISE_CONNECT = 1;
+     static final int VIEW = 2;
+     static final int MESSAGE = 3;
+     
+     /**
+      * indicates whether the event is a departure, a surprise connect
+      * (i.e., before the view message arrived), a view, or a regular
+      * message
+      * 
+      * @see #SURPRISE_CONNECT
+      * @see #VIEW
+      * @see #MESSAGE
+      */
+     private int kind;
+     
+     // Miscellaneous state depending on the kind of event
+     InternalDistributedMember member;
+     boolean crashed;
+     String reason;
+     DistributionMessage dmsg;
+     NetView gmsView;
+     
+     @Override
+     public String toString() {
+       StringBuffer sb = new StringBuffer();
+       sb.append("kind=");
+       switch (kind) {
+       case SURPRISE_CONNECT:
+         sb.append("connect; member = <" + member + ">");
+         break;
+       case VIEW:
+         String text = gmsView.toString();
+         sb.append("view <" + text + ">");
+         break;
+       case MESSAGE:
+         sb.append("message <" + dmsg + ">");
+         break;
+       default:
+         sb.append("unknown=<" + kind + ">");
+         break;
+       }
+       return sb.toString();
+     }
+ 
+     /**
+      * Create a surprise connect event
+      * @param member the member connecting
+      */
+     StartupEvent(final InternalDistributedMember member) {
+       this.kind = SURPRISE_CONNECT;
+       this.member = member;
+     }
+     /**
+      * Indicate if this is a surprise connect event
+      * @return true if this is a connect event
+      */
+     boolean isSurpriseConnect() {
+       return this.kind == SURPRISE_CONNECT;
+     }
+ 
+     /**
+      * Create a view event
+      * @param v the new view
+      */
+     StartupEvent(NetView v) {
+       this.kind = VIEW;
+       this.gmsView = v;
+     }
+     
+     /**
+      * Indicate if this is a view event
+      * @return true if this is a view event
+      */
+     boolean isGmsView() {
+       return this.kind == VIEW;
+     }
+ 
+     /**
+      * Create a message event
+      * @param d the message
+      */
+     StartupEvent(DistributionMessage d) {
+       this.kind = MESSAGE;
+       this.dmsg = d;
+     }
+     /**
+      * Indicate if this is a message event
+      * @return true if this is a message event
+      */
+     boolean isDistributionMessage() {
+       return this.kind == MESSAGE;
+     }
+   }
+   
+   private int membershipCheckTimeout = DistributionConfig.DEFAULT_SECURITY_PEER_VERIFYMEMBER_TIMEOUT;
+ 
+   /**
+    * This object synchronizes threads waiting for
+    * startup to finish.  Updates to {@link #startupMessages}
+    * are synchronized through this object.
+    */
+   protected final EventProcessingLock startupLock = new EventProcessingLock();
+   
+   /**
+    * This is the latest view (ordered list of DistributedMembers) 
+    * that has been installed
+    * 
+    * All accesses to this object are protected via {@link #latestViewLock}
+    */
+   protected NetView latestView = new NetView();
+ 
+   /**
+    * This is the lock for protecting access to latestView
+    * 
+    * @see #latestView
+    */
+   protected ReadWriteLock latestViewLock = new ReentrantReadWriteLock();
+   
+   /**
+    * This is the listener that accepts our membership events
+    */
+   protected com.gemstone.gemfire.distributed.internal.membership.DistributedMembershipListener listener;
+ 
+   /**
+    * Membership failure listeners - for testing
+    */
+   List membershipTestHooks;
+   
+   /**
+    * This is a representation of the local member (ourself)
+    */
+   protected InternalDistributedMember address = null; // new DistributedMember(-1);
+ 
+   protected DirectChannel directChannel;
+ 
+   protected MyDCReceiver dcReceiver;
+   
+   volatile boolean isJoining;
+   
+   /** have we joined successfully? */
+   volatile boolean hasJoined;
+   
+   /**
+    * Members of the distributed system that we believe have shut down.
+    * Keys are instances of {@link InternalDistributedMember}, values are 
+    * Longs indicating the time this member was shunned.
+    * 
+    * Members are removed after {@link #SHUNNED_SUNSET} seconds have
+    * passed.
+    * 
+    * Accesses to this list needs to be under the read or write lock of {@link #latestViewLock}
+    * 
+    * @see System#currentTimeMillis()
+    */
+ //  protected final Set shunnedMembers = Collections.synchronizedSet(new HashSet());
+   protected final Map shunnedMembers = new ConcurrentHashMap();
+ 
+   /**
+    * Members that have sent a shutdown message.  This is used to suppress
+    * suspect processing that otherwise becomes pretty aggressive 
+    * when a member is shutting down.
+    */
+   private final Map shutdownMembers = new BoundedLinkedHashMap(1000);
+   
+   /**
+    * per bug 39552, keep a list of members that have been shunned and for
+    * which a message is printed.  Contents of this list are cleared at the
+    * same time they are removed from {@link #shunnedMembers}.
+    * 
+    * Accesses to this list needs to be under the read or write lock of {@link #latestViewLock}
+    */
+   protected final HashSet shunnedAndWarnedMembers = new HashSet();
+   /**
+    * The identities and birth-times of others that we have allowed into
+    * membership at the distributed system level, but have not yet appeared
+    * in a view.
+    * <p>
+    * Keys are instances of {@link InternalDistributedMember}, values are 
+    * Longs indicating the time this member was shunned.
+    * <p>
+    * Members are removed when a view containing them is processed.  If,
+    * after {@link #surpriseMemberTimeout} milliseconds have passed, a view
+    * containing the member has not arrived, the member is removed from
+    * membership and member-left notification is performed. 
+    * <p>>
+    * Accesses to this list needs to be under the read or write lock of {@link #latestViewLock}
+    * 
+    * @see System#currentTimeMillis()
+    */
+   protected final Map<InternalDistributedMember, Long> surpriseMembers = new ConcurrentHashMap();
+ 
+   /**
+    * the timeout interval for surprise members.  This is calculated from 
+    * the member-timeout setting
+    */
+   protected int surpriseMemberTimeout;
+   
+   /**
+    * javagroups can skip views and omit telling us about a crashed member.
+    * This map holds a history of suspected members that we use to detect
+    * crashes.
+    */
+   private final Map<InternalDistributedMember, Long> suspectedMembers = new ConcurrentHashMap();
+   
+   /**
+    * the timeout interval for suspected members
+    */
+   private final long suspectMemberTimeout = 180000;
+   
+   /**
+    * Length of time, in seconds, that a member is retained in the zombie set
+    * 
+    * @see #shunnedMembers
+    */
+   static private final int SHUNNED_SUNSET = Integer.getInteger(
+       "gemfire.shunned-member-timeout", 300).intValue();
+   
+   /**
+    * Set to true when the service should stop.
+    */
+   protected volatile boolean shutdownInProgress = false;
+   
+   /**
+    * Set to true when upcalls should be generated for
+    * events.
+    */
+   protected volatile boolean processingEvents = false;
+   
+   /**
+    * This is the latest viewId installed
+    */
+   long latestViewId = -1;
+   
+   /** distribution manager statistics */
+   DMStats stats;
+ 
+   /**
+    A list of messages received during channel startup that couldn't be processed yet.
+    Additions or removals of this list must be synchronized
+    via {@link #startupLock}.
+    @since 5.0
+    */
+   protected LinkedList<StartupEvent> startupMessages = new LinkedList<StartupEvent>();
+   
+   /**
+    * ARB: the map of latches is used to block peer handshakes till
+    * authentication is confirmed.
+    */
+   final private HashMap memberLatch = new HashMap();
+   
+   /**
+    * Insert our own MessageReceiver between us and the direct channel, in order
+    * to correctly filter membership events.
+    * 
+    * @author jpenney
+    * 
+    */
+   class MyDCReceiver implements DirectChannelListener
+   {
+ 
+     DirectChannelListener upCall;
+     
+     /**
+      * Don't provide events until the caller has told us we are ready.
+      * 
+      * Synchronization provided via GroupMembershipService.class.
+      * 
+      * Note that in practice we only need to delay accepting the first
+      * client; we don't need to put this check before every call...
+      *
+      */
+    MyDCReceiver(DirectChannelListener up) {
+       upCall = up;
+     }
+ 
+     public void messageReceived(DistributionMessage msg) {
+       // bug 36851 - notify failure detection that we've had contact from a member
+       services.getHealthMonitor().contactedBy(msg.getSender());
+       handleOrDeferMessage(msg);
+     }
+ 
+     public DistributionManager getDM() {
+      return upCall.getDM();
+     }
+ 
+   }
+ 
+ 
+   /** if we connect to a locator that has NPD enabled then we enable it in this VM */
+   public void enableNetworkPartitionDetection() {
+     if (logger.isDebugEnabled()) {
+       logger.debug("Network partition detection is being enabled");
+     }
+     this.services.getConfig().getDistributionConfig().setEnableNetworkPartitionDetection(true);
+     this.services.getConfig().setNetworkPartitionDetectionEnabled(true);
+   }
+   
+   /**
+    * Analyze a given view object, generate events as appropriate
+    * 
+    * @param newView
+    */
+   protected void processView(long newViewId, NetView newView)
+   {
+     // Sanity check...
+      if (logger.isDebugEnabled()) {
+       StringBuffer msg = new StringBuffer(200);
+       msg.append("Membership: Processing view ");
+       msg.append(newView);
+       msg.append("} on " + address.toString());
+       if (!newView.contains(address)) {
+         logger.info(LocalizedMessage.create(
+             LocalizedStrings.GroupMembershipService_THE_MEMBER_WITH_ID_0_IS_NO_LONGER_IN_MY_OWN_VIEW_1,
+             new Object[] {address, newView}));
+       }
+     }
+      
+ //     if (newView.getCrashedMembers().size() > 0) {
+ //       // dump stack for debugging #39827
+ //       OSProcess.printStacks(0);
+ //     }
+     // We perform the update under a global lock so that other
+     // incoming events will not be lost in terms of our global view.
+     latestViewLock.writeLock().lock();
+     try {
+       // first determine the version for multicast message serialization
+       Version version = Version.CURRENT;
+       for (Iterator<Map.Entry<InternalDistributedMember, Long>> it=surpriseMembers.entrySet().iterator(); it.hasNext(); ) {
+         InternalDistributedMember mbr = it.next().getKey();
+         Version itsVersion = mbr.getVersionObject();
+         if (itsVersion != null && version.compareTo(itsVersion) < 0) {
+           version = itsVersion;
+         }
+       }
+       for (InternalDistributedMember mbr: newView.getMembers()) {
+         Version itsVersion = mbr.getVersionObject();
+         if (itsVersion != null && itsVersion.compareTo(version) < 0) {
+           version = mbr.getVersionObject();
+         }
+       }
+       disableMulticastForRollingUpgrade = !version.equals(Version.CURRENT);
+       
+       if (newViewId < latestViewId) {
+         // ignore this view since it is old news
+         return;
+       }
+ 
+       // Save previous view, for delta analysis
+       NetView priorView = latestView;
+       
+       // update the view to reflect our changes, so that
+       // callbacks will see the new (updated) view.
+       latestViewId = newViewId;
+       latestView = new NetView(newView, newView.getViewId());
+       
+       // look for additions
+       for (int i = 0; i < newView.getMembers().size(); i++) { // additions
+         InternalDistributedMember m = (InternalDistributedMember)newView.getMembers().get(i);
+         
+         // Once a member has been seen via a view, remove them from the
+         // newborn set
+         boolean wasSurprise = surpriseMembers.remove(m) != null;
+         
+         // bug #45155 - membership view processing was slow, causing a member to connect as "surprise"
+         // and the surprise timeout removed the member and shunned it, keeping it from being
+         // recognized as a valid member when it was finally seen in a view
+ //        if (isShunned(m)) {
+ //          warnShuns.add(m);
+ //          continue;
+ //        }
+ 
+         // if it's in a view, it's no longer suspect
+         suspectedMembers.remove(m);
+ 
+         if (priorView.contains(m) || wasSurprise) {
+           continue; // already seen
+         }
+       
+         // ARB: unblock any waiters for this particular member.
+         // i.e. signal any waiting threads in tcpconduit.
+         String authInit = this.services.getConfig().getDistributionConfig().getSecurityPeerAuthInit();
+         boolean isSecure = authInit != null && authInit.length() != 0;
+ 
+         if (isSecure) {
+           CountDownLatch currentLatch;
+           if ((currentLatch = (CountDownLatch)memberLatch.get(m)) != null) {
+             currentLatch.countDown();
+           }
+         }
+ 
+         if (shutdownInProgress()) {
+           addShunnedMember(m);
+           continue; // no additions processed after shutdown begins
+         } else {
+           boolean wasShunned = endShun(m); // bug #45158 - no longer shun a process that is now in view
+           if (wasShunned && logger.isDebugEnabled()) {
+             logger.debug("No longer shunning {} as it is in the current membership view", m);
+           }
+         }
+         
+         logger.info(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_MEMBERSHIP_PROCESSING_ADDITION__0_, m));
+ 
+         try {
+           listener.newMemberConnected(m);
+         }
+         catch (VirtualMachineError err) {
+           SystemFailure.initiateFailure(err);
+           // If this ever returns, rethrow the error.  We're poisoned
+           // now, so don't let this thread continue.
+           throw err;
+         }
+         catch (DistributedSystemDisconnectedException e) {
+           // don't log shutdown exceptions
+         }
+         catch (Throwable t) {
+           // Whenever you catch Error or Throwable, you must also
+           // catch VirtualMachineError (see above).  However, there is
+           // _still_ a possibility that you are dealing with a cascading
+           // error condition, so you also need to check to see if the JVM
+           // is still usable:
+           SystemFailure.checkFailure();
+           logger.info(LocalizedMessage.create(
+               LocalizedStrings.GroupMembershipService_MEMBERSHIP_FAULT_WHILE_PROCESSING_VIEW_ADDITION_OF__0, m), t);
+         }
+       } // additions
+       
+       // look for departures
+       for (int i = 0; i < priorView.getMembers().size(); i++) { // departures
+         InternalDistributedMember m = (InternalDistributedMember)priorView.getMembers().get(i);
+         if (newView.contains(m)) {
+           continue; // still alive
+         }
+         
+         if (surpriseMembers.containsKey(m)) {
+           continue; // member has not yet appeared in a view
+         }
+ 
+         try {
+           removeWithViewLock(m,
+               newView.getCrashedMembers().contains(m) || suspectedMembers.containsKey(m)
+               , "departed membership view");
+         }
+         catch (VirtualMachineError err) {
+           SystemFailure.initiateFailure(err);
+           // If this ever returns, rethrow the error.  We're poisoned
+           // now, so don't let this thread continue.
+           throw err;
+         }
+         catch (Throwable t) {
+           // Whenever you catch Error or Throwable, you must also
+           // catch VirtualMachineError (see above).  However, there is
+           // _still_ a possibility that you are dealing with a cascading
+           // error condition, so you also need to check to see if the JVM
+           // is still usable:
+           SystemFailure.checkFailure();
+           logger.info(LocalizedMessage.create(
+               LocalizedStrings.GroupMembershipService_MEMBERSHIP_FAULT_WHILE_PROCESSING_VIEW_REMOVAL_OF__0, m), t);
+         }
+       } // departures
+       
+       // expire surprise members, add others to view
+       long oldestAllowed = System.currentTimeMillis() - this.surpriseMemberTimeout;
+       for (Iterator<Map.Entry<InternalDistributedMember, Long>> it=surpriseMembers.entrySet().iterator(); it.hasNext(); ) {
+         Map.Entry<InternalDistributedMember, Long> entry = it.next();
+         Long birthtime = (Long)entry.getValue();
+         if (birthtime.longValue() < oldestAllowed) {
+           it.remove();
+           InternalDistributedMember m = entry.getKey();
+           logger.info(LocalizedMessage.create(
+             LocalizedStrings.GroupMembershipService_MEMBERSHIP_EXPIRING_MEMBERSHIP_OF_SURPRISE_MEMBER_0, m));
+           removeWithViewLock(m, true, "not seen in membership view in "
+               + this.surpriseMemberTimeout + "ms");
+         }
+         else {
+           if (!latestView.contains(entry.getKey())) {
+             latestView.add(entry.getKey());
+           }
+         }
+       }
+       // expire suspected members
+       oldestAllowed = System.currentTimeMillis() - this.suspectMemberTimeout;
+       for (Iterator it=suspectedMembers.entrySet().iterator(); it.hasNext(); ) {
+         Map.Entry entry = (Map.Entry)it.next();
+         Long birthtime = (Long)entry.getValue();
+         if (birthtime.longValue() < oldestAllowed) {
+           InternalDistributedMember m = (InternalDistributedMember)entry.getKey();
+           it.remove();
+         }
+       }
+       try {
+         listener.viewInstalled(latestView);
+         startCleanupTimer();
+       }
+       catch (DistributedSystemDisconnectedException se) {
+       }
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+ 
+   /**
+    * the timer used to perform periodic tasks
+    * 
+    * Concurrency: protected by {@link #latestViewLock} ReentrantReadWriteLock
+    */
+   private SystemTimer cleanupTimer;
+ 
+   private Services services;
+ 
+   private boolean mcastEnabled;
+ 
+   private boolean tcpDisabled;
+ 
+ 
+   @Override
+   public boolean isMulticastAllowed() {
+     return !disableMulticastForRollingUpgrade;
+   }
+ 
+   /**
+    * Joins the distributed system
+    * 
+    * @throws GemFireConfigException - configuration error
+    * @throws SystemConnectException - problem joining
+    */
+   private void join() {
+     services.setShutdownCause(null);
+     services.getCancelCriterion().cancel(null);
+     
+     latestViewLock.writeLock().lock();
+     try {
+       try {
+         this.isJoining = true; // added for bug #44373
+ 
+         // connect
+         long start = System.currentTimeMillis();
+ 
+         boolean ok = services.getJoinLeave().join();
+         
+         if (!ok) {
+           throw new GemFireConfigException("Unable to join the distributed system.  " +
+               "Operation either timed out, was stopped or Locator does not exist.");
+         }
+ 
+         long delta = System.currentTimeMillis() - start;
+ 
+         logger.info(LogMarker.DISTRIBUTION, LocalizedMessage.create(
+             LocalizedStrings.GroupMembershipService_JOINED_TOOK__0__MS, delta));
+ 
+         NetView initialView = services.getJoinLeave().getView();
+         latestView = new NetView(initialView, initialView.getViewId());
+         listener.viewInstalled(latestView);
+         
+       } catch (RuntimeException ex) {
+         throw ex;
+       }
+       catch (Exception ex) {
+         if (ex.getCause() != null && ex.getCause().getCause() instanceof SystemConnectException) {
+           throw (SystemConnectException)(ex.getCause().getCause());
+         }
+         throw new DistributionException(LocalizedStrings.GroupMembershipService_AN_EXCEPTION_WAS_THROWN_WHILE_JOINING.toLocalizedString(), ex);
+       }
+       finally {
+         this.isJoining = false;
+       }
+     }
+     finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+ 
+ 
+   public GMSMembershipManager(DistributedMembershipListener listener) {
+     Assert.assertTrue(listener != null);
+     this.listener = listener;
+   }
+   
+   @Override
+   public void init(Services services) {
+     this.services = services;
+ 
+     Assert.assertTrue(services != null);
+     
+     this.stats = services.getStatistics();
+     DistributionConfig config = services.getConfig().getDistributionConfig();
+     RemoteTransportConfig transport = services.getConfig().getTransport();
+ 
+     this.membershipCheckTimeout = config.getSecurityPeerMembershipTimeout();
+     this.wasReconnectingSystem = transport.getIsReconnectingDS();
+     
+     // cache these settings for use in send()
+     this.mcastEnabled = transport.isMcastEnabled();
+     this.tcpDisabled  = transport.isTcpDisabled();
+ 
+     if (!this.tcpDisabled) {
+       dcReceiver = new MyDCReceiver(listener);
+     }
+     
+     surpriseMemberTimeout = Math.max(20 * DistributionConfig.DEFAULT_MEMBER_TIMEOUT,
+         20 * config.getMemberTimeout());
+     surpriseMemberTimeout = Integer.getInteger("gemfire.surprise-member-timeout", surpriseMemberTimeout).intValue();
+     
+   }
+   
+   @Override
+   public void start() {
+     DistributionConfig config = services.getConfig().getDistributionConfig();
+     RemoteTransportConfig transport = services.getConfig().getTransport();
+ 
+     int dcPort = 0;
+     if (!tcpDisabled) {
+       directChannel = new DirectChannel(this, dcReceiver, config);
+       dcPort = directChannel.getPort();
+     }
+ 
+     
+     services.getMessenger().getMemberID().setDirectChannelPort(dcPort);
+ 
+   }
+   
+   
+   @Override
+   public void joinDistributedSystem() {
+     long startTime = System.currentTimeMillis();
+     
+     try {
+       join();
+     }
+     catch (RuntimeException e) {
+       if (directChannel != null) {
+         directChannel.disconnect(e);
+       }
+       throw e;
+     }
+     
+     this.address = services.getMessenger().getMemberID();
+ 
+     int dcPort = 0;
+     if (directChannel != null) {
+       dcPort = directChannel.getPort();
+     }
+     
+     if (directChannel != null) {
+       directChannel.setLocalAddr(address);
+     }
+ 
+     this.hasJoined = true;
+ 
+     // in order to debug startup issues we need to announce the membership
+     // ID as soon as we know it
+     logger.info(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_entered_into_membership_in_group_0_with_id_1,
+         new Object[]{""+(System.currentTimeMillis()-startTime)}));
+ 
+   }
+   
+   @Override
+   public void started() {
+   }
+   
+ 
+   /** this is invoked by JoinLeave when there is a loss of quorum in the membership system */
+   public void quorumLost(Collection<InternalDistributedMember> failures, NetView view) {
+     // notify of quorum loss if split-brain detection is enabled (meaning we'll shut down) or
+     // if the loss is more than one member
+     
+     boolean notify = failures.size() > 1;
+     if (!notify) {
+       notify = services.getConfig().isNetworkPartitionDetectionEnabled();
+     }
+     
+     if (notify) {
+       List<InternalDistributedMember> remaining = new ArrayList<InternalDistributedMember>(view.getMembers());
+       remaining.removeAll(failures);
+       
+       if (inhibitForceDisconnectLogging) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("<ExpectedException action=add>Possible loss of quorum</ExpectedException>");
+         }
+       }
+       logger.fatal(LocalizedMessage.create(
+           LocalizedStrings.GroupMembershipService_POSSIBLE_LOSS_OF_QUORUM_DETECTED, new Object[] {failures.size(), failures}));
+       if (inhibitForceDisconnectLogging) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("<ExpectedException action=remove>Possible loss of quorum</ExpectedException>");
+         }
+       }
+       
+   
+       try {
+         this.listener.quorumLost(new HashSet<InternalDistributedMember>(failures),
+             remaining);
+       } catch (CancelException e) {
+         // safe to ignore - a forced disconnect probably occurred
+       }
+     }
+   }
+   
+ 
+   @Override
+   public boolean testMulticast() {
+     try {
+       return services.getMessenger().testMulticast(services.getConfig().getMemberTimeout());
+     } catch (InterruptedException e) {
+       services.getCancelCriterion().checkCancelInProgress(e);
+       Thread.currentThread().interrupt();
+       return false;
+     }
+   }
+   
+   /**
+    * Remove a member.  {@link #latestViewLock} must be held
+    * before this method is called.  If member is not already shunned,
+    * the uplevel event handler is invoked.
+    * 
+    * @param dm
+    * @param crashed
+    * @param reason
+    */
+   protected void removeWithViewLock(InternalDistributedMember dm,
+       boolean crashed, String reason) {
+     boolean wasShunned = isShunned(dm);
+ 
+     // Delete resources
+     destroyMember(dm, crashed, reason);
+ 
+     if (wasShunned) {
+       return; // Explicit deletion, no upcall.
+     }
+     
+     try {
+       listener.memberDeparted(dm, crashed, reason);
+     }
+     catch (DistributedSystemDisconnectedException se) {
+       // let's not get huffy about it
+     }
+   }
+   
+   /**
+    * Process a surprise connect event, or place it on the startup queue.
+    * @param member the member
+    */
+   protected void handleOrDeferSurpriseConnect(InternalDistributedMember member) {
+     synchronized (startupLock) {
+       if (!processingEvents) {
+         startupMessages.add(new StartupEvent(member));
+         return;
+       }
+     }
+     processSurpriseConnect(member);
+   }
+   
+   public void startupMessageFailed(DistributedMember mbr, String failureMessage) {
+     // fix for bug #40666
+     addShunnedMember((InternalDistributedMember)mbr);
+     // fix for bug #41329, hang waiting for replies
+     try {
+       listener.memberDeparted((InternalDistributedMember)mbr, true, "failed to pass startup checks");
+     }
+     catch (DistributedSystemDisconnectedException se) {
+       // let's not get huffy about it
+     }
+   }
+ 
+   
+   /**
+    * Logic for handling a direct connection event (message received
+    * from a member not in the view).  Does not employ the
+    * startup queue.
+    * <p>
+    * Must be called with {@link #latestViewLock} held.  Waits
+    * until there is a stable view.  If the member has already
+    * been added, simply returns; else adds the member.
+    * 
+    * @param dm the member joining
+    */
+   public boolean addSurpriseMember(DistributedMember dm) {
+     final InternalDistributedMember member = (InternalDistributedMember)dm;
+     boolean warn = false;
+     
+     latestViewLock.writeLock().lock();
+     try {
+       // At this point, the join may have been discovered by
+       // other means.
+       if (latestView.contains(member)) {
+         return true;
+       }
+       if (surpriseMembers.containsKey(member)) {
+         return true;
+       }
+       if (member.getVmViewId() < 0) {
+         logger.warn("adding a surprise member that has not yet joined the distributed system: " + member, new Exception("stack trace"));
+       }
+       if (latestView.getViewId() > member.getVmViewId()) {
+         // tell the process that it should shut down distribution.
+         // Run in a separate thread so we don't hold the view lock during the request.  Bug #44995
+         new Thread(Thread.currentThread().getThreadGroup(),
+             "Removing shunned GemFire node " + member) {
+           @Override
+           public void run() {
+             // fix for bug #42548
+             // this is an old member that shouldn't be added
+             logger.warn(LocalizedMessage.create(
+                 LocalizedStrings.GroupMembershipService_Invalid_Surprise_Member, new Object[]{member, latestView}));
+             requestMemberRemoval(member, "this member is no longer in the view but is initiating connections");
+           }
+         }.start();
+         addShunnedMember(member);
+         return false;
+       }
+ 
+       // Adding him to this set ensures we won't remove him if a new
+       // view comes in and he's still not visible.
+       surpriseMembers.put(member, Long.valueOf(System.currentTimeMillis()));
+ 
+       if (shutdownInProgress()) {
+         // Force disconnect, esp. the TCPConduit
+         String msg = LocalizedStrings.GroupMembershipService_THIS_DISTRIBUTED_SYSTEM_IS_SHUTTING_DOWN.toLocalizedString();
+         if (directChannel != null) {
+           try {
+             directChannel.closeEndpoint(member, msg);
+           } catch (DistributedSystemDisconnectedException e) {
+             // ignore - happens during shutdown
+           }
+         }
+         destroyMember(member, false, msg); // for good luck
+         return true; // allow during shutdown
+       }
+ 
+       if (isShunned(member)) {
+         warn = true;
+         surpriseMembers.remove(member);
+       } else {
+ 
+         // Now that we're sure the member is new, add them.
+         // make sure the surprise-member cleanup task is running
+         if (this.cleanupTimer == null) {
+           startCleanupTimer();
+         } // cleanupTimer == null
+ 
+         // Ensure that the member is accounted for in the view
+         // Conjure up a new view including the new member. This is necessary
+         // because we are about to tell the listener about a new member, so
+         // the listener should rightfully expect that the member is in our
+         // membership view.
+ 
+         // However, we put the new member at the end of the list.  This
+         // should ensure he's not chosen as an elder.
+         // This will get corrected when he finally shows up in the
+         // view.
+         NetView newMembers = new NetView(latestView, latestView.getViewId());
+         newMembers.add(member);
+         latestView = newMembers;
+       }
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+     if (warn) { // fix for bug #41538 - deadlock while alerting
+       logger.warn(LocalizedMessage.create(
+           LocalizedStrings.GroupMembershipService_MEMBERSHIP_IGNORING_SURPRISE_CONNECT_FROM_SHUNNED_MEMBER_0, member));
+     } else {
+       listener.newMemberConnected(member);
+     }
+     return !warn;
+   }
+   
+ 
+   /** starts periodic task to perform cleanup chores such as expire surprise members */
+   private void startCleanupTimer() {
+     latestViewLock.writeLock().lock();
+     try {
+       if (this.cleanupTimer != null) {
+         return;
+       }
+       DistributedSystem ds = InternalDistributedSystem.getAnyInstance();
+       if (ds != null && ds.isConnected()) {
+         this.cleanupTimer = new SystemTimer(ds, true);
+         SystemTimer.SystemTimerTask st = new SystemTimer.SystemTimerTask() {
+           @Override
+           public void run2() {
+             latestViewLock.writeLock().lock();
+             try {
+               long oldestAllowed = System.currentTimeMillis() - surpriseMemberTimeout;
+               for (Iterator it=surpriseMembers.entrySet().iterator(); it.hasNext(); ) {
+                 Map.Entry entry = (Map.Entry)it.next();
+                 Long birthtime = (Long)entry.getValue();
+                 if (birthtime.longValue() < oldestAllowed) {
+                   it.remove();
+                   InternalDistributedMember m = (InternalDistributedMember)entry.getKey();
+                   logger.info(LocalizedMessage.create(
+                       LocalizedStrings.GroupMembershipService_MEMBERSHIP_EXPIRING_MEMBERSHIP_OF_SURPRISE_MEMBER_0, m));
+                   removeWithViewLock(m, true, "not seen in membership view in "
+                       + surpriseMemberTimeout + "ms");
+                 }
+               }
+             } finally {
+               latestViewLock.writeLock().unlock();
+             }
+           }
+         };
+         this.cleanupTimer.scheduleAtFixedRate(st, surpriseMemberTimeout, surpriseMemberTimeout/3);
+       } // ds != null && ds.isConnected()
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+   /**
+    * Dispatch the distribution message, or place it on the startup queue.
+    * 
+    * @param msg the message to process
+    */
+   protected void handleOrDeferMessage(DistributionMessage msg) {
+     synchronized(startupLock) {
+       if (!processingEvents) {
+         startupMessages.add(new StartupEvent(msg));
+         return;
+       }
+     }
+     dispatchMessage(msg);
+   }
+   
+   public void warnShun(DistributedMember m) {
+     latestViewLock.writeLock().lock();
+     try {
+       if (!shunnedMembers.containsKey(m)) {
+         return; // not shunned
+       }
+       if (shunnedAndWarnedMembers.contains(m)) {
+         return; // already warned
+       }
+       shunnedAndWarnedMembers.add(m);
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+     // issue warning outside of sync since it may cause messaging and we don't
+     // want to hold the view lock while doing that
+     logger.warn(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_MEMBERSHIP_DISREGARDING_SHUNNED_MEMBER_0, m));
+   }
+   
+   @Override
+   public void processMessage(DistributionMessage msg) {
+     handleOrDeferMessage(msg);
+   }
+   
+   /**
+    * Logic for processing a distribution message.  
+    * <p>
+    * It is possible to receive messages not consistent with our view.
+    * We handle this here, and generate an uplevel event if necessary
+    * @param msg the message
+    */
+   public void dispatchMessage(DistributionMessage msg) {
+     boolean isNew = false;
+     InternalDistributedMember m = msg.getSender();
+     boolean shunned = false;
+ 
+     // First grab the lock: check the sender against our stabilized view.
+     latestViewLock.writeLock().lock();
+     try {
+       if (isShunned(m)) {
+         if (msg instanceof StartupMessage) {
+           endShun(m);
+         }
+         else {
+           // fix for bug 41538 - sick alert listener causes deadlock
+           // due to view lock being held during messaging
+           shunned = true;
+         }
+       } // isShunned
+ 
+       if (!shunned) {
+         isNew = !latestView.contains(m) && !surpriseMembers.containsKey(m);
+ 
+         // If it's a new sender, wait our turn, generate the event
+         if (isNew) {
+           shunned = !addSurpriseMember(m);
+         } // isNew
+       }
+ 
+       // Latch the view before we unlock
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+     
+     if (shunned) { // bug #41538 - shun notification must be outside synchronization to avoid hanging
+       warnShun(m);
+       logger.info("Membership: Ignoring message from shunned member <{}>:{}", m, msg);
+       throw new MemberShunnedException(m);
+     }
+     
+     listener.messageReceived(msg);
+   }
+ 
+   /**
+    * Process a new view object, or place on the startup queue
+    * @param viewArg the new view
+    */
+   protected void handleOrDeferViewEvent(NetView viewArg) {
+     if (this.isJoining) {
+       // bug #44373 - queue all view messages while joining.
+       // This is done under the latestViewLock, but we can't block here because
+       // we're sitting in the UDP reader thread.
+       synchronized(startupLock) {
+         startupMessages.add(new StartupEvent(viewArg));
+         return;
+       }
+     }
+     latestViewLock.writeLock().lock();
+     try {
+       synchronized(startupLock) {
+         if (!processingEvents) {
+           startupMessages.add(new StartupEvent(viewArg));
+           return;
+         }
+       }
+       // view processing can take a while, so we use a separate thread
+       // to avoid blocking a reader thread
+       NetView newView = viewArg;
+       long newId = viewArg.getViewId();
+       LocalViewMessage v = new LocalViewMessage(address, newId, newView,
+           GMSMembershipManager.this);
+ 
+       listener.messageReceived(v);
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+   
+   @Override
+   public void memberSuspected(InternalDistributedMember initiator, InternalDistributedMember suspect, String reason) {
+     SuspectMember s = new SuspectMember(initiator, suspect, reason);
+     handleOrDeferSuspect(s);
+   }
+ 
+   /**
+    * Process a new view object, or place on the startup queue
+    * @param suspectInfo the suspectee and suspector
+    */
+   protected void handleOrDeferSuspect(SuspectMember suspectInfo) {
+     latestViewLock.writeLock().lock();
+     try {
+       synchronized(startupLock) {
+         if (!processingEvents) {
+           return;
+         }
+       }
+       InternalDistributedMember suspect = suspectInfo.suspectedMember;
+       InternalDistributedMember who = suspectInfo.whoSuspected;
+       this.suspectedMembers.put(suspect, Long.valueOf(System.currentTimeMillis()));
+       try {
+         listener.memberSuspect(suspect, who, suspectInfo.reason);
+       }
+       catch (DistributedSystemDisconnectedException se) {
+         // let's not get huffy about it
+       }
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+ 
+   /**
+    * Process a potential direct connect.  Does not use
+    * the startup queue.  It grabs the {@link #latestViewLock} 
+    * and then processes the event.
+    * <p>
+    * It is a <em>potential</em> event, because we don't know until we've
+    * grabbed a stable view if this is really a new member.
+    * 
+    * @param member
+    */
+   private void processSurpriseConnect(
+       InternalDistributedMember member) 
+   {
+     addSurpriseMember(member);
+   }
+   
+   /**
+    * Dispatch routine for processing a single startup event
+    * @param o the startup event to handle
+    */
+   private void processStartupEvent(StartupEvent o) {
+     // Most common events first
+     
+     if (o.isDistributionMessage()) { // normal message
+       try {
+         dispatchMessage(o.dmsg);
+       }
+       catch (MemberShunnedException e) {
+         // message from non-member - ignore
+       }
+     } 
+     else if (o.isGmsView()) { // view event
+       processView(o.gmsView.getViewId(), o.gmsView);
+     }
+     else if (o.isSurpriseConnect()) { // connect
+       processSurpriseConnect(o.member);
+     }
+     
+     else // sanity
+       throw new InternalGemFireError(LocalizedStrings.GroupMembershipService_UNKNOWN_STARTUP_EVENT_0.toLocalizedString(o));
+   }
+   
+   /**
+    * Special mutex to create a critical section for
+    * {@link #startEventProcessing()}
+    */
+   private final Object startupMutex = new Object();
+ 
+   
+   public void startEventProcessing()
+   {
+     // Only allow one thread to perform the work
+     synchronized (startupMutex) {
+       if (logger.isDebugEnabled())
+         logger.debug("Membership: draining startup events.");
+       // Remove the backqueue of messages, but allow
+       // additional messages to be added.
+       for (;;) {
+         StartupEvent ev;
+         // Only grab the mutex while reading the queue.
+         // Other events may arrive while we're attempting to
+         // drain the queue.  This is OK, we'll just keep processing
+         // events here until we've caught up.
+         synchronized (startupLock) {
+           int remaining = startupMessages.size();
+           if (remaining == 0) {
+             // While holding the lock, flip the bit so that
+             // no more events get put into startupMessages, and
+             // notify all waiters to proceed.
+             processingEvents = true;
+             startupLock.notifyAll();
+             break;  // ...and we're done.
+           }
+           if (logger.isDebugEnabled()) {
+             logger.debug("Membership: {} remaining startup message(s)", remaining);
+           }
+           ev = (StartupEvent)startupMessages.removeFirst();
+         } // startupLock
+         try {
+           processStartupEvent(ev);
+         }
+         catch (VirtualMachineError err) {
+           SystemFailure.initiateFailure(err);
+           // If this ever returns, rethrow the error.  We're poisoned
+           // now, so don't let this thread continue.
+           throw err;
+         }
+         catch (Throwable t) {
+           // Whenever you catch Error or Throwable, you must also
+           // catch VirtualMachineError (see above).  However, there is
+           // _still_ a possibility that you are dealing with a cascading
+           // error condition, so you also need to check to see if the JVM
+           // is still usable:
+           SystemFailure.checkFailure();
+           logger.warn(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_MEMBERSHIP_ERROR_HANDLING_STARTUP_EVENT), t);
+         }
+         
+       } // for
+       if (logger.isDebugEnabled())
+         logger.debug("Membership: finished processing startup events.");
+     } // startupMutex
+   }
+ 
+  
+   public void waitForEventProcessing() throws InterruptedException {
+     // First check outside of a synchronized block.  Cheaper and sufficient.
+     if (Thread.interrupted()) throw new InterruptedException();
+     if (processingEvents)
+       return;
+     if (logger.isDebugEnabled()) {
+       logger.debug("Membership: waiting until the system is ready for events");
+     }
+     for (;;) {
+       directChannel.getCancelCriterion().checkCancelInProgress(null);
+       synchronized (startupLock) {
+         // Now check using a memory fence and synchronization.
+         if (processingEvents)
+           break;
+         boolean interrupted = Thread.interrupted();
+         try {
+           startupLock.wait();
+         }
+         catch (InterruptedException e) {
+           interrupted = true;
+           directChannel.getCancelCriterion().checkCancelInProgress(e);
+         }
+         finally {
+           if (interrupted) {
+             Thread.currentThread().interrupt();
+           }
+         }
+       } // synchronized
+     } // for
+     if (logger.isDebugEnabled()) {
+       logger.debug("Membership: continuing");
+     }
+   }
+ 
+   /**
+    * for testing we need to validate the startup event list
+    */
+   public List<StartupEvent> getStartupEvents() {
+     return this.startupMessages;
+   }
+ 
+   public ReadWriteLock getViewLock() {
+     return this.latestViewLock;
+   }
+ 
+   /**
+    * Returns a copy (possibly not current) of the current
+    * view (a list of {@link DistributedMember}s)
+    */
+   public NetView getView()
+   {
+     // Grab the latest view under a mutex...
+     NetView v;
+ 
+     latestViewLock.readLock().lock();
+     v = latestView;
+     latestViewLock.readLock().unlock();
+ 
+     NetView result = new NetView(v, v.getViewId());
+     
+     for (InternalDistributedMember m: v.getMembers()) {
+       if (isShunned(m)) {
+         result.remove(m);
+       }
+     }
+     
+     return result;
+   }
+   
+   /**
+    * test hook<p>
+    * The lead member is the eldest member with partition detection enabled.<p>
+    * If no members have partition detection enabled, there will be no
+    * lead member and this method will return null.
+    * @return the lead member associated with the latest view
+    */
+   public DistributedMember getLeadMember() {
+     latestViewLock.readLock().lock();
+     try {
+       return latestView == null? null : latestView.getLeadMember();
+     } finally {
+       latestViewLock.readLock().unlock();
+     }
+   }
+   
+   protected boolean isJoining() {
+     return this.isJoining;
+   }
+   
+   /**
+    * test hook
+    * @return the current membership view coordinator
+    */
+   public DistributedMember getCoordinator() {
 -    // note - we go straight to JoinLeave because the
 -    // DistributionManager queues view changes in a serial executor, where
 -    // they're asynchronously installed.  The DS may still see the old coordinator
+     latestViewLock.readLock().lock();
+     try {
+       return latestView == null? null : latestView.getCoordinator();
+     } finally {
+       latestViewLock.readLock().unlock();
+     }
+   }
+ 
+   public boolean memberExists(DistributedMember m) {
+     latestViewLock.readLock().lock();
+     NetView v = latestView;
+     latestViewLock.readLock().unlock();
+     return v.getMembers().contains(m);
+   }
+   
+   /**
+    * Returns the identity associated with this member. WARNING: this value will
+    * be returned after the channel is closed, but in that case it is good for
+    * logging purposes only. :-)
+    */
+   public InternalDistributedMember getLocalMember()
+   {
+     return address;
+   }
+   
+   public Services getServices() {
+     return services;
+   }
+ 
+   public void postConnect() {
+   }
+   
+   /**
+    * @see SystemFailure#loadEmergencyClasses()
+    /**
+    * break any potential circularity in {@link #loadEmergencyClasses()}
+    */
+   private static volatile boolean emergencyClassesLoaded = false;
+ 
+   /**
+    * inhibits logging of ForcedDisconnectException to keep dunit logs clean
+    * while testing this feature
+    */
+   protected static volatile boolean inhibitForceDisconnectLogging;
+   
+   /**
+    * Ensure that the critical classes from components
+    * get loaded.
+    * 
+    * @see SystemFailure#loadEmergencyClasses()
+    */
+   public static void loadEmergencyClasses() {
+     if (emergencyClassesLoaded) return;
+     emergencyClassesLoaded = true;
+     DirectChannel.loadEmergencyClasses();
+     GMSJoinLeave.loadEmergencyClasses();
+     GMSHealthMonitor.loadEmergencyClasses();
+   }
+   /**
+    * Close the receiver, avoiding all potential deadlocks and
+    * eschewing any attempts at being graceful.
+    * 
+    * @see SystemFailure#emergencyClose()
+    */
+   public void emergencyClose() {
+     final boolean DEBUG = SystemFailure.TRACE_CLOSE;
+     
+     setShutdown(); 
+ 
+     // We can't call close() because they will allocate objects.  Attempt
+     // a surgical strike and touch the important protocols.
+     
+     // MOST important, kill the FD protocols...
+     services.emergencyClose();
+     
+     // Close the TCPConduit sockets...
+     if (directChannel != null) {
+       if (DEBUG) {
+         System.err.println("DEBUG: emergency close of DirectChannel");
+       }
+       directChannel.emergencyClose();
+     }
+     
+     if (DEBUG) {
+       System.err.println("DEBUG: done closing GroupMembershipService");
+     }
+   }
+   
+   
+   /**
+    * in order to avoid split-brain occurring when a member is shutting down due to
+    * race conditions in view management we add it as a shutdown member when we receive
+    * a shutdown message.  This is not the same as a SHUNNED member.
+    */
+   public void shutdownMessageReceived(InternalDistributedMember id, String reason) {
+     if (logger.isDebugEnabled()) {
+       logger.debug("Membership: recording shutdown status of {}", id);
+     }
+     synchronized(this.shutdownMembers) { 
+       this.shutdownMembers.put(id, id);
+       services.getHealthMonitor().memberShutdown(id, reason);
+       services.getJoinLeave().memberShutdown(id, reason);
+     }
+   }
+   
+   /**
+    * returns true if a shutdown message has been received from the given address but
+    * that member is still in the membership view or is a surprise member.
+    */
+   public boolean isShuttingDown(InternalDistributedMember mbr) {
+     synchronized(shutdownMembers) {
+       return shutdownMembers.containsKey(mbr);
+     }
+   }
+ 
+   
+   public void shutdown() {
+     setShutdown();
+     services.stop();
+   }
+   
+   @Override
+   public void stop() {
+     
+     // [bruce] Do not null out the channel w/o adding appropriate synchronization
+     
+     logger.debug("MembershipManager closing");
+     
+     if (directChannel != null) {
+       directChannel.disconnect(null);
+ 
+       if (address != null) {
+         // Make sure that channel information is consistent
+         // Probably not important in this particular case, but just
+         // to be consistent...
+         latestViewLock.writeLock().lock();
+         try {
+           destroyMember(address, false, "orderly shutdown");
+         } finally {
+           latestViewLock.writeLock().unlock();
+         }
+       }
+     }
+     
+     if (cleanupTimer != null) {
+       cleanupTimer.cancel();
+     }
+     
+     if (logger.isDebugEnabled()) {
+       logger.debug("Membership: channel closed");
+     }
+   }
+   
+   public void uncleanShutdown(String reason, final Exception e) {
+     inhibitForcedDisconnectLogging(false);
+     
+     if (services.getShutdownCause() == null) {
+       services.setShutdownCause(e);
+     }
+     
+     if (this.directChannel != null) {
+       this.directChannel.disconnect(e);
+     }
+     
+     // first shut down communication so we don't do any more harm to other
+     // members
+     services.emergencyClose();
+     
+     if (e != null) {
+       try {
+         if (membershipTestHooks != null) {
+           List l = membershipTestHooks;
+           for (Iterator it=l.iterator(); it.hasNext(); ) {
+             MembershipTestHook dml = (MembershipTestHook)it.next();
+             dml.beforeMembershipFailure(reason, e);
+           }
+         }
+         listener.membershipFailure(reason, e);
+         if (membershipTestHooks != null) {
+           List l = membershipTestHooks;
+           for (Iterator it=l.iterator(); it.hasNext(); ) {
+             MembershipTestHook dml = (MembershipTestHook)it.next();
+             dml.afterMembershipFailure(reason, e);
+           }
+         }
+       }
+       catch (RuntimeException re) {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_EXCEPTION_CAUGHT_WHILE_SHUTTING_DOWN), re);
+       }
+     }
+   }
+   
+   /** generate XML for the cache before shutting down due to forced disconnect */
+   public void saveCacheXmlForReconnect() {
+     // there are two versions of this method so it can be unit-tested
+     boolean sharedConfigEnabled = services.getConfig().getDistributionConfig().getUseSharedConfiguration();
+     saveCacheXmlForReconnect(sharedConfigEnabled);
+   }
+   
+   /** generate XML from the cache before shutting down due to forced disconnect */
+   public void saveCacheXmlForReconnect(boolean sharedConfigEnabled) {
+     // first save the current cache description so reconnect can rebuild the cache
+     GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+     if (cache != null && (cache instanceof Cache)) {
+       if (!Boolean.getBoolean("gemfire.autoReconnect-useCacheXMLFile")
+           && !cache.isSqlfSystem() && !sharedConfigEnabled) {
+         try {
+           logger.info("generating XML to rebuild the cache after reconnect completes");
+           StringPrintWriter pw = new StringPrintWriter(); 
+           CacheXmlGenerator.generate((Cache)cache, pw, true, false);
+           String cacheXML = pw.toString();
+           cache.getCacheConfig().setCacheXMLDescription(cacheXML);
+           logger.info("XML generation completed: {}", cacheXML);
+         } catch (CancelException e) {
+           logger.info(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_PROBLEM_GENERATING_CACHE_XML), e);
+         }
+       } else if (sharedConfigEnabled && !cache.getCacheServers().isEmpty()) {
+         // we need to retain a cache-server description if this JVM was started by gfsh
+         List<CacheServerCreation> list = new ArrayList<CacheServerCreation>(cache.getCacheServers().size());
+         for (Iterator it = cache.getCacheServers().iterator(); it.hasNext(); ) {
+           CacheServerImpl cs = (CacheServerImpl)it.next();
+           if (cs.isDefaultServer()) {
+             CacheServerCreation bsc = new CacheServerCreation(cache, cs);
+             list.add(bsc);
+           }
+         }
+         cache.getCacheConfig().setCacheServerCreation(list);
+         logger.info("CacheServer configuration saved");
+       }
+     }
+   }
+ 
+   public boolean requestMemberRemoval(DistributedMember mbr, String reason) {
+     if (mbr.equals(this.address)) {
+       return false;
+     }
+     logger.warn(LocalizedMessage.create(
+         LocalizedStrings.GroupMembershipService_MEMBERSHIP_REQUESTING_REMOVAL_OF_0_REASON_1,
+         new Object[] {mbr, reason}));
+     try {
+       services.getJoinLeave().remove((InternalDistributedMember)mbr, reason);
+     }
+     catch (RuntimeException e) {
+       Throwable problem = e;
+       if (services.getShutdownCause() != null) {
+         Throwable cause = services.getShutdownCause();
+         // If ForcedDisconnectException occurred then report it as actual
+         // problem.
+         if (cause instanceof ForcedDisconnectException) {
+           problem = (Exception) cause;
+         } else {
+           Throwable ne = problem;
+           while (ne.getCause() != null) {
+             ne = ne.getCause();
+           }
+           try {
+             ne.initCause(services.getShutdownCause());
+           }
+           catch (IllegalArgumentException selfCausation) {
+             // fix for bug 38895 - the cause is already in place
+           }
+         }
+       }
+       if (!services.getConfig().getDistributionConfig().getDisableAutoReconnect()) {
+         saveCacheXmlForReconnect();
+       }
+       listener.membershipFailure("Channel closed", problem);
+       throw new DistributedSystemDisconnectedException("Channel closed", problem);
+     }
+     return true;
+   }
+   
+   public void suspectMembers(Set members, String reason) {
+     for (Iterator it=members.iterator(); it.hasNext(); ) {
+       verifyMember((DistributedMember)it.next(), reason);
+     }
+   }
+   
+   public void suspectMember(DistributedMember mbr, String reason) {
+     if (!this.shutdownInProgress && !this.shutdownMembers.containsKey(mbr)) {
+       verifyMember(mbr, reason);
+     }
+   }
+ 
+   /* like memberExists() this checks to see if the given ID is in the current
+    * membership view.  If it is in the view though we try to contact it
+    * to see if it's still around.  If we can't contact it then
+    * suspect messages are sent to initiate final checks
+    * @param mbr the member to verify
+    * @param reason why the check is being done (must not be blank/null)
+    * @return true if the member checks out
+    */
+   public boolean verifyMember(DistributedMember mbr, String reason) {
+     if (mbr != null && memberExists((InternalDistributedMember)mbr)) {
+       return this.services.getHealthMonitor().checkIfAvailable(mbr, reason, true);
+     }
+     return false;
+   }
+ 
+   /**
+    * Perform the grossness associated with sending a message over
+    * a DirectChannel
+    * 
+    * @param destinations the list of destinations
+    * @param content the message
+    * @param theStats the statistics object to update
+    * @return all recipients who did not receive the message (null if
+    * all received it)
+    * @throws NotSerializableException if the message is not serializable
+    */
+   protected Set<InternalDistributedMember> directChannelSend(InternalDistributedMember[] destinations,
+       DistributionMessage content,
+       DMStats theStats)
+       throws NotSerializableException
+   {
+     boolean allDestinations;
+     InternalDistributedMember[] keys;
+     if (content.forAll()) {
+       allDestinations = true;
+       latestViewLock.writeLock().lock();
+       try {
+         List<InternalDistributedMember> keySet = latestView.getMembers();
+         keys = new InternalDistributedMember[keySet.size()];
+         keys = (InternalDistributedMember[])keySet.toArray(keys);
+       } finally {
+         latestViewLock.writeLock().unlock();
+       }
+     }
+     else {
+       allDestinations = false;
+       keys = destinations;
+     }
+ 
+     int sentBytes = 0;
+     try {
+       sentBytes = directChannel.send(this, keys, content,
+           this.services.getConfig().getDistributionConfig().getAckWaitThreshold(),
+           this.services.getConfig().getDistributionConfig().getAckSevereAlertThreshold());
+                                      
+       if (theStats != null) {
+         theStats.incSentBytes(sentBytes);
+       }
+       
+       if (sentBytes == 0) {
+         if (services.getCancelCriterion().cancelInProgress() != null) {
+           throw new DistributedSystemDisconnectedException();
+         }
+       }
+     }
+     catch (DistributedSystemDisconnectedException ex) {
+       if (services.getShutdownCause() != null) {
+         throw new DistributedSystemDisconnectedException("DistributedSystem is shutting down", services.getShutdownCause());
+       } else {
+         throw ex; // see bug 41416
+       }
+     }
+     catch (ConnectExceptions ex) {
+       if (allDestinations)
+         return null;
+       
+       List members = ex.getMembers(); // We need to return this list of failures
+       
+       // SANITY CHECK:  If we fail to send a message to an existing member 
+       // of the view, we have a serious error (bug36202).
+       NetView view = services.getJoinLeave().getView(); // grab a recent view, excluding shunned members
+       
+       // Iterate through members and causes in tandem :-(
+       Iterator it_mem = members.iterator();
+       Iterator it_causes = ex.getCauses().iterator();
+       while (it_mem.hasNext()) {
+         InternalDistributedMember member = (InternalDistributedMember)it_mem.next();
+         Throwable th = (Throwable)it_causes.next();
+         
+         if (!view.contains(member) || (th instanceof ShunnedMemberException)) {
+           continue;
+         }
+         logger.fatal(LocalizedMessage.create(
+             LocalizedStrings.GroupMembershipService_FAILED_TO_SEND_MESSAGE_0_TO_MEMBER_1_VIEW_2,
+             new Object[] {content, member, view}), th);
+ //        Assert.assertTrue(false, "messaging contract failure");
+       }
+       return new HashSet<InternalDistributedMember>(members);
+     } // catch ConnectionExceptions
+     catch (ToDataException | CancelException e) {
+       throw e;
+     }
+     catch (IOException e) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("Membership: directChannelSend caught exception: {}", e.getMessage(), e);
+       }
+       if (e instanceof NotSerializableException) {
+         throw (NotSerializableException)e;
+       }
+     }
+     catch (RuntimeException e) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("Membership: directChannelSend caught exception: {}", e.getMessage(), e);
+       }
+       throw e;
+     }
+     catch (Error e) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("Membership: directChannelSend caught exception: {}", e.getMessage(), e);
+       }
+       throw e;
+     }
+     return null;
+   }
+ 
+   /*
+    * (non-Javadoc)
+    * @see com.gemstone.gemfire.distributed.internal.membership.MembershipManager#isConnected()
+    */
+   public boolean isConnected() {
+     return (this.hasJoined && !this.shutdownInProgress); 
+   }
+   
+   /**
+    * Returns true if the distributed system is in the process of auto-reconnecting.
+    * Otherwise returns false.
+    */
+   public boolean isReconnectingDS() {
+     if (this.hasJoined) {
+       return false;
+     } else {
+       return this.wasReconnectingSystem;
+     }
+   }
+   
+   @Override
+   public QuorumChecker getQuorumChecker() {
+     if ( ! (services.isShutdownDueToForcedDisconnect()) ) {
+       return null;
+     }
+     if (this.quorumChecker != null) {
+       return this.quorumChecker;
+     }
+ 
+     QuorumChecker impl = services.getMessenger().getQuorumChecker();
+     this.quorumChecker = impl;
+     return impl;
+   }
+   
+   @Override
+   public void releaseQuorumChecker(QuorumChecker checker) {
+     ((GMSQuorumChecker)checker).suspend();
+     InternalDistributedSystem system = InternalDistributedSystem.getAnyInstance();
+     if (system == null || !system.isConnected()) {
+       checker.close();
+     }
+   }
+   
+   public Set send(InternalDistributedMember dest, DistributionMessage msg)
+     throws NotSerializableException {
+     
+     InternalDistributedMember dests[] = new InternalDistributedMember[] { dest };
+     return send (dests, msg, null);
+   }
+   
+   public Set send(InternalDistributedMember[] destinations,
+       DistributionMessage msg,
+       DMStats theStats)
+       throws NotSerializableException
+   {
+     Set result = null;
+     boolean allDestinations = msg.forAll();
+     
+     if (services.getCancelCriterion().cancelInProgress() != null) {
+       throw new DistributedSystemDisconnectedException("Distributed System is shutting down",
+           services.getCancelCriterion().generateCancelledException(null));
+     }
+     
+     if (playingDead) { // wellness test hook
+       while (playingDead && !shutdownInProgress) {
+         try {
+           Thread.sleep(1000);
+         } catch (InterruptedException e) {
+           Thread.currentThread().interrupt();
+         }
+       }
+     }
+     
+     if (isJoining()) {
+       // If we get here, we are starting up, so just report a failure.
+       if (allDestinations)
+         return null;
+       else {
+         result = new HashSet();
+         for (int i = 0; i < destinations.length; i ++)
+           result.add(destinations[i]);
+         return result;
+       }
+     }
+     
+     if (msg instanceof AdminMessageType
+         && this.shutdownInProgress) {
+       // no admin messages while shutting down - this can cause threads to hang
+       return new HashSet(Arrays.asList(msg.getRecipients()));
+     }
+ 
+     // Handle trivial cases
+     if (destinations == null) {
+       if (logger.isTraceEnabled())
+         logger.trace("Membership: Message send: returning early because null set passed in: '{}'", msg);
+       return null; // trivially: all recipients received the message
+     }
+     if (destinations.length == 0) {
+       if (logger.isTraceEnabled())
+         logger.trace("Membership: Message send: returning early because empty destination list passed in: '{}'", msg);
+       return null; // trivially: all recipients received the message
+     }
+ 
+     msg.setSender(address);
+     
+     msg.setBreadcrumbsInSender();
+     Breadcrumbs.setProblem(null);
+ 
+     boolean useMcast = false;
+     if (mcastEnabled) {
+       useMcast = (msg.getMulticast() || allDestinations);
+     }
+     
+     boolean sendViaMessenger = isForceUDPCommunications(); // enable when bug #46438 is fixed: || msg.sendViaUDP();
+ 
+     if (useMcast || tcpDisabled || sendViaMessenger) {
+       checkAddressesForUUIDs(destinations);
+       result = services.getMessenger().send(msg);
+     }
+     else {
+       result = directChannelSend(destinations, msg, theStats);
+     }
+ 
+     // If the message was a broadcast, don't enumerate failures.
+     if (allDestinations)
+       return null;
+     else {
+       return result;
+     }
+   }
+   
+   // MembershipManager method
+   @Override
+   public void forceUDPMessagingForCurrentThread() {
+     forceUseUDPMessaging.set(null);
+   }
+   
+   void checkAddressesForUUIDs(InternalDistributedMember[] addresses) {
+     for (int i=0; i<addresses.length; i++) {
+       InternalDistributedMember m = addresses[i];
+       if(m != null) {
+         GMSMember id = (GMSMember)m.getNetMember();
+         if (!id.hasUUID()) {
+           latestViewLock.readLock().lock();
+           try {
+             addresses[i] = latestView.getCanonicalID(addresses[i]);
+           } finally {
+             latestViewLock.readLock().unlock();
+           }
+         }
+       }
+     }
+   }
+   
+   private boolean isForceUDPCommunications() {
+     Boolean forced = forceUseUDPMessaging.get();
+     return forced == Boolean.TRUE;
+   }
+ 
+   // MembershipManager method
+   @Override
+   public void releaseUDPMessagingForCurrentThread() {
+     // not currently supported by this manager
+   }
+   
+   public void setShutdown()
+   {
+     latestViewLock.writeLock().lock();
+     shutdownInProgress = true;
+     latestViewLock.writeLock().unlock();
+   }
+ 
+   @Override
+   public boolean shutdownInProgress() {
+     // Impossible condition (bug36329): make sure that we check DM's
+     // view of shutdown here
+     DistributionManager dm = listener.getDM();
+     return shutdownInProgress || (dm != null && dm.shutdownInProgress());
+   }
+   
+ 
+   /**
+    * Clean up and create consistent new view with member removed.
+    * No uplevel events are generated.
+    * 
+    * Must be called with the {@link #latestViewLock} held.
+    */
+   protected void destroyMember(final InternalDistributedMember member,
+       boolean crashed, final String reason) {
+     
+     // Make sure it is removed from the view
+     latestViewLock.writeLock().lock();
+     try {
+       if (latestView.contains(member)) {
+         NetView newView = new NetView(latestView, latestView.getViewId());
+         newView.remove(member);
+         latestView = newView;
+       }
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+     
+     surpriseMembers.remove(member);
+     
+     // Trickiness: there is a minor recursion
+     // with addShunnedMembers, since it will
+     // attempt to destroy really really old members.  Performing the check
+     // here breaks the recursion.
+     if (!isShunned(member)) {
+       addShunnedMember(member);
+     }
+ 
+     final DirectChannel dc = directChannel;
+     if (dc != null) {
+ //      if (crashed) {
+ //        dc.closeEndpoint(member, reason);
+ //      }
+ //      else
+       // Bug 37944: make sure this is always done in a separate thread,
+       // so that shutdown conditions don't wedge the view lock
+       { // fix for bug 34010
+         Thread t = new Thread() {
+           @Override
+           public void run() {
+             try {
+               Thread.sleep(
+                   Integer.getInteger("p2p.disconnectDelay", 3000).intValue());
+             }
+             catch (InterruptedException ie) {
+               Thread.currentThread().interrupt();
+               // Keep going, try to close the endpoint.
+             }
+             if (!dc.isOpen()) {
+               return;
+             }
+             if (logger.isDebugEnabled())
+               logger.debug("Membership: closing connections for departed member {}", member);
+             // close connections, but don't do membership notification since it's already been done
+             dc.closeEndpoint(member, reason, false); 
+           }
+         };
+         t.setDaemon(true);
+         t.setName("disconnect thread for " + member);
+         t.start();
+       } // fix for bug 34010
+     }
+   }
+   
+   /**
+    * Indicate whether the given member is in the zombie list (dead or dying)
+    * @param m the member in question
+    * 
+    * This also checks the time the given member was shunned, and
+    * has the side effect of removing the member from the
+    * list if it was shunned too far in the past.
+    * 
+    * Concurrency: protected by {@link #latestViewLock} ReentrantReadWriteLock
+    * 
+    * @return true if the given member is a zombie
+    */
+   public boolean isShunned(DistributedMember m) {
+     latestViewLock.writeLock().lock();
+     try {
+       if (!shunnedMembers.containsKey(m))
+         return false;
+       
+       // Make sure that the entry isn't stale...
+       long shunTime = ((Long)shunnedMembers.get(m)).longValue();
+       long now = System.currentTimeMillis();
+       if (shunTime + SHUNNED_SUNSET * 1000 > now)
+         return true;
+       
+       // Oh, it _is_ stale.  Remove it while we're here.
+       endShun(m);
+       return false;
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+ 
+   /**
+    * Indicate whether the given member is in the surprise member list
+    * <P>
+    * Unlike isShunned, this method will not cause expiry of a surprise member.
+    * That must be done during view processing.
+    * <p>
+    * Like isShunned, this method holds the view lock while executing
+    * 
+    * Concurrency: protected by {@link #latestViewLock} ReentrantReadWriteLock
+    * 
+    * @param m the member in question
+    * @return true if the given member is a surprise member
+    */
+   public boolean isSurpriseMember(DistributedMember m) {
+     latestViewLock.readLock().lock();
+     try  {
+       if (surpriseMembers.containsKey(m)) {
+         long birthTime = ((Long)surpriseMembers.get(m)).longValue();
+         long now = System.currentTimeMillis();
+         return (birthTime >= (now - this.surpriseMemberTimeout));
+       }
+       return false;
+     } finally {
+       latestViewLock.readLock().unlock();
+     }
+   }
+   
+   /**
+    * for testing we need to be able to inject surprise members into
+    * the view to ensure that sunsetting works properly
+    * @param m the member ID to add
+    * @param birthTime the millisecond clock time that the member was first seen
+    */
+   public void addSurpriseMemberForTesting(DistributedMember m, long birthTime) {
+     if (logger.isDebugEnabled()) {
+       logger.debug("test hook is adding surprise member {} birthTime={}", m, birthTime);
+     }
+     latestViewLock.writeLock().lock();
+     try {
+       surpriseMembers.put((InternalDistributedMember)m, Long.valueOf(birthTime));
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+   }
+   
+   /**
+    * returns the surpriseMemberTimeout interval, in milliseconds
+    */
+   public int getSurpriseMemberTimeout() {
+     return this.surpriseMemberTimeout;
+   }
+   
+   private boolean endShun(DistributedMember m) {
+     boolean wasShunned = (shunnedMembers.remove(m) != null);
+     shunnedAndWarnedMembers.remove(m);
+     return wasShunned;
+   }
+   
+  /**
+    * Add the given member to the shunned list.  Also, purge any shunned
+    * members that are really really old.
+    * <p>
+    * Must be called with {@link #latestViewLock} held and
+    * the view stable.
+    * 
+    * @param m the member to add
+    */
+   protected void addShunnedMember(InternalDistributedMember m) {
+     long deathTime = System.currentTimeMillis() - SHUNNED_SUNSET * 1000;
+     
+     surpriseMembers.remove(m); // for safety
+ 
+     // Update the shunned set.
+     if (!isShunned(m)) {
+       shunnedMembers.put(m, Long.valueOf(System.currentTimeMillis()));
+     }
+ 
+     // Remove really really old shunned members.
+     // First, make a copy of the old set.  New arrivals _a priori_ don't matter,
+     // and we're going to be updating the list so we don't want to disturb
+     // the iterator.
+     Set oldMembers = new HashSet(shunnedMembers.entrySet());
+     
+     Set removedMembers = new HashSet();
+     
+     Iterator it = oldMembers.iterator();
+     while (it.hasNext()) {
+       Map.Entry e = (Map.Entry)it.next();
+       
+       // Key is the member.  Value is the time to remove it.
+       long ll = ((Long)e.getValue()).longValue(); 
+       if (ll >= deathTime) {
+         continue; // too new.
+       }
+       
+       InternalDistributedMember mm = (InternalDistributedMember)e.getKey();
+ 
+       if (latestView.contains(mm)) {
+         // Fault tolerance: a shunned member can conceivably linger but never 
+         // disconnect.
+         //
+         // We may not delete it at the time that we shun it because the view 
+         // isn't necessarily stable.  (Note that a well-behaved cache member
+         // will depart on its own accord, but we force the issue here.)
+         destroyMember(mm, true, "shunned but never disconnected");
+       }
+       if (logger.isDebugEnabled()) {
+         logger.debug("Membership: finally removed shunned member entry <{}>", mm);
+       }
+       
+       removedMembers.add(mm);
+     }
+     
+     // removed timed-out entries from the shunned-members collections
+     if (removedMembers.size() > 0) {
+       it = removedMembers.iterator();
+       while (it.hasNext()) {
+         InternalDistributedMember idm = (InternalDistributedMember)it.next();
+         endShun(idm);
+       }
+     }
+   }
+   
+   
+   /**
+    * Retrieve thread-local data for transport to another thread in hydra
+    */
+   public Object getThreadLocalData() {
+     Map result = new HashMap();
+     return result;
+   }
+   
+   /**
+    * for testing verification purposes, this return the port for the
+    * direct channel, or zero if there is no direct
+    * channel
+    */
+   public int getDirectChannelPort() {
+     return directChannel == null? 0 : directChannel.getPort();
+   }
+   
+   /**
+    * for mock testing this allows insertion of a DirectChannel mock
+    */
+   protected void setDirectChannel(DirectChannel dc) {
+     this.directChannel = dc;
+     this.tcpDisabled = false;
+   }
+   
+   /* non-thread-owned serial channels and high priority channels are not
+    * included
+    */
+   public Map getMessageState(DistributedMember member, boolean includeMulticast) {
+     Map result = new HashMap();
+     DirectChannel dc = directChannel;
+     if (dc != null) {
+       dc.getChannelStates(member, result);
+     }
+     services.getMessenger().getMessageState((InternalDistributedMember)member, result, includeMulticast);
+     return result;
+   }
+ 
+   public void waitForMessageState(DistributedMember otherMember, Map state)
+     throws InterruptedException
+   {
+     if (Thread.interrupted()) throw new InterruptedException();
+     DirectChannel dc = directChannel;
+     if (dc != null) {
+       dc.waitForChannelState(otherMember, state);
+     }
+     services.getMessenger().waitForMessageState((InternalDistributedMember)otherMember, state);
+   }
+   
+   /* 
+    * (non-Javadoc)
+    * MembershipManager method: wait for the given member to be gone.  Throws TimeoutException if
+    * the wait goes too long
+    * @see com.gemstone.gemfire.distributed.internal.membership.MembershipManager#waitForDeparture(com.gemstone.gemfire.distributed.DistributedMember)
+    */
+   public boolean waitForDeparture(DistributedMember mbr) throws TimeoutException, InterruptedException {
+     if (Thread.interrupted()) throw new InterruptedException();
+     boolean result = false;
+     DirectChannel dc = directChannel;
+     InternalDistributedMember idm = (InternalDistributedMember)mbr;
+     int memberTimeout = this.services.getConfig().getDistributionConfig().getMemberTimeout();
+     long pauseTime = (memberTimeout < 1000) ? 100 : memberTimeout / 10;
+     boolean wait;
+     int numWaits = 0;
+     do {
+       wait = false;
+       if (dc != null) {
+         if (dc.hasReceiversFor(idm)) {
+           wait = true;
+         }
+         if (wait && logger.isDebugEnabled()) {
+           logger.info("waiting for receivers for {} to shut down", mbr);
+         }
+       }
+       if (!wait) {
+         latestViewLock.readLock().lock();
+         try {
+           wait = this.latestView.contains(idm);
+         } finally {
+           latestViewLock.readLock().unlock();
+         }
+         if (wait && logger.isDebugEnabled()) {
+           logger.debug("waiting for {} to leave the membership view", mbr);
+         }
+       }
+       if (!wait) {
+         // run a message through the member's serial execution queue to ensure that all of its
+         // current messages have been processed
+         OverflowQueueWithDMStats serialQueue = listener.getDM().getSerialQueue(idm);
+         if (serialQueue != null) {
+           final boolean done[] = new boolean[1];
+           final FlushingMessage msg = new FlushingMessage(done);
+           serialQueue.add(new SizeableRunnable(100) {
+             public void run() {
+               msg.invoke();
+             }
+             public String toString() {
+               return "Processing fake message";
+             }
+           });
+           synchronized(done) {
+             while (done[0] == false) {
+               done.wait(10);
+             }
+             result = true;
+           }
+         }
+       }
+       if (wait) {
+         numWaits++;
+         if (numWaits > 40) {
+           // waited over 4 * memberTimeout ms.  Give up at this point
+           throw new TimeoutException("waited too long for " + idm + " to be removed");
+         }
+         Thread.sleep(pauseTime);
+       }
+     } while (wait && (dc != null && dc.isOpen())
+         && services.getCancelCriterion().cancelInProgress()==null );
+     if (logger.isDebugEnabled()) {
+       logger.debug("operations for {} should all be in the cache at this point", mbr);
+     }
+     return result;
+   }
+   
+ 
+   // TODO remove this overly complex method and replace its use with
+   // waitForViewChange using the remote member's view ID
+   public boolean waitForMembershipCheck(InternalDistributedMember remoteId) {
+     boolean foundRemoteId = false;
+     CountDownLatch currentLatch = null;
+     // ARB: preconditions
+     // remoteId != null
+     latestViewLock.writeLock().lock();
+     try {
+       if (latestView == null) {
+         // Not sure how this would happen, but see bug 38460.
+         // No view?? Not found!
+       }
+       else if (latestView.contains(remoteId)) {
+         // ARB: check if remoteId is already in membership view.
+         // If not, then create a latch if needed and wait for the latch to open.
+         foundRemoteId = true;
+       }
+       else if ((currentLatch = (CountDownLatch)this.memberLatch.get(remoteId)) == null) {
+         currentLatch = new CountDownLatch(1);
+         this.memberLatch.put(remoteId, currentLatch);
+       }
+     } finally {
+       latestViewLock.writeLock().unlock();
+     }
+ 
+     if (!foundRemoteId) {
+       try {
+         if (currentLatch.await(membershipCheckTimeout, TimeUnit.MILLISECONDS)) {
+           foundRemoteId = true;
+           // @todo 
+           // ARB: remove latch from memberLatch map if this is the last thread waiting on latch.
+         }
+       }
+       catch (InterruptedException ex) {
+         // ARB: latch attempt was interrupted.
+         Thread.currentThread().interrupt();
+         logger.warn(LocalizedMessage.create(
+             LocalizedStrings.GroupMembershipService_THE_MEMBERSHIP_CHECK_WAS_TERMINATED_WITH_AN_EXCEPTION));
+       }
+     }
+ 
+     // ARB: postconditions
+     // (foundRemoteId == true) ==> (currentLatch is non-null ==> currentLatch is open)
+     return foundRemoteId;
+   }
+   
+   /* returns the cause of shutdown, if known */
+   public Throwable getShutdownCause() {
+     return services.getShutdownCause();
+   }
+ 
+ //  @Override
+ //  public void membershipFailure(String reason, Exception e) {
+ //    try {
+ //      if (this.membershipTestHooks != null) {
+ //        List l = this.membershipTestHooks;
+ //        for (Iterator it=l.iterator(); it.h

<TRUNCATED>

[052/100] [abbrv] incubator-geode git commit: GEODE-866: Removing a debugging suite that was accidentially checked in

Posted by ud...@apache.org.
GEODE-866: Removing a debugging suite that was accidentially checked in

This suite method was calling checkMissedTests to fail.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/53510e58
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/53510e58
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/53510e58

Branch: refs/heads/feature/GEODE-870
Commit: 53510e58e9283be6950bb05d817b01db5fe29f74
Parents: 110a5b4
Author: Dan Smith <up...@apache.org>
Authored: Fri Feb 19 12:03:54 2016 -0800
Committer: Dan Smith <up...@apache.org>
Committed: Fri Feb 19 12:03:54 2016 -0800

----------------------------------------------------------------------
 .../internal/cache/ha/CQListGIIDUnitTest.java        | 15 ---------------
 1 file changed, 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/53510e58/gemfire-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java b/gemfire-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
index 6a3de04..95d46a4 100755
--- a/gemfire-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
+++ b/gemfire-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
@@ -187,21 +187,6 @@ public class CQListGIIDUnitTest extends DistributedTestCase {
     disconnectAllFromDS();
   }
   
-  public static Test suite() {
-    Class[] classes = new Class[] {com.gemstone.gemfire.internal.cache.ha.CQListGIIDUnitTest.class,
-        com.gemstone.gemfire.cache30.RegionReliabilityDistAckDUnitTest.class,
-        com.gemstone.gemfire.cache30.RegionReliabilityGlobalDUnitTest.class,
-        com.gemstone.gemfire.internal.cache.execute.PRClientServerFunctionExecutionNoAckDUnitTest.class,
-        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionDUnitTest.class,
-        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionNoSingleHopDUnitTest.class,
-        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionSelectorNoSingleHopDUnitTest.class,
-        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionSingleHopDUnitTest.class,
-        com.gemstone.gemfire.internal.cache.ha.HASlowReceiverDUnitTest.class};
-    
-    return new TestSuite(classes);
-  }
-
-
   private void createCache(Properties props) throws Exception {
     DistributedSystem ds = getSystem(props);
     ds.disconnect();


[077/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
index 0000000,4df8f35..e19d7bf
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
@@@ -1,0 -1,1286 +1,1286 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.wan;
+ 
+ import java.io.DataInput;
+ import java.io.DataOutput;
+ import java.io.IOException;
+ import java.io.InputStream;
+ 
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.InternalGemFireError;
+ import com.gemstone.gemfire.cache.CacheEvent;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.EntryEvent;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.SerializedCacheValue;
+ import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
+ import com.gemstone.gemfire.cache.util.ObjectSizer;
+ import com.gemstone.gemfire.cache.wan.EventSequenceID;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.internal.DataSerializableFixedID;
+ import com.gemstone.gemfire.internal.InternalDataSerializer;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.VersionedDataInputStream;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializableFactory;
+ import com.gemstone.gemfire.internal.cache.Conflatable;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.cache.EnumListenerEvent;
+ import com.gemstone.gemfire.internal.cache.EventID;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.Token;
+ import com.gemstone.gemfire.internal.cache.WrappedCallbackArgument;
+ import com.gemstone.gemfire.internal.cache.lru.Sizeable;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerHelper;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
 -import com.gemstone.gemfire.internal.offheap.ChunkWithHeapForm;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunkWithHeapForm;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
+ import com.gemstone.gemfire.internal.offheap.Releasable;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ /**
+  * Class <code>GatewaySenderEventImpl</code> represents an event sent between
+  * <code>GatewaySender</code>
+  * 
+  * @author Suranjan Kumar
+  * 
+  * @since 7.0
+  * 
+  */
+ public class GatewaySenderEventImpl implements 
+     AsyncEvent, DataSerializableFixedID, Conflatable, Sizeable, Releasable {
+   private static final long serialVersionUID = -5690172020872255422L;
+ 
+   protected static final Object TOKEN_NULL = new Object();
+ 
+   protected static final short VERSION = 0x11;
+   
+   protected EnumListenerEvent operation;
+ 
+   protected Object substituteValue;
+ 
+   /**
+    * The action to be taken (e.g. AFTER_CREATE)
+    */
+   protected int action;
+   
+   /**
+    * The operation detail of EntryEvent (e.g. LOAD, PUTALL etc.)
+    */
+   protected int operationDetail;
+   
+   /**
+    * The number of parts for the <code>Message</code>
+    * 
+    * @see com.gemstone.gemfire.internal.cache.tier.sockets.Message
+    */
+   protected int numberOfParts;
+ 
+   /**
+    * The identifier of this event
+    */
+   protected EventID id;
+ 
+   /**
+    * The <code>Region</code> that was updated
+    */
+   private transient LocalRegion region;
+ 
+   /**
+    * The name of the region being affected by this event
+    */
+   protected String regionPath;
+ 
+   /**
+    * The key being affected by this event
+    */
+   protected Object key;
+ 
+   /**
+    * The serialized new value for this event's key.
+    * May not be computed at construction time.
+    */
+   protected byte[] value;
+   
+   /**
+    * The "object" form of the value.
+    * Will be null after this object is deserialized.
+    */
+   @Retained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+   protected transient Object valueObj;
+   protected transient boolean valueObjReleased;
+ 
+   /**
+    * Whether the value is a serialized object or just a byte[]
+    */
+   protected byte valueIsObject;
+ 
+   /**
+    * The callback argument for this event
+    */
+   protected GatewaySenderEventCallbackArgument callbackArgument;
+ 
+   /**
+    * The version timestamp
+    */
+   protected long versionTimeStamp;
+   
+   /**
+    * Whether this event is a possible duplicate
+    */
+   protected boolean possibleDuplicate;
+ 
+   /**
+    * Whether this event is acknowledged after the ack received by
+    * AckReaderThread. As of now this is getting used for PDX related
+    * GatewaySenderEvent. But can be extended for for other GatewaySenderEvent.
+    */
+   protected volatile boolean isAcked;
+   
+   /**
+    * Whether this event is dispatched by dispatcher. As of now this is getting
+    * used for PDX related GatewaySenderEvent. But can be extended for for other
+    * GatewaySenderEvent.
+    */
+   protected volatile boolean isDispatched;
+   /**
+    * The creation timestamp in ms
+    */
+   protected long creationTime;
+ 
+   /**
+    * For ParalledGatewaySender we need bucketId of the PartitionRegion on which
+    * the update operation was applied.
+    */
+   protected int bucketId;
+ 
+   protected Long shadowKey = Long.valueOf(-1L);
+   
+   protected boolean isInitialized;
+ 
+   /**
+    * Is this thread in the process of serializing this event?
+    */
+   public static final ThreadLocal isSerializingValue = new ThreadLocal() {
+     @Override
+     protected Object initialValue() {
+       return Boolean.FALSE;
+     }
+   };
+ 
+   private static final int CREATE_ACTION = 0;
+ 
+   private static final int UPDATE_ACTION = 1;
+ 
+   private static final int DESTROY_ACTION = 2;
+ 
+   private static final int VERSION_ACTION = 3;
+   
+   private static final int INVALIDATE_ACTION = 5;
+   /**
+    * Static constants for Operation detail of EntryEvent.
+    */
+   private static final int OP_DETAIL_NONE = 10;
+   
+   private static final int OP_DETAIL_LOCAL_LOAD = 11;
+   
+   private static final int OP_DETAIL_NET_LOAD = 12;
+   
+   private static final int OP_DETAIL_PUTALL = 13;
+   
+   private static final int OP_DETAIL_REMOVEALL = 14;
+ 
+ //  /**
+ //   * Is this thread in the process of deserializing this event?
+ //   */
+ //  public static final ThreadLocal isDeserializingValue = new ThreadLocal() {
+ //    @Override
+ //    protected Object initialValue() {
+ //      return Boolean.FALSE;
+ //    }
+ //  };
+ 
+   /**
+    * Constructor. No-arg constructor for data serialization.
+    * 
+    * @see DataSerializer
+    */
+   public GatewaySenderEventImpl() {
+   }
+ 
+   /**
+    * Constructor. Creates an initialized <code>GatewayEventImpl</code>
+    * 
+    * @param operation
+    *          The operation for this event (e.g. AFTER_CREATE)
+    * @param event
+    *          The <code>CacheEvent</code> on which this
+    *          <code>GatewayEventImpl</code> is based
+    * @param substituteValue
+    *          The value to be enqueued instead of the value in the event.
+    * 
+    * @throws IOException
+    */
+   @Retained
+   public GatewaySenderEventImpl(EnumListenerEvent operation, CacheEvent event,
+       Object substituteValue) throws IOException {
+     this(operation, event, substituteValue, true);
+   }
+ 
+   @Retained
+   public GatewaySenderEventImpl(EnumListenerEvent operation, CacheEvent event,
+       Object substituteValue, boolean initialize, int bucketId)
+       throws IOException {
+     this(operation, event, substituteValue, initialize);
+     this.bucketId = bucketId;
+   }
+ 
+   /**
+    * Constructor.
+    * 
+    * @param operation
+    *          The operation for this event (e.g. AFTER_CREATE)
+    * @param ce
+    *          The <code>CacheEvent</code> on which this
+    *          <code>GatewayEventImpl</code> is based
+    * @param substituteValue
+    *          The value to be enqueued instead of the value in the event.
+    * @param initialize
+    *          Whether to initialize this instance
+    * 
+    * @throws IOException
+    */
+   @Retained
+   public GatewaySenderEventImpl(EnumListenerEvent operation, CacheEvent ce,
+       Object substituteValue, boolean initialize) throws IOException {
+     // Set the operation and event
+     final EntryEventImpl event = (EntryEventImpl)ce;
+     this.operation = operation;
+     this.substituteValue = substituteValue;
+ 
+     // Initialize the region name. This is being done here because the event
+     // can get serialized/deserialized (for some reason) between the time
+     // it is set above and used (in initialize). If this happens, the
+     // region is null because it is a transient field of the event.
+     this.region = (LocalRegion)event.getRegion();
+     this.regionPath = this.region.getFullPath();
+ 
+     // Initialize the unique id
+     initializeId(event);
+ 
+     // Initialize possible duplicate
+     this.possibleDuplicate = event.isPossibleDuplicate(); 
+     
+     //Initialize ack and dispatch status of events
+     this.isAcked = false;
+     this.isDispatched = false;
+     
+ 
+     // Initialize the creation timestamp
+     this.creationTime = System.currentTimeMillis();
+ 
+     if (event.getVersionTag() != null) {
+       this.versionTimeStamp = event.getVersionTag().getVersionTimeStamp();
+     }
+ 
+     // Set key
+     // System.out.println("this._entryEvent: " + event);
+     // System.out.println("this._entryEvent.getKey(): " +
+     // event.getKey());
+     this.key = event.getKey();
+ 
+     initializeValue(event);
+ 
+     // Set the callback arg
+     this.callbackArgument = (GatewaySenderEventCallbackArgument)
+         event.getRawCallbackArgument();
+ 
+     // Initialize the action and number of parts (called after _callbackArgument
+     // is set above)
+     initializeAction(this.operation);
+     
+     //initialize the operation detail 
+     initializeOperationDetail(event.getOperation());
+ 
+     setShadowKey(event.getTailKey());
+     
+     if (initialize) {
+       initialize();
+     }
+   }
+ 
+   /**
+    * Used to create a heap copy of an offHeap event.
+    * Note that this constructor produces an instance that does not need to be released.
+    */
+   protected GatewaySenderEventImpl(GatewaySenderEventImpl offHeapEvent) {
+     this.operation = offHeapEvent.operation;
+     this.action = offHeapEvent.action;
+     this.numberOfParts = offHeapEvent.numberOfParts;
+     this.id = offHeapEvent.id;
+     this.region = offHeapEvent.region;
+     this.regionPath = offHeapEvent.regionPath;
+     this.key = offHeapEvent.key;
+     this.callbackArgument = offHeapEvent.callbackArgument;
+     this.versionTimeStamp = offHeapEvent.versionTimeStamp;
+     this.possibleDuplicate = offHeapEvent.possibleDuplicate;
+     this.isAcked = offHeapEvent.isAcked;
+     this.isDispatched = offHeapEvent.isDispatched;
+     this.creationTime = offHeapEvent.creationTime;
+     this.bucketId = offHeapEvent.bucketId;
+     this.shadowKey = offHeapEvent.shadowKey;
+     this.isInitialized = offHeapEvent.isInitialized;
+ 
+     this.valueObj = null;
+     this.valueObjReleased = false;
+     this.valueIsObject = offHeapEvent.valueIsObject;
+     this.value = offHeapEvent.getSerializedValue();
+   }
+   
+   /**
+    * Returns this event's action
+    * 
+    * @return this event's action
+    */
+   public int getAction() {
+     return this.action;
+   }
+ 
+   /**
+    * Returns this event's operation
+    * 
+    * @return this event's operation
+    */
+   public Operation getOperation() {
+     Operation op = null;
+     switch (this.action) {
+     case CREATE_ACTION:
+       switch (this.operationDetail) {
+       case OP_DETAIL_LOCAL_LOAD:
+         op = Operation.LOCAL_LOAD_CREATE;
+         break;
+       case OP_DETAIL_NET_LOAD:
+     	op = Operation.NET_LOAD_CREATE;
+     	break;
+       case OP_DETAIL_PUTALL:
+         op = Operation.PUTALL_CREATE;
+     	break;
+       case OP_DETAIL_NONE:
+     	op = Operation.CREATE;
+     	break;
+       //if operationDetail is none of the above, then default should be NONE 
+       default:
+     	op = Operation.CREATE;
+     	break;
+       }
+       break;
+     case UPDATE_ACTION:
+       switch (this.operationDetail) {
+       case OP_DETAIL_LOCAL_LOAD:
+     	op = Operation.LOCAL_LOAD_UPDATE;
+     	break;
+       case OP_DETAIL_NET_LOAD:
+     	op = Operation.NET_LOAD_UPDATE;
+     	break;
+       case OP_DETAIL_PUTALL:
+     	op = Operation.PUTALL_UPDATE;
+     	break;
+       case OP_DETAIL_NONE:
+     	op = Operation.UPDATE;
+     	break;
+       //if operationDetail is none of the above, then default should be NONE 
+       default:
+     	op = Operation.UPDATE;
+     	break;
+       }
+       break;
+     case DESTROY_ACTION:
+       if (this.operationDetail == OP_DETAIL_REMOVEALL) {
+         op = Operation.REMOVEALL_DESTROY;
+       } else {
+         op = Operation.DESTROY;
+       }
+       break;
+     case VERSION_ACTION:
+       op = Operation.UPDATE_VERSION_STAMP;
+       break;
+     case INVALIDATE_ACTION:
+       op = Operation.INVALIDATE;
+       break;
+     }
+     return op;
+   }
+ 
+   public Object getSubstituteValue() {
+     return this.substituteValue;
+   }
+   
+   public EnumListenerEvent getEnumListenerEvent(){
+     return this.operation;
+   }
+   /**
+    * Return this event's region name
+    * 
+    * @return this event's region name
+    */
+   public String getRegionPath() {
+     return this.regionPath;
+   }
+ 
+   public boolean isInitialized() {
+     return this.isInitialized;
+   }
+   /**
+    * Returns this event's key
+    * 
+    * @return this event's key
+    */
+   public Object getKey() {
+     // TODO:Asif : Ideally would like to have throw exception if the key
+     // is TOKEN_UN_INITIALIZED, but for the time being trying to retain the GFE
+     // behaviour
+     // of returning null if getKey is invoked on un-initialized gateway event
+     return isInitialized() ? this.key : null;
+   }
+ 
+   /**
+    * Returns whether this event's value is a serialized object
+    * 
+    * @return whether this event's value is a serialized object
+    */
+   public byte getValueIsObject() {
+     return this.valueIsObject;
+   }
+ 
+   /**
+    * Return this event's callback argument
+    * 
+    * @return this event's callback argument
+    */
+   public Object getCallbackArgument() {
+     Object result = getSenderCallbackArgument();
+     while (result instanceof WrappedCallbackArgument) {
+       WrappedCallbackArgument wca = (WrappedCallbackArgument)result;
+       result = wca.getOriginalCallbackArg();
+     }
+     return result;
+   }
+ 
+   public GatewaySenderEventCallbackArgument getSenderCallbackArgument() {
+     return this.callbackArgument;
+   }
+ 
+   /**
+    * Return this event's number of parts
+    * 
+    * @return this event's number of parts
+    */
+   public int getNumberOfParts() {
+     return this.numberOfParts;
+   }
+   
+   /**
+    * Return the value as a byte[] array, if it is plain byte array,
+    * otherwise return a cache deserializable or plain object, depending
+    * on if the currently held form of the object is serialized or not.
+    * 
+    * If the object is held off heap, this will copy it to the heap return the heap copy.
+    * 
+    *  //OFFHEAP TODO: Optimize callers by returning a reference to the off heap value
+    */
+   public Object getValue() {
+     if (CachedDeserializableFactory.preferObject()) {
+       // sqlf does not use CacheDeserializable wrappers
+       return getDeserializedValue();
+     }
+     Object rawValue = this.value;
+     if (rawValue == null) {
+       @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+       Object vo = this.valueObj;
+       if (vo instanceof StoredObject) {
+         rawValue = ((StoredObject) vo).getValueAsHeapByteArray();
+       } else {
+         rawValue = vo;
+       }
+     }
+     if (valueIsObject == 0x00) {
+       //if the value is a byte array, just return it
+       return rawValue;
+     } else if (CachedDeserializableFactory.preferObject()) {
+       // sqlf does not use CacheDeserializable wrappers
+       return rawValue;
+     } else if (rawValue instanceof byte[]) {
+       return CachedDeserializableFactory.create((byte[]) rawValue);
+     } else {
+       return rawValue;
+     }
+   }
+   
+   /**
+    * Return the currently held form of the object.
+    * May return a retained OFF_HEAP_REFERENCE.
+    */
+   @Retained
+   public Object getRawValue() {
+     @Retained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+     Object result = this.value;
+     if (result == null) {
+       result = this.valueObj;
 -      if (result instanceof Chunk) {
++      if (result instanceof ObjectChunk) {
+         if (this.valueObjReleased) {
+           result = null;
+         } else {
 -          Chunk ohref = (Chunk) result;
++          ObjectChunk ohref = (ObjectChunk) result;
+           if (!ohref.retain()) {
+             result = null;
+           } else if (this.valueObjReleased) {
+             ohref.release();
+             result = null;
+           }
+         }
+       }
+     }
+     return result;
+   }
+ 
+   /**
+    * This method is meant for internal use by the SimpleMemoryAllocatorImpl.
+    * Others should use getRawValue instead.
+    * @return if the result is an off-heap reference then callers must use it before this event is released.
+    */
+   @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+   public Object getValueObject() {
+     return this.valueObj;
+   }
+ 
+   /**
+    * Return this event's deserialized value
+    * 
+    * @return this event's deserialized value
+    */
+   public Object getDeserializedValue() {
+ // TODO OFFHEAP MERGE: handle substituteValue here?
+     if (this.valueIsObject == 0x00) {
+       Object result = this.value;
+       if (result == null) {
+         @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+         Object so = this.valueObj;
+         if (this.valueObjReleased) {
+           throw new IllegalStateException("Value is no longer available. getDeserializedValue must be called before processEvents returns.");
+         }
+         if (so instanceof StoredObject) {
+           // TODO OFFHEAP: returns off-heap PdxInstance
+           return ((StoredObject)so).getValueAsDeserializedHeapObject();
+         } else {
+           throw new IllegalStateException("expected valueObj field to be an instance of StoredObject but it was " + so);
+         }
+       }
+       return result;
+     }
+     else {
+       Object vo = this.valueObj;
+       if (vo != null) {
+         if (vo instanceof StoredObject) {
+           @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+           StoredObject so = (StoredObject)vo;
+           // TODO OFFHEAP: returns off-heap PdxInstance
+           return so.getValueAsDeserializedHeapObject();
+         } else {
+           return vo; // it is already deserialized
+         }
+       } else {
+         if (this.value != null) {
+           Object result = EntryEventImpl.deserialize(this.value);
+           this.valueObj = result;
+           return result;
+         } else {
+           if (this.valueObjReleased) {
+             throw new IllegalStateException("Value is no longer available. getDeserializedValue must be called before processEvents returns.");
+           }
+           // both value and valueObj are null but we did not free it.
+           return null;
+         }
+       }
+     }
+   }
+   
+   /**
+    * Returns the value in the form of a String.
+    * This should be used by code that wants to log
+    * the value. This is a debugging exception.
+    */
+   public String getValueAsString(boolean deserialize) {
+ // TODO OFFHEAP MERGE: handle substituteValue here?
+     Object v = this.value;
+     if (deserialize) {
+       try {
+         v = getDeserializedValue();
+       } catch (Exception e) {
+         return "Could not convert value to string because " + e;
+       } catch (InternalGemFireError e) { // catch this error for bug 49147
+         return "Could not convert value to string because " + e;
+       }
+     }
+     if (v == null) {
+       @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+       Object ov = this.valueObj;
+       if (ov instanceof CachedDeserializable) {
+         return ((CachedDeserializable) ov).getStringForm();
+       }
+     }
+     if (v != null) {
+       if (v instanceof byte[]) {
+         byte[] bav = (byte[]) v;
+         // Using Arrays.toString(bav) can cause us to run out of memory
+         return "byte[" + bav.length + "]";
+       } else {
+         return v.toString();
+       }
+     } else {
+       return "";
+     }
+   }
+ 
+   /**
+    * If the value owned of this event is just bytes return that byte array;
+    * otherwise serialize the value object and return the serialized bytes.
+    * Use {@link #getValueIsObject()} to determine if the result is raw or serialized bytes.
+    */
+   public byte[] getSerializedValue() {
+     byte[] result = this.value;
+     if (result == null) {
+       @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+       Object vo = this.valueObj;
+       if (vo instanceof StoredObject) {
+         synchronized (this) {
+           result = this.value;
+           if (result == null) {
+             StoredObject so = (StoredObject) vo;
+             result = so.getValueAsHeapByteArray();
+             this.value = result;
+           }
+         }
+       } else {
+         synchronized (this) {
+           result = this.value;
+           if (result == null && vo != null && !(vo instanceof Token)) {
+             result = EntryEventImpl.serialize(vo);
+             this.value = result;
+           } else if (result == null) {
+             if (this.valueObjReleased) {
+               throw new IllegalStateException("Value is no longer available. getSerializedValue must be called before processEvents returns.");
+             }
+           }
+         }
+       }
+     }
+     return result;
+   }
+ 
+   public void setPossibleDuplicate(boolean possibleDuplicate) {
+     this.possibleDuplicate = possibleDuplicate;
+   }
+ 
+   public boolean getPossibleDuplicate() {
+     return this.possibleDuplicate;
+   }
+ 
+   public long getCreationTime() {
+     return this.creationTime;
+   }
+ 
+   public int getDSFID() {
+     return GATEWAY_SENDER_EVENT_IMPL;
+   }
+ 
+   public void toData(DataOutput out) throws IOException {
+     // Make sure we are initialized before we serialize.
+     initialize();
+     out.writeShort(VERSION);
+     out.writeInt(this.action);
+     out.writeInt(this.numberOfParts);
+     // out.writeUTF(this._id);
+     DataSerializer.writeObject(this.id, out);
+     DataSerializer.writeString(this.regionPath, out);
+     out.writeByte(this.valueIsObject);
+     serializeKey(out);
+     DataSerializer.writeByteArray(getSerializedValue(), out);
+     DataSerializer.writeObject(this.callbackArgument, out);
+     out.writeBoolean(this.possibleDuplicate);
+     out.writeLong(this.creationTime);
+     out.writeInt(this.bucketId);
+     out.writeLong(this.shadowKey);
+     out.writeLong(getVersionTimeStamp());    
+   }
+ 
+   protected void serializeKey(DataOutput out) throws IOException {
+     DataSerializer.writeObject(this.key, out);
+   }
+ 
+   public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+     short version = in.readShort();
+     if (version != VERSION) {
+       // warning?
+     }
+     this.isInitialized = true;
+     this.action = in.readInt();
+     this.numberOfParts = in.readInt();
+     // this._id = in.readUTF();
+     if (version < 0x11 &&
+         (in instanceof InputStream) &&
+         InternalDataSerializer.getVersionForDataStream(in) == Version.CURRENT) {
+       in = new VersionedDataInputStream((InputStream)in, Version.GFE_701);
+     }
+     this.id = (EventID)DataSerializer.readObject(in);   
+     // TODO:Asif ; Check if this violates Barry's logic of not assiging VM
+     // specific Token.FROM_GATEWAY
+     // and retain the serialized Token.FROM_GATEWAY
+     // this._id.setFromGateway(false);
+     this.regionPath = DataSerializer.readString(in);
+     this.valueIsObject = in.readByte();
+     deserializeKey(in);
+     this.value = DataSerializer.readByteArray(in);
+     this.callbackArgument = (GatewaySenderEventCallbackArgument)DataSerializer
+         .readObject(in);
+     this.possibleDuplicate = in.readBoolean();
+     this.creationTime = in.readLong();
+     this.bucketId = in.readInt();
+     this.shadowKey = in.readLong();
+     this.versionTimeStamp = in.readLong();
+     // TODO should this call initializeKey()?
+   }
+ 
+   protected void deserializeKey(DataInput in) throws IOException,
+       ClassNotFoundException {
+     this.key = DataSerializer.readObject(in);
+   }
+ 
+   @Override
+   public String toString() {
+     StringBuffer buffer = new StringBuffer();
+     buffer.append("SenderEventImpl[").append("id=").append(this.id)
+         .append(";action=").append(this.action).append(";operation=")
+         .append(getOperation()).append(";region=").append(this.regionPath)
+         .append(";key=").append(this.key).append(";value=")
+         .append(getValueAsString(true)).append(";valueIsObject=")
+         .append(this.valueIsObject).append(";numberOfParts=")
+         .append(this.numberOfParts).append(";callbackArgument=")
+         .append(this.callbackArgument).append(";possibleDuplicate=")
+         .append(this.possibleDuplicate).append(";creationTime=")
+         .append(this.creationTime).append(";shadowKey= ")
+         .append(this.shadowKey)
+         .append(";timeStamp=").append(this.versionTimeStamp)
+         .append(";acked=").append(this.isAcked)
+         .append(";dispatched=").append(this.isDispatched)
+         .append("]");
+     return buffer.toString();
+   }
+ 
+   public static boolean isSerializingValue() {
+     return ((Boolean)isSerializingValue.get()).booleanValue();
+   }
+ 
+ //   public static boolean isDeserializingValue() {
+ //     return ((Boolean)isDeserializingValue.get()).booleanValue();
+ //   }
+ 
+   // / Conflatable interface methods ///
+ 
+   /**
+    * Determines whether or not to conflate this message. This method will answer
+    * true IFF the message's operation is AFTER_UPDATE and its region has enabled
+    * are conflation. Otherwise, this method will answer false. Messages whose
+    * operation is AFTER_CREATE, AFTER_DESTROY, AFTER_INVALIDATE or
+    * AFTER_REGION_DESTROY are not conflated.
+    * 
+    * @return Whether to conflate this message
+    */
+   public boolean shouldBeConflated() {
+     // If the message is an update, it may be conflatable. If it is a
+     // create, destroy, invalidate or destroy-region, it is not conflatable.
+     // Only updates are conflated.
+     return isUpdate();
+   }
+ 
+   public String getRegionToConflate() {
+     return this.regionPath;
+   }
+ 
+   public Object getKeyToConflate() {
+     return this.key;
+   }
+ 
+   public Object getValueToConflate() {
+     // Since all the uses of this are for logging
+     // changing it to return the string form of the value
+     // instead of the actual value.
+     return this.getValueAsString(true);
+   }
+ 
+   public void setLatestValue(Object value) {
+     // Currently this method is never used.
+     // If someone does want to use it in the future
+     // then the implementation needs to be updated
+     // to correctly update value, valueObj, and valueIsObject
+     throw new UnsupportedOperationException();
+   }
+ 
+   // / End Conflatable interface methods ///
+ 
+   /**
+    * Returns whether this <code>GatewayEvent</code> represents an update.
+    * 
+    * @return whether this <code>GatewayEvent</code> represents an update
+    */
+   protected boolean isUpdate() {
+     // This event can be in one of three states:
+     // - in memory primary (initialized)
+     // - in memory secondary (not initialized)
+     // - evicted to disk, read back in (initialized)
+     // In the first case, both the operation and action are set.
+     // In the second case, only the operation is set.
+     // In the third case, only the action is set.
+     return this.operation == null ? this.action == UPDATE_ACTION
+         : this.operation == EnumListenerEvent.AFTER_UPDATE;
+   }
+ 
+   /**
+    * Returns whether this <code>GatewayEvent</code> represents a create.
+    * 
+    * @return whether this <code>GatewayEvent</code> represents a create
+    */
+   protected boolean isCreate() {
+     // See the comment in isUpdate() for additional details
+     return this.operation == null ? this.action == CREATE_ACTION
+         : this.operation == EnumListenerEvent.AFTER_CREATE;
+   }
+ 
+   /**
+    * Returns whether this <code>GatewayEvent</code> represents a destroy.
+    * 
+    * @return whether this <code>GatewayEvent</code> represents a destroy
+    */
+   protected boolean isDestroy() {
+     // See the comment in isUpdate() for additional details
+     return this.operation == null ? this.action == DESTROY_ACTION
+         : this.operation == EnumListenerEvent.AFTER_DESTROY;
+   }
+ 
+   /**
+    * Initialize the unique identifier for this event. This id is used by the
+    * receiving <code>Gateway</code> to keep track of which events have been
+    * processed. Duplicates can be dropped.
+    */
+   private void initializeId(EntryEventImpl event) {
+     // CS43_HA
+     this.id = event.getEventId();
+     // TODO:ASIF :Once stabilized remove the check below
+     if (this.id == null) {
+       throw new IllegalStateException(
+           LocalizedStrings.GatewayEventImpl_NO_EVENT_ID_IS_AVAILABLE_FOR_THIS_GATEWAY_EVENT
+               .toLocalizedString());
+     }
+ 
+   }
+ 
+   /**
+    * Initialize this instance. Get the useful parts of the input operation and
+    * event.
+    */
+   public void initialize() {
+     if (isInitialized()) {
+       return;
+     }
+     this.isInitialized = true;
+   }
+ 
+ 
+   // Initializes the value object. This function need a relook because the 
+   // serialization of the value looks unnecessary.
+   @Retained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+   protected void initializeValue(EntryEventImpl event) throws IOException {
+     // Set the value to be a byte[] representation of either the value or
+     // substituteValue (if set).
+     if (this.substituteValue == null) {
+     // If the value is already serialized, use it.
+     this.valueIsObject = 0x01;
+     /**
+      * so ends up being stored in this.valueObj
+      */
+     @Retained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+     StoredObject so = null;
+     if (event.hasDelta()) {
+       this.valueIsObject = 0x02;
+     } else {
+       ReferenceCountHelper.setReferenceCountOwner(this);
+       so = event.getOffHeapNewValue();
+       ReferenceCountHelper.setReferenceCountOwner(null);      
+         // TODO OFFHEAP MERGE: check for a cached serialized value first
+         // so we can use it instead of reading offheap
+         // If we do read offheap then add the serialize new value to the event cache
+     }
+     
+     if (so != null) {
+ //    if (so != null  && !event.hasDelta()) {
+       // Since GatewaySenderEventImpl instances can live for a long time in the gateway region queue
+       // we do not want the StoredObject to be one that keeps the heap form cached.
 -      if (so instanceof ChunkWithHeapForm) {
 -        so = ((ChunkWithHeapForm) so).getChunkWithoutHeapForm(); // fixes 51999
++      if (so instanceof ObjectChunkWithHeapForm) {
++        so = ((ObjectChunkWithHeapForm) so).getChunkWithoutHeapForm(); // fixes 51999
+       }
+       this.valueObj = so;
+       if (!so.isSerialized()) {
+         this.valueIsObject = 0x00;
+       }
+     } else if (event.getCachedSerializedNewValue() != null) {
+       // We want this to have lower precedence than StoredObject so that the gateway
+       // can share a reference to the off-heap value.
+       this.value = event.getCachedSerializedNewValue();
+     } else {
+       final Object newValue = event.getRawNewValue(shouldApplyDelta());
+       assert !(newValue instanceof StoredObject); // since we already called getOffHeapNewValue() and it returned null
+       if (newValue instanceof CachedDeserializable) {
+         this.value = ((CachedDeserializable) newValue).getSerializedValue();
+       } else if (newValue instanceof byte[]) {
+         // The value is byte[]. Set _valueIsObject flag to 0x00 (not an object)
+         this.value = (byte[])newValue;
+         this.valueIsObject = 0x00;
+       } else {
+         // The value is an object. It will be serialized later when getSerializedValue is called.
+         this.valueObj = newValue;
+         // to prevent bug 48281 we need to serialize it now
+         this.getSerializedValue();
+         this.valueObj = null;
+       }
+     }
+     } else {
+       // The substituteValue is set. Use it.
+       if (this.substituteValue instanceof byte[]) {
+         // The substituteValue is byte[]. Set valueIsObject flag to 0x00 (not an object)
+         this.value = (byte[]) this.substituteValue;
+         this.valueIsObject = 0x00;
+       } else if (this.substituteValue == TOKEN_NULL) {
+         // The substituteValue represents null. Set the value to null.
+         this.value = null;
+         this.valueIsObject = 0x01;
+       } else {
+         // The substituteValue is an object. Serialize it.
+         isSerializingValue.set(Boolean.TRUE);
+         this.value = CacheServerHelper.serialize(this.substituteValue);
+         isSerializingValue.set(Boolean.FALSE);
+         event.setCachedSerializedNewValue(this.value);
+         this.valueIsObject = 0x01;
+       }
+     }
+   }
+ 
+   protected boolean shouldApplyDelta() {
+     return false;
+   }
+ 
+   /**
+    * Initialize this event's action and number of parts
+    * 
+    * @param operation
+    *          The operation from which to initialize this event's action and
+    *          number of parts
+    */
+   protected void initializeAction(EnumListenerEvent operation) {
+     if (operation == EnumListenerEvent.AFTER_CREATE) {
+       // Initialize after create action
+       this.action = CREATE_ACTION;
+ 
+       // Initialize number of parts
+       // part 1 = action
+       // part 2 = posDup flag
+       // part 3 = regionName
+       // part 4 = eventId
+       // part 5 = key
+       // part 6 = value (create and update only)
+       // part 7 = whether callbackArgument is non-null
+       // part 8 = callbackArgument (if non-null)
+       // part 9 = versionTimeStamp;
+       this.numberOfParts = (this.callbackArgument == null) ? 8 : 9;
+     } else if (operation == EnumListenerEvent.AFTER_UPDATE) {
+       // Initialize after update action
+       this.action = UPDATE_ACTION;
+ 
+       // Initialize number of parts
+       this.numberOfParts = (this.callbackArgument == null) ? 8 : 9;
+     } else if (operation == EnumListenerEvent.AFTER_DESTROY) {
+       // Initialize after destroy action
+       this.action = DESTROY_ACTION;
+ 
+       // Initialize number of parts
+       // Since there is no value, there is one less part
+       this.numberOfParts = (this.callbackArgument == null) ? 7 : 8;
+     } else if (operation == EnumListenerEvent.TIMESTAMP_UPDATE) {
+       // Initialize after destroy action
+       this.action = VERSION_ACTION;
+ 
+       // Initialize number of parts
+       // Since there is no value, there is one less part
+       this.numberOfParts = (this.callbackArgument == null) ? 7 : 8;
+     } else if (operation == EnumListenerEvent.AFTER_INVALIDATE) {
+       // Initialize after invalidate action
+       this.action = INVALIDATE_ACTION;
+ 
+       // Initialize number of parts
+       // Since there is no value, there is one less part
+       this.numberOfParts = (this.callbackArgument == null) ? 7 : 8;
+     }
+   }
+   
+   private void initializeOperationDetail(Operation operation) {
+     if (operation.isLocalLoad()) {
+       operationDetail = OP_DETAIL_LOCAL_LOAD;
+     } else if (operation.isNetLoad()) {
+       operationDetail = OP_DETAIL_NET_LOAD;
+     } else if (operation.isPutAll()) {
+       operationDetail = OP_DETAIL_PUTALL;
+     } else if (operation.isRemoveAll()) {
+       operationDetail = OP_DETAIL_REMOVEALL;
+     } else {
+       operationDetail = OP_DETAIL_NONE;
+     }
+   }
+ 
+   public EventID getEventId() {
+     return this.id;
+   }
+ 
+   /**
+    * Return the EventSequenceID of the Event
+    * @return    EventSequenceID
+    */
+   public EventSequenceID getEventSequenceID() {
+     return new EventSequenceID(id.getMembershipID(), id.getThreadID(), id
+         .getSequenceID());
+   }
+   
+   public long getVersionTimeStamp() {
+     return this.versionTimeStamp;
+   }
+   
+   public int getSizeInBytes() {
+     // Calculate the size of this event. This is used for overflow to disk.
+ 
+     // The sizes of the following variables are calculated:
+     //
+     // - the value (byte[])
+     // - the original callback argument (Object)
+     // - primitive and object instance variable references
+     //
+     // The sizes of the following variables are not calculated:
+ 
+     // - the key because it is a reference
+     // - the region and regionName because they are references
+     // - the operation because it is a reference
+     // - the entry event because it is nulled prior to calling this method
+ 
+     // The size of instances of the following internal datatypes were estimated
+     // using a NullDataOutputStream and hardcoded into this method:
+ 
+     // - the id (an instance of EventId)
+     // - the callbackArgument (an instance of GatewayEventCallbackArgument)
+ 
+     int size = 0;
+ 
+     // Add this event overhead
+     size += Sizeable.PER_OBJECT_OVERHEAD;
+ 
+     // Add object references
+     // _id reference = 4 bytes
+     // _region reference = 4 bytes
+     // _regionName reference = 4 bytes
+     // _key reference = 4 bytes
+     // _callbackArgument reference = 4 bytes
+     // _operation reference = 4 bytes
+     // _entryEvent reference = 4 bytes
+     size += 28;
+ 
+     // Add primitive references
+     // int _action = 4 bytes
+     // int _numberOfParts = 4 bytes
+     // byte _valueIsObject = 1 byte
+     // boolean _possibleDuplicate = 1 byte
+     // int bucketId = 4 bytes
+     // long shadowKey = 8 bytes
+     // long creationTime = 8 bytes
+     size += 30;
+ 
+     // Add the id (an instance of EventId)
+     // The hardcoded value below was estimated using a NullDataOutputStream
+     size += Sizeable.PER_OBJECT_OVERHEAD + 56;
+ 
+     // The value (a byte[])
+     size += getSerializedValueSize();
+ 
+     // The callback argument (a GatewayEventCallbackArgument wrapping an Object
+     // which is the original callback argument)
+     // The hardcoded value below represents the GatewayEventCallbackArgument
+     // and was estimated using a NullDataOutputStream
+     size += Sizeable.PER_OBJECT_OVERHEAD + 194;
+     // The sizeOf call gets the size of the input callback argument.
+     size += Sizeable.PER_OBJECT_OVERHEAD + sizeOf(getCallbackArgument());
+ 
+     // the version timestamp
+     size += 8;
+     
+     return size;
+   }
+ 
+   private int sizeOf(Object obj) {
+     int size = 0;
+     if (obj == null) {
+       return size;
+     }
+     if (obj instanceof String) {
+       size = ObjectSizer.DEFAULT.sizeof(obj);
+     } else if (obj instanceof Integer) {
+       size = 4; // estimate
+     } else if (obj instanceof Long) {
+       size = 8; // estimate
+     } else {
+       size = CachedDeserializableFactory.calcMemSize(obj)
+           - Sizeable.PER_OBJECT_OVERHEAD;
+     }
+     return size;
+   }
+ 
+ 
+   // Asif: If the GatewayEvent serializes to a node where the region itself may
+   // not be present or the
+   // region is not created yet , and if the gateway event queue is persistent,
+   // then even if
+   // we try to set the region in the fromData , we may still get null. Though
+   // the product is
+   // not using this method anywhere still not comfortable changing the Interface
+   // so
+   // modifying the implementation a bit.
+ 
+   public Region<?, ?> getRegion() {
+     // The region will be null mostly for the other node where the gateway event
+     // is serialized
+     return this.region != null ? this.region : CacheFactory.getAnyInstance()
+         .getRegion(this.regionPath);
+   }
+ 
+   public int getBucketId() {
+     return bucketId;
+   }
+ 
+   /**
+    * @param tailKey
+    *          the tailKey to set
+    */
+   public void setShadowKey(Long tailKey) {
+     this.shadowKey = tailKey;
+   }
+ 
+   /**
+    * @return the tailKey
+    */
+   public Long getShadowKey() {
+     return this.shadowKey;
+   }
+ 
+   @Override
+   public Version[] getSerializationVersions() {
+     // TODO Auto-generated method stub
+     return null;
+   }
+ 
+   public int getSerializedValueSize() {
+     @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+     Object vo = this.valueObj;
+     if (vo instanceof StoredObject) {
+       return ((StoredObject) vo).getSizeInBytes();
+     } else {
+       return CachedDeserializableFactory.calcMemSize(getSerializedValue());
+     }
+   }
+   
+   @Override
+   @Released(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+   public void release() {
+     @Released(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+     Object vo = this.valueObj;
+     if (OffHeapHelper.releaseAndTrackOwner(vo, this)) {
+       this.valueObj = null;
+       this.valueObjReleased = true;
+     }
+   }
+   
+   public static void release(@Released(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE) Object o) {
+     if (o instanceof GatewaySenderEventImpl) {
+       ((GatewaySenderEventImpl) o).release();
+     }
+   }
+ 
+   /**
+    * Make a heap copy of this off-heap event and return it.
+    * A copy only needs to be made if the event's value is stored off-heap.
+    * If it is already on the java heap then just return "this".
+    * If it was stored off-heap and is no longer available (because it was released) then return null.
+    */
+   public GatewaySenderEventImpl makeHeapCopyIfOffHeap() {
+     if (this.value != null) {
+       // we have the value stored on the heap so return this
+       return this;
+     } else {
+       Object v = this.valueObj;
+       if (v == null) {
+         if (this.valueObjReleased) {
+           // this means that the original off heap value was freed
+           return null;
+         } else {
+           return this;
+         }
+       }
 -      if (v instanceof Chunk) {
++      if (v instanceof ObjectChunk) {
+         try {
+           return makeCopy();
+         } catch (IllegalStateException ex) {
+           // this means that the original off heap value was freed
+           return null;
+         }
+       } else {
+         // the valueObj does not use refCounts so just return this.
+         return this;
+       }
+     }
+   }
+   
+   protected GatewaySenderEventImpl makeCopy() {
+     return new GatewaySenderEventImpl(this);
+   }
+ 
+   public void copyOffHeapValue() {
+     if (this.value == null) {
+       this.value = getSerializedValue();
+     }
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java
index 0000000,0000000..7916e1f
new file mode 100644
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java
@@@ -1,0 -1,0 +1,29 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.offheap;
++
++/**
++ * A memory chunk that also has an address of its memory.
++ */
++public interface AddressableMemoryChunk extends MemoryChunk {
++
++  /**
++   * Return the address of the memory of this chunk.
++   */
++  public long getMemoryAddress();
++
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java
index 0000000,0000000..fa2dd78
new file mode 100644
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java
@@@ -1,0 -1,0 +1,27 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.offheap;
++
++/**
++ * Used to create AddressableMemoryChunk instances.
++ */
++public interface AddressableMemoryChunkFactory {
++  /** Create and return an AddressableMemoryChunk.
++   * @throws OutOfMemoryError if the create fails
++   */
++  public AddressableMemoryChunk create(int size);
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
index 0000000,ef56627..d337cfc
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
@@@ -1,0 -1,139 +1,139 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+ 
+ /**
+  * A fragment is a block of memory that can have chunks allocated from it.
+  * The allocations are always from the front so the free memory is always
+  * at the end. The freeIdx keeps track of the first byte of free memory in
+  * the fragment.
+  * The base memory address and the total size of a fragment never change.
+  * During compaction fragments go away and are recreated.
+  * 
+  * @author darrel
+  *
+  */
+ public class Fragment implements MemoryBlock {
 -  private static final byte FILL_BYTE = Chunk.FILL_BYTE;
++  private static final byte FILL_BYTE = ObjectChunk.FILL_BYTE;
+   private final long baseAddr;
+   private final int size;
+   @SuppressWarnings("unused")
+   private volatile int freeIdx;
+   private static AtomicIntegerFieldUpdater<Fragment> freeIdxUpdater = AtomicIntegerFieldUpdater.newUpdater(Fragment.class, "freeIdx");
+   
+   public Fragment(long addr, int size) {
+     SimpleMemoryAllocatorImpl.validateAddress(addr);
+     this.baseAddr = addr;
+     this.size = size;
+     freeIdxUpdater.set(this, 0);
+   }
+   
+   public int freeSpace() {
+     return getSize() - getFreeIndex();
+   }
+ 
+   public boolean allocate(int oldOffset, int newOffset) {
+     return freeIdxUpdater.compareAndSet(this, oldOffset, newOffset);
+   }
+ 
+   public int getFreeIndex() {
+     return freeIdxUpdater.get(this);
+   }
+ 
+   public int getSize() {
+     return this.size;
+   }
+ 
+   public long getMemoryAddress() {
+     return this.baseAddr;
+   }
+ 
+   @Override
+   public State getState() {
+     return State.UNUSED;
+   }
+ 
+   @Override
+   public MemoryBlock getNextBlock() {
+     throw new UnsupportedOperationException();
+   }
+   
+   @Override
+   public int getBlockSize() {
+     return freeSpace();
+   }
+   
+   @Override
+   public int getSlabId() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   @Override
+   public int getFreeListId() {
+     return -1;
+   }
+ 
+   @Override
+   public int getRefCount() {
+     return 0;
+   }
+ 
+   @Override
+   public String getDataType() {
+     return "N/A";
+   }
+ 
+   @Override
+   public boolean isSerialized() {
+     return false;
+   }
+ 
+   @Override
+   public boolean isCompressed() {
+     return false;
+   }
+ 
+   @Override
+   public Object getDataValue() {
+     return null;
+   }
+   
+   public void fill() {
+     UnsafeMemoryChunk.fill(this.baseAddr, this.size, FILL_BYTE);
+   }
+ 
+   @Override
 -  public ChunkType getChunkType() {
 -    return null;
 -  }
 -  
 -  @Override
+   public boolean equals(Object o) {
+     if (o instanceof Fragment) {
+       return getMemoryAddress() == ((Fragment) o).getMemoryAddress();
+     }
+     return false;
+   }
+   
+   @Override
+   public int hashCode() {
+     long value = this.getMemoryAddress();
+     return (int)(value ^ (value >>> 32));
+   }
++  @Override
++  public String toString() {
++    return "Fragment [baseAddr=" + baseAddr + ", size=" + size + ", freeIdx=" + freeIdx + "]";
++  }
++
+ }


[091/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
index 0000000,83a77fd..aab99cb
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
@@@ -1,0 -1,2405 +1,2405 @@@
+ /*
+  * 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 com.gemstone.gemfire.cache.query.internal.index;
+ 
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.concurrent.locks.ReadWriteLock;
+ import java.util.concurrent.locks.ReentrantReadWriteLock;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.query.AmbiguousNameException;
+ import com.gemstone.gemfire.cache.query.FunctionDomainException;
+ import com.gemstone.gemfire.cache.query.Index;
+ import com.gemstone.gemfire.cache.query.IndexStatistics;
+ import com.gemstone.gemfire.cache.query.NameResolutionException;
+ import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+ import com.gemstone.gemfire.cache.query.QueryService;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.query.Struct;
+ import com.gemstone.gemfire.cache.query.TypeMismatchException;
+ import com.gemstone.gemfire.cache.query.internal.Bag;
+ import com.gemstone.gemfire.cache.query.internal.CompiledID;
+ import com.gemstone.gemfire.cache.query.internal.CompiledIndexOperation;
+ import com.gemstone.gemfire.cache.query.internal.CompiledIteratorDef;
+ import com.gemstone.gemfire.cache.query.internal.CompiledOperation;
+ import com.gemstone.gemfire.cache.query.internal.CompiledPath;
+ import com.gemstone.gemfire.cache.query.internal.CompiledValue;
+ import com.gemstone.gemfire.cache.query.internal.CqEntry;
+ import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
+ import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
+ import com.gemstone.gemfire.cache.query.internal.IndexInfo;
+ import com.gemstone.gemfire.cache.query.internal.QRegion;
+ import com.gemstone.gemfire.cache.query.internal.QueryMonitor;
+ import com.gemstone.gemfire.cache.query.internal.QueryUtils;
+ import com.gemstone.gemfire.cache.query.internal.RuntimeIterator;
+ import com.gemstone.gemfire.cache.query.internal.StructFields;
+ import com.gemstone.gemfire.cache.query.internal.StructImpl;
+ import com.gemstone.gemfire.cache.query.internal.Support;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexStore.IndexStoreEntry;
+ import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
+ import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
+ import com.gemstone.gemfire.cache.query.internal.types.TypeUtils;
+ import com.gemstone.gemfire.cache.query.types.ObjectType;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.cache.BucketRegion;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+ import com.gemstone.gemfire.internal.cache.RegionEntry;
+ import com.gemstone.gemfire.internal.cache.persistence.query.CloseableIterator;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.pdx.PdxInstance;
+ import com.gemstone.gemfire.pdx.internal.PdxString;
+ 
+ /**
+  * This class implements abstract algorithms common to all indexes, such as
+  * index creation, use of a path evaluator object, etc. It serves as the factory
+  * for a path evaluator object and maintains the path evaluator object to use
+  * for index creation and index maintenance. It also maintains a reference to
+  * the root collection on which the index is created. This class also implements
+  * the abstract methods to add and remove entries to an underlying storage
+  * structure (e.g. a btree), and as part of this algorithm, maintains a map of
+  * entries that map to null at the end of the index path, and entries that
+  * cannot be traversed to the end of the index path (traversal is undefined).
+  * 
+  * @author asif
+  * @author vaibhav
+  */
+ public abstract class AbstractIndex implements IndexProtocol
+ {
+   private static final Logger logger = LogService.getLogger();
+   
+   final String indexName;
+ 
+   final Region region;
+ 
+   final String indexedExpression;
+ 
+   final String fromClause;
+ 
+   final String projectionAttributes;
+ 
+   final String originalIndexedExpression;
+ 
+   final String originalFromClause;
+ 
+   final String originalProjectionAttributes;
+ 
+   final String[] canonicalizedDefinitions;
+   
+   private boolean isValid;
+   
+   protected IndexedExpressionEvaluator evaluator;
+   // Statistics
+   protected InternalIndexStatistics internalIndexStats;
+ 
+   //For PartitionedIndex for now
+   protected Index prIndex;
+   //Flag to indicate if index map has keys as PdxString
+   //All the keys in the index map should be either Strings or PdxStrings
+   protected Boolean isIndexedPdxKeys = false;
+   
+   //Flag to indicate if the flag isIndexedPdxKeys is set
+   protected Boolean isIndexedPdxKeysFlagSet = false;
+ 
+   protected boolean indexOnRegionKeys = false;
+ 
+   protected boolean indexOnValues = false;
+   
+   private final ReadWriteLock removeIndexLock = new ReentrantReadWriteLock();
+ 
+   //Flag to indicate if the index is populated with data
+   protected volatile boolean isPopulated = false;
+ 
+   AbstractIndex(String indexName, Region region, String fromClause,
+       String indexedExpression, String projectionAttributes,
+       String origFromClause, String origIndxExpr, String[] defintions, IndexStatistics stats) {
+     this.indexName = indexName;
+     this.region = region;
+     this.indexedExpression = indexedExpression;
+     this.fromClause = fromClause;
+     this.originalIndexedExpression = origIndxExpr;
+     this.originalFromClause = origFromClause;
+     this.canonicalizedDefinitions = defintions;
+     if (projectionAttributes == null || projectionAttributes.length() == 0) {
+       projectionAttributes = "*";
+     }
+     this.projectionAttributes = projectionAttributes;
+     this.originalProjectionAttributes = projectionAttributes;
+     if (stats != null) {
+       this.internalIndexStats = (InternalIndexStatistics)stats;
+     } else {
+       this.internalIndexStats = createStats(indexName);
+     }
+   }
+ 
+   /**
+    * Must be implemented by all implementing classes
+    * iff they have any forward map for index-key->RE.
+    *
+    * @return the forward map of respective index.
+    */
+   public Map getValueToEntriesMap() {
+     return null;
+   }
+   /**
+    * Get statistics information for this index.
+    */
+   public IndexStatistics getStatistics()
+   {
+     return this.internalIndexStats;
+   }
+ 
+   public void destroy()
+   {
+     markValid(false);
+     if (this.internalIndexStats != null) {
+       this.internalIndexStats.updateNumKeys(0);
+       this.internalIndexStats.close();
+     }
+   }
+ 
+   long updateIndexUpdateStats()
+   {
+     long result = System.nanoTime();
+     this.internalIndexStats.incUpdatesInProgress(1);
+     return result;
+   }
+ 
+   void updateIndexUpdateStats(long start)
+   {
+     long end = System.nanoTime();
+     this.internalIndexStats.incUpdatesInProgress(-1);
+     this.internalIndexStats.incUpdateTime(end - start);
+   }
+   
+   long updateIndexUseStats() {
+     return updateIndexUseStats(true);
+   }
+   
+   long updateIndexUseStats(boolean updateStats)
+   {
+     long result = 0;
+     if (updateStats) {
+       this.internalIndexStats.incUsesInProgress(1);
+       result = System.nanoTime();
+     }
+     return result;
+   }
+ 
+   void updateIndexUseEndStats(long start) {
+     updateIndexUseEndStats(start, true);
+   }
+   
+   void updateIndexUseEndStats(long start, boolean updateStats)
+   {
+     if (updateStats) {
+       long end = System.nanoTime();
+       this.internalIndexStats.incUsesInProgress(-1);
+       this.internalIndexStats.incNumUses();
+       this.internalIndexStats.incUseTime(end - start);
+     }
+   }
+ 
+   public IndexedExpressionEvaluator getEvaluator()
+   {
+     return evaluator;
+   }
+ 
+   /**
+    * The Region this index is on
+    * 
+    * @return the Region for this index
+    */
+   public Region getRegion()
+   {
+     return this.region;
+   }
+ 
+   /**
+    * Returns the unique name of this index
+    */
+   public String getName()
+   {
+     return this.indexName;
+   }
+ 
+   // ////////// Index default implementation
+   public void query(Object key, int operator, Collection results, ExecutionContext context)
+   throws TypeMismatchException, FunctionDomainException,
+   NameResolutionException, QueryInvocationTargetException {
+     // get a read lock when doing a lookup
+     if (context.getBucketList() != null && (this.region instanceof BucketRegion)) {
+         PartitionedRegion pr = ((BucketRegion)region).getPartitionedRegion();
+         long start = updateIndexUseStats();
+         try {
+           for (Object b :context.getBucketList()) {
+             AbstractIndex i = PartitionedIndex.getBucketIndex(pr, this.indexName, (Integer)b);
+             if (i == null) {
+               continue;
+             }
+             i.lockedQuery(key, operator, results, null/* No Keys to be removed */, context);
+           
+           }
+         } finally {
+           updateIndexUseEndStats(start);
+         }
+     } else {
+       long start = updateIndexUseStats();
+       try {
+         lockedQuery(key, operator, results, null/* No Keys to be removed */, context);
+         return;
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     }
+   }
+ 
+   public void query(Object key, int operator, Collection results,
+       @Retained CompiledValue iterOp, RuntimeIterator indpndntIr,
+       ExecutionContext context, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection)
+   throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException {
+     // get a read lock when doing a lookup
+     if (context.getBucketList() != null
+         && (this.region instanceof BucketRegion)) {
+       PartitionedRegion pr = ((BucketRegion) region).getPartitionedRegion();
+       long start = updateIndexUseStats();
+       try {
+         for (Object b : context.getBucketList()) {
+           AbstractIndex i = PartitionedIndex.getBucketIndex(pr, this.indexName,
+               (Integer) b);
+           if (i == null) {
+             continue;
+           }
+           i.lockedQuery(key, operator, results, iterOp, indpndntIr, context,
+               projAttrib, intermediateResults, isIntersection);
+         }
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     } else {
+       long start = updateIndexUseStats();
+       try {
+         lockedQuery(key, operator, results, iterOp, indpndntIr, context,
+             projAttrib, intermediateResults, isIntersection);
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     }
+     return;
+   }
+   
+   public void query(Object key, int operator, Collection results,
+       Set keysToRemove, ExecutionContext context) throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException {
+     // get a read lock when doing a lookup
+     if (context.getBucketList() != null && (this.region instanceof BucketRegion)) {
+         PartitionedRegion pr = ((BucketRegion)region).getPartitionedRegion();
+         long start = updateIndexUseStats();
+         try {
+           for (Object b :context.getBucketList()) {
+             AbstractIndex i = PartitionedIndex.getBucketIndex(pr, this.indexName, (Integer)b);
+             if (i == null) {
+               continue;
+             }
+             i.lockedQuery(key, operator, results, keysToRemove, context);
+           }
+         } finally {
+           updateIndexUseEndStats(start);
+         }
+     } else {
+       long start = updateIndexUseStats();
+       try {
+         lockedQuery(key, operator, results, keysToRemove, context);
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     }
+     return;
+   }
+ 
+   public void query(Collection results, Set keysToRemove, ExecutionContext context)
+   throws TypeMismatchException, FunctionDomainException,
+   NameResolutionException, QueryInvocationTargetException {
+     Iterator itr = keysToRemove.iterator();
+     Object temp = itr.next();
+     itr.remove();
+     if (context.getBucketList() != null && (this.region instanceof BucketRegion)) {
+       long start = updateIndexUseStats();
+       try {
+         PartitionedRegion pr = ((BucketRegion)region).getPartitionedRegion();
+         for (Object b :context.getBucketList()) {
+           AbstractIndex i = PartitionedIndex.getBucketIndex(pr, this.indexName, (Integer)b);
+           if (i == null) {
+             continue;
+           }
+           i.lockedQuery(temp, OQLLexerTokenTypes.TOK_NE, results,
+             itr.hasNext() ? keysToRemove : null, context);
+         } 
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     } else {
+       long start = updateIndexUseStats();
+       try {
+         lockedQuery(temp, OQLLexerTokenTypes.TOK_NE, results,
+             itr.hasNext() ? keysToRemove : null, context);
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     }
+     return;
+   }
+ 
+   public void query(Object lowerBoundKey, int lowerBoundOperator,
+       Object upperBoundKey, int upperBoundOperator, Collection results,
+       Set keysToRemove, ExecutionContext context) throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException {
+     if (context.getBucketList() != null) {
+       if (this.region instanceof BucketRegion) {
+         PartitionedRegion pr = ((BucketRegion)region).getPartitionedRegion();
+         long start = updateIndexUseStats();
+         try {
+           for (Object b :context.getBucketList()) {
+             AbstractIndex i = PartitionedIndex.getBucketIndex(pr, this.indexName, (Integer)b);
+             if (i == null) {
+               continue;
+             }
+             i.lockedQuery(lowerBoundKey, lowerBoundOperator, upperBoundKey,
+                 upperBoundOperator, results, keysToRemove, context);
+          }
+         } finally {
+           updateIndexUseEndStats(start);
+         }
+       }
+     } else {
+       long start = updateIndexUseStats();
+       try {
+         lockedQuery(lowerBoundKey, lowerBoundOperator, upperBoundKey,
+             upperBoundOperator, results, keysToRemove, context);
+       } finally {
+         updateIndexUseEndStats(start);
+       }
+     }
+     return;
+   }
+ 
+   
+   public List queryEquijoinCondition(IndexProtocol index, ExecutionContext context)
+       throws TypeMismatchException, FunctionDomainException, NameResolutionException, QueryInvocationTargetException
+   {
+     Support
+         .assertionFailed(" This function should have never got invoked as its meaningful implementation is present only in RangeIndex class");
+     return null;
+   }
+ 
+   /**
+    * Get the projectionAttributes for this expression.
+    * 
+    * @return the projectionAttributes, or "*" if there were none specified at
+    *         index creation.
+    */
+   public String getProjectionAttributes()
+   {
+     return this.originalProjectionAttributes;
+   }
+ 
+   /**
+    * Get the projectionAttributes for this expression.
+    * 
+    * @return the projectionAttributes, or "*" if there were none specified at
+    *         index creation.
+    */
+   public String getCanonicalizedProjectionAttributes()
+   {
+     return this.projectionAttributes;
+   }
+ 
+   /**
+    * Get the Original indexedExpression for this index.
+    */
+   public String getIndexedExpression()
+   {
+     return this.originalIndexedExpression;
+   }
+ 
+   /**
+    * Get the Canonicalized indexedExpression for this index.
+    */
+   public String getCanonicalizedIndexedExpression()
+   {
+     return this.indexedExpression;
+   }
+ 
+   /**
+    * Get the original fromClause for this index.
+    */
+   public String getFromClause()
+   {
+     return this.originalFromClause;
+   }
+ 
+   /**
+    * Get the canonicalized fromClause for this index.
+    */
+   public String getCanonicalizedFromClause()
+   {
+     return this.fromClause;
+   }
+ 
+   public boolean isMapType()
+   {
+     return false;
+   }
+ 
+   // ////////// IndexProtocol default implementation
+   public boolean addIndexMapping(RegionEntry entry) throws IMQException
+   {
+     this.addMapping(entry);
+     return true; // if no exception, then success
+   }
+ 
+   public boolean addAllIndexMappings(Collection c) throws IMQException
+   {
+     Iterator iterator = c.iterator();
+     while (iterator.hasNext()) {
+       this.addMapping((RegionEntry)iterator.next());
+     }
+     return true; // if no exception, then success
+   }
+ 
+   /**
+    * @param opCode
+    *          one of OTHER_OP, BEFORE_UPDATE_OP, AFTER_UPDATE_OP.
+    */
+   public boolean removeIndexMapping(RegionEntry entry, int opCode)
+       throws IMQException
+   {
+     removeMapping(entry, opCode);
+     return true; // if no exception, then success
+   }
+ 
+   public boolean removeAllIndexMappings(Collection c) throws IMQException
+   {
+     Iterator iterator = c.iterator();
+     while (iterator.hasNext()) {
+       removeMapping((RegionEntry)iterator.next(), OTHER_OP);
+     }
+     return true; // if no exception, then success
+   }
+ 
+   public boolean isValid()
+   {
+     return isValid;
+   }
+ 
+   public void markValid(boolean b)
+   {
+     isValid = b;
+   }
+ 
+   public boolean isMatchingWithIndexExpression(CompiledValue indexExpr,
+       String conditionExprStr, ExecutionContext context)
+       throws AmbiguousNameException, TypeMismatchException,
+       NameResolutionException
+   {
+     return this.indexedExpression.equals(conditionExprStr);
+   }
+ 
+   private Object verifyAndGetPdxDomainObject(Object value) {
+     if (value instanceof StructImpl) {
+       // Doing hasPdx check first, since its cheaper.
+       if (((StructImpl)value).isHasPdx() && !((GemFireCacheImpl)
+           this.region.getCache()).getPdxReadSerializedByAnyGemFireServices()) {
+         // Set the pdx values for the struct object.
+         StructImpl v = (StructImpl)value;
+         Object[] fieldValues = v.getPdxFieldValues();
+         return new StructImpl((StructTypeImpl)v.getStructType(), fieldValues);
+       }
+     } else if (value instanceof PdxInstance && !((GemFireCacheImpl) 
+         this.region.getCache()).getPdxReadSerializedByAnyGemFireServices()) {
+       return ((PdxInstance)value).getObject();
+     }
+     return value;
+   }
+ 
+   private void addToResultsWithUnionOrIntersection(Collection results,
+       SelectResults intermediateResults, boolean isIntersection, Object value)
+   {
+     value = verifyAndGetPdxDomainObject(value);
+     
+     if (intermediateResults == null) {
+       results.add(value);
+     }
+     else {
+       if (isIntersection) {
+         int numOcc = intermediateResults.occurrences(value);
+         if (numOcc > 0) {
+           results.add(value);
+           intermediateResults.remove(value);
+         }
+       }
+       else {
+         // intermediateResults.add(value);
+         results.add(value);
+       }
+     }
+   }
+ 
+   private void addToStructsWithUnionOrIntersection(Collection results,
+       SelectResults intermediateResults, boolean isIntersection, Object[] values)
+   {
+     for (int i=0; i < values.length; i++) {
+       values[i] = verifyAndGetPdxDomainObject(values[i]);
+     }
+     
+     if (intermediateResults == null) {
+       if( results instanceof StructFields) {
+         ((StructFields)results).addFieldValues(values);
+       }else {
+         //The results could be LinkedStructSet or SortedResultsBag or StructSet
+         //LinkedStructSet lss = (LinkedStructSet)results;
+         SelectResults sr = (SelectResults)results;
+         StructImpl structImpl = new StructImpl( (StructTypeImpl)sr.getCollectionType().getElementType(), values);
+         //lss.add(structImpl);
+         sr.add(structImpl);
+       }
+     }
+     else {
+       if (isIntersection) {
+         if(results instanceof StructFields) {
+           int numOcc = intermediateResults.occurrences(values);
+           if (numOcc > 0) {
+             ((StructFields)results).addFieldValues(values);
+             ((StructFields)intermediateResults).removeFieldValues(values);
+           }
+         }else {
+           //LinkedStructSet lss = (LinkedStructSet)results;
+           // could be LinkedStructSet or SortedResultsBag
+           SelectResults sr = (SelectResults)results;
+           StructImpl structImpl = new StructImpl( (StructTypeImpl)sr.getCollectionType().getElementType(), values);
+           if( intermediateResults.remove(structImpl)) {
+             sr.add(structImpl);
+           }          
+         }
+       }
+       else {
+         if( results instanceof StructFields) {
+           ((StructFields)results).addFieldValues(values);
+         }else {
+           // could be LinkedStructSet or SortedResultsBag
+           SelectResults sr = (SelectResults)results;
+           //LinkedStructSet lss = (LinkedStructSet)results;
+           StructImpl structImpl = new StructImpl( (StructTypeImpl)sr.getCollectionType().getElementType(), values);
+           if( ((SelectResults)intermediateResults).remove(structImpl)) {
+             sr.add(structImpl);
+           }
+         }
+       }
+     }
+   }
+ 
+   void applyProjection(List projAttrib, ExecutionContext context,
+       Collection result, Object iterValue, SelectResults intermediateResults,
+       boolean isIntersection) throws FunctionDomainException,
+       TypeMismatchException, NameResolutionException,
+       QueryInvocationTargetException
+   {
+     if (projAttrib == null) {
+       iterValue = deserializePdxForLocalDistinctQuery(context, iterValue);
+       this.addToResultsWithUnionOrIntersection(result, intermediateResults,
+           isIntersection, iterValue);
+     }
+     else {
+       //TODO : Asif : Optimize this . This condition looks ugly.
+      /* if (result instanceof StructBag || result instanceof LinkedStructSet
+           || result instanceof LinkedStructBag) {*/
+       boolean isStruct = result instanceof SelectResults 
+           && ((SelectResults)result).getCollectionType().getElementType() != null
+           && ((SelectResults)result).getCollectionType().getElementType().isStructType();
+       if (isStruct) {
+         int projCount = projAttrib.size();
+         Object[] values = new Object[projCount];
+         Iterator projIter = projAttrib.iterator();
+         int i = 0;
+         while (projIter.hasNext()) {
+           Object projDef[] = (Object[])projIter.next();
+           values[i] = deserializePdxForLocalDistinctQuery(context, ((CompiledValue)projDef[1]).evaluate(context));
+           i++;
+         }
+         this.addToStructsWithUnionOrIntersection(result, intermediateResults,
+             isIntersection, values);
+       }
+       else {
+         Object[] temp = (Object[])projAttrib.get(0);
+         Object val = deserializePdxForLocalDistinctQuery(context, ((CompiledValue)temp[1]).evaluate(context));
+         this.addToResultsWithUnionOrIntersection(result,
+             intermediateResults, isIntersection, val);
+       }
+     }
+   }
+ 
+   // For local queries with distinct, deserialize all PdxInstances
+   // as we do not have a way to compare Pdx and non Pdx objects in case
+   // the cache has a mix of pdx and non pdx objects.
+   // We still have to honor the cache level readserialized flag in 
+   // case of all Pdx objects in cache.
+   // Also always convert PdxString to String before adding to resultset
+   // for remote queries
+   private Object deserializePdxForLocalDistinctQuery(ExecutionContext context,
+       Object val) throws QueryInvocationTargetException {
+     if (!((DefaultQuery) context.getQuery()).isRemoteQuery()) {
+       if (context.isDistinct() && val instanceof PdxInstance
+           && !this.region.getCache().getPdxReadSerialized()) {
+         try {
+           val = ((PdxInstance) val).getObject();
+         } catch (Exception ex) {
+           throw new QueryInvocationTargetException(
+               "Unable to retrieve domain object from PdxInstance while building the ResultSet. "
+                   + ex.getMessage());
+         }
+       } else if (val instanceof PdxString) {
+         val = ((PdxString) val).toString();
+       }
+     }
+     return val;
+   }
+   
+   private void removeFromResultsWithUnionOrIntersection(Collection results,
+       SelectResults intermediateResults, boolean isIntersection, Object value)
+   {
+     if (intermediateResults == null) {
+       results.remove(value);
+     }
+     else {
+       if (isIntersection) {
+         int numOcc = ((SelectResults)results).occurrences(value);
+         if (numOcc > 0) {
+           results.remove(value);
+           intermediateResults.add(value);
+         }
+       }
+       else {
+         results.remove(value);
+       }
+     }
+   }
+ 
+   private void removeFromStructsWithUnionOrIntersection(Collection results,
+       SelectResults intermediateResults, boolean isIntersection,
+       Object values[], ExecutionContext context)
+   {
+     if (intermediateResults == null) {      
+         ((StructFields)results).removeFieldValues(values);      
+     }
+     else {
+       if (isIntersection) {
+         int numOcc = ((SelectResults)results).occurrences(values);
+         if (numOcc > 0) {
+             ((StructFields)results).removeFieldValues(values);
+             ((StructFields)intermediateResults).addFieldValues(values);
+           
+         }
+       }
+       else {        
+         ((StructFields)results).removeFieldValues(values);        
+       }
+     }
+   }
+ 
+   void removeProjection(List projAttrib, ExecutionContext context,
+       Collection result, Object iterValue, SelectResults intermediateResults,
+       boolean isIntersection) throws FunctionDomainException,
+       TypeMismatchException, NameResolutionException,
+       QueryInvocationTargetException
+   {
+     if (projAttrib == null) {
+       this.removeFromResultsWithUnionOrIntersection(result,
+           intermediateResults, isIntersection, iterValue);
+     }
+     else {
+       if (result instanceof StructFields) {
+         int projCount = projAttrib.size();
+         Object[] values = new Object[projCount];
+         Iterator projIter = projAttrib.iterator();
+         int i = 0;
+         while (projIter.hasNext()) {
+           Object projDef[] = (Object[])projIter.next();
+           values[i++] = ((CompiledValue)projDef[1]).evaluate(context);
+         }
+         this.removeFromStructsWithUnionOrIntersection(result,
+             intermediateResults, isIntersection, values, context);
+       }
+       else {
+         Object[] temp = (Object[])projAttrib.get(0);
+         Object val = ((CompiledValue)temp[1]).evaluate(context);
+         this.removeFromResultsWithUnionOrIntersection(result,
+             intermediateResults, isIntersection, val);
+       }
+     }
+ 
+   }
+ 
+   /*
+    * This function returns the canonicalized defintions of the from clauses used
+    * in Index creation TODO:Asif :How to make it final so that it is immutable
+    */
+   public String[] getCanonicalizedIteratorDefinitions()
+   {
+     return this.canonicalizedDefinitions;
+   }
+ 
+   // Asif : This implementation is for PrimaryKeyIndex. RangeIndex has its
+   // own implementation. For PrimaryKeyIndex , this method should not be used
+   // TODO: Asif : Check if an Exception should be thrown if the function
+   // implementation of this class gets invoked
+   public boolean containsEntry(RegionEntry entry)
+   {
+     return false;
+   }
+ 
+   void instantiateEvaluator(IndexCreationHelper ich)
+   {
+   }
+ 
+   public void initializeIndex(boolean loadEntries) throws IMQException
+   {
+   }
+   
+   
+   @Override
+   public String toString()
+   {
+     StringBuffer sb = new StringBuffer();
+     sb.append("Index [");
+     sb.append(" Name=").append(getName());
+     sb.append(" Type =").append(getType());
+     sb.append(" IdxExp=").append(getIndexedExpression());
+     sb.append(" From=").append(getFromClause());
+     sb.append(" Proj=").append(getProjectionAttributes());
+     sb.append("]");
+     return sb.toString();
+   }
+ 
+   public abstract boolean isEmpty();
+ 
+   protected abstract boolean isCompactRangeIndex();
+   
+   protected abstract InternalIndexStatistics createStats(String indexName);
+ 
+   public abstract ObjectType getResultSetType();
+ 
+   abstract void recreateIndexData() throws IMQException;
+ 
+   abstract void addMapping(RegionEntry entry) throws IMQException;
+ 
+   abstract void removeMapping(RegionEntry entry, int opCode)
+       throws IMQException;
+ 
+   abstract void addMapping(Object key, Object value, RegionEntry entry)
+       throws IMQException;
+ 
+   /**
+    * Shobhit: This is used to buffer the index entries evaluated from a
+    * RegionEntry which is getting updated at present. These buffered index
+    * entries are replaced into the index later all together to avoid
+    * remove-add sequence.
+    * @param key
+    * @param value
+    * @param entry
+    * @throws IMQException
+    */
+   abstract void saveMapping(Object key, Object value, RegionEntry entry)
+   throws IMQException;
+ 
+   /** Lookup method used when appropriate lock is held */
+   abstract void lockedQuery(Object key, int operator, Collection results,
+       CompiledValue iterOps, RuntimeIterator indpndntItr,
+       ExecutionContext context, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection)
+       throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException;
+ 
+   abstract void lockedQuery(Object lowerBoundKey, int lowerBoundOperator,
+       Object upperBoundKey, int upperBoundOperator, Collection results,
+       Set keysToRemove, ExecutionContext context) throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException;
+ 
+   abstract void lockedQuery(Object key, int operator, Collection results,
+       Set keysToRemove, ExecutionContext context) throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException;
+   
+   public Index getPRIndex() {
+     return prIndex;
+   }
+ 
+   public void setPRIndex(Index parIndex) {
+     this.prIndex = parIndex;
+   }
+ 
+ 
+   /**
+    * Dummy implementation that subclasses can override.
+    */
+   protected static abstract class InternalIndexStatistics implements
+       IndexStatistics
+   {
+     public long getNumUpdates()
+     {
+       return 0L;
+     }
+ 
+     public long getTotalUpdateTime()
+     {
+       return 0L;
+     }
+ 
+     public long getTotalUses()
+     {
+       return 0L;
+     }
+ 
+     public long getNumberOfKeys()
+     {
+       return 0L;
+     }
+ 
+     public long getNumberOfValues()
+     {
+       return 0L;
+     }
+ 
+     public long getNumberOfValues(Object key)
+     {
+       return 0L;
+     }
+ 
+     public long getUpdateTime() {
+       return 0L;
+     }
+     
+     public long getUseTime() {
+       return 0L;
+     }
+    
+     public int getReadLockCount() {
+       return 0;
+     }
+     
+     public long getNumberOfMapIndexKeys() {
+       return 0;
+     }
+ 
+     public int getNumberOfBucketIndexes(){
+       return 0;
+     }
+     
+     public void close()
+     {
+     }
+ 
+     public void incNumValues(int delta)
+     {
+     }
+ 
+     public void incNumUpdates()
+     {
+     }
+ 
+     public void incNumUpdates(int delta)
+     {
+     }
+ 
+     public void incUpdatesInProgress(int delta)
+     {
+     }
+ 
+     public void incUsesInProgress(int delta)
+     {
+     }
+ 
+     public void updateNumKeys(long count)
+     {
+     }
+ 
+     public void incNumKeys(long count)
+     {
+     }
+ 
+     public void incNumMapIndexKeys(long numKeys) {
+     }
+ 
+     public void incUpdateTime(long delta)
+     {
+     }
+ 
+     public void incNumUses()
+     {
+     }
+ 
+     public void incUseTime(long delta)
+     {
+     }
+ 
+     public void incReadLockCount(int delta) 
+     {
+     }
+     
+     public void incNumBucketIndexes(int delta) 
+     {
+     }
+   }
+ 
+   /**
+    * 
+    * @author vaibhav
+    * @author Asif
+    */
+   class IMQEvaluator implements IndexedExpressionEvaluator
+   {
+     private Cache cache;
+ 
+     private List fromIterators = null;
+ 
+     private CompiledValue indexedExpr = null;
+ 
+     final private String[] canonicalIterNames;
+ 
+     private ObjectType indexResultSetType = null;
+ 
+     private Map dependencyGraph = null;
+ 
+     /*
+      * Asif : The boolean if true indicates that the 0th iterator is on entries
+      * . If the 0th iterator is on collection of Region.Entry objects, then the
+      * RegionEntry object used in Index data objects is obtained directly from
+      * its corresponding Region.Entry object. However if the 0th iterator is not
+      * on entries then the boolean is false. In this case the additional
+      * projection attribute gives us the original value of the iterator while
+      * the Region.Entry object is obtained from 0th iterator. It is possible to
+      * have index being created on a Region Entry itself , instead of a Region.
+      * A Map operator( Compiled Index Operator) used with Region enables, us to
+      * create such indexes. In such case the 0th iterator, even if it represents
+      * a collection of Objects which are not Region.Entry objects, still the
+      * boolean remains true, as the Entry object can be easily obtained from the
+      * 0th iterator. In this case, the additional projection attribute s not
+      * null as it is used to evaluate the Entry object from the 0th iterator.
+      */
+     private boolean isFirstItrOnEntry = false;
+ 
+     //Shobhit: The boolean if true indicates that the 0th iterator is on keys.
+     private boolean isFirstItrOnKey = false;
+ 
+     // Asif: List of modified iterators, not null only when the booelan
+     // isFirstItrOnEntry is false.
+     private List indexInitIterators = null;
+ 
+     // Asif : The additional Projection attribute representing the value of the
+     // original 0th iterator.
+     // If the isFirstItrOnEntry is false, then it is not null. However if the
+     // isFirstItrOnEntry is
+     // true but & still this attribute is not null, this indicates that the 0th
+     // iterator
+     // is derived using an individual entry thru Map operator on the Region.
+     private CompiledValue additionalProj = null;
+ 
+     // Asif : This is not null iff the boolean isFirstItrOnEntry is false.
+     private CompiledValue modifiedIndexExpr = null;
+ 
+     private ObjectType addnlProjType = null;
+ 
+     private int initEntriesUpdated = 0;
+ 
+     private boolean hasInitOccuredOnce = false;
+ 
+     private ExecutionContext initContext = null;
+ 
+     private int iteratorSize = -1;
+ 
+     private Region rgn = null;
+ 
+     /** Creates a new instance of IMQEvaluator */
+     IMQEvaluator(IndexCreationHelper helper) {
+       this.cache = helper.getCache();
+       this.fromIterators = helper.getIterators();
+       this.indexedExpr = helper.getCompiledIndexedExpression();
+       this.rgn  = helper.getRegion();
+       // Asif : The modified iterators for optmizing Index cxreation
+       isFirstItrOnEntry = ((FunctionalIndexCreationHelper)helper).isFirstIteratorRegionEntry;
+       isFirstItrOnKey = ((FunctionalIndexCreationHelper)helper).isFirstIteratorRegionKey;
+       additionalProj = ((FunctionalIndexCreationHelper)helper).additionalProj;
+       Object params1[] = { new QRegion(rgn, false) };
+       initContext = new ExecutionContext(params1, cache);
+       this.canonicalIterNames = ((FunctionalIndexCreationHelper)helper).canonicalizedIteratorNames;
+       if (isFirstItrOnEntry) {
+         this.indexInitIterators = this.fromIterators;
+       }
+       else {
+         this.indexInitIterators = ((FunctionalIndexCreationHelper)helper).indexInitIterators;
+         modifiedIndexExpr = ((FunctionalIndexCreationHelper)helper).modifiedIndexExpr;
+         addnlProjType = ((FunctionalIndexCreationHelper)helper).addnlProjType;
+       }
+       this.iteratorSize = this.indexInitIterators.size();
+ 
+     }
+ 
+     public String getIndexedExpression()
+     {
+       return AbstractIndex.this.getCanonicalizedIndexedExpression();
+     }
+ 
+     public String getProjectionAttributes()
+     {
+       return AbstractIndex.this.getCanonicalizedProjectionAttributes();
+     }
+ 
+     public String getFromClause()
+     {
+       return AbstractIndex.this.getCanonicalizedFromClause();
+     }
+     
+     public void expansion(List expandedResults, Object lowerBoundKey, Object upperBoundKey, int lowerBoundOperator, int upperBoundOperator, Object value) throws IMQException {
+       //no-op
+     }
+ 
+     public void evaluate(RegionEntry target, boolean add) throws IMQException
+     {
+       assert add; // ignored, but should be true here
+       DummyQRegion dQRegion = new DummyQRegion(rgn);
+       dQRegion.setEntry(target);
+       Object params[] = { dQRegion };
+       ExecutionContext context = new ExecutionContext(params, this.cache);
+       context.newScope(IndexCreationHelper.INDEX_QUERY_SCOPE_ID);
+       try {
+         boolean computeDependency = true;
+         if (dependencyGraph != null) {
+           context.setDependencyGraph(dependencyGraph);
+           computeDependency = false;
+         }
+         
+         for (int i = 0; i < this.iteratorSize; i++) {
+           CompiledIteratorDef iterDef = (CompiledIteratorDef) fromIterators.get(i);
+           // Asif: Compute the dependency only once. The call to methods of this
+           // class are thread safe as for update lock on Index is taken .
+           if (computeDependency) {
+             iterDef.computeDependencies(context);
+           }
+           RuntimeIterator rIter = iterDef.getRuntimeIterator(context);
+           context.addToIndependentRuntimeItrMapForIndexCreation(iterDef);
+           context.bindIterator(rIter);
+         }
+         // Save the dependency graph for future updates.
+         if (dependencyGraph == null) {
+           dependencyGraph = context.getDependencyGraph();
+         }
+         
+         Support
+             .Assert(
+                 this.indexResultSetType != null,
+                 "IMQEvaluator::evaluate:The StrcutType should have been initialized during index creation");
+ 
+         doNestedIterations(0, context);
+       }
+       catch (IMQException imqe) {
+         throw imqe;
+       }
+       catch (Exception e) {
+         throw new IMQException(e);
+       }
+       finally {
+         context.popScope();
+       }
+     }
+ 
+     /**
+      * Asif : This function is used for creating Index data at the start
+      * 
+      */
+     public void initializeIndex(boolean loadEntries) throws IMQException
+     {
+       this.initEntriesUpdated = 0;
+       try {
+         // Asif: Since an index initialization can happen multiple times
+         // for a given region, due to clear operation, we are using harcoded
+         // scope ID of 1 , as otherwise if obtained from ExecutionContext
+         // object,
+         // it will get incremented on very index initialization
+         this.initContext.newScope(1);
+         for (int i = 0; i < this.iteratorSize; i++) {
+           CompiledIteratorDef iterDef = (CompiledIteratorDef)this.indexInitIterators.get(i);
+           RuntimeIterator rIter = null;
+           if (!this.hasInitOccuredOnce) {
+             iterDef.computeDependencies(this.initContext);
+             rIter = iterDef.getRuntimeIterator(this.initContext);
+             this.initContext.addToIndependentRuntimeItrMapForIndexCreation(iterDef);
+           }
+           if (rIter == null) {
+             rIter = iterDef.getRuntimeIterator(this.initContext);
+           }
+           this.initContext.bindIterator(rIter);
+         }
+         this.hasInitOccuredOnce = true;
+         if (this.indexResultSetType == null) {
+           this.indexResultSetType = createIndexResultSetType();
+         }
+         if(loadEntries) {
+           doNestedIterationsForIndexInit(0, this.initContext
+             .getCurrentIterators());
+         }
+       }
+       catch (IMQException imqe) {
+         throw imqe;
+       }
+       catch (Exception e) {
+         throw new IMQException(e);
+       }
+       finally {
+         this.initContext.popScope();
+       }
+     }
+ 
+     private void doNestedIterationsForIndexInit(int level, List runtimeIterators)
+         throws TypeMismatchException, AmbiguousNameException,
+         FunctionDomainException, NameResolutionException,
+         QueryInvocationTargetException, IMQException
+     {
+       if (level == 1) {
+         ++this.initEntriesUpdated;
+       }
+       if (level == this.iteratorSize) {
+         applyProjectionForIndexInit(runtimeIterators);
+       }
+       else {
+         RuntimeIterator rIter = (RuntimeIterator)runtimeIterators.get(level);
+         // System.out.println("Level = "+level+" Iter = "+rIter.getDef());
+         Collection c = rIter.evaluateCollection(this.initContext);
+         if (c == null)
+           return;
+         Iterator cIter = c.iterator();
+         while (cIter.hasNext()) {
+           rIter.setCurrent(cIter.next());
+           doNestedIterationsForIndexInit(level + 1, runtimeIterators);
+         }
+       }
+     }
+ 
+     /*
+      * Asif : This function is used to obtain Indxe data at the time of index
+      * creation. Each element of the List is an Object Array of size 3. The 0th
+      * element of Object Array stores the value of Index Expression. The 1st
+      * element of ObjectArray contains the RegionEntry object ( If the booelan
+      * isFirstItrOnEntry is false, then the 0th iterator will give us the
+      * Region.Entry object which can be used to obtain the underlying
+      * RegionEntry object. If the boolean is true & additional projection
+      * attribute is not null, then the Region.Entry object can be obtained by
+      * evaluating the additional projection attribute. If the boolean
+      * isFirstItrOnEntry is tru e& additional projection attribute is null, then
+      * teh 0th iterator itself will evaluate to Region.Entry Object.
+      * 
+      * The 2nd element of Object Array contains the Struct object ( tuple)
+      * created. If the boolean isFirstItrOnEntry is false, then the first
+      * attribute of the Struct object is obtained by evaluating the additional
+      * projection attribute.
+      */
+     private void applyProjectionForIndexInit(List currrentRuntimeIters)
+         throws FunctionDomainException, TypeMismatchException,
+         NameResolutionException, QueryInvocationTargetException, IMQException
+     {
+       if (QueryMonitor.isLowMemory()) {
+         throw new IMQException(LocalizedStrings.IndexCreationMsg_CANCELED_DUE_TO_LOW_MEMORY.toLocalizedString());
+       }
+       
+       LocalRegion.NonTXEntry temp = null;
+ 
+       //Evaluate NonTXEntry for index on entries or additional projections
+       //on Entry or just entry value.
+       if (this.isFirstItrOnEntry && this.additionalProj != null) {
+         temp = (LocalRegion.NonTXEntry)additionalProj
+             .evaluate(this.initContext);
+       }
+       else {
+         temp = (LocalRegion.NonTXEntry)(((RuntimeIterator)currrentRuntimeIters
+             .get(0)).evaluate(this.initContext));
+       }
+ 
+       RegionEntry re = temp.getRegionEntry();
+       Object indxResultSet = null;
+ 
+       // Object tuple[] ;
+       if (this.iteratorSize == 1) {
+         indxResultSet = this.isFirstItrOnEntry ? ((this.additionalProj == null) ? temp
+             : ((RuntimeIterator)currrentRuntimeIters.get(0))
+                 .evaluate(this.initContext))
+             : additionalProj.evaluate(this.initContext);
+       }
+       else {
+         Object[] tuple = new Object[this.iteratorSize];
+         int i = (this.isFirstItrOnEntry) ? 0 : 1;
+         for (; i < this.iteratorSize; i++) {
+           RuntimeIterator iter = (RuntimeIterator)currrentRuntimeIters.get(i);
+           tuple[i] = iter.evaluate(this.initContext);
+         }
+         if (!this.isFirstItrOnEntry)
+           tuple[0] = additionalProj.evaluate(this.initContext);
+         Support
+             .Assert(
+                 this.indexResultSetType instanceof StructTypeImpl,
+                 "The Index ResultType should have been an instance of StructTypeImpl rather than ObjectTypeImpl. The indxeResultType is "
+                     + this.indexResultSetType);
+         indxResultSet = new StructImpl(
+             (StructTypeImpl)this.indexResultSetType, tuple);
+       }
+ 
+       //Key must be evaluated after indexResultSet evaluation is done as Entry might be getting destroyed
+       //and so if value is UNDEFINED, key will definitely will be UNDEFINED.
+       Object indexKey = this.isFirstItrOnEntry ? this.indexedExpr
+           .evaluate(this.initContext) : modifiedIndexExpr
+           .evaluate(this.initContext);
+       //based on the first key convert the rest to PdxString or String
+       if(!isIndexedPdxKeysFlagSet){
+         setPdxStringFlag(indexKey);
+       }
+       indexKey = getPdxStringForIndexedPdxKeys(indexKey);
+       addMapping(indexKey, indxResultSet, re);
+     }
+ 
+     // TODO:Asif : This appears to be incorrect.
+     private void doNestedIterations(int level, ExecutionContext context) throws TypeMismatchException,
+         AmbiguousNameException, FunctionDomainException,
+         NameResolutionException, QueryInvocationTargetException, IMQException
+     {
+       List iterList = context.getCurrentIterators();
+       if (level == this.iteratorSize) {
+         applyProjection(context);
+       }
+       else {
+         RuntimeIterator rIter = (RuntimeIterator)iterList.get(level);
+         // System.out.println("Level = "+level+" Iter = "+rIter.getDef());
+         Collection c = rIter.evaluateCollection(context);
+         if (c == null)
+           return;
+         Iterator cIter = c.iterator();
+         while (cIter.hasNext()) {
+           rIter.setCurrent(cIter.next());
+           doNestedIterations(level + 1, context);
+         }
+       }
+     }
+ 
+     private void applyProjection(ExecutionContext context) throws FunctionDomainException,
+         TypeMismatchException, NameResolutionException,
+         QueryInvocationTargetException, IMQException
+     {
+       List currrentRuntimeIters = context.getCurrentIterators();
+       Object indxResultSet = null;
+       // int size = currrentRuntimeIters.size();
+       Object indexKey = indexedExpr.evaluate(context);
+       //based on the first key convert the rest to PdxString or String
+       if(!isIndexedPdxKeysFlagSet){
+         setPdxStringFlag(indexKey);
+       }
+       indexKey = getPdxStringForIndexedPdxKeys(indexKey);
+       if (this.iteratorSize == 1) {
+         RuntimeIterator iter = (RuntimeIterator)currrentRuntimeIters.get(0);
+         indxResultSet = iter.evaluate(context);
+       }
+       else {
+         Object tuple[] = new Object[this.iteratorSize];
+         for (int i = 0; i < this.iteratorSize; i++) {
+           RuntimeIterator iter = (RuntimeIterator)currrentRuntimeIters.get(i);
+           tuple[i] = iter.evaluate(context);
+         }
+         Support
+             .Assert(
+                 this.indexResultSetType instanceof StructTypeImpl,
+                 "The Index ResultType should have been an instance of StructTypeImpl rather than ObjectTypeImpl. The indxeResultType is "
+                     + this.indexResultSetType);
+         indxResultSet = new StructImpl(
+             (StructTypeImpl)this.indexResultSetType, tuple);
+       }
+ 
+       //Keep Entry value in fly untill all keys are evaluated
+       RegionEntry entry = ((DummyQRegion) context.getBindArgument(1)).getEntry();
+       saveMapping(indexKey, indxResultSet, entry);
+     }
+ 
+     // TODO :Asif: Test this function .
+     // The struct type calculation is modified if the
+     // 0th iterator is modified to make it dependent on Entry
+     private ObjectType createIndexResultSetType()
+     {
+       List currentIterators = this.initContext.getCurrentIterators();
+       int len = currentIterators.size();
+       ObjectType type = null;
+       // String fieldNames[] = new String[len];
+       ObjectType fieldTypes[] = new ObjectType[len];
+       int start = this.isFirstItrOnEntry ? 0 : 1;
+       for (; start < len; start++) {
+         RuntimeIterator iter = (RuntimeIterator)currentIterators.get(start);
+         // fieldNames[start] = iter.getInternalId();
+         fieldTypes[start] = iter.getElementType();
+       }
+       if (!this.isFirstItrOnEntry) {
+         // fieldNames[0] = "iter1";
+         fieldTypes[0] = addnlProjType;
+       }
+       type = (len == 1) ? fieldTypes[0] : new StructTypeImpl(
+           this.canonicalIterNames, fieldTypes);
+       return type;
+     }
+ 
+     private void printList(List list)
+     {
+       System.out.println("results.size = " + list.size());
+       for (int i = 0; i < list.size(); i++) {
+         Object arr[] = (Object[])list.get(i);
+         System.out.println("Key = " + arr[0]);
+         System.out.println("Value =" + arr[1]);
+       }
+     }
+ 
+     int getTotalEntriesUpdated()
+     {
+       return this.initEntriesUpdated;
+     }
+ 
+     public ObjectType getIndexResultSetType()
+     {
+       return this.indexResultSetType;
+     }
+ 
+     public boolean isFirstItrOnEntry() {
+       return isFirstItrOnEntry;
+     }
+ 
+     public boolean isFirstItrOnKey() {
+       return isFirstItrOnKey;
+     }
+ 
+     @Override
+     public List getAllDependentIterators() {
+       return fromIterators;
+     }
+   }
+ 
+   /**
+    * Checks the limit for the resultset for distinct and non-distinct
+    * queries separately. In case of non-distinct distinct elements size
+    * of result-set is matched against limit passed in as an argument.
+    * 
+    * @param result
+    * @param limit
+    * @param context
+    * @return true if limit is satisfied.
+    */
+   protected boolean verifyLimit(Collection result, int limit,
+       ExecutionContext context) {   
+     if (limit > 0) {
+      /* if (!context.isDistinct()) {
+         return ((Bag)result).size() == limit;
+       } else if (result.size() == limit) {
+         return true;
+       }*/
+       return result.size() == limit;
+     }
+     return false;
+   }
+   
+   /**
+    * This will verify the consistency between RegionEntry and IndexEntry.
+    * RangeIndex has following entry structure,
+    * 
+    *  IndexKey --> [RegionEntry, [Iterator1, Iterator2....., IteratorN]]
+    *
+    * Where Iterator1 to IteratorN are iterators defined in index from clause.
+    *
+    * For example: "/portfolio p, p.positions.values pos" from clause has two
+    * iterators where p is independent iterator and pos is dependent iterator.
+    * 
+    * Query iterators can be a subset, superset or exact match of index iterators.
+    * But we take query iterators which are matching with index iterators to evaluate
+    * RegionEntry for new value and compare it with index value which could be
+    * a plain object or a Struct. 
+    *
+    * Note: Struct evaluated from RegionEntry can NOT have more field values than
+    * Index Value Struct as we filter out iterators in query context before evaluating
+    * Struct from RegionEntry.
+    * @param re
+    * @param value
+    * @param context 
+    * @return True if Region and Index entries are consistent.
+    */
+   protected boolean verifyEntryAndIndexVaue(RegionEntry re, Object value, ExecutionContext context) {
+     IMQEvaluator evaluator = (IMQEvaluator)getEvaluator();
+     List valuesInRegion = null;
+     Object valueInIndex = null;
+ 
+     try {
+       // In a RegionEntry key and Entry itself can not be modified else
+       // RegionEntry itself will change. So no need to verify anything just return
+       // true.
+       if (evaluator.isFirstItrOnKey()) {
+         return true;
+       } else if (evaluator.isFirstItrOnEntry()) {
+         valuesInRegion = evaluateIndexIteratorsFromRE(re, context);
+         valueInIndex = verifyAndGetPdxDomainObject(value);
+       } else{
+         @Released Object val = re.getValueInVM(context.getPartitionedRegion());
 -        Chunk valToFree = null;
 -        if (val instanceof Chunk) {
 -          valToFree = (Chunk)val;
++        ObjectChunk valToFree = null;
++        if (val instanceof ObjectChunk) {
++          valToFree = (ObjectChunk)val;
+         }
+         try {
+         if (val instanceof CachedDeserializable) {
+           val = ((CachedDeserializable)val).getDeserializedValue(getRegion(), re);
+         }
+         val = verifyAndGetPdxDomainObject(val);   
+         valueInIndex = verifyAndGetPdxDomainObject(value);
+         valuesInRegion = evaluateIndexIteratorsFromRE(val, context);
+         } finally {
+           if (valToFree != null) {
+             valToFree.release();
+           }
+         }
+       }
+     } catch (Exception e) {
+       // TODO: Create a new LocalizedString for this.
+       if (logger.isDebugEnabled()) {
+         logger.debug("Exception occured while verifying a Region Entry value during a Query when the Region Entry is under update operation", e);
+       }
+     }
+ 
+     // We could have many index keys available in one Region entry or just one.
+     if (!valuesInRegion.isEmpty()) {
+       for (Object valueInRegion : valuesInRegion) {
+         if (compareStructWithNonStruct(valueInRegion, valueInIndex)) {
+           return true;
+         }
+       }
+       return false;
+     } else {
+       // Seems like value has been invalidated.
+       return false;
+     }
+   }
+ 
+   /**
+    * This method compares two objects in which one could be StructType and
+    * other ObjectType.
+    * Fur conditions are possible,
+    * Object1 -> Struct  Object2-> Struct
+    * Object1 -> Struct  Object2-> Object
+    * Object1 -> Object  Object2-> Struct
+    * Object1 -> Object  Object2-> Object
+    *
+    * @param valueInRegion
+    * @param valueInIndex
+    * @return true if valueInRegion's all objects are part of valueInIndex. 
+    */
+   private boolean compareStructWithNonStruct(Object valueInRegion,
+       Object valueInIndex) {
+     if (valueInRegion instanceof Struct && valueInIndex instanceof Struct) {
+       Object[] regFields = ((StructImpl) valueInRegion).getFieldValues();
+       List indFields = Arrays.asList(((StructImpl) valueInIndex).getFieldValues());
+       for (Object regField : regFields) {
+         if (!indFields.contains(regField)) {
+           return false;
+         }
+       }
+       return true;
+     } else if (valueInRegion instanceof Struct && !(valueInIndex instanceof Struct)) {
+       Object[] fields = ((StructImpl) valueInRegion).getFieldValues();
+       for (Object field : fields) {
+         if (field.equals(valueInIndex)) {
+           return true;
+         }
+       }
+     } else if (!(valueInRegion instanceof Struct) && valueInIndex instanceof Struct) {
+       Object[] fields = ((StructImpl) valueInIndex).getFieldValues();
+       for (Object field : fields) {
+         if (field.equals(valueInRegion)) {
+           return true;
+         }
+       }
+     } else {
+       return valueInRegion.equals(valueInIndex);
+     }
+     return false;
+   }
+ 
+   /**
+    * Returns evaluated collection for dependent runtime iterator for this index
+    * from clause and given RegionEntry.
+    *
+    * @param context passed here is query context.
+    * @return Evaluated second level collection.
+    * @throws QueryInvocationTargetException 
+    * @throws NameResolutionException 
+    * @throws TypeMismatchException 
+    * @throws FunctionDomainException 
+    */
+   protected List evaluateIndexIteratorsFromRE(Object value, ExecutionContext context)
+       throws FunctionDomainException,
+       TypeMismatchException, NameResolutionException,
+       QueryInvocationTargetException {
+     //We need NonTxEntry to call getValue() on it. RegionEntry does
+     //NOT have public getValue() method.
+     if (value instanceof RegionEntry) {
+       value = ((LocalRegion) this.getRegion()).new NonTXEntry(
+           (RegionEntry) value);
+     }
+     // Get all Independent and dependent iterators for this Index.
+     List itrs = getAllDependentRuntimeIterators(context);
+ 
+     List values = evaluateLastColl(value, context, itrs, 0);
+     return values;
+   }
+ 
+   private List evaluateLastColl(Object value, ExecutionContext context,
+       List itrs, int level)
+       throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+     // A tuple is a value generated from RegionEntry value which could be
+     // a StructType (Multiple Dependent Iterators) or ObjectType (Single
+     // Iterator) value.
+     List tuples = new ArrayList(1);
+     
+     RuntimeIterator currItrator = (RuntimeIterator) itrs.get(level);
+     currItrator.setCurrent(value);
+     // If its last iterator then just evaluate final struct.
+     if ((itrs.size() - 1) == level) {
+       if (itrs.size() > 1) {
+         Object tuple[] = new Object[itrs.size()];
+         for (int i = 0; i < itrs.size(); i++) {
+           RuntimeIterator iter = (RuntimeIterator)itrs.get(i);
+           tuple[i] = iter.evaluate(context);
+         }
+         // Its ok to pass type as null as we are only interested in values.
+         tuples.add(new StructImpl(new StructTypeImpl(), tuple));
+       } else {
+         tuples.add(currItrator.evaluate(context));
+       }
+     } else {
+       // Not the last iterator.
+       RuntimeIterator nextItr = (RuntimeIterator) itrs.get(level + 1);
+       Collection nextLevelValues = nextItr.evaluateCollection(context);
+ 
+       // If value is null or INVALID then the evaluated collection would be
+       // Null.
+       if (nextLevelValues != null) {
+         for (Object nextLevelValue : nextLevelValues) {
+           tuples.addAll(evaluateLastColl(nextLevelValue, context,
+               itrs, level + 1));
+         }
+       }
+     }
+     return tuples;
+   }
+ 
+   /**
+    * Matches the Collection reference in given context for this index's
+    * from-clause in all current independent collection references associated to
+    * the context. For example, if a join Query has "/region1 p, region2 e" from clause
+    * context contains two region references for p and e and Index could be used for
+    * any of those of both of those regions.
+    *
+    * Note: This Index contains its own from clause definition which corresponds to
+    * a region collection reference in given context and must be contained at 0th index
+    * in {@link AbstractIndex#canonicalizedDefinitions}.  
+    * 
+    * @param context
+    * @return {@link RuntimeIterator} this should not be null ever.
+    */
+   public RuntimeIterator getRuntimeIteratorForThisIndex(ExecutionContext context) {
+     List<RuntimeIterator> indItrs = context.getCurrentIterators();
+     Region rgn  = this.getRegion();
+     if (rgn instanceof BucketRegion) {
+       rgn = ((BucketRegion)rgn).getPartitionedRegion();
+     }
+     String regionPath = rgn.getFullPath();
+     String definition = this.getCanonicalizedIteratorDefinitions()[0];
+     for (RuntimeIterator itr: indItrs) {
+       //GemFireCacheImpl.getInstance().getLogger().fine("Shobhit: "+ itr.getDefinition() + "  "+ this.getRegion().getFullPath());
+       if (itr.getDefinition().equals(regionPath) || itr.getDefinition().equals(definition)) {
+         return itr;
+       }
+     }
+     return null;
+   }
+   
+   /**
+    * Similar to {@link #getRuntimeIteratorForThisIndex(ExecutionContext)} except
+    * that this one also matches the iterator name if present with alias used
+    * in the {@link IndexInfo}
+    * 
+    * @param context
+    * @param info
+    * @return {@link RuntimeIterator}
+    */
+   public RuntimeIterator getRuntimeIteratorForThisIndex(
+       ExecutionContext context, IndexInfo info) {
+     List<RuntimeIterator> indItrs = context.getCurrentIterators();
+     Region rgn = this.getRegion();
+     if (rgn instanceof BucketRegion) {
+       rgn = ((BucketRegion) rgn).getPartitionedRegion();
+     }
+     String regionPath = rgn.getFullPath();
+     String definition = this.getCanonicalizedIteratorDefinitions()[0];
+     for (RuntimeIterator itr : indItrs) {
+       if ((itr.getDefinition().equals(regionPath) || itr.getDefinition()
+           .equals(definition))) {
+         // if iterator has name alias must be used in the query
+         if(itr.getName() != null){
+           CompiledValue path = info._path();
+           // match the iterator name with alias
+           String pathName = getReceiverNameFromPath(path);
+           if(path.getType() == OQLLexerTokenTypes.Identifier
+               || itr.getName().equals(pathName)) {
+             return itr;
+           }
+         } else{
+           return itr;
+         }
+       }
+     }
+     return null;
+   }
+   
+   private String getReceiverNameFromPath(CompiledValue path) {
+     if (path instanceof CompiledID) {
+       return ((CompiledID) path).getId();
+     }
+     else if (path instanceof CompiledPath) {
+       return getReceiverNameFromPath(path.getReceiver());
+     }
+     else if (path instanceof CompiledOperation) {
+       return getReceiverNameFromPath(path.getReceiver());
+     }
+     else if (path instanceof CompiledIndexOperation) {
+       return getReceiverNameFromPath(((CompiledIndexOperation)path).getReceiver());
+     }
+     return "";
+   }
+ 
+   /**
+    * Take all independent iterators from context and remove the one which
+    * matches for this Index's independent iterator. Then get all Dependent
+    * iterators from given context for this Index's independent iterator. 
+    *
+    * @param context from executing query.
+    * @return List of all iterators pertaining to this Index.
+    */
+   public List getAllDependentRuntimeIterators(ExecutionContext context) {
+     List<RuntimeIterator> indItrs = context
+         .getCurrScopeDpndntItrsBasedOnSingleIndpndntItr(getRuntimeIteratorForThisIndex(context));
+ 
+     List<String> definitions = Arrays.asList(this.getCanonicalizedIteratorDefinitions());
+     // These are the common iterators between query from clause and index from clause.
+     ArrayList itrs = new ArrayList();
+ 
+     for (RuntimeIterator itr : indItrs) {
+       if (definitions.contains(itr.getDefinition())) {
+         itrs.add(itr);
+       }
+     }
+     return itrs;
+   }
+ 
+   /**
+    * This map is not thread-safe. We rely on the fact that every thread which is
+    * trying to update this kind of map (In Indexes), must have RegionEntry lock
+    * before adding OR removing elements.
+    * 
+    * This map does NOT provide an iterator. To iterate over its element caller
+    * has to get inside the map itself through addValuesToCollection() calls.
+    * 
+    * @author shobhit
+    *
+    */
+   class RegionEntryToValuesMap
+   {
+     protected Map map;
+     private boolean useList;
+     private AtomicInteger numValues = new AtomicInteger(0);
+ 
+     RegionEntryToValuesMap(boolean useList) {
+       this.map = new ConcurrentHashMap(2, 0.75f, 1);
+       this.useList = useList; 
+     }
+ 
+     RegionEntryToValuesMap(Map map, boolean useList) {
+       this.map = map;
+       this.useList = useList;
+     }
+ 
+     /**
+      * We do NOT use any locks here as every add is for a RegionEntry
+      * which is locked before coming here. No two threads can be
+      * entering in this method together for a RegionEntry.
+      * 
+      * @param entry
+      * @param value
+      */
+     public void add(RegionEntry entry, Object value)
+     {
+       assert value != null;
+       // Values must NOT be null and ConcurrentHashMap does not
+       // support null values.
+       if (value == null) {
+         return;
+       }
+       Object object = map.get(entry);
+       if (object == null) {
+         map.put(entry, value);
+       } else if (object instanceof Collection) {
+         Collection coll = (Collection) object;
+         // If its a list query might get ConcurrentModificationException.
+         // This can only happen for Null mapped or Undefined entries in a
+         // RangeIndex. So we are synchronizing on ArrayList.
+         if (useList) {
+           synchronized (coll) {
+             coll.add(value); 
+           }
+         } else {
+           coll.add(value);
+         }
+       } else {
+         Collection coll = useList?new ArrayList(2):new IndexConcurrentHashSet(2, 0.75f, 1);
+         coll.add(object);
+         coll.add(value);
+         map.put(entry, coll);
+       }
+       numValues.incrementAndGet();
+     }
+ 
+     public void addAll(RegionEntry entry, Collection values)
+     {
+       Object object = map.get(entry);
+       if (object == null) {
+         Collection coll = useList?new ArrayList(values.size()):new IndexConcurrentHashSet(values.size(), 0.75f, 1);
+         coll.addAll(values);
+         map.put(entry, coll);
+         numValues.addAndGet(values.size());
+       } else if (object instanceof Collection) {
+         Collection coll = (Collection) object;
+         // If its a list query might get ConcurrentModificationException.
+         // This can only happen for Null mapped or Undefined entries in a
+         // RangeIndex. So we are synchronizing on ArrayList.
+         if (useList) {
+           synchronized (coll) {
+             coll.addAll(values);
+           }
+         } else {
+           coll.addAll(values);
+         }
+       } else {
+         Collection coll = useList?new ArrayList(values.size() + 1):new IndexConcurrentHashSet(values.size()+1, 0.75f, 1);
+         coll.addAll(values);
+         coll.add(object);
+         map.put(entry, coll);
+       }
+       numValues.addAndGet(values.size());
+     }
+ 
+     public Object get(RegionEntry entry)
+     {
+       return map.get(entry);
+     }
+ 
+     /**
+      * We do NOT use any locks here as every remove is for a RegionEntry
+      * which is locked before coming here. No two threads can be
+      * entering in this method together for a RegionEntry.
+      *
+      * @param entry
+      * @param value
+      */
+     public void remove(RegionEntry entry, Object value)
+     {
+       Object object = map.get(entry);
+       if (object == null)
+         return;
+       if (object instanceof Collection) {
+         Collection coll= (Collection)object;
+         boolean removed = false;
+         // If its a list query might get ConcurrentModificationException.
+         // This can only happen for Null mapped or Undefined entries in a
+         // RangeIndex. So we are synchronizing on ArrayList.
+         if (useList) {
+           synchronized (coll) {
+             removed = coll.remove(value);
+           }
+         } else {
+           removed = coll.remove(value);
+         }
+         if (removed) {
+           if (coll.size() == 0) {
+             map.remove(entry);
+           }
+           numValues.decrementAndGet();
+         }
+       }
+       else {
+         if (object.equals(value)) {
+           map.remove(entry);
+         }
+         this.numValues.decrementAndGet();
+       }
+     }
+ 
+     public Object remove(RegionEntry entry)
+     {
+       Object retVal = map.remove(entry);
+       if (retVal != null) {
+             numValues.addAndGet((retVal instanceof Collection) ?
+               - ((Collection) retVal).size() : -1 );
+       }
+       return retVal;
+     }
+ 
+     public int getNumValues(RegionEntry entry)
+     {
+       Object object = map.get(entry);
+       if (object == null)
+         return 0;
+       if (object instanceof Collection) {
+         Collection coll = (Collection) object;
+         return coll.size();
+       } else {
+         return 1;
+       }
+     }
+ 
+     public int getNumValues()
+     {
+       return this.numValues.get();
+     }
+ 
+     public int getNumEntries()
+     {
+       return map.keySet().size();
+     }
+ 
+     public void addValuesToCollection(Collection result, int limit, ExecutionContext context )
+     {
+ 
+       Iterator entriesIter = map.entrySet().iterator();
+       while (entriesIter.hasNext()) {
+         // Check if query execution on this thread is canceled.
+         QueryMonitor.isQueryExecutionCanceled();
+         if (this.verifylimit(result, limit, context)) {
+           return;
+         }
+         Map.Entry e = (Map.Entry)entriesIter.next();
+         Object value = e.getValue();
+         assert value != null;
+ 
+         RegionEntry re = (RegionEntry) e.getKey();
+         boolean reUpdateInProgress = re.isUpdateInProgress();
+         if (value instanceof Collection) {
+           // If its a list query might get ConcurrentModificationException.
+           // This can only happen for Null mapped or Undefined entries in a
+           // RangeIndex. So we are synchronizing on ArrayList.
+           if (this.useList) {
+             synchronized (value) {
+               Iterator itr = ((Collection) value).iterator();
+               while (itr.hasNext()) {
+                 Object val = itr.next();
+                 //Shobhit: Compare the value in index with in RegionEntry.
+                 if (!reUpdateInProgress || verifyEntryAndIndexVaue(re, val, context)) {
+                   result.add(val);
+                 }
+                 if (limit != -1) {
+                   if (result.size() == limit) {
+                     return;
+                   }
+                 }
+               } 
+             }
+           } else {
+             Iterator itr = ((Collection) value).iterator();
+             while (itr.hasNext()) {
+               Object val = itr.next();
+               //Shobhit: Compare the value in index with in RegionEntry.
+               if (!reUpdateInProgress || verifyEntryAndIndexVaue(re, val, context)) {
+                 result.add(val);
+               }
+               if (limit != -1) {
+                 if (this.verifylimit(result, limit, context)) {
+                   return;
+                 }
+               }
+             }
+           }
+         }
+         else {
+           if (!reUpdateInProgress
+               || verifyEntryAndIndexVaue(re, value, context)) {
+             if (context.isCqQueryContext()) {
+               result
+                   .add(new CqEntry(((RegionEntry) e.getKey()).getKey(), value));
+             } else {
+               result.add(verifyAndGetPdxDomainObject(value));
+             }
+           }
+         }
+       }
+     }
+ 
+     public void addValuesToCollection(Collection result, CompiledValue iterOp,
+         RuntimeIterator runtimeItr, ExecutionContext context, List projAttrib,
+         SelectResults intermediateResults, boolean isIntersection, int limit)
+         throws FunctionDomainException, TypeMismatchException,
+         NameResolutionException, QueryInvocationTargetException
+     {
+       if (this.verifylimit(result, limit, context)) {
+         return;
+       }
+       // Iterator valuesIter = map.values().iterator();
+       Iterator entries = map.entrySet().iterator();
+       while (entries.hasNext()) {
+         // Check if query execution on this thread is canceled.
+         QueryMonitor.isQueryExecutionCanceled();
+         Map.Entry e = (Map.Entry)entries.next();
+         Object value = e.getValue();
+         //Key is a RegionEntry here.
+         RegionEntry entry = (RegionEntry)e.getKey();
+         boolean reUpdateInProgress = false;
+         if (value != null) {
+           if (entry.isUpdateInProgress()) {
+             reUpdateInProgress = true;
+           }
+           if (value instanceof Collection) {
+             // If its a list query might get ConcurrentModificationException.
+             // This can only happen for Null mapped or Undefined entries in a
+             // RangeIndex. So we are synchronizing on ArrayList.
+             if (this.useList) {
+               synchronized (value) {
+                 Iterator itr = ((Collection)value).iterator();
+                 while (itr.hasNext()) {
+                   boolean ok = true;
+                   Object val = itr.next();
+                   if (reUpdateInProgress) {
+                     //Shobhit: Compare the value in index with value in RegionEntry.
+                     ok = verifyEntryAndIndexVaue(entry, val, context);
+                   }
+                   if (ok && runtimeItr != null) {
+                     runtimeItr.setCurrent(val);
+                     ok = QueryUtils.applyCondition(iterOp, context);
+                   }
+                   if (ok) {
+                     applyProjection(projAttrib, context, result, val,
+                         intermediateResults, isIntersection);
+                     if (limit != -1 && result.size() == limit) {
+                       return;
+                     }
+                     // return pResultSet;
+                   }
+                 } 
+               }
+             } else {
+               Iterator itr = ((Collection)value).iterator();
+               while (itr.hasNext()) {
+                 boolean ok = true;
+                 Object val = itr.next();
+                 if (reUpdateInProgress) {
+                   //Shobhit: Compare the value in index with value in RegionEntry.
+                   ok = verifyEntryAndIndexVaue(entry, val, context);
+                 }
+                 if (ok && runtimeItr != null) {
+                   runtimeItr.setCurrent(val);
+                   ok = QueryUtils.applyCondition(iterOp, context);
+                 }
+                 if (ok) {
+                   applyProjection(projAttrib, context, result, val,
+                       intermediateResults, isIntersection);
+                   if (this.verifylimit(result, limit, context)) {
+                     return;
+                   }
+                   // return pResultSet;
+                 }
+               }
+             }
+           }
+           else {
+             boolean ok = true;
+             if (reUpdateInProgress) {
+               //Shobhit: Compare the value in index with in RegionEntry.
+               ok = verifyEntryAndIndexVaue(entry, value, context);
+             }
+             if (ok && runtimeItr != null) {
+               runtimeItr.setCurrent(value);
+               ok = QueryUtils.applyCondition(iterOp, context);
+             }
+             if (ok) {
+               if (context.isCqQueryContext()) {
+                 result.add(new CqEntry(((RegionEntry)e.getKey()).getKey(),
+                     value));
+               }
+               else {
+                 applyProjection(projAttrib, context, result, value,
+                     intermediateResults, isIntersection);
+               }
+             }
+           }
+         }
+       }
+     }
+ 
+     public void removeValuesFromCollection(Collection result,
+         CompiledValue iterOps, RuntimeIterator runtimeItr,
+         ExecutionContext context, List projAttrib,
+         SelectResults intermediateResults, boolean isIntersection)
+         throws FunctionDomainException, TypeMismatchException,
+         NameResolutionException, QueryInvocationTargetException
+     {
+       // Iterator valuesIter = map.values().iterator();
+       Iterator entries = map.entrySet().iterator();
+       while (entries.hasNext()) {
+         Map.Entry e = (Map.Entry)entries.next();
+         Object value = e.getValue();
+         if (value instanceof Collection) {
+           Iterator itr = ((Collection)value).iterator();
+           while (itr.hasNext()) {
+             boolean ok = true;
+             Object val = itr.next();
+             if (runtimeItr != null) {
+               runtimeItr.setCurrent(val);
+               ok = QueryUtils.applyCondition(iterOps, context);
+ 
+             }
+             if (ok) {
+               removeProjection(projAttrib, context, result, val,
+                   intermediateResults, isIntersection);
+             }
+           }
+         }
+         else {
+           boolean ok = true;
+           if (runtimeItr != null) {
+             // Attempt to remove only if it was apossibly added
+             runtimeItr.setCurrent(value);
+             ok = QueryUtils.applyCondition(iterOps, context);
+           }
+           if (ok) {
+             if (context.isCqQueryContext()) {
+               result.remove(new CqEntry(((RegionEntry)e.getKey()).getKey(),
+                   value));
+             }
+             else {
+               removeProjection(projAttrib, context, result, value,
+                   intermediateResults, isIntersection);
+             }
+           }
+ 
+         }
+       }
+     }
+ 
+     public void removeValuesFromCollection(Collection result)
+     {
+       Iterator valuesIter = map.values().iterator();
+       while (valuesIter.hasNext()) {
+         Object value = valuesIter.next();
+         if (value instanceof Collection)
+           result.removeAll((Collection)value);
+         else
+           result.remove(value);
+       }
+     }
+ 
+     private boolean verifylimit(Collection result, int limit,
+         ExecutionContext context) {     
+       if (limit > 0) {
+         if (!context.isDistinct()) {
+           return ((Bag)result).size() == limit;
+         } else if (result.size() == limit) {
+           return true;
+         }
+       }
+       return false;
+     }
+ 
+     public boolean containsEntry(RegionEntry entry)
+     {
+       return map.containsKey(entry);
+     }
+ 
+     public boolean containsValue(Object value)
+     {
+       throw new RuntimeException(
+           LocalizedStrings.RangeIndex_NOT_YET_IMPLEMENTED.toLocalizedString());
+     }
+ 
+     public void clear()
+     {
+       map.clear();
+       this.numValues.set(0);
+     }
+ 
+     public Set entrySet()
+     {
+       return map.entrySet();
+     }
+ 
+     /**
+      * This replaces a key's value along with updating the numValues
+      * correctly.
+      * @param entry
+      * @param values
+      */
+     public void replace(RegionEntry entry, Object values) {
+       int numOldValues = getNumValues(entry);
+       this.map.put(entry, values);
+       this.numValues.addAndGet(((values instanceof Collection) ? ((Collection) values)
+           .size() : 1) - numOldValues);
+     }
+   }
+ 
+   /**
+    * This will populate resultset from both type of indexes,
+    * {@link CompactRangeIndex} and {@link RangeIndex}.
+    * 
+    * @param list
+    * @param outerEntries
+    * @param innerEntries
+    * @param context
+    * @param key
+    * @throws FunctionDomainException
+    * @throws TypeMismatchException
+    * @throws NameResolutionException
+    * @throws QueryInvocationTargetException
+    */
+   protected void populateListForEquiJoin(List list, Object outerEntries,
+       Object innerEntries, ExecutionContext context, Object key)
+       throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+ 
+     Assert.assertTrue((outerEntries != null && innerEntries != null), "OuterEntries or InnerEntries must not be null");
+     
+     Object values[][] = new Object[2][];
+     Iterator itr = null;
+     int j = 0;
+ 
+     while (j < 2) {
+       boolean isRangeIndex = false;
+       if (j == 0) {
+         if (outerEntries instanceof RegionEntryToValuesMap) {
+           itr = ((RegionEntryToValuesMap)outerEntries).map.entrySet().iterator();
+           isRangeIndex = true;
+         } else if (outerEntries instanceof CloseableIterator){
+           itr = (Iterator) outerEntries;
+         } 
+       }
+       else {
+         if (innerEntries instanceof RegionEntryToValuesMap) {
+           itr = ((RegionEntryToValuesMap)innerEntries).map.entrySet().iterator();
+           isRangeIndex = true;
+         } else if (innerEntries instanceof CloseableIterator){
+           itr = (Iterator) innerEntries;
+         } 
+       }
+       //TODO :Asif Identify appropriate size of the List
+       
+       // extract the values from the RegionEntries
+       List dummy = new ArrayList();
+       RegionEntry re = null;
+       IndexStoreEntry ie = null;
+       Object val = null;
+       Object entryVal = null;
+ 
+       IndexInfo[] indexInfo = (IndexInfo[]) context.cacheGet(CompiledValue.INDEX_INFO);
+       IndexInfo indInfo = indexInfo[j];
+ 
+       while (itr.hasNext()) {
+         if (isRangeIndex) {
+           Map.Entry entry = (Map.Entry)itr.next();
+           val = entry.getValue();
+           if (val instanceof Collection) {
+             entryVal = ((Collection)val).iterator().next();
+           } else {
+             entryVal = val;
+           }
+           re = (RegionEntry) entry.getKey();
+         } else {
+           ie = (IndexStoreEntry)itr.next();
+         }
+         //Bug#41010: We need to verify if Inner and Outer Entries
+         // are consistent with index key values.
+         boolean ok = true;
+         if (isRangeIndex) {
+           if(re.isUpdateInProgress()) {
+            ok = ((RangeIndex) indInfo._getIndex()).verifyEntryAndIndexVaue(re,
+               entryVal, context);
+           }
+         } else if (ie.isUpdateInProgress()) {
+           ok = ((CompactRangeIndex) indInfo._getIndex())
+               .verifyInnerAndOuterEntryValues(ie, context, indInfo, key);
+         }
+         if (ok) {
+           if (isRangeIndex) {
+             if (val instanceof Collection) {
+               dummy.addAll((Collection) val);
+             }
+             else {
+               dummy.add(val);
+             }
+           } else {
+             if (IndexManager.IS_TEST_EXPANSION) {
+               dummy.addAll(((CompactRangeIndex)indInfo._getIndex()).expandValue(context, key, null, OQLLexerTokenTypes.TOK_EQ, -1, ie.getDeserializedValue()));
+             }
+             else {
+               dummy.add(ie.getDeserializedValue());
+             }
+           }
+         }
+       }
+       Object[] newValues = new Object[dummy.size()];
+       dummy.toArray(newValues);
+       values[j++] = newValues;
+     }
+     list.add(values);
+   }
+ 
+   /**
+    * Sets the isIndexedPdxKeys flag indicating if all the keys in the index are
+    * Strings or PdxStrings. Also sets another flag isIndexedPdxKeysFlagSet that
+    * indicates isIndexedPdxKeys has been set/reset to avoid frequent calculation
+    * of map size
+    * 
+    * @param key
+    */
+   public synchronized void setPdxStringFlag(Object key) {
+     // For Null and Undefined keys do not set the isIndexedPdxKeysFlagSet flag
+     if (key == null || key == IndexManager.NULL
+         || key == QueryService.UNDEFINED) {
+       return;
+     }
+     if (!isIndexedPdxKeys) {
+       if (key instanceof PdxString) {
+         isIndexedPdxKeys = true;
+       }
+     }
+     isIndexedPdxKeysFlagSet = true;
+   }
+ 
+   /**
+    * Converts Strings to PdxStrings and vice-versa based on the isIndexedPdxKeys
+    * flag
+    * 
+    * @param key
+    * @return PdxString or String based on isIndexedPdxKeys flag
+    */
+   public Object getPdxStringForIndexedPdxKeys(Object key) {
+     if (isIndexedPdxKeys) {
+       if (key instanceof String){
+         return new PdxString((String) key);
+       }
+     } else if (key instanceof PdxString) {
+        return ((PdxString) key).toString();
+     }
+     return key; 
+   }
+   
+   public boolean removeFromKeysToRemove(Collection keysToRemove, Object key) {
+     Iterator iterator = keysToRemove.iterator();
+     while (iterator.hasNext()) {
+       try {
+         if (TypeUtils.compare(key, iterator.next(), OQLLexerTokenTypes.TOK_EQ).equals(Boolean.TRUE)) {
+           iterator.remove();
+           return true;
+         }
+       }
+       catch (TypeMismatchException e) {
+         //they are not equals, so we just continue iterating
+       }
+     }
+     return false;
+   }
+  
+   public boolean acquireIndexReadLockForRemove() {
+     boolean success = this.removeIndexLock.readLock().tryLock();
+     if (success) {
+       this.internalIndexStats.incReadLockCount(1);
+       if (logger.isDebugEnabled()) {
+         logger.debug("Acquired read lock on index {}", this.getName());
+       }
+     }
+     return success;
+   }
+ 
+   public void releaseIndexReadLockForRemove() {
+     this.removeIndexLock.readLock().unlock();
+     this.internalIndexStats.incReadLockCount(-1);
+     if (logger.isDebugEnabled()) {
+       logger.debug("Released read lock on index {}", this.getName());
+     }
+   }
+   
+   /**
+    * This makes current thread wait until all query threads are done using it.
+    */
+   public void acquireIndexWriteLockForRemove() {
+     final boolean isDebugEnabled = logger.isDebugEnabled();
+     if (logger.isDebugEnabled()) {
+       logger.debug("Acquiring write lock on Index {}", this.getName());
+     }
+     removeIndexLock.writeLock().lock();
+     if (logger.isDebugEnabled()) {
+       logger.debug("Acquired write lock on index {}", this.getName());
+     }
+   }
+ 
+   public void releaseIndexWriteLockForRemove() {
+     final boolean isDebugEnabled = logger.isDebugEnabled();
+     if (isDebugEnabled) {
+       logger.debug("Releasing write lock on Index {}", this.getName());
+     }
+     removeIndexLock.writeLock().unlock();
+     if (isDebugEnabled) {
+       logger.debug("Released write lock on Index {}", this.getName());
+     }
+   }
+ 
+   public boolean isPopulated() {
+     return isPopulated;
+   }
+ 
+   public void setPopulated(boolean isPopulated) {
+     this.isPopulated = isPopulated;
+   }
+   
+   
+ }



[081/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
index 0000000,b145a91..541c453
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
@@@ -1,0 -1,11398 +1,11398 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
+ import java.io.Serializable;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Hashtable;
+ import java.util.Iterator;
+ import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.NoSuchElementException;
+ import java.util.Random;
+ import java.util.Set;
+ import java.util.concurrent.Callable;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.CopyOnWriteArrayList;
+ import java.util.concurrent.ExecutionException;
+ import java.util.concurrent.Executors;
+ import java.util.concurrent.Future;
+ import java.util.concurrent.FutureTask;
+ import java.util.concurrent.ScheduledExecutorService;
+ import java.util.concurrent.ThreadFactory;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.concurrent.locks.Lock;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.InternalGemFireException;
+ import com.gemstone.gemfire.StatisticsFactory;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.AttributesFactory;
+ import com.gemstone.gemfire.cache.AttributesMutator;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.cache.CacheException;
+ import com.gemstone.gemfire.cache.CacheListener;
+ import com.gemstone.gemfire.cache.CacheLoader;
+ import com.gemstone.gemfire.cache.CacheLoaderException;
+ import com.gemstone.gemfire.cache.CacheStatistics;
+ import com.gemstone.gemfire.cache.CacheWriter;
+ import com.gemstone.gemfire.cache.CacheWriterException;
+ import com.gemstone.gemfire.cache.CustomExpiry;
+ import com.gemstone.gemfire.cache.DataPolicy;
+ import com.gemstone.gemfire.cache.DiskAccessException;
+ import com.gemstone.gemfire.cache.EntryExistsException;
+ import com.gemstone.gemfire.cache.EntryNotFoundException;
+ import com.gemstone.gemfire.cache.ExpirationAttributes;
+ import com.gemstone.gemfire.cache.InterestPolicy;
+ import com.gemstone.gemfire.cache.InterestRegistrationEvent;
+ import com.gemstone.gemfire.cache.LoaderHelper;
+ import com.gemstone.gemfire.cache.LowMemoryException;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.PartitionAttributes;
+ import com.gemstone.gemfire.cache.PartitionResolver;
+ import com.gemstone.gemfire.cache.PartitionedRegionDistributionException;
+ import com.gemstone.gemfire.cache.PartitionedRegionStorageException;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionAttributes;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.RegionEvent;
+ import com.gemstone.gemfire.cache.RegionExistsException;
+ import com.gemstone.gemfire.cache.RegionMembershipListener;
+ import com.gemstone.gemfire.cache.TimeoutException;
+ import com.gemstone.gemfire.cache.TransactionDataNotColocatedException;
+ import com.gemstone.gemfire.cache.TransactionDataRebalancedException;
+ import com.gemstone.gemfire.cache.TransactionException;
+ import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueImpl;
+ import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueStats;
+ import com.gemstone.gemfire.cache.execute.EmtpyRegionFunctionException;
+ import com.gemstone.gemfire.cache.execute.Function;
+ import com.gemstone.gemfire.cache.execute.FunctionContext;
+ import com.gemstone.gemfire.cache.execute.FunctionException;
+ import com.gemstone.gemfire.cache.execute.FunctionService;
+ import com.gemstone.gemfire.cache.execute.ResultCollector;
+ import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreFactoryImpl;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.CompactionStatus;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSFlushQueueFunction;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSForceCompactionArgs;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSForceCompactionFunction;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSForceCompactionResultCollector;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSLastCompactionTimeFunction;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSRegionDirector;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HoplogOrganizer;
+ import com.gemstone.gemfire.cache.partition.PartitionListener;
+ import com.gemstone.gemfire.cache.partition.PartitionNotAvailableException;
+ import com.gemstone.gemfire.cache.query.FunctionDomainException;
+ import com.gemstone.gemfire.cache.query.Index;
+ import com.gemstone.gemfire.cache.query.IndexCreationException;
+ import com.gemstone.gemfire.cache.query.IndexExistsException;
+ import com.gemstone.gemfire.cache.query.IndexInvalidException;
+ import com.gemstone.gemfire.cache.query.IndexNameConflictException;
+ import com.gemstone.gemfire.cache.query.IndexType;
+ import com.gemstone.gemfire.cache.query.MultiIndexCreationException;
+ import com.gemstone.gemfire.cache.query.NameResolutionException;
+ import com.gemstone.gemfire.cache.query.QueryException;
+ import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.query.TypeMismatchException;
+ import com.gemstone.gemfire.cache.query.internal.CompiledSelect;
+ import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
+ import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
+ import com.gemstone.gemfire.cache.query.internal.QCompiler;
+ import com.gemstone.gemfire.cache.query.internal.QueryExecutor;
+ import com.gemstone.gemfire.cache.query.internal.ResultsBag;
+ import com.gemstone.gemfire.cache.query.internal.ResultsCollectionWrapper;
+ import com.gemstone.gemfire.cache.query.internal.ResultsSet;
+ import com.gemstone.gemfire.cache.query.internal.index.AbstractIndex;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexCreationData;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexUtils;
+ import com.gemstone.gemfire.cache.query.internal.index.PartitionedIndex;
+ import com.gemstone.gemfire.cache.query.internal.types.ObjectTypeImpl;
+ import com.gemstone.gemfire.cache.query.types.ObjectType;
+ import com.gemstone.gemfire.cache.wan.GatewaySender;
+ import com.gemstone.gemfire.distributed.DistributedLockService;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.LockServiceDestroyedException;
+ import com.gemstone.gemfire.distributed.internal.DM;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisee;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
+ import com.gemstone.gemfire.distributed.internal.DistributionManager;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.DisconnectListener;
+ import com.gemstone.gemfire.distributed.internal.MembershipListener;
+ import com.gemstone.gemfire.distributed.internal.ProfileListener;
+ import com.gemstone.gemfire.distributed.internal.ReplyException;
+ import com.gemstone.gemfire.distributed.internal.ReplyProcessor21;
+ import com.gemstone.gemfire.distributed.internal.locks.DLockRemoteToken;
+ import com.gemstone.gemfire.distributed.internal.locks.DLockService;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.distributed.internal.membership.MemberAttributes;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.NanoTimer;
+ import com.gemstone.gemfire.internal.SetUtils;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.BucketAdvisor.ServerBucketProfile;
+ import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.CacheProfile;
+ import com.gemstone.gemfire.internal.cache.DestroyPartitionedRegionMessage.DestroyPartitionedRegionResponse;
+ import com.gemstone.gemfire.internal.cache.PutAllPartialResultException.PutAllPartialResult;
+ import com.gemstone.gemfire.internal.cache.control.HeapMemoryMonitor;
+ import com.gemstone.gemfire.internal.cache.control.InternalResourceManager;
+ import com.gemstone.gemfire.internal.cache.control.InternalResourceManager.ResourceType;
+ import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
+ import com.gemstone.gemfire.internal.cache.control.MemoryThresholds;
+ import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
+ import com.gemstone.gemfire.internal.cache.execute.FunctionExecutionNodePruner;
+ import com.gemstone.gemfire.internal.cache.execute.FunctionRemoteContext;
+ import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
+ import com.gemstone.gemfire.internal.cache.execute.LocalResultCollector;
+ import com.gemstone.gemfire.internal.cache.execute.PartitionedRegionFunctionExecutor;
+ import com.gemstone.gemfire.internal.cache.execute.PartitionedRegionFunctionResultSender;
+ import com.gemstone.gemfire.internal.cache.execute.PartitionedRegionFunctionResultWaiter;
+ import com.gemstone.gemfire.internal.cache.execute.RegionFunctionContextImpl;
+ import com.gemstone.gemfire.internal.cache.execute.ServerToClientFunctionResultSender;
+ import com.gemstone.gemfire.internal.cache.ha.ThreadIdentifier;
+ import com.gemstone.gemfire.internal.cache.lru.HeapEvictor;
+ import com.gemstone.gemfire.internal.cache.lru.LRUStatistics;
+ import com.gemstone.gemfire.internal.cache.partitioned.ContainsKeyValueMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.ContainsKeyValueMessage.ContainsKeyValueResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.DestroyMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.DestroyMessage.DestroyResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.DestroyRegionOnDataStoreMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.DumpAllPRConfigMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.DumpB2NRegion;
+ import com.gemstone.gemfire.internal.cache.partitioned.DumpB2NRegion.DumpB2NResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.DumpBucketsMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchBulkEntriesMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchBulkEntriesMessage.FetchBulkEntriesResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchEntriesMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchEntriesMessage.FetchEntriesResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchEntryMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchEntryMessage.FetchEntryResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchKeysMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.FetchKeysMessage.FetchKeysResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.GetMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.GetMessage.GetResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.IdentityRequestMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.IdentityRequestMessage.IdentityResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.IdentityUpdateMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.IdentityUpdateMessage.IdentityUpdateResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.IndexCreationMsg;
+ import com.gemstone.gemfire.internal.cache.partitioned.InterestEventMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.InterestEventMessage.InterestEventResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.InvalidateMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.InvalidateMessage.InvalidateResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.PREntriesIterator;
+ import com.gemstone.gemfire.internal.cache.partitioned.PRLocallyDestroyedException;
+ import com.gemstone.gemfire.internal.cache.partitioned.PRSanityCheckMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.PRUpdateEntryVersionMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.PRUpdateEntryVersionMessage.UpdateEntryVersionResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.PartitionMessage.PartitionResponse;
+ import com.gemstone.gemfire.internal.cache.partitioned.PartitionedRegionObserver;
+ import com.gemstone.gemfire.internal.cache.partitioned.PartitionedRegionObserverHolder;
+ import com.gemstone.gemfire.internal.cache.partitioned.PutAllPRMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.PutMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.PutMessage.PutResult;
+ import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor;
+ import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor.BucketVisitor;
+ import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor.PartitionProfile;
+ import com.gemstone.gemfire.internal.cache.partitioned.RemoveAllPRMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.RemoveIndexesMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.SizeMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.SizeMessage.SizeResponse;
+ import com.gemstone.gemfire.internal.cache.persistence.PRPersistentConfig;
+ import com.gemstone.gemfire.internal.cache.tier.InterestType;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.command.Get70;
+ import com.gemstone.gemfire.internal.cache.versions.ConcurrentCacheModificationException;
+ import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
+ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
+ import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderConfigurationException;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderException;
+ import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewaySenderQueue;
+ import com.gemstone.gemfire.internal.cache.wan.parallel.ParallelGatewaySenderQueue;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.internal.sequencelog.RegionLogger;
+ import com.gemstone.gemfire.internal.util.TransformUtils;
+ import com.gemstone.gemfire.internal.util.concurrent.FutureResult;
+ import com.gemstone.gemfire.internal.util.concurrent.StoppableCountDownLatch;
+ import com.gemstone.gemfire.i18n.StringId;
+ 
+ /**
+  * A Region whose total storage is split into chunks of data (partitions) which
+  * are copied up to a configurable level (for high availability) and placed on
+  * multiple VMs for improved performance and increased storage capacity.
+  * 
+  */
+ public class PartitionedRegion extends LocalRegion implements 
+   CacheDistributionAdvisee, QueryExecutor {
+ 
+   public static final Random rand = new Random(Long.getLong(
+       "gemfire.PartitionedRegionRandomSeed", NanoTimer.getTime()).longValue());
+   
+   private static final AtomicInteger SERIAL_NUMBER_GENERATOR = new AtomicInteger();
+   
+   private final DiskRegionStats diskRegionStats;
+   /**
+    * Changes scope of replication to secondary bucket to SCOPE.DISTRIBUTED_NO_ACK
+    */
+   public static final boolean DISABLE_SECONDARY_BUCKET_ACK = Boolean.getBoolean(
+       "gemfire.disablePartitionedRegionBucketAck");
+   
+   /**
+    * A debug flag used for testing calculation of starting bucket id
+    */
+   public static boolean BEFORE_CALCULATE_STARTING_BUCKET_FLAG = false;
+   
+   /**
+    * Thread specific random number
+    */
+   private static ThreadLocal threadRandom = new ThreadLocal() {
+     @Override
+     protected Object initialValue() {
+       int i = rand.nextInt();
+       if (i < 0) {
+         i = -1 * i;
+       }
+       return Integer.valueOf(i);
+     }
+   };
+ 
+   /**
+    * Global Region for storing PR config ( PRName->PRConfig). This region would
+    * be used to resolve PR name conflict.*
+    */
+   private volatile Region<String, PartitionRegionConfig> prRoot;
+ 
+   /**
+    * 
+    * PartitionedRegionDataStore class takes care of data storage for the PR.
+    * This will contain the bucket Regions to store data entries for PR*
+    */
+   protected PartitionedRegionDataStore dataStore;
+ 
+   /**
+    * The advisor that hold information about this partitioned region
+    */
+   private final RegionAdvisor distAdvisor;
+ 
+   /** Logging mechanism for debugging */
+   private static final Logger logger = LogService.getLogger();
+ 
+   /** cleanup flags * */
+   private boolean cleanPRRegistration = false;
+ 
+   /** Time to wait for for acquiring distributed lock ownership */
+   final static long VM_OWNERSHIP_WAIT_TIME = PRSystemPropertyGetter
+       .parseLong(
+           System
+               .getProperty(PartitionedRegionHelper.VM_OWNERSHIP_WAIT_TIME_PROPERTY),
+           PartitionedRegionHelper.VM_OWNERSHIP_WAIT_TIME_DEFAULT);
+ 
+   /**
+    * default redundancy level is 0.
+    */
+   final int redundantCopies;
+ 
+   /**
+    * The miminum amount of redundancy needed for a write operation
+    */
+   final int minimumWriteRedundancy;
+ 
+   /**
+    * The miminum amount of redundancy needed for a read operation
+    */
+   final int minimumReadRedundancy;
+ 
+   /**
+    * Ratio of currently allocated memory to maxMemory that triggers rebalance
+    * activity.
+    */
+   final static float rebalanceThreshold = 0.75f;
+ 
+   /** The maximum memory allocated for this node in Mb */
+   final int localMaxMemory;
+ 
+   /** The maximum milliseconds for retrying operations */
+   final private int retryTimeout;
+ 
+   /**
+    * The statistics for this PR
+    */
+   public final PartitionedRegionStats prStats;
+ 
+   // private Random random = new Random(System.currentTimeMillis());
+ 
+   /** Number of initial buckets */
+   private final int totalNumberOfBuckets;
+ 
+   /**
+    * To check if local cache is enabled.
+    */
+   private static final boolean localCacheEnabled = false;
+ 
+   // private static final boolean throwIfNoNodesLeft = true;
+ 
+   public static final int DEFAULT_RETRY_ITERATIONS = 3;
+ 
+   /**
+    * Flag to indicate if a cache loader is present
+    */
+   private volatile boolean haveCacheLoader;
+ 
+   /**
+    * Region identifier used for DLocks (Bucket and Region)
+    */
+   private final String regionIdentifier;
+ 
+   /**
+    * Maps each PR to a prId. This prId will uniquely identify the PR.
+    */
+   static final PRIdMap prIdToPR = new PRIdMap();
+ 
+   /**
+    * Flag to indicate whether region is closed
+    * 
+    */
+   public volatile boolean isClosed = false;
+ 
+   /**
+    * a flag indicating that the PR is destroyed in this VM
+    */
+   public volatile boolean isLocallyDestroyed = false;
+   
+   /**
+    * the thread locally destroying this pr.  not volatile,
+    * so always check isLocallyDestroyed before checking locallyDestroyingThread
+    * 
+    * Concurrency: {@link #isLocallyDestroyed} is volatile
+    */
+   public Thread locallyDestroyingThread;
+ 
+   // TODO someone please add a javadoc for this
+   private volatile boolean hasPartitionedIndex = false;
+ 
+   /**
+    * regionMembershipListener notification requires this to be plugged into
+    * a PR's RegionAdvisor
+    */
+   private final AdvisorListener advisorListener = new AdvisorListener();
+ 
+   /*
+    * Map containing <IndexTask, FutureTask<IndexTask> or Index>.
+    * IndexTask represents an index thats completely created or
+    * one thats in create phase. This is done in order to avoid
+    * synchronization on the indexes.
+    */
+   private final ConcurrentMap indexes = new ConcurrentHashMap();
+ 
+   private volatile boolean recoveredFromDisk;
+ 
+   public static final int RUNNING_MODE = -1;
+   public static final int PRIMARY_BUCKETS_LOCKED = 1;
+   public static final int DISK_STORE_FLUSHED = 2;
+   public static final int OFFLINE_EQUAL_PERSISTED = 3;
+ 
+   private volatile int shutDownAllStatus = RUNNING_MODE;
+   
+   private final long birthTime = System.currentTimeMillis();
+ 
+   public void setShutDownAllStatus(int newStatus) {
+     this.shutDownAllStatus = newStatus;
+   }
+   
+   private final PartitionedRegion colocatedWithRegion;
+ 
+   private List<BucketRegion> sortedBuckets; 
+   
+   private ScheduledExecutorService bucketSorter;
+ 
+   private ConcurrentMap<String, Integer[]> partitionsMap = new ConcurrentHashMap<String, Integer[]>();
+ 
+   public ConcurrentMap<String, Integer[]> getPartitionsMap() {
+     return this.partitionsMap;
+   }
+   /**
+   * for wan shadowPR
+   */
+   private boolean enableConflation;
+  
+   private final Object indexLock = new Object();
+  
+   /**
+    * Byte 0 = no NWHOP Byte 1 = NWHOP to servers in same server-grp Byte 2 =
+    * NWHOP tp servers in other server-grp
+    */
+   private final ThreadLocal<Byte> isNetworkHop = new ThreadLocal<Byte>() {
+     @Override
+     protected Byte initialValue() {
+       return Byte.valueOf((byte)0);
+     }
+   };
+ 
+   public void setIsNetworkHop(Byte value) {
+     this.isNetworkHop.set(value);
+   }
+ 
+   public Byte isNetworkHop() {
+     return this.isNetworkHop.get();
+   }
+   
+   private final ThreadLocal<Byte> metadataVersion = new ThreadLocal<Byte>() {
+     @Override
+     protected Byte initialValue() {
+       return 0;
+     }
+   };
+ 
+   public void setMetadataVersion(Byte value) {
+     this.metadataVersion.set(value);
+   }
+ 
+   public Byte getMetadataVersion() {
+     return this.metadataVersion.get();
+   }
+       
+ 
+   /**
+    * Returns the LRUStatistics for this PR.
+    * This is needed to find the single instance of LRUStatistics
+    * created early for a PR when it is recovered from disk.
+    * This fixes bug 41938
+    */
+   public LRUStatistics getPRLRUStatsDuringInitialization() {
+     LRUStatistics result = null;
+     if (getDiskStore() != null) {
+       result = getDiskStore().getPRLRUStats(this);
+     }
+     return result;
+   }
+                
+   
+   //////////////////  ConcurrentMap methods //////////////////               
+           
+   @Override
+    public boolean remove(Object key, Object value, Object callbackArg) {
+      final long startTime = PartitionedRegionStats.startTime();
+      try {
+        return super.remove(key, value, callbackArg);
+      }
+      finally {
+        this.prStats.endDestroy(startTime);
+      }
+    }
+    
+    
+                
+    //////////////////  End of ConcurrentMap methods ////////////////// 
+                
+ 
+   public PartitionListener[] getPartitionListeners() {
+     return this.partitionListeners;
+   }
+   
+   /**
+    * Return canonical representation for a bucket (for logging)
+    * 
+    * @param bucketId
+    *                the bucket
+    * @return a String representing this PR and the bucket
+    */
+   public String bucketStringForLogs(int bucketId) {
+     return getPRId() + BUCKET_ID_SEPARATOR + bucketId;
+   }
+ 
+   /** Separator between PRId and bucketId for creating bucketString */
+   public static final String BUCKET_ID_SEPARATOR = ":";
+ 
+   /**
+    * Clear the prIdMap, typically used when disconnecting from the distributed
+    * system or clearing the cache
+    */
+   public static void clearPRIdMap() {
+     synchronized (prIdToPR) {
+       prIdToPR.clear();
+     }
+   }
+ 
+   private static DisconnectListener dsPRIdCleanUpListener = new DisconnectListener() {
+     @Override
+     public String toString() {
+       return LocalizedStrings.PartitionedRegion_SHUTDOWN_LISTENER_FOR_PARTITIONEDREGION.toLocalizedString();
+     }
+ 
+     public void onDisconnect(InternalDistributedSystem sys) {
+       clearPRIdMap();
+     }
+   };
+ 
+ 
+   public static class PRIdMap extends HashMap {
+     private static final long serialVersionUID = 3667357372967498179L;
+     public final static String DESTROYED = "Partitioned Region Destroyed";
+ 
+     final static String LOCALLY_DESTROYED = "Partitioned Region Is Locally Destroyed";
+ 
+     final static String FAILED_REGISTRATION = "Partitioned Region's Registration Failed";
+ 
+     public final static String NO_PATH_FOUND = "NoPathFound";
+ 
+     private volatile boolean cleared = true;
+ 
+     @Override
+     public Object get(Object key) {
+       throw new UnsupportedOperationException(LocalizedStrings.PartitionedRegion_PRIDMAPGET_NOT_SUPPORTED_USE_GETREGION_INSTEAD.toLocalizedString());
+     }
+ 
+     public Object getRegion(Object key) throws PRLocallyDestroyedException {
+       if (cleared) {
+         Cache c = GemFireCacheImpl.getInstance();
+         if (c == null) {
+           throw new CacheClosedException();
+         }
+         else {
+           c.getCancelCriterion().checkCancelInProgress(null);
+         }
+       }
+       Assert.assertTrue(key instanceof Integer);
+ 
+       Object o = super.get(key);
+       if (o == DESTROYED) {
+         throw new RegionDestroyedException(LocalizedStrings.PartitionedRegion_REGION_FOR_PRID_0_IS_DESTROYED.toLocalizedString(key), NO_PATH_FOUND);
+       }
+       if (o == LOCALLY_DESTROYED) {
+         throw new PRLocallyDestroyedException(LocalizedStrings.PartitionedRegion_REGION_WITH_PRID_0_IS_LOCALLY_DESTROYED_ON_THIS_NODE.toLocalizedString(key));
+       }
+       if (o == FAILED_REGISTRATION) {
+         throw new PRLocallyDestroyedException(LocalizedStrings.PartitionedRegion_REGION_WITH_PRID_0_FAILED_INITIALIZATION_ON_THIS_NODE.toLocalizedString(key));
+       }
+       return o;
+     }
+ 
+     @Override
+     public Object remove(final Object key) {
+       return put(key, DESTROYED, true);
+     }
+ 
+     @Override
+     public Object put(final Object key, final Object value) {
+       return put(key, value, true);
+     }
+ 
+     public Object put(final Object key, final Object value,
+         boolean sendIdentityRequestMessage) {
+       if (cleared) {
+         cleared = false;
+       }
+ 
+       if (key == null) {
+         throw new NullPointerException(LocalizedStrings.PartitionedRegion_NULL_KEY_NOT_ALLOWED_FOR_PRIDTOPR_MAP.toLocalizedString());
+       }
+       if (value == null) {
+         throw new NullPointerException(LocalizedStrings.PartitionedRegion_NULL_VALUE_NOT_ALLOWED_FOR_PRIDTOPR_MAP.toLocalizedString());
+       }
+       Assert.assertTrue(key instanceof Integer);
+       if (sendIdentityRequestMessage)
+         IdentityRequestMessage.setLatestId(((Integer)key).intValue());
+       if ((super.get(key) == DESTROYED) && (value instanceof PartitionedRegion)) {
+         PartitionedRegionException pre = new PartitionedRegionException(LocalizedStrings.PartitionedRegion_CAN_NOT_REUSE_OLD_PARTITIONED_REGION_ID_0.toLocalizedString(key));
+         throw pre;
+       }
+       return super.put(key, value);
+     }
+ 
+     @Override
+     public void clear() {
+       this.cleared = true;
+       super.clear();
+     }
+ 
+     public synchronized String dump() {
+       StringBuffer b = new StringBuffer("prIdToPR Map@");
+       b.append(System.identityHashCode(prIdToPR)).append(":\n");
+       Map.Entry me;
+       for (Iterator i = prIdToPR.entrySet().iterator(); i.hasNext();) {
+         me = (Map.Entry)i.next();
+         b.append(me.getKey()).append("=>").append(me.getValue());
+         if (i.hasNext()) {
+           b.append("\n");
+         }
+       }
+       return b.toString();
+     }
+   }
+ 
+   private int partitionedRegionId = -3;
+ 
+   // final private Scope userScope;
+ 
+   /** Node description */
+   final private Node node;
+ 
+   /** Helper Object for redundancy Management of PartitionedRegion */
+   private final PRHARedundancyProvider redundancyProvider;
+ 
+   /**
+    * flag saying whether this VM needs cache operation notifications from other
+    * members
+    */
+   private boolean requiresNotification;
+ 
+   /**
+    * Latch that signals when the Bucket meta-data is ready to receive updates
+    */
+   private final StoppableCountDownLatch initializationLatchAfterBucketIntialization;
+ 
+   /**
+    * Constructor for a PartitionedRegion. This has an accessor (Region API)
+    * functionality and contains a datastore for actual storage. An accessor can
+    * act as a local cache by having a local storage enabled. A PartitionedRegion
+    * can be created by a factory method of RegionFactory.java and also by
+    * invoking Cache.createRegion(). (Cache.xml etc to be added)
+    * 
+    */
+ 
+   static public final String RETRY_TIMEOUT_PROPERTY = 
+       "gemfire.partitionedRegionRetryTimeout";
+   
+   private final PartitionRegionConfigValidator validator ;
+   
+   final List<FixedPartitionAttributesImpl> fixedPAttrs;
+   
+   private byte fixedPASet;
+   
+   public List<PartitionedRegion> colocatedByList= new CopyOnWriteArrayList<PartitionedRegion>();
+   
+   private final PartitionListener[] partitionListeners;
+ 
+   private boolean isShadowPR = false;
+   private boolean isShadowPRForHDFS = false;
+   
+   private AbstractGatewaySender parallelGatewaySender = null;
+   
+   private final ThreadLocal<Boolean> queryHDFS = new ThreadLocal<Boolean>() {
+     @Override
+     protected Boolean initialValue() {
+       return false;
+     }
+   };
+   
+   public PartitionedRegion(String regionname, RegionAttributes ra,
+       LocalRegion parentRegion, GemFireCacheImpl cache,
+       InternalRegionArguments internalRegionArgs) {
+     super(regionname, ra, parentRegion, cache, internalRegionArgs);
+ 
+     this.node = initializeNode();
+     this.prStats = new PartitionedRegionStats(cache.getDistributedSystem(), getFullPath());
+     this.regionIdentifier = getFullPath().replace('/', '#');
+ 
+     if (logger.isDebugEnabled()) {
+       logger.debug("Constructing Partitioned Region {}", regionname);
+     }
+ 
+     // By adding this disconnect listener we ensure that the pridmap is cleaned
+     // up upon
+     // distributed system disconnect even this (or other) PRs are destroyed
+     // (which prevents pridmap cleanup).
+     cache.getDistributedSystem().addDisconnectListener(dsPRIdCleanUpListener);
+     
+     // add an async queue for the region if the store name is not null. 
+     if (this.getHDFSStoreName() != null) {
+       String eventQueueName = getHDFSEventQueueName();
+       super.addAsyncEventQueueId(eventQueueName);
+     }
+ 
+     // this.userScope = ra.getScope();
+     this.partitionAttributes = ra.getPartitionAttributes();
+     this.localMaxMemory = this.partitionAttributes.getLocalMaxMemory();
+     this.retryTimeout = Integer.getInteger(RETRY_TIMEOUT_PROPERTY,
+         PartitionedRegionHelper.DEFAULT_TOTAL_WAIT_RETRY_ITERATION).intValue();
+     this.totalNumberOfBuckets = this.partitionAttributes.getTotalNumBuckets();
+     this.prStats.incTotalNumBuckets(this.totalNumberOfBuckets);
+     this.distAdvisor = RegionAdvisor.createRegionAdvisor(this); // Warning: potential early escape of instance
+     this.redundancyProvider = new PRHARedundancyProvider(this); // Warning:
+                                                                 // potential
+                                                                 // early escape
+                                                                 // instance
+ 
+     // localCacheEnabled = ra.getPartitionAttributes().isLocalCacheEnabled();
+     // This is to make sure that local-cache get and put works properly.
+     // getScope is overridden to return the correct scope.
+     // this.scope = Scope.LOCAL;
+     this.redundantCopies = ra.getPartitionAttributes().getRedundantCopies();
+     this.prStats.setConfiguredRedundantCopies(ra.getPartitionAttributes().getRedundantCopies());
+     this.prStats.setLocalMaxMemory(ra.getPartitionAttributes().getLocalMaxMemory() * 1024L * 1024);
+     
+     // No redundancy required for writes
+     this.minimumWriteRedundancy = Integer.getInteger(
+         "gemfire.mimimumPartitionedRegionWriteRedundancy", 0).intValue();
+     // No redundancy required for reads
+     this.minimumReadRedundancy = Integer.getInteger(
+         "gemfire.mimimumPartitionedRegionReadRedundancy", 0).intValue();
+ 
+     this.haveCacheLoader = ra.getCacheLoader() != null;
+ 
+     this.initializationLatchAfterBucketIntialization = new StoppableCountDownLatch(
+         this.getCancelCriterion(), 1);
+     
+     this.validator = new PartitionRegionConfigValidator(this);
+     this.partitionListeners = this.partitionAttributes.getPartitionListeners(); 
+ 
+     this.colocatedWithRegion = ColocationHelper.getColocatedRegion(this);
+     if (colocatedWithRegion != null) {
+       //In colocation chain, child region inherita the fixed partitin attributes from parent region.
+       this.fixedPAttrs = colocatedWithRegion.getFixedPartitionAttributesImpl();
+       this.fixedPASet = colocatedWithRegion.fixedPASet;
+       synchronized (colocatedWithRegion.colocatedByList) {
+         colocatedWithRegion.colocatedByList.add(this);
+       }
+     }
+     else {
+       this.fixedPAttrs = this.partitionAttributes.getFixedPartitionAttributes();
+       this.fixedPASet = 0;
+     }
+     if (logger.isDebugEnabled()) {
+       logger.debug("Partitioned Region {} constructed {}", regionname, (this.haveCacheLoader ? "with a cache loader" : ""));
+     }
+     if (this.getEvictionAttributes() != null
+         && this.getEvictionAttributes().getAlgorithm().isLRUHeap()) {
+       this.sortedBuckets = new ArrayList<BucketRegion>();
+       final ThreadGroup grp = LoggingThreadGroup.createThreadGroup("BucketSorterThread", logger);
+       ThreadFactory tf = new ThreadFactory() {
+         public Thread newThread(Runnable r) {
+           Thread t = new Thread(grp, r, "BucketSorterThread");
+           t.setDaemon(true);
+           return t;
+         }
+       };
+       this.bucketSorter = Executors.newScheduledThreadPool(1, tf);
+     }
+     // If eviction is on, Create an instance of PartitionedRegionLRUStatistics
+     if ((this.getEvictionAttributes() != null
+         && !this.getEvictionAttributes().getAlgorithm().isNone()
+         && this.getEvictionAttributes().getAction().isOverflowToDisk())
+         || this.getDataPolicy().withPersistence()) {
+       StatisticsFactory sf = this.getCache().getDistributedSystem();
+       this.diskRegionStats = new DiskRegionStats(sf, getFullPath());
+     } else {
+       this.diskRegionStats = null;
+     }
+     if (internalRegionArgs.isUsedForParallelGatewaySenderQueue()) {
+       this.isShadowPR = true;
+       this.parallelGatewaySender = internalRegionArgs.getParallelGatewaySender();
+       if (internalRegionArgs.isUsedForHDFSParallelGatewaySenderQueue())
+         this.isShadowPRForHDFS = true;
+     }
+     
+     
+     /*
+      * Start persistent profile logging if we are a persistent region.
+      */
+     if(dataPolicy.withPersistence()) {
+       startPersistenceProfileLogging();      
+     }
+   }
+ 
+   /**
+    * Monitors when other members that participate in this persistent region are removed and creates
+    * a log entry marking the event.
+    */
+   private void startPersistenceProfileLogging() {
+     this.distAdvisor.addProfileChangeListener(new ProfileListener() {
+       @Override
+       public void profileCreated(Profile profile) {
+       }
+ 
+       @Override
+       public void profileUpdated(Profile profile) {
+       }
+       
+       @Override
+       public void profileRemoved(Profile profile, boolean destroyed) {
+         /*
+          * Don't bother logging membership activity if our region isn't ready.
+          */
+         if(isInitialized()) {
+           CacheProfile cacheProfile = ((profile instanceof CacheProfile) ? (CacheProfile) profile : null);
+           Set<String> onlineMembers = new HashSet<String>();
+ 
+           TransformUtils.transform(PartitionedRegion.this.distAdvisor.advisePersistentMembers().values(),onlineMembers,TransformUtils.persistentMemberIdToLogEntryTransformer);
+ 
+           logger.info(LocalizedMessage.create(LocalizedStrings.PersistenceAdvisorImpl_PERSISTENT_VIEW,
+               new Object[] {PartitionedRegion.this.getName(),TransformUtils.persistentMemberIdToLogEntryTransformer.transform(cacheProfile.persistentID),onlineMembers}));                          
+         }
+       }      
+     });
+   }
+ 
+   @Override
+   public final boolean isHDFSRegion() {
+     return this.getHDFSStoreName() != null;
+   }
+ 
+   @Override
+   public final boolean isHDFSReadWriteRegion() {
+     return isHDFSRegion() && !getHDFSWriteOnly();
+   }
+ 
+   @Override
+   protected final boolean isHDFSWriteOnly() {
+     return isHDFSRegion() && getHDFSWriteOnly();
+   }
+ 
+   public final void setQueryHDFS(boolean includeHDFS) {
+     queryHDFS.set(includeHDFS);
+   }
+ 
+   @Override
+   public final boolean includeHDFSResults() {
+     return queryHDFS.get();
+   }
+ 
+   public final boolean isShadowPR() {
+     return isShadowPR;
+   }
+ 
+   public final boolean isShadowPRForHDFS() {
+     return isShadowPRForHDFS;
+   }
+   
+   public AbstractGatewaySender getParallelGatewaySender() {
+     return parallelGatewaySender;
+   }
+   
+   public Set<String> getParallelGatewaySenderIds() {
+     Set<String> regionGatewaySenderIds = this.getAllGatewaySenderIds();
+     if (regionGatewaySenderIds.isEmpty()) {
+       return Collections.EMPTY_SET;
+     }
+     Set<GatewaySender> cacheGatewaySenders = getCache().getAllGatewaySenders();
+     Set<String> parallelGatewaySenderIds = new HashSet<String>();
+     for (GatewaySender sender : cacheGatewaySenders) {
+       if (regionGatewaySenderIds.contains(sender.getId())
+           && sender.isParallel()) {
+         parallelGatewaySenderIds.add(sender.getId());
+       }
+     }
+     return parallelGatewaySenderIds;
+   }
+   
+   List<PartitionedRegion> getColocatedByList() {
+ 	return this.colocatedByList;
+   }
+ 
+   public boolean isColocatedBy() {
+     return !this.colocatedByList.isEmpty();
+   } 
+ 
+   private void createAndValidatePersistentConfig() {
+     DiskStoreImpl dsi = this.getDiskStore();
+     if (this.dataPolicy.withPersistence() && !this.concurrencyChecksEnabled
+         && supportsConcurrencyChecks()) {
+       logger.info(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_ENABLING_CONCURRENCY_CHECKS_FOR_PERSISTENT_PR, this.getFullPath()));
+       this.concurrencyChecksEnabled = true;
+     }
+     if (dsi != null && this.getDataPolicy().withPersistence()) {
+       String colocatedWith = colocatedWithRegion == null 
+           ? "" : colocatedWithRegion.getFullPath(); 
+       PRPersistentConfig config = dsi.getPersistentPRConfig(this.getFullPath());
+       if(config != null) {
+         if (config.getTotalNumBuckets() != this.getTotalNumberOfBuckets()) {
+           Object[] prms = new Object[] { this.getFullPath(), this.getTotalNumberOfBuckets(),
+               config.getTotalNumBuckets() };
+           IllegalStateException ise = new IllegalStateException(
+               LocalizedStrings.PartitionedRegion_FOR_REGION_0_TotalBucketNum_1_SHOULD_NOT_BE_CHANGED_Previous_Configured_2.toString(prms));
+           throw ise;
+         }
+         //Make sure we don't change to be colocated with a different region
+         //We also can't change from colocated to not colocated without writing
+         //a record to disk, so we won't allow that right now either.
+         if (!colocatedWith.equals(config.getColocatedWith())) {
+           Object[] prms = new Object[] { this.getFullPath(), colocatedWith,
+               config.getColocatedWith() };
+           DiskAccessException dae = new DiskAccessException(LocalizedStrings.LocalRegion_A_DISKACCESSEXCEPTION_HAS_OCCURED_WHILE_WRITING_TO_THE_DISK_FOR_REGION_0_THE_REGION_WILL_BE_CLOSED.toLocalizedString(this.getFullPath()), null, dsi);
+           dsi.handleDiskAccessException(dae);
+           IllegalStateException ise = new IllegalStateException(
+               LocalizedStrings.PartitionedRegion_FOR_REGION_0_ColocatedWith_1_SHOULD_NOT_BE_CHANGED_Previous_Configured_2.toString(prms));
+           throw ise;
+         }
+       } else {
+         
+         config= new PRPersistentConfig(this.getTotalNumberOfBuckets(), 
+             colocatedWith);
+         dsi.addPersistentPR(this.getFullPath(), config);
+         //Fix for support issue 7870 - the parent region needs to be able
+         //to discover that there is a persistent colocated child region. So
+         //if this is a child region, persist its config to the parent disk store
+         //as well.
+         if(colocatedWithRegion != null 
+             && colocatedWithRegion.getDiskStore() != null
+             && colocatedWithRegion.getDiskStore() != dsi) {
+           colocatedWithRegion.getDiskStore().addPersistentPR(this.getFullPath(), config);
+         }
+       }
+       
+     }
+   }
+   
+   /**
+    * Initializes the PartitionedRegion meta data, adding this Node and starting
+    * the service on this node (if not already started).
+    * Made this synchronized for bug 41982
+    * @return true if initialize was done; false if not because it was destroyed
+    */
+   private synchronized boolean initPRInternals(InternalRegionArguments internalRegionArgs) {
+     
+     if (this.isLocallyDestroyed) {
+       // don't initialize if we are already destroyed for bug 41982
+       return false;
+     }
+     /* Initialize the PartitionRegion */
+     if (cache.isCacheAtShutdownAll()) {
+       throw new CacheClosedException("Cache is shutting down");
+     }
+     validator.validateColocation();
+     
+     //Do this after the validation, to avoid creating a persistent config
+     //for an invalid PR.
+     createAndValidatePersistentConfig();
+     initializePartitionedRegion();
+     
+     /* set the total number of buckets */
+     // setTotalNumOfBuckets();
+     // If localMaxMemory is set to 0, do not initialize Data Store.
+     final boolean storesData = this.localMaxMemory > 0;
+     if (storesData) {
+       initializeDataStore(this.getAttributes());
+     }
+ 
+     // register this PartitionedRegion, Create a PartitionRegionConfig and bind
+     // it into the allPartitionedRegion system wide Region.
+     // IMPORTANT: do this before advising peers that we have this region
+     registerPartitionedRegion(storesData);
+     
+     getRegionAdvisor().initializeRegionAdvisor(); // must be BEFORE initializeRegion call
+     getRegionAdvisor().addMembershipListener(this.advisorListener); // fix for bug 38719
+ 
+     // 3rd part of eviction attributes validation, after eviction attributes
+     // have potentially been published (by the first VM) but before buckets are created
+     validator.validateEvictionAttributesAgainstLocalMaxMemory();
+     validator.validateFixedPartitionAttributes();
+ 
+     // Register with the other Nodes that have this region defined, this
+     // allows for an Advisor profile exchange, also notifies the Admin
+     // callbacks that this Region is created.
+     try {
+       new CreateRegionProcessor(this).initializeRegion();
+     } catch (IllegalStateException e) {
+       // If this is a PARTITION_PROXY then retry region creation
+       // after toggling the concurrencyChecksEnabled flag. This is
+       // required because for persistent regions, we enforce concurrencyChecks
+       if (!this.isDataStore() && supportsConcurrencyChecks()) {
+         this.concurrencyChecksEnabled = !this.concurrencyChecksEnabled;
+         new CreateRegionProcessor(this).initializeRegion();
+       } else {
+         throw e;
+       }
+     }
+ 
+     if (!this.isDestroyed && !this.isLocallyDestroyed) {
+       // Register at this point so that other members are known
+       this.cache.getResourceManager().addResourceListener(ResourceType.MEMORY, this);
+     }
+     
+     // Create OQL indexes before starting GII.
+     createOQLIndexes(internalRegionArgs);
+     
+     // if any other services are dependent on notifications from this region,
+     // then we need to make sure that in-process ops are distributed before
+     // releasing the GII latches
+     if (this.isAllEvents()) {
+       StateFlushOperation sfo = new StateFlushOperation(getDistributionManager());
+       try {
+         sfo.flush(this.distAdvisor.adviseAllPRNodes(),
+           getDistributionManager().getId(),
+           DistributionManager.HIGH_PRIORITY_EXECUTOR, false);
+       } catch (InterruptedException ie) {
+         Thread.currentThread().interrupt();
+         getCancelCriterion().checkCancelInProgress(ie);
+       }
+     }
+ 
+     releaseBeforeGetInitialImageLatch(); // moved to this spot for bug 36671
+ 
+     // requires prid assignment mthomas 4/3/2007
+     getRegionAdvisor().processProfilesQueuedDuringInitialization(); 
+ 
+     releaseAfterBucketMetadataSetupLatch();
+         
+     try {
+       if(storesData) {
+         if(this.redundancyProvider.recoverPersistentBuckets()) {
+           //Mark members as recovered from disk recursively, starting
+           //with the leader region.
+           PartitionedRegion leaderRegion = ColocationHelper.getLeaderRegion(this);
+           markRecoveredRecursively(leaderRegion);
+         }
+       }
+     }
+     catch (RegionDestroyedException rde) {
+       // Do nothing.
+       if (logger.isDebugEnabled()) {
+         logger.debug("initPRInternals: failed due to exception", rde);
+       }
+     }
+ 
+     releaseAfterGetInitialImageLatch();
+ 
+     try {
+       if(storesData) {
+         this.redundancyProvider.scheduleCreateMissingBuckets();
+ 
+         if (this.redundantCopies > 0) {
+           this.redundancyProvider.startRedundancyRecovery();
+         }
+       }
+     }
+     catch (RegionDestroyedException rde) {
+       // Do nothing.
+       if (logger.isDebugEnabled()) {
+         logger.debug("initPRInternals: failed due to exception", rde);
+       }
+     }
+ 
+     return true;
+   }
+   
+   private void markRecoveredRecursively(PartitionedRegion region) {
+     region.setRecoveredFromDisk();
+     for(PartitionedRegion colocatedRegion : ColocationHelper.getColocatedChildRegions(region)) {
+       markRecoveredRecursively(colocatedRegion);
+     }
+   }
+ 
+   @Override
+   protected void postCreateRegion() {
+     super.postCreateRegion();
+     CacheListener[] listeners = fetchCacheListenersField();
+     if (listeners != null && listeners.length > 0) {
+       Set others = getRegionAdvisor().adviseGeneric();
+       for (int i = 0; i < listeners.length; i++) {
+         if (listeners[i] instanceof RegionMembershipListener) {
+           RegionMembershipListener rml = (RegionMembershipListener)listeners[i];
+           try {
+             DistributedMember[] otherDms = new DistributedMember[others
+                 .size()];
+             others.toArray(otherDms);
+             rml.initialMembers(this, otherDms);
+           }
+           catch (VirtualMachineError err) {
+             SystemFailure.initiateFailure(err);
+             // If this ever returns, rethrow the error.  We're poisoned
+             // now, so don't let this thread continue.
+             throw err;
+           }
+           catch (Throwable t) {
+             // Whenever you catch Error or Throwable, you must also
+             // catch VirtualMachineError (see above).  However, there is
+             // _still_ a possibility that you are dealing with a cascading
+             // error condition, so you also need to check to see if the JVM
+             // is still usable:
+             SystemFailure.checkFailure();
+             logger.error(LocalizedMessage.create(LocalizedStrings.DistributedRegion_EXCEPTION_OCCURRED_IN_REGIONMEMBERSHIPLISTENER), t);
+           }
+         }
+       }
+     }
+     
+     PartitionListener[] partitionListeners = this.getPartitionListeners();
+     if (partitionListeners != null && partitionListeners.length != 0) {
+       for (int i = 0; i < partitionListeners.length; i++) {
+         PartitionListener listener = partitionListeners[i];
+         if (listener != null) {
+           listener.afterRegionCreate(this);
+         }
+       }     
+     }
+ 
+     Set<String> allGatewaySenderIds = getAllGatewaySenderIds();
+     if (!allGatewaySenderIds.isEmpty()) {
+       for (GatewaySender sender : cache.getAllGatewaySenders()) {
+         if (sender.isParallel()
+             && allGatewaySenderIds.contains(sender.getId())) {
+           /**
+            * get the ParallelGatewaySender to create the colocated partitioned
+            * region for this region.
+            */
+           if (sender.isRunning() ) {
+             AbstractGatewaySender senderImpl = (AbstractGatewaySender)sender;
+             ((ConcurrentParallelGatewaySenderQueue)senderImpl.getQueues().toArray(new RegionQueue[1])[0])
+                 .addShadowPartitionedRegionForUserPR(this);
+           }
+         }
+       }
+     }   
+   }
+ 
+   /*
+    * Initializes the PartitionedRegion. OVERRIDES
+    */
+   @Override
+   protected void initialize(InputStream snapshotInputStream,
+       InternalDistributedMember imageTarget,
+       InternalRegionArguments internalRegionArgs) throws TimeoutException,
+       ClassNotFoundException {
+     if (logger.isDebugEnabled()) {
+       logger.debug("PartitionedRegion#initialize {}", getName());
+     }
+     RegionLogger.logCreate(getName(), getDistributionManager().getDistributionManagerId());
+ 
+     this.requiresNotification = this.cache.requiresNotificationFromPR(this);
+     initPRInternals(internalRegionArgs);
+ 
+     if (logger.isDebugEnabled()) {
+       logger.debug("PartitionRegion#initialize: finished with {}", this);
+     }
+     this.cache.addPartitionedRegion(this);
+ 
+   }
+ 
+   /**
+    * Initializes the Node for this Map.
+    */
+   private Node initializeNode() {
+     return new Node(getDistributionManager().getId(),
+         SERIAL_NUMBER_GENERATOR.getAndIncrement());
+   }
+ 
+   /**
+    * receive notification that a bridge server or wan gateway has been created
+    * that requires notification of cache events from this region
+    */
+   public void cacheRequiresNotification() {
+     if (!this.requiresNotification
+         && !(this.isClosed || this.isLocallyDestroyed)) {
+       // tell others of the change in status
+       this.requiresNotification = true;
+       new UpdateAttributesProcessor(this).distribute(false);
+     }    
+   }
+   
+   @Override
+   void distributeUpdatedProfileOnHubCreation()
+   {
+     if (!(this.isClosed || this.isLocallyDestroyed)) {
+       // tell others of the change in status
+       this.requiresNotification = true;
+       new UpdateAttributesProcessor(this).distribute(false);      
+     }
+   }
+ 
+   @Override
+   void distributeUpdatedProfileOnSenderCreation()
+   {
+     if (!(this.isClosed || this.isLocallyDestroyed)) {
+       // tell others of the change in status
+       this.requiresNotification = true;
+       new UpdateAttributesProcessor(this).distribute(false);      
+     }
+   }
+   
+   public void addGatewaySenderId(String gatewaySenderId) {
+     super.addGatewaySenderId(gatewaySenderId);
+     new UpdateAttributesProcessor(this).distribute();
+     ((PartitionedRegion)this).distributeUpdatedProfileOnSenderCreation();
+     GatewaySender sender = getCache().getGatewaySender(gatewaySenderId);
+     if (sender!= null && sender.isParallel() && sender.isRunning()) {
+       AbstractGatewaySender senderImpl = (AbstractGatewaySender)sender;
+       ((ConcurrentParallelGatewaySenderQueue)senderImpl.getQueues().toArray(
+           new RegionQueue[1])[0]).addShadowPartitionedRegionForUserPR(this);
+     }
+   }
+   
+   public void removeGatewaySenderId(String gatewaySenderId){
+     super.removeGatewaySenderId(gatewaySenderId);
+     new UpdateAttributesProcessor(this).distribute();
+   }
+   
+   public void addAsyncEventQueueId(String asyncEventQueueId) {
+     super.addAsyncEventQueueId(asyncEventQueueId);
+     new UpdateAttributesProcessor(this).distribute();
+     ((PartitionedRegion)this).distributeUpdatedProfileOnSenderCreation();
+     GatewaySender sender = getCache().getGatewaySender(AsyncEventQueueImpl.getSenderIdFromAsyncEventQueueId(asyncEventQueueId));
+     if (sender!= null && sender.isParallel() && sender.isRunning()) {
+       AbstractGatewaySender senderImpl = (AbstractGatewaySender)sender;
+       ((ConcurrentParallelGatewaySenderQueue)senderImpl.getQueues().toArray(
+           new RegionQueue[1])[0]).addShadowPartitionedRegionForUserPR(this);
+     }
+   }
+   
+   public void removeAsyncEventQueueId(String asyncEventQueueId) {
+     super.removeAsyncEventQueueId(asyncEventQueueId);
+     new UpdateAttributesProcessor(this).distribute();
+   }
+   
+   public void checkSameSenderIdsAvailableOnAllNodes() {
+     List senderIds = this.getCacheDistributionAdvisor()
+         .adviseSameGatewaySenderIds(getGatewaySenderIds());
+     if (!senderIds.isEmpty()) {
+       throw new GatewaySenderConfigurationException(
+           LocalizedStrings.Region_REGION_0_HAS_1_GATEWAY_SENDER_IDS_ANOTHER_CACHE_HAS_THE_SAME_REGION_WITH_2_GATEWAY_SENDER_IDS_FOR_REGION_ACROSS_ALL_MEMBERS_IN_DS_GATEWAY_SENDER_IDS_SHOULD_BE_SAME
+               .toLocalizedString(new Object[] { this.getName(),
+                   senderIds.get(0), senderIds.get(1) }));
+     }
+ 
+     List asycnQueueIds = this.getCacheDistributionAdvisor()
+         .adviseSameAsyncEventQueueIds(getAsyncEventQueueIds());
+     if (!asycnQueueIds.isEmpty()) {
+       throw new GatewaySenderConfigurationException(
+           LocalizedStrings.Region_REGION_0_HAS_1_ASYNC_EVENT_QUEUE_IDS_ANOTHER_CACHE_HAS_THE_SAME_REGION_WITH_2_ASYNC_EVENT_QUEUE_IDS_FOR_REGION_ACROSS_ALL_MEMBERS_IN_DS_ASYNC_EVENT_QUEUE_IDS_SHOULD_BE_SAME
+               .toLocalizedString(new Object[] { this.getName(),
+                   asycnQueueIds.get(0), asycnQueueIds.get(1) }));
+     }
+   }
+   
+   /**
+    * Initializes the PartitionedRegion - create the Global regions for storing
+    * the PartitiotnedRegion configs.
+    */
+   private void initializePartitionedRegion() {
+     this.prRoot = PartitionedRegionHelper.getPRRoot(getCache());
+   }
+ 
+   @Override
+   public void remoteRegionInitialized(CacheProfile profile) {
+     if (isInitialized() && hasListener()) {
+       Object callback = DistributedRegion.TEST_HOOK_ADD_PROFILE? profile : null;
+       RegionEventImpl event = new RegionEventImpl(PartitionedRegion.this,
+           Operation.REGION_CREATE, callback, true, profile.peerMemberId);
+       dispatchListenerEvent(EnumListenerEvent.AFTER_REMOTE_REGION_CREATE,
+             event);
+     }
+   }
+ 
+   /**
+    * This method initializes the partitionedRegionDataStore for this PR.
+    * 
+    * @param ra
+    *                Region attributes
+    */
+   private void initializeDataStore(RegionAttributes ra) {
+ 
+     this.dataStore = PartitionedRegionDataStore.createDataStore(cache, this, ra
+         .getPartitionAttributes());
+   }
+ 
+   protected DistributedLockService getPartitionedRegionLockService() {
+     return getGemFireCache().getPartitionedRegionLockService();
+   }
+   
+   /**
+    * Register this PartitionedRegion by: 1) Create a PartitionRegionConfig and
+    * 2) Bind it into the allPartitionedRegion system wide Region.
+    * 
+    * @param storesData
+    *                which indicates whether the instance in this cache stores
+    *                data, effecting the Nodes PRType
+    * 
+    * @see Node#setPRType(int)
+    */
+   private void registerPartitionedRegion(boolean storesData) {
+     // Register this ParitionedRegion. First check if the ParitionedRegion
+     // entry already exists globally.
+     PartitionRegionConfig prConfig = null;
+     PartitionAttributes prAttribs = getAttributes().getPartitionAttributes();
+     if (storesData) {
+       if (this.fixedPAttrs != null) {
+         this.node.setPRType(Node.FIXED_PR_DATASTORE);
+       } else {
+         this.node.setPRType(Node.ACCESSOR_DATASTORE);
+       }
+       this.node.setPersistence(getAttributes().getDataPolicy() == DataPolicy.PERSISTENT_PARTITION);
+       byte loaderByte = (byte)(getAttributes().getCacheLoader() != null ? 0x01 : 0x00);
+       byte writerByte = (byte)(getAttributes().getCacheWriter() != null ? 0x02 : 0x00);
+       this.node.setLoaderWriterByte((byte)(loaderByte + writerByte));
+     }
+     else {
+       if (this.fixedPAttrs != null) {
+         this.node.setPRType(Node.FIXED_PR_ACCESSOR);
+       } else {
+         this.node.setPRType(Node.ACCESSOR);
+       }
+     }
+     final RegionLock rl = getRegionLock();
+     try {
+       // if (!rl.lock()) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("registerPartitionedRegion: obtaining lock");
+       }
+       rl.lock();
+       checkReadiness();
+       
+       prConfig = this.prRoot.get(getRegionIdentifier());
+       
+       if (prConfig == null) {
+         validateParalleGatewaySenderIds();
+         this.partitionedRegionId = generatePRId(getSystem());
+         prConfig = new PartitionRegionConfig(this.partitionedRegionId,
+             this.getFullPath(), prAttribs, this.getScope(),
+             getAttributes().getEvictionAttributes(), 
+             getAttributes().getRegionIdleTimeout(), 
+             getAttributes().getRegionTimeToLive(), 
+             getAttributes().getEntryIdleTimeout(),
+             getAttributes().getEntryTimeToLive(),
+             this.getAllGatewaySenderIds());
+         logger.info(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_PARTITIONED_REGION_0_IS_BORN_WITH_PRID_1_IDENT_2,
+               new Object[] { getFullPath(), Integer.valueOf(this.partitionedRegionId), getRegionIdentifier()}));
+ 
+         PRSanityCheckMessage.schedule(this);
+       }
+       else {
+         validator.validatePartitionAttrsFromPRConfig(prConfig);
+         if (storesData) {
+           validator.validatePersistentMatchBetweenDataStores(prConfig);
+           validator.validateCacheLoaderWriterBetweenDataStores(prConfig);
+           validator.validateFixedPABetweenDataStores(prConfig);
+         }
+         
+         this.partitionedRegionId = prConfig.getPRId();
+         logger.info(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_PARTITIONED_REGION_0_IS_CREATED_WITH_PRID_1,
+               new Object[] { getFullPath(), Integer.valueOf(this.partitionedRegionId)}));
+       }
+ 
+       synchronized (prIdToPR) {
+         prIdToPR.put(Integer.valueOf(this.partitionedRegionId), this); // last
+       }
+       prConfig.addNode(this.node);
+       if (this.getFixedPartitionAttributesImpl() != null) {
+         calculateStartingBucketIDs(prConfig);
+       }
+       updatePRConfig(prConfig, false);
+       /*
+        * try { if (this.redundantCopies > 0) { if (storesData) {
+        * this.dataStore.grabBackupBuckets(false); } } } catch
+        * (RegionDestroyedException rde) { if (!this.isClosed) throw rde; }
+        */
+       this.cleanPRRegistration = true;
+     }
+     catch (LockServiceDestroyedException lsde) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("registerPartitionedRegion: unable to obtain lock for {}", this);
+       }
+       cleanupFailedInitialization();
+       throw new PartitionedRegionException(
+           LocalizedStrings.PartitionedRegion_CAN_NOT_CREATE_PARTITIONEDREGION_FAILED_TO_ACQUIRE_REGIONLOCK
+               .toLocalizedString(), lsde);
+     }
+     catch (IllegalStateException ill) {
+       cleanupFailedInitialization();
+       throw ill;
+     }
+     catch (VirtualMachineError err) {
+       SystemFailure.initiateFailure(err);
+       // If this ever returns, rethrow the error.  We're poisoned
+       // now, so don't let this thread continue.
+       throw err;
+     }
+     catch (Throwable t) {
+       // Whenever you catch Error or Throwable, you must also
+       // catch VirtualMachineError (see above).  However, there is
+       // _still_ a possibility that you are dealing with a cascading
+       // error condition, so you also need to check to see if the JVM
+       // is still usable:
+       SystemFailure.checkFailure();
+       String registerErrMsg = 
+         LocalizedStrings.PartitionedRegion_AN_EXCEPTION_WAS_CAUGHT_WHILE_REGISTERING_PARTITIONEDREGION_0_DUMPPRID_1
+         .toLocalizedString(new Object[] {getFullPath(), prIdToPR.dump()});
+       try {
+         synchronized (prIdToPR) {
+           if (prIdToPR.containsKey(Integer.valueOf(this.partitionedRegionId))) {
+             prIdToPR.put(Integer.valueOf(this.partitionedRegionId),
+                 PRIdMap.FAILED_REGISTRATION, false);
+             logger.info(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_FAILED_REGISTRATION_PRID_0_NAMED_1,
+                   new Object[] {Integer.valueOf(this.partitionedRegionId), this.getName()}));
+           }
+         }
+       }
+       catch (VirtualMachineError err) {
+         SystemFailure.initiateFailure(err);
+         // If this ever returns, rethrow the error.  We're poisoned
+         // now, so don't let this thread continue.
+         throw err;
+       }
+       catch (Throwable ignore) {
+         // Whenever you catch Error or Throwable, you must also
+         // catch VirtualMachineError (see above).  However, there is
+         // _still_ a possibility that you are dealing with a cascading
+         // error condition, so you also need to check to see if the JVM
+         // is still usable:
+         SystemFailure.checkFailure();
+         if (logger.isDebugEnabled()) {
+           logger.debug("Partitioned Region creation, could not clean up after caught exception", ignore);
+         }
+       }
+       throw new PartitionedRegionException(registerErrMsg, t);
+     }
+     finally {
+       try {
+         rl.unlock();
+         if (logger.isDebugEnabled()) {
+           logger.debug("registerPartitionedRegion: released lock");
+         }
+       }
+       catch (Exception es) {
+         if (logger.isDebugEnabled()) {
+           logger.warn(es.getMessage(), es);
+         }
+       }
+     }
+   }
+ 
+   public void validateParalleGatewaySenderIds() throws PRLocallyDestroyedException{
+     for (String senderId : this.getParallelGatewaySenderIds()) {
+       for (PartitionRegionConfig config : this.prRoot.values()) {
+         if (config.getGatewaySenderIds().contains(senderId)) {
+           Map<String, PartitionedRegion> colocationMap = ColocationHelper
+               .getAllColocationRegions(this);
+           if (!colocationMap.isEmpty()) {
+             if (colocationMap.containsKey(config.getFullPath())) {
+               continue;
+             }
+             else {
+               int prID = config.getPRId();
+               PartitionedRegion colocatedPR = PartitionedRegion
+                   .getPRFromId(prID);
+               PartitionedRegion leader = ColocationHelper
+                   .getLeaderRegion(colocatedPR);
+               if (colocationMap.containsValue(leader)) {
+                 continue;
+               }
+               else {
+                 throw new IllegalStateException(
+                     LocalizedStrings.PartitionRegion_NON_COLOCATED_REGIONS_1_2_CANNOT_HAVE_SAME_PARALLEL_GATEWAY_SENDER_ID_2.toString(new Object[] {
+                         this.getFullPath(),
+                         config.getFullPath(),
+                         senderId.contains(AsyncEventQueueImpl.ASYNC_EVENT_QUEUE_PREFIX) ? "async event queue": "gateway sender",
+                         senderId }));
+               }
+             }
+           }
+           else {
+             throw new IllegalStateException(
+                 LocalizedStrings.PartitionRegion_NON_COLOCATED_REGIONS_1_2_CANNOT_HAVE_SAME_PARALLEL_GATEWAY_SENDER_ID_2.toString(new Object[] {
+                     this.getFullPath(),
+                     config.getFullPath(),
+                     senderId.contains(AsyncEventQueueImpl.ASYNC_EVENT_QUEUE_PREFIX) ? "async event queue": "gateway sender",
+                     senderId }));
+           }
+ 
+         }
+       }
+     }
+   }
+ 
+   /**
+    * @return whether this region requires event notification for all cache
+    *         content changes from other nodes
+    */
+   public boolean getRequiresNotification() {
+     return this.requiresNotification;
+   }
+ 
+   /**
+    * Get the Partitioned Region identifier used for DLocks (Bucket and Region)
+    */
+   final public String getRegionIdentifier() {
+     return this.regionIdentifier;
+   }
+   
+   void setRecoveredFromDisk() {
+     this.recoveredFromDisk = true;
+     new UpdateAttributesProcessor(this).distribute(false);
+   }
+ 
+   public final void updatePRConfig(PartitionRegionConfig prConfig,
+       boolean putOnlyIfUpdated) {
+     final Set<Node> nodes = prConfig.getNodes();
+     final PartitionedRegion colocatedRegion = ColocationHelper
+         .getColocatedRegion(this);
+     RegionLock colocatedLock = null;
+     boolean colocatedLockAcquired = false;
+     try {
+       boolean colocationComplete = false;
+       if (colocatedRegion != null && !prConfig.isColocationComplete() &&
+         // if the current node is marked uninitialized (SQLF DDL replay in
+         // progress) then colocation will definitely not be marked complete so
+         // avoid taking the expensive region lock
+           !getCache().isUnInitializedMember(getDistributionManager().getId())) {
+         colocatedLock = colocatedRegion.getRegionLock();
+         colocatedLock.lock();
+         colocatedLockAcquired = true;
+         final PartitionRegionConfig parentConf = this.prRoot
+             .get(colocatedRegion.getRegionIdentifier());
+         if (parentConf.isColocationComplete()
+             && parentConf.hasSameDataStoreMembers(prConfig)) {
+           colocationComplete = true;
+           // check if all the nodes have been initialized (SQLF bug #42089)
+           for (Node node : nodes) {
+             if (getCache().isUnInitializedMember(node.getMemberId())) {
+               colocationComplete = false;
+               break;
+             }
+           }
+           if (colocationComplete) {
+             prConfig.setColocationComplete();
+           }
+         }
+       }
+ 
+       if(isDataStore() && !prConfig.isFirstDataStoreCreated()) {
+         prConfig.setDatastoreCreated(getEvictionAttributes());
+       }
+       // N.B.: this put could fail with a CacheClosedException:
+       if (!putOnlyIfUpdated || colocationComplete) {
+         this.prRoot.put(getRegionIdentifier(), prConfig);
+       }
+     } finally {
+       if (colocatedLockAcquired) {
+         colocatedLock.unlock();
+       }
+     }
+   }
+ 
+   /**
+    * 
+    * @param keyInfo
+    * @param access
+    *          true if caller wants last accessed time updated
+    * @param allowTombstones - whether a tombstone can be returned
+    * @return TODO
+    */
+   @Override
+   protected Region.Entry<?, ?> nonTXGetEntry(KeyInfo keyInfo, boolean access, boolean allowTombstones) {
+     final long startTime = PartitionedRegionStats.startTime();
+     final Object key = keyInfo.getKey();
+     try {
+       int bucketId = keyInfo.getBucketId();
+       if (bucketId == KeyInfo.UNKNOWN_BUCKET) {
+         bucketId = PartitionedRegionHelper.getHashKey(this,
+             Operation.GET_ENTRY, key, null, null);
+         keyInfo.setBucketId(bucketId);
+       }
+       InternalDistributedMember targetNode = getOrCreateNodeForBucketRead(bucketId);
+       return getEntryInBucket(targetNode, bucketId, key, access, allowTombstones);
+     }
+     finally {
+       this.prStats.endGetEntry(startTime);
+     }
+   }
+ 
+   protected EntrySnapshot getEntryInBucket(
+       final DistributedMember targetNode, final int bucketId,
+       final Object key, boolean access, final boolean allowTombstones) {
+     final int retryAttempts = calcRetry();
+     if (logger.isTraceEnabled()) {
+       logger.trace("getEntryInBucket: " + "Key key={} ({}) from: {} bucketId={}",
+           key, key.hashCode(), targetNode, bucketStringForLogs(bucketId));
+     }
+     Integer bucketIdInt = Integer.valueOf(bucketId);
+     EntrySnapshot ret = null;
+     int count = 0;
+     RetryTimeKeeper retryTime = null;
+     InternalDistributedMember retryNode = (InternalDistributedMember)targetNode;
+     while (count <= retryAttempts) {
+       // Every continuation should check for DM cancellation
+       if (retryNode == null) {
+         checkReadiness();
+         if (retryTime == null) {
+           retryTime = new RetryTimeKeeper(this.retryTimeout);
+         }
+         if (retryTime.overMaximum()) {
+           break;
+         }
+         retryNode = getOrCreateNodeForBucketRead(bucketId);
+ 
+         // No storage found for bucket, early out preventing hot loop, bug 36819
+         if (retryNode == null) {
+           checkShutdown();
+           return null;
+         }
+         continue;
+       }
+       try {
+         final boolean loc = (this.localMaxMemory > 0) && retryNode.equals(getMyId());
+         if (loc) {
+           ret = this.dataStore.getEntryLocally(bucketId, key, access, allowTombstones, true);
+         } else {
+           ret = getEntryRemotely(retryNode, bucketIdInt, key, access, allowTombstones);
+           // TODO:Suranjan&Yogesh : there should be better way than this one
+           String name = Thread.currentThread().getName();
+           if (name.startsWith("ServerConnection")
+               && !getMyId().equals(targetNode)) {
+             setNetworkHop(bucketIdInt, (InternalDistributedMember)targetNode);
+           }
+         }
+         
+         return ret;
+       }
+       catch (PRLocallyDestroyedException pde) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("getEntryInBucket: Encountered PRLocallyDestroyedException ");
+         }
+         checkReadiness();
+       }
+       catch (EntryNotFoundException enfe) {
+         return null;
+       }
+       catch (ForceReattemptException prce) {
+         prce.checkKey(key);
+         if (logger.isDebugEnabled()) {
+           logger.debug("getEntryInBucket: retrying, attempts so far: {}", count, prce);
+         }
+         checkReadiness();
+         InternalDistributedMember lastNode = retryNode;
+         retryNode = getOrCreateNodeForBucketRead(bucketIdInt.intValue());
+         if (lastNode.equals(retryNode)) {
+           if (retryTime == null) {
+             retryTime = new RetryTimeKeeper(this.retryTimeout);
+           }
+           if (retryTime.overMaximum()) {
+             break;
+           }
+           retryTime.waitToRetryNode();
+         }
+       }
+       catch (PrimaryBucketException notPrimary) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("Bucket {} on Node {} not primary", notPrimary.getLocalizedMessage(), retryNode);
+         }
+         getRegionAdvisor().notPrimary(bucketIdInt.intValue(), retryNode);
+         retryNode = getOrCreateNodeForBucketRead(bucketIdInt.intValue());
+       }
+ 
+       // It's possible this is a GemFire thread e.g. ServerConnection
+       // which got to this point because of a distributed system shutdown or
+       // region closure which uses interrupt to break any sleep() or wait()
+       // calls
+       // e.g. waitForPrimary
+       checkShutdown();
+ 
+       count++;
+       if (count == 1) {
+         this.prStats.incContainsKeyValueOpsRetried();
+       }
+       this.prStats.incContainsKeyValueRetries();
+ 
+     }
+ 
+     PartitionedRegionDistributionException e = null; // Fix for bug 36014
+     if (logger.isDebugEnabled()) {
+       e = new PartitionedRegionDistributionException(LocalizedStrings.PartitionRegion_NO_VM_AVAILABLE_FOR_GETENTRY_IN_0_ATTEMPTS.toLocalizedString(Integer.valueOf(count)));
+     }
+     logger.warn(LocalizedMessage.create(LocalizedStrings.PartitionRegion_NO_VM_AVAILABLE_FOR_GETENTRY_IN_0_ATTEMPTS, Integer.valueOf(count)), e);
+     return null;
+   }
+ 
+   /**
+    * Check for region closure, region destruction, cache closure as well as
+    * distributed system disconnect. As of 6/21/2007, there were at least four
+    * volatile variables reads and one synchonrization performed upon completion
+    * of this method.
+    */
+   private void checkShutdown() {
+     checkReadiness();
+     this.cache.getCancelCriterion().checkCancelInProgress(null);
+   }
+ 
+   /**
+    * Checks if a key is contained remotely.
+    * 
+    * @param targetNode
+    *          the node where bucket region for the key exists.
+    * @param bucketId
+    *          the bucket id for the key.
+    * @param key
+    *          the key, whose value needs to be checks
+    * @param access
+    *          true if caller wants last access time updated
+    * @param allowTombstones whether tombstones should be returned
+    * @throws EntryNotFoundException
+    *           if the entry doesn't exist
+    * @throws ForceReattemptException
+    *           if the peer is no longer available
+    * @throws PrimaryBucketException
+    * @return true if the passed key is contained remotely.
+    */
+   public EntrySnapshot getEntryRemotely(
+       InternalDistributedMember targetNode,
+       Integer bucketId, Object key, boolean access, boolean allowTombstones)
+       throws EntryNotFoundException, PrimaryBucketException,
+       ForceReattemptException {
+     FetchEntryResponse r = FetchEntryMessage
+         .send(targetNode, this, key, access);
+     this.prStats.incPartitionMessagesSent();
+     EntrySnapshot entry = r.waitForResponse();
+     if (entry != null && entry.getRawValue() == Token.TOMBSTONE){
+       if (!allowTombstones) {
+         return null;
+   }
+     }
+     return entry;
+   }
+ 
+   // /////////////////////////////////////////////////////////////////
+   // Following methods would throw, operation Not Supported Exception
+   // /////////////////////////////////////////////////////////////////
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public void becomeLockGrantor() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   final public Region createSubregion(String subregionName,
+       RegionAttributes regionAttributes) throws RegionExistsException,
+       TimeoutException {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public Lock getDistributedLock(Object key) throws IllegalStateException {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public CacheStatistics getStatistics() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   public Region getSubregion() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public Lock getRegionDistributedLock() throws IllegalStateException {
+ 
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public void loadSnapshot(InputStream inputStream) throws IOException,
+       ClassNotFoundException, CacheWriterException, TimeoutException {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * Should it destroy entry from local accessor????? 
+    * OVERRIDES
+    */
+   @Override
+   public void localDestroy(Object key, Object aCallbackArgument)
+       throws EntryNotFoundException {
+ 
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public void localInvalidate(Object key, Object aCallbackArgument)
+       throws EntryNotFoundException {
+ 
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public void localInvalidateRegion(Object aCallbackArgument) {
+     getDataView().checkSupportsRegionInvalidate();
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * Executes a query on this PartitionedRegion. The restrictions have already
+    * been checked. The query is a SELECT expression, and the only region it
+    * refers to is this region.
+    * 
+    * @see DefaultQuery#execute()
+    * 
+    * @since 5.1
+    */
+   public Object executeQuery(DefaultQuery query, Object[] parameters,
+       Set buckets) throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+     for (;;) {
+       try {
+         return doExecuteQuery(query, parameters, buckets);
+       } catch (ForceReattemptException fre) {
+         // fall through and loop
+       }
+     }
+   }
+   /**
+    * If ForceReattemptException is thrown then the caller must loop and call us again.
+    * @throws ForceReattemptException if one of the buckets moved out from under us
+    */
+   private Object doExecuteQuery(DefaultQuery query, Object[] parameters,
+       Set buckets)
+   throws FunctionDomainException, TypeMismatchException,
+   NameResolutionException, QueryInvocationTargetException,
+   ForceReattemptException
+   {
+     if (logger.isDebugEnabled()) {
+       logger.debug("Executing query :{}", query);
+     }
+ 
+     HashSet<Integer> allBuckets = new HashSet<Integer>();
+     
+     if (buckets==null) { // remote buckets
+       final Iterator remoteIter = getRegionAdvisor().getBucketSet().iterator();
+       try {
+         while (remoteIter.hasNext()) {
+           allBuckets.add((Integer)remoteIter.next());
+         }
+       }
+       catch (NoSuchElementException stop) {
+       }
+     }
+     else { // local buckets
+       Iterator localIter = null;
+       if (this.dataStore != null) {
+         localIter = buckets.iterator();
+       }
+       else {
+         localIter = Collections.EMPTY_SET.iterator();
+       }
+       try {
+         while (localIter.hasNext()) {
+           allBuckets.add((Integer)localIter.next());        
+         }
+       }
+       catch (NoSuchElementException stop) {
+       }
+     }
+ 
+     if (allBuckets.size() == 0) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("No bucket storage allocated. PR has no data yet.");
+       }
+       ResultsSet resSet = new ResultsSet();
+       resSet.setElementType(new ObjectTypeImpl(
+           this.getValueConstraint() == null ? Object.class : this
+               .getValueConstraint()));
+       return resSet;
+     }
+ 
+     CompiledSelect selectExpr = query.getSimpleSelect();
+     if (selectExpr == null) {
+       throw new IllegalArgumentException(
+         LocalizedStrings.
+           PartitionedRegion_QUERY_MUST_BE_A_SELECT_EXPRESSION_ONLY
+             .toLocalizedString());
+     }    
+ 
+     // this can return a BAG even if it's a DISTINCT select expression,
+     // since the expectation is that the duplicates will be removed at the end
+     SelectResults results = selectExpr
+         .getEmptyResultSet(parameters, getCache(), query);
+ 
+     PartitionedRegionQueryEvaluator prqe = new PartitionedRegionQueryEvaluator(this.getSystem(), this, query,
+         parameters, results, allBuckets);
+     for (;;) {
+       this.getCancelCriterion().checkCancelInProgress(null);
+       boolean interrupted = Thread.interrupted();
+       try {
+         results = prqe.queryBuckets(null);
+         break;
+       }
+       catch (InterruptedException e) {
+         interrupted = true;
+       }
+       catch (FunctionDomainException e) {
+ 	throw e;
+       }
+       catch (TypeMismatchException e) {
+ 	throw e;
+       }
+       catch (NameResolutionException e) {
+ 	throw e;
+       }
+       catch (QueryInvocationTargetException e) {
+ 	throw e;
+       }
+       catch (QueryException qe) {
+         throw new QueryInvocationTargetException(LocalizedStrings.PartitionedRegion_UNEXPECTED_QUERY_EXCEPTION_OCCURED_DURING_QUERY_EXECUTION_0.toLocalizedString(qe.getMessage()), qe);
+       }
+       finally {
+         if (interrupted) {
+           Thread.currentThread().interrupt();
+         }
+       }
+     } // for
+ 
+     // Drop Duplicates if this is a DISTINCT query
+     boolean allowsDuplicates = results.getCollectionType().allowsDuplicates();
+     //Asif: No need to apply the limit to the SelectResults. 
+     // We know that even if we do not apply the limit,
+     //the results will satisfy the limit
+     // as it has been evaluated in the iteration of List to 
+     // populate the SelectsResuts     
+     //So if the results is instance of ResultsBag or is a StructSet or 
+     // a ResultsSet, if the limit exists, the data set size will 
+     // be exactly matching the limit
+     if (selectExpr.isDistinct()) {
+       // don't just convert to a ResultsSet (or StructSet), since
+       // the bags can convert themselves to a Set more efficiently
+       ObjectType elementType = results.getCollectionType().getElementType();
+       if (selectExpr.getOrderByAttrs() != null) {
+         // Set limit also, its not applied while building the final result set as order by is involved.
+        // results = new ResultsCollectionWrapper(elementType, results.asSet(), query.getLimit(parameters));
+       } else if (allowsDuplicates) {
+         results = new ResultsCollectionWrapper(elementType, results.asSet());
+       }
+       if (selectExpr.isCount() && (results.isEmpty() || selectExpr.isDistinct())) {
+         SelectResults resultCount = new ResultsBag(getCachePerfStats());//Constructor with elementType not visible.
+         resultCount.setElementType(new ObjectTypeImpl(Integer.class));
+         ((ResultsBag)resultCount).addAndGetOccurence(results.size());
+         return resultCount;
+       }
+     }
+     return results;
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public void saveSnapshot(OutputStream outputStream) throws IOException {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+   @Override
+   public void writeToDisk() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * @since 5.0
+    * @throws UnsupportedOperationException
+    * OVERRIDES
+    */
+  @Override
+  public void clear() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   @Override
+   void basicClear(RegionEventImpl regionEvent, boolean cacheWrite) {
+     throw new UnsupportedOperationException();
+   }
+ 
+   @Override
+   void basicLocalClear(RegionEventImpl event) {
+     throw new UnsupportedOperationException();
+   }
+ 
+   // /////////////////////////////////////////////////////////////////////
+   // ////////////// Operation Supported for this release
+   // //////////////////////////////
+   // /////////////////////////////////////////////////////////////////////
+ 
+   @Override
+   boolean virtualPut(EntryEventImpl event,
+                      boolean ifNew,
+                      boolean ifOld,
+                      Object expectedOldValue,
+                      boolean requireOldValue,
+                      long lastModified,
+                      boolean overwriteDestroyed)
+   throws TimeoutException, CacheWriterException {
+     final long startTime = PartitionedRegionStats.startTime();
+     boolean result = false;
+     final DistributedPutAllOperation putAllOp_save = event.setPutAllOperation(null);
+     
+     if (event.getEventId() == null) {
+       event.setNewEventId(this.cache.getDistributedSystem());
+     }
+     boolean bucketStorageAssigned = true;
+     try {
+       final Integer bucketId = event.getKeyInfo().getBucketId();
+       assert bucketId != KeyInfo.UNKNOWN_BUCKET;
+       // check in bucket2Node region
+       InternalDistributedMember targetNode = getNodeForBucketWrite(bucketId
+           .intValue(), null);
+       // force all values to be serialized early to make size computation cheap
+       // and to optimize distribution.
+       if (logger.isDebugEnabled()) {
+         logger.debug("PR.virtualPut putting event={}", event);
+       }
+ 
+       if (targetNode == null) {
+         try {
+           bucketStorageAssigned=false;
+           // if this is a Delta update, then throw exception since the key doesn't
+           // exist if there is no bucket for it yet
+           // For HDFS region, we will recover key, so allow bucket creation
+           if (!this.dataPolicy.withHDFS() && event.hasDelta()) {
+             throw new EntryNotFoundException(LocalizedStrings.
+               PartitionedRegion_CANNOT_APPLY_A_DELTA_WITHOUT_EXISTING_ENTRY
+                 .toLocalizedString());
+           }
+           targetNode = createBucket(bucketId.intValue(), event.getNewValSizeForPR(),
+               null);
+         }
+         catch (PartitionedRegionStorageException e) {
+           // try not to throw a PRSE if the cache is closing or this region was
+           // destroyed during createBucket() (bug 36574)
+           this.checkReadiness();
+           if (this.cache.isClosed()) {
+             throw new RegionDestroyedException(toString(), getFullPath());
+           }
+           throw e;
+         }
+       }
+ 
+       if (event.isBridgeEvent() && bucketStorageAssigned) {
+         setNetworkHop(bucketId, targetNode);
+       }
+       if (putAllOp_save == null) {
+         result = putInBucket(targetNode,
+                            bucketId,
+                            event,
+                            ifNew,
+                            ifOld,
+                            expectedOldValue,

<TRUNCATED>


[038/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
index 3bd1e83,0000000..f3ba7a2
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
@@@ -1,1109 -1,0 +1,1116 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal.membership.gms.messenger;
 +
 +import static com.gemstone.gemfire.distributed.internal.membership.gms.GMSUtil.replaceStrings;
 +import static com.gemstone.gemfire.internal.DataSerializableFixedID.JOIN_REQUEST;
 +import static com.gemstone.gemfire.internal.DataSerializableFixedID.JOIN_RESPONSE;
 +
 +import java.io.BufferedReader;
 +import java.io.ByteArrayInputStream;
 +import java.io.DataInputStream;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.InputStreamReader;
 +import java.lang.reflect.Field;
 +import java.lang.reflect.InvocationTargetException;
 +import java.lang.reflect.Method;
 +import java.net.UnknownHostException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.atomic.AtomicLong;
 +
 +import org.apache.logging.log4j.Logger;
 +import org.jgroups.Address;
 +import org.jgroups.Event;
 +import org.jgroups.JChannel;
 +import org.jgroups.Message;
 +import org.jgroups.Message.Flag;
 +import org.jgroups.Message.TransientFlag;
 +import org.jgroups.ReceiverAdapter;
 +import org.jgroups.View;
 +import org.jgroups.ViewId;
 +import org.jgroups.conf.ClassConfigurator;
 +import org.jgroups.protocols.UDP;
 +import org.jgroups.protocols.pbcast.NAKACK2;
 +import org.jgroups.stack.IpAddress;
 +import org.jgroups.util.Digest;
 +import org.jgroups.util.UUID;
 +
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.ForcedDisconnectException;
 +import com.gemstone.gemfire.GemFireConfigException;
 +import com.gemstone.gemfire.GemFireIOException;
 +import com.gemstone.gemfire.SystemConnectException;
 +import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 +import com.gemstone.gemfire.distributed.DurableClientAttributes;
 +import com.gemstone.gemfire.distributed.internal.DMStats;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.distributed.internal.DistributionMessage;
++import com.gemstone.gemfire.distributed.internal.DistributionStats;
 +import com.gemstone.gemfire.distributed.internal.HighPriorityDistributionMessage;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.MemberAttributes;
 +import com.gemstone.gemfire.distributed.internal.membership.NetView;
 +import com.gemstone.gemfire.distributed.internal.membership.QuorumChecker;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.GMSMember;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.MessageHandler;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.Messenger;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.messages.JoinRequestMessage;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.messages.JoinResponseMessage;
 +import com.gemstone.gemfire.internal.ClassPathLoader;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.OSProcess;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.VersionedDataInputStream;
 +import com.gemstone.gemfire.internal.admin.remote.RemoteTransportConfig;
 +import com.gemstone.gemfire.internal.cache.DirectReplyMessage;
 +import com.gemstone.gemfire.internal.cache.DistributedCacheOperation;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.tcp.MemberShunnedException;
 +
 +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 +
 +public class JGroupsMessenger implements Messenger {
 +
 +  private static final Logger logger = Services.getLogger();
 +
 +  /**
 +   * The location (in the product) of the locator Jgroups config file.
 +   */
 +  private static final String DEFAULT_JGROUPS_TCP_CONFIG = "com/gemstone/gemfire/distributed/internal/membership/gms/messenger/jgroups-config.xml";
 +
 +  /**
 +   * The location (in the product) of the mcast Jgroups config file.
 +   */
 +  private static final String JGROUPS_MCAST_CONFIG_FILE_NAME = "com/gemstone/gemfire/distributed/internal/membership/gms/messenger/jgroups-mcast.xml";
 +
 +  /** JG magic numbers for types added to the JG ClassConfigurator */
 +  public static final short JGROUPS_TYPE_JGADDRESS = 2000;
 +  public static final short JGROUPS_PROTOCOL_TRANSPORT = 1000;
 +
 +  public static boolean THROW_EXCEPTION_ON_START_HOOK;
 +
 +  String jgStackConfig;
 +  
 +  JChannel myChannel;
 +  InternalDistributedMember localAddress;
 +  JGAddress jgAddress;
 +  Services services;
 +
 +  /** handlers that receive certain classes of messages instead of the Manager */
 +  Map<Class, MessageHandler> handlers = new ConcurrentHashMap<Class, MessageHandler>();
 +  
 +  private volatile NetView view;
 +
 +  private GMSPingPonger pingPonger = new GMSPingPonger();
 +  
 +  protected AtomicLong pongsReceived = new AtomicLong(0);
 +  
 +  /**
 +   * A set that contains addresses that we have logged JGroups IOExceptions for in the
 +   * current membership view and possibly initiated suspect processing.  This
 +   * reduces the amount of suspect processing initiated by IOExceptions and the
 +   * amount of exceptions logged
 +   */
 +  private Set<Address> addressesWithioExceptionsProcessed = Collections.synchronizedSet(new HashSet<Address>());
 +  
 +  static {
 +    // register classes that we've added to jgroups that are put on the wire
 +    // or need a header ID
 +    ClassConfigurator.add(JGROUPS_TYPE_JGADDRESS, JGAddress.class);
 +    ClassConfigurator.addProtocol(JGROUPS_PROTOCOL_TRANSPORT, Transport.class);
 +  }
 +
 +  @Override
 +  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
 +  public void init(Services s) {
 +    this.services = s;
 +
 +    RemoteTransportConfig transport = services.getConfig().getTransport();
 +    DistributionConfig dc = services.getConfig().getDistributionConfig();
 +    
 +
 +    boolean b = dc.getEnableNetworkPartitionDetection();
 +    if (b) {
 +      if (!SocketCreator.FORCE_DNS_USE) {
 +        SocketCreator.resolve_dns = false;
 +      }
 +    }
 +    System.setProperty("jgroups.resolve_dns", String.valueOf(!b));
 +
 +    InputStream is= null;
 +
 +    String r = null;
 +    if (transport.isMcastEnabled()) {
 +      r = JGROUPS_MCAST_CONFIG_FILE_NAME;
 +    } else {
 +      r = DEFAULT_JGROUPS_TCP_CONFIG;
 +    }
 +    is = ClassPathLoader.getLatest().getResourceAsStream(getClass(), r);
 +    if (is == null) {
 +      throw new GemFireConfigException(LocalizedStrings.GroupMembershipService_CANNOT_FIND_0.toLocalizedString(r));
 +    }
 +
 +    String properties;
 +    try {
 +      //PlainConfigurator config = PlainConfigurator.getInstance(is);
 +      //properties = config.getProtocolStackString();
 +      StringBuffer sb = new StringBuffer(3000);
 +      BufferedReader br;
 +      br = new BufferedReader(new InputStreamReader(is, "US-ASCII"));
 +      String input;
 +      while ((input=br.readLine()) != null) {
 +        sb.append(input);
 +      }
 +      br.close();
 +      properties = sb.toString();
 +    }
 +    catch (Exception ex) {
 +      throw new GemFireConfigException(LocalizedStrings.GroupMembershipService_AN_EXCEPTION_WAS_THROWN_WHILE_READING_JGROUPS_CONFIG.toLocalizedString(), ex);
 +    }
 +    
 +    
 +    if (transport.isMcastEnabled()) {
 +      properties = replaceStrings(properties, "MCAST_PORT", String.valueOf(transport.getMcastId().getPort()));
 +      properties = replaceStrings(properties, "MCAST_ADDRESS", dc.getMcastAddress().getHostAddress());
 +      properties = replaceStrings(properties, "MCAST_TTL", String.valueOf(dc.getMcastTtl()));
 +      properties = replaceStrings(properties, "MCAST_SEND_BUFFER_SIZE", String.valueOf(dc.getMcastSendBufferSize()));
 +      properties = replaceStrings(properties, "MCAST_RECV_BUFFER_SIZE", String.valueOf(dc.getMcastRecvBufferSize()));
 +      properties = replaceStrings(properties, "MCAST_RETRANSMIT_INTERVAL", ""+Integer.getInteger("gemfire.mcast-retransmit-interval", 500));
 +      properties = replaceStrings(properties, "RETRANSMIT_LIMIT", String.valueOf(dc.getUdpFragmentSize()-256));
 +    }
 +
 +    if (transport.isMcastEnabled() || transport.isTcpDisabled() ||
 +        (dc.getUdpRecvBufferSize() != DistributionConfig.DEFAULT_UDP_RECV_BUFFER_SIZE) ) {
 +      properties = replaceStrings(properties, "UDP_RECV_BUFFER_SIZE", ""+dc.getUdpRecvBufferSize());
 +    }
 +    else {
 +      properties = replaceStrings(properties, "UDP_RECV_BUFFER_SIZE", ""+DistributionConfig.DEFAULT_UDP_RECV_BUFFER_SIZE_REDUCED);
 +    }
 +    properties = replaceStrings(properties, "UDP_SEND_BUFFER_SIZE", ""+dc.getUdpSendBufferSize());
 +
 +    String str = transport.getBindAddress();
 +    // JGroups UDP protocol requires a bind address
 +    if (str == null || str.length() == 0) {
 +      try {
 +        str = SocketCreator.getLocalHost().getHostAddress();
 +      } catch (UnknownHostException e) {
 +        throw new GemFireConfigException(e.getMessage(), e);
 +      }
 +    }
 +    properties = replaceStrings(properties, "BIND_ADDR_SETTING", "bind_addr=\""+str+"\"");
 +
 +    int port = Integer.getInteger("gemfire.jg-bind-port", 0);
 +    if (port != 0) {
 +      properties = replaceStrings(properties, "MEMBERSHIP_PORT_RANGE_START", ""+port);
 +    } else {
 +      int[] ports = dc.getMembershipPortRange();
 +      properties = replaceStrings(properties, "MEMBERSHIP_PORT_RANGE_START", ""+ports[0]);
 +      properties = replaceStrings(properties, "MEMBERSHIP_PORT_RANGE_END", ""+(ports[1]-ports[0]));
 +    }
 +    
 +    properties = replaceStrings(properties, "UDP_FRAGMENT_SIZE", ""+dc.getUdpFragmentSize());
 +    
 +    properties = replaceStrings(properties, "FC_MAX_CREDITS", ""+dc.getMcastFlowControl().getByteAllowance());
 +    properties = replaceStrings(properties, "FC_THRESHOLD", ""+dc.getMcastFlowControl().getRechargeThreshold());
 +    properties = replaceStrings(properties, "FC_MAX_BLOCK", ""+dc.getMcastFlowControl().getRechargeBlockMs());
 +
 +    this.jgStackConfig = properties;
 +    
 +  }
 +
 +  @Override
 +  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
 +  public void start() {
 +    // create the configuration XML string for JGroups
 +    String properties = this.jgStackConfig;
 +    
 +    long start = System.currentTimeMillis();
 +    
 +    // start the jgroups channel and establish the membership ID
 +    boolean reconnecting = false;
 +    try {
 +      Object oldChannel = services.getConfig().getTransport().getOldDSMembershipInfo();
 +      if (oldChannel != null) {
 +        logger.debug("Reusing JGroups channel from previous system", properties);
 +        
 +        myChannel = (JChannel)oldChannel;
 +        // scrub the old channel
 +        ViewId vid = new ViewId(new JGAddress(), 0);
 +        View jgv = new View(vid, new ArrayList<Address>());
 +        this.myChannel.down(new Event(Event.VIEW_CHANGE, jgv));
 +        UUID logicalAddress = (UUID)myChannel.getAddress();
 +        if (logicalAddress instanceof JGAddress) {
 +          ((JGAddress)logicalAddress).setVmViewId(-1);
 +        }
 +        reconnecting = true;
 +      }
 +      else {
 +        logger.debug("JGroups configuration: {}", properties);
 +        
 +        checkForIPv6();
 +        InputStream is = new ByteArrayInputStream(properties.getBytes("UTF-8"));
 +        myChannel = new JChannel(is);
 +      }
 +    } catch (Exception e) {
 +      throw new GemFireConfigException("unable to create jgroups channel", e);
 +    }
 +    
 +    // give the stats to the jchannel statistics recorder
 +    StatRecorder sr = (StatRecorder)myChannel.getProtocolStack().findProtocol(StatRecorder.class);
 +    if (sr != null) {
 +      sr.setDMStats(services.getStatistics());
 +    }
 +    
 +    Transport transport = (Transport)myChannel.getProtocolStack().getTransport();
 +    transport.setMessenger(this);
 +
 +    try {
 +      myChannel.setReceiver(null);
 +      myChannel.setReceiver(new JGroupsReceiver());
 +      if (!reconnecting) {
 +        myChannel.connect("AG"); // apache g***** (whatever we end up calling it)
 +      }
 +    } catch (Exception e) {
 +      myChannel.close();
 +      throw new SystemConnectException("unable to create jgroups channel", e);
 +    }
 +    
 +    if (JGroupsMessenger.THROW_EXCEPTION_ON_START_HOOK) {
 +      JGroupsMessenger.THROW_EXCEPTION_ON_START_HOOK = false;
 +      throw new SystemConnectException("failing for test");
 +    }
 +    
 +    establishLocalAddress();
 +    
 +    logger.info("JGroups channel {} (took {}ms)", (reconnecting? "reinitialized" : "created"), System.currentTimeMillis()-start);
 +    
 +  }
 +  
 +  /**
 +   * JGroups picks an IPv6 address if preferIPv4Stack is false or not set
 +   * and preferIPv6Addresses is not set or is true.  We want it to use an
 +   * IPv4 address for a dual-IP stack so that both IPv4 and IPv6 messaging work
 +   */
 +  private void checkForIPv6() throws Exception {
 +    boolean preferIpV6Addr = Boolean.getBoolean("java.net.preferIPv6Addresses");
 +    if (!preferIpV6Addr) {
 +      logger.debug("forcing JGroups to think IPv4 is being used so it will choose an IPv4 address");
 +      Field m = org.jgroups.util.Util.class.getDeclaredField("ip_stack_type");
 +      m.setAccessible(true);
 +      m.set(null, org.jgroups.util.StackType.IPv4);
 +    }
 +  }
 +
 +  @Override
 +  public void started() {
 +  }
 +
 +  @Override
 +  public void stop() {
 +    if (this.myChannel != null) {
 +      if ((services.isShutdownDueToForcedDisconnect() && services.isAutoReconnectEnabled()) || services.getManager().isReconnectingDS()) {
 +        // leave the channel open for reconnect attempts
 +      }
 +      else {
 +        this.myChannel.close();
 +      }
 +    }
 +  }
 +
 +  @Override
 +  public void stopped() {
 +  }
 +
 +  @Override
 +  public void memberSuspected(InternalDistributedMember initiator, InternalDistributedMember suspect, String reason) {
 +  }
 +
 +  @Override
 +  public void installView(NetView v) {
 +    this.view = v;
 +    
 +    if (this.jgAddress.getVmViewId() < 0) {
 +      this.jgAddress.setVmViewId(this.localAddress.getVmViewId());
 +    }
 +    List<JGAddress> mbrs = new ArrayList<JGAddress>(v.size());
 +    for (InternalDistributedMember idm: v.getMembers()) {
 +      mbrs.add(new JGAddress(idm));
 +    }
 +    ViewId vid = new ViewId(new JGAddress(v.getCoordinator()), v.getViewId());
 +    View jgv = new View(vid, new ArrayList<Address>(mbrs));
 +    logger.trace("installing JGroups view: {}", jgv);
 +    this.myChannel.down(new Event(Event.VIEW_CHANGE, jgv));
 +
 +    addressesWithioExceptionsProcessed.clear();
 +  }
 +  
 +
 +  /**
 +   * If JGroups is unable to send a message it may mean that the network
 +   * is down.  If so we need to initiate suspect processing on the
 +   * recipient.<p>
 +   * see Transport._send()
 +   */
 +  public void handleJGroupsIOException(IOException e, Address dest) {
 +    if (services.getManager().shutdownInProgress()) { // GEODE-634 - don't log IOExceptions during shutdown
 +      return;
 +    }
 +    if (addressesWithioExceptionsProcessed.contains(dest)) {
 +      return;
 +    }
 +    addressesWithioExceptionsProcessed.add(dest);
 +    NetView v = this.view;
 +    JGAddress jgMbr = (JGAddress)dest;
 +    if (jgMbr != null && v != null) {
 +      List<InternalDistributedMember> members = v.getMembers();
 +      InternalDistributedMember recipient = null;
 +      for (InternalDistributedMember mbr: members) {
 +        GMSMember gmsMbr = ((GMSMember)mbr.getNetMember());
 +        if (jgMbr.getUUIDLsbs() == gmsMbr.getUuidLSBs()
 +            && jgMbr.getUUIDMsbs() == gmsMbr.getUuidMSBs()
 +            && jgMbr.getVmViewId() == gmsMbr.getVmViewId()) {
 +          recipient = mbr;
 +          break;
 +        }
 +      }
 +      if (recipient != null) {
 +        services.getHealthMonitor().suspect(recipient,
 +            "Unable to send messages to this member via JGroups");
 +      }
 +    }
 +  }
 +  
 +  private void establishLocalAddress() {
 +    UUID logicalAddress = (UUID)myChannel.getAddress();
 +    logicalAddress = logicalAddress.copy();
 +    
 +    IpAddress ipaddr = (IpAddress)myChannel.down(new Event(Event.GET_PHYSICAL_ADDRESS));
 +    
 +    if (ipaddr != null) {
 +      this.jgAddress = new JGAddress(logicalAddress, ipaddr);
 +    }
 +    else {
 +      UDP udp = (UDP)myChannel.getProtocolStack().getTransport();
 +
 +      try {
 +        Method getAddress = UDP.class.getDeclaredMethod("getPhysicalAddress");
 +        getAddress.setAccessible(true);
 +        ipaddr = (IpAddress)getAddress.invoke(udp, new Object[0]);
 +        this.jgAddress = new JGAddress(logicalAddress, ipaddr);
 +      } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
 +        logger.info("Unable to find getPhysicallAddress method in UDP - parsing its address instead");
 +      }
 +      
 +//      if (this.jgAddress == null) {
 +//        String addr = udp.getLocalPhysicalAddress();
 +//        int cidx = addr.lastIndexOf(':');  // IPv6 literals might have colons
 +//        String host = addr.substring(0, cidx);
 +//        int jgport = Integer.parseInt(addr.substring(cidx+1, addr.length()));
 +//        try {
 +//          this.jgAddress = new JGAddress(logicalAddress, new IpAddress(InetAddress.getByName(host), jgport));
 +//        } catch (UnknownHostException e) {
 +//          myChannel.disconnect();
 +//          throw new SystemConnectException("unable to initialize jgroups address", e);
 +//        }
 +//      }
 +    }
 +  
 +    // install the address in the JGroups channel protocols
 +    myChannel.down(new Event(Event.SET_LOCAL_ADDRESS, this.jgAddress));
 +
 +    DistributionConfig config = services.getConfig().getDistributionConfig();
 +    boolean isLocator = (services.getConfig().getTransport().getVmKind() == DistributionManager.LOCATOR_DM_TYPE)
 +        || !services.getConfig().getDistributionConfig().getStartLocator().isEmpty();
 +    
 +    // establish the DistributedSystem's address
 +    DurableClientAttributes dca = null;
 +    if (config.getDurableClientId() != null) {
 +      dca = new DurableClientAttributes(config.getDurableClientId(), config
 +          .getDurableClientTimeout());
 +    }
 +    MemberAttributes attr = new MemberAttributes(
 +        -1/*dcPort - not known at this time*/,
 +        OSProcess.getId(),
 +        services.getConfig().getTransport().getVmKind(),
 +        -1/*view id - not known at this time*/,
 +        config.getName(),
 +        MemberAttributes.parseGroups(config.getRoles(), config.getGroups()),
 +        dca);
 +    localAddress = new InternalDistributedMember(jgAddress.getInetAddress(),
 +        jgAddress.getPort(), config.getEnableNetworkPartitionDetection(),
 +        isLocator, attr);
 +
 +    // add the JGroups logical address to the GMSMember
 +    UUID uuid = this.jgAddress;
 +    ((GMSMember)localAddress.getNetMember()).setUUID(uuid);
 +    ((GMSMember)localAddress.getNetMember()).setMemberWeight((byte)(services.getConfig().getMemberWeight() & 0xff));
 +  }
 +  
 +  @Override
 +  public void beSick() {
 +  }
 +
 +  @Override
 +  public void playDead() {
 +  }
 +
 +  @Override
 +  public void beHealthy() {
 +  }
 +
 +  @Override
 +  public void addHandler(Class c, MessageHandler h) {
 +    handlers.put(c, h);
 +  }
 +  
 +  @Override
 +  public boolean testMulticast(long timeout) throws InterruptedException {
 +    long pongsSnapshot = pongsReceived.longValue();
 +    JGAddress dest = null;
 +    try {
 +      pingPonger.sendPingMessage(myChannel, jgAddress, dest);
 +    } catch (Exception e) {
 +      logger.warn("unable to send multicast message: {}", (jgAddress==null? "multicast recipients":jgAddress),
 +          e.getMessage());
 +      return false;
 +    }
 +    long giveupTime = System.currentTimeMillis() + timeout;
 +    while (pongsReceived.longValue() == pongsSnapshot && System.currentTimeMillis() < giveupTime) {
 +      Thread.sleep(100);
 +    }
 +    return pongsReceived.longValue() > pongsSnapshot;
 +  }
 +  
 +  @Override
 +  public void getMessageState(InternalDistributedMember target, Map state, boolean includeMulticast) {
 +    if (includeMulticast) {
 +      NAKACK2 nakack = (NAKACK2)myChannel.getProtocolStack().findProtocol("NAKACK2");
 +      if (nakack != null) {
 +        long seqno = nakack.getCurrentSeqno();
 +        state.put("JGroups.mcastState", Long.valueOf(seqno));
 +      }
 +    }
 +  }
 +  
 +  @Override
 +  public void waitForMessageState(InternalDistributedMember sender, Map state) throws InterruptedException {
 +    NAKACK2 nakack = (NAKACK2)myChannel.getProtocolStack().findProtocol("NAKACK2");
 +    Long seqno = (Long)state.get("JGroups.mcastState");
 +    if (nakack != null && seqno != null) {
 +      waitForMessageState(nakack, sender, seqno);
 +    }
 +  }
 +  
 +  /**
 +   * wait for the mcast state from the given member to reach the given seqno 
 +   */
 +  protected void waitForMessageState(NAKACK2 nakack, InternalDistributedMember sender, Long seqno)
 +    throws InterruptedException {
 +    long timeout = services.getConfig().getDistributionConfig().getAckWaitThreshold() * 1000L;
 +    long startTime = System.currentTimeMillis();
 +    long warnTime = startTime + timeout;
 +    long quitTime = warnTime + timeout - 1000L;
 +    boolean warned = false;
 +    
 +    JGAddress jgSender = new JGAddress(sender);
 +    
 +    for (;;) {
 +      Digest digest = nakack.getDigest(jgSender);
 +      if (digest == null) {
 +        return;
 +      }
 +      String received = "none";
 +      long[] senderSeqnos = digest.get(jgSender);
 +      if (senderSeqnos == null || senderSeqnos[0] >= seqno.longValue()) {
 +        break;
 +      }
 +      long now = System.currentTimeMillis();
 +      if (!warned && now >= warnTime) {
 +        warned = true;
 +        if (senderSeqnos != null) {
 +          received = String.valueOf(senderSeqnos[0]);
 +        }
 +        logger.warn("{} seconds have elapsed while waiting for multicast messages from {}.  Received {} but expecting at least {}.",
 +            Long.toString((warnTime-startTime)/1000L), sender, received, seqno);
 +      }
 +      if (now >= quitTime) {
 +        throw new GemFireIOException("Multicast operations from " + sender + " did not distribute within " + (now - startTime) + " milliseconds");
 +      }
 +      Thread.sleep(50);
 +    }
 +  }
 +
 +  @Override
 +  public Set<InternalDistributedMember> sendUnreliably(DistributionMessage msg) {
 +    return send(msg, false);
 +  }
 +    
 +  @Override
 +  public Set<InternalDistributedMember> send(DistributionMessage msg) {
 +    return send(msg, true);
 +  }
 +    
 +  public Set<InternalDistributedMember> send(DistributionMessage msg, boolean reliably) {
 +      
 +    // perform the same jgroups messaging as in 8.2's GMSMembershipManager.send() method
 +
 +    // BUT: when marshalling messages we need to include the version of the product and
 +    // localAddress at the beginning of the message.  These should be used in the receiver
 +    // code to create a versioned input stream, read the sender address, then read the message
 +    // and set its sender address
 +    DMStats theStats = services.getStatistics();
 +    NetView oldView = this.view;
 +
 +    if (!myChannel.isConnected()) {
 +      logger.info("JGroupsMessenger channel is closed - messaging is not possible");
 +      throw new DistributedSystemDisconnectedException("Distributed System is shutting down");
 +    }
 +    
 +    filterOutgoingMessage(msg);
 +
 +    // JGroupsMessenger does not support direct-replies, so register
 +    // the message's processor if necessary
 +    if ((msg instanceof DirectReplyMessage) && msg.isDirectAck() && msg.getProcessorId() <= 0) {
 +      ((DirectReplyMessage)msg).registerProcessor();
 +    }
 +
 +    InternalDistributedMember[] destinations = msg.getRecipients();
 +    boolean allDestinations = msg.forAll();
 +    
 +    boolean useMcast = false;
 +    if (services.getConfig().getTransport().isMcastEnabled()) {
 +      if (msg.getMulticast() || allDestinations) {
 +        useMcast = services.getManager().isMulticastAllowed();
 +      }
 +    }
 +    
 +    if (logger.isDebugEnabled() && reliably) {
 +      String recips = useMcast? "multicast" : Arrays.toString(msg.getRecipients());
 +      logger.debug("sending via JGroups: [{}] recipients: {}", msg, recips);
 +    }
 +    
 +    JGAddress local = this.jgAddress;
 +    
 +    if (useMcast) {
 +
 +      long startSer = theStats.startMsgSerialization();
 +      Message jmsg = createJGMessage(msg, local, Version.CURRENT_ORDINAL);
 +      theStats.endMsgSerialization(startSer);
 +
 +      Exception problem = null;
 +      try {
 +        jmsg.setTransientFlag(TransientFlag.DONT_LOOPBACK);
 +        if (!reliably) {
 +          jmsg.setFlag(Message.Flag.NO_RELIABILITY);
 +        }
 +        theStats.incSentBytes(jmsg.getLength());
 +        logger.trace("Sending JGroups message: {}", jmsg);
 +        myChannel.send(jmsg);
 +      }
 +      catch (Exception e) {
 +        logger.debug("caught unexpected exception", e);
 +        Throwable cause = e.getCause();
 +        if (cause instanceof ForcedDisconnectException) {
 +          problem = (Exception) cause;
 +        } else {
 +          problem = e;
 +        }
 +        if (services.getShutdownCause() != null) {
 +          Throwable shutdownCause = services.getShutdownCause();
 +          // If ForcedDisconnectException occurred then report it as actual
 +          // problem.
 +          if (shutdownCause instanceof ForcedDisconnectException) {
 +            problem = (Exception) shutdownCause;
 +          } else {
 +            Throwable ne = problem;
 +            while (ne.getCause() != null) {
 +              ne = ne.getCause();
 +            }
 +            ne.initCause(services.getShutdownCause());
 +          }
 +        }
 +        final String channelClosed = LocalizedStrings.GroupMembershipService_CHANNEL_CLOSED.toLocalizedString();
 +//        services.getManager().membershipFailure(channelClosed, problem);
 +        throw new DistributedSystemDisconnectedException(channelClosed, problem);
 +      }
 +    } // useMcast
 +    else { // ! useMcast
 +      int len = destinations.length;
 +      List<GMSMember> calculatedMembers; // explicit list of members
 +      int calculatedLen; // == calculatedMembers.len
 +      if (len == 1 && destinations[0] == DistributionMessage.ALL_RECIPIENTS) { // send to all
 +        // Grab a copy of the current membership
 +        NetView v = services.getJoinLeave().getView();
 +
 +        // Construct the list
 +        calculatedLen = v.size();
 +        calculatedMembers = new LinkedList<GMSMember>();
 +        for (int i = 0; i < calculatedLen; i ++) {
 +          InternalDistributedMember m = (InternalDistributedMember)v.get(i);
 +          calculatedMembers.add((GMSMember)m.getNetMember());
 +        }
 +      } // send to all
 +      else { // send to explicit list
 +        calculatedLen = len;
 +        calculatedMembers = new LinkedList<GMSMember>();
 +        for (int i = 0; i < calculatedLen; i ++) {
 +          calculatedMembers.add((GMSMember)destinations[i].getNetMember());
 +        }
 +      } // send to explicit list
 +      Int2ObjectOpenHashMap<Message> messages = new Int2ObjectOpenHashMap<>();
 +      long startSer = theStats.startMsgSerialization();
 +      boolean firstMessage = true;
 +      for (Iterator<GMSMember> it=calculatedMembers.iterator(); it.hasNext(); ) {
 +        GMSMember mbr = it.next();
 +        short version = mbr.getVersionOrdinal();
 +        if ( !messages.containsKey(version) ) {
 +          Message jmsg = createJGMessage(msg, local, version);
 +          messages.put(version, jmsg);
 +          if (firstMessage) {
 +            theStats.incSentBytes(jmsg.getLength());
 +            firstMessage = false;
 +          }
 +        }
 +      }
 +      theStats.endMsgSerialization(startSer);
 +      Collections.shuffle(calculatedMembers);
 +      int i=0;
 +      for (GMSMember mbr: calculatedMembers) {
 +        JGAddress to = new JGAddress(mbr);
 +        short version = mbr.getVersionOrdinal();
 +        Message jmsg = (Message)messages.get(version);
 +        Exception problem = null;
 +        try {
 +          Message tmp = (i < (calculatedLen-1)) ? jmsg.copy(true) : jmsg;
 +          if (!reliably) {
 +            jmsg.setFlag(Message.Flag.NO_RELIABILITY);
 +          }
 +          tmp.setDest(to);
 +          tmp.setSrc(this.jgAddress);
 +          logger.trace("Unicasting to {}", to);
 +          myChannel.send(tmp);
 +        }
 +        catch (Exception e) {
 +          problem = e;
 +        }
 +        if (problem != null) {
 +          Throwable cause = services.getShutdownCause();
 +          if (cause != null) {
 +            // If ForcedDisconnectException occurred then report it as actual
 +            // problem.
 +            if (cause instanceof ForcedDisconnectException) {
 +              problem = (Exception) cause;
 +            } else {
 +              Throwable ne = problem;
 +              while (ne.getCause() != null) {
 +                ne = ne.getCause();
 +              }
 +              ne.initCause(cause);
 +            }
 +          }
 +          final String channelClosed = LocalizedStrings.GroupMembershipService_CHANNEL_CLOSED.toLocalizedString();
 +          //          services.getManager().membershipFailure(channelClosed, problem);
 +          throw new DistributedSystemDisconnectedException(channelClosed, problem);
 +        }
 +      } // send individually
 +    } // !useMcast
 +
 +    // The contract is that every destination enumerated in the
 +    // message should have received the message.  If one left
 +    // (i.e., left the view), we signal it here.
 +    if (msg.forAll()) {
 +      return Collections.emptySet();
 +    }
 +    Set<InternalDistributedMember> result = new HashSet<InternalDistributedMember>();
 +    NetView newView = this.view;
 +    if (newView != null && newView != oldView) {
 +      for (int i = 0; i < destinations.length; i ++) {
 +        InternalDistributedMember d = destinations[i];
 +        if (!newView.contains(d)) {
 +          logger.debug("messenger: member has left the view: {}  view is now {}", d, newView);
 +          result.add(d);
 +        }
 +      }
 +    }
 +    return result;
 +  }
 +
 +  /**
 +   * This is the constructor to use to create a JGroups message holding a GemFire
 +   * DistributionMessage.  It sets the appropriate flags in the Message and properly
 +   * serializes the DistributionMessage for the recipient's product version
 +   * 
 +   * @param gfmsg the DistributionMessage
 +   * @param src the sender address
 +   * @param version the version of the recipient
 +   * @return the new message
 +   */
 +  Message createJGMessage(DistributionMessage gfmsg, JGAddress src, short version) {
 +    if(gfmsg instanceof DirectReplyMessage) {
 +      ((DirectReplyMessage) gfmsg).registerProcessor();
 +    }
 +    Message msg = new Message();
 +    msg.setDest(null);
 +    msg.setSrc(src);
 +    // GemFire uses its own reply processors so there is no need
 +    // to maintain message order
 +    msg.setFlag(Flag.OOB);
 +    // Bundling is mostly only useful if we're doing no-ack work,
 +    // which is fairly rare
 +    msg.setFlag(Flag.DONT_BUNDLE);
 +
 +    //log.info("Creating message with payload " + gfmsg);
 +    if (gfmsg.getProcessorType() == DistributionManager.HIGH_PRIORITY_EXECUTOR
 +        || gfmsg instanceof HighPriorityDistributionMessage) {
 +      msg.setFlag(Flag.NO_FC);
 +      msg.setFlag(Flag.SKIP_BARRIER);
 +    }
 +    if (gfmsg instanceof DistributedCacheOperation.CacheOperationMessage) {
 +      // we don't want to see our own cache operation messages
 +      msg.setTransientFlag(Message.TransientFlag.DONT_LOOPBACK);
 +    }
 +    try {
 +      long start = services.getStatistics().startMsgSerialization();
 +      HeapDataOutputStream out_stream =
 +        new HeapDataOutputStream(Version.fromOrdinalOrCurrent(version));
 +      Version.CURRENT.writeOrdinal(out_stream, true);
 +      DataSerializer.writeObject(this.localAddress.getNetMember(), out_stream);
 +      DataSerializer.writeObject(gfmsg, out_stream);
 +      msg.setBuffer(out_stream.toByteArray());
 +      services.getStatistics().endMsgSerialization(start);
 +    }
 +    catch(IOException | GemFireIOException ex) {
 +      logger.warn("Error serializing message", ex);
 +      if (ex instanceof GemFireIOException) {
 +        throw (GemFireIOException)ex;
 +      } else {
 +        GemFireIOException ioe = new
 +          GemFireIOException("Error serializing message");
 +        ioe.initCause(ex);
 +        throw ioe;
 +      }
 +    }
 +    return msg;
 +  }
 +
 +
 +  /**
 +   * deserialize a jgroups payload.  If it's a DistributionMessage find
 +   * the ID of the sender and establish it as the message's sender
 +   */
 +  Object readJGMessage(Message jgmsg) {
 +    Object result = null;
 +    
 +    int messageLength = jgmsg.getLength();
 +    
 +    if (logger.isTraceEnabled()) {
 +      logger.trace("deserializing a message of length "+messageLength);
 +    }
 +    
 +    if (messageLength == 0) {
 +      // jgroups messages with no payload are used for protocol interchange, such
 +      // as STABLE_GOSSIP
 +      logger.trace("message length is zero - ignoring");
 +      return null;
 +    }
 +
 +    InternalDistributedMember sender = null;
 +
 +    Exception problem = null;
 +    byte[] buf = jgmsg.getRawBuffer();
 +    try {
 +      long start = services.getStatistics().startMsgDeserialization();
 +      
 +      DataInputStream dis = new DataInputStream(new ByteArrayInputStream(buf, 
 +          jgmsg.getOffset(), jgmsg.getLength()));
 +
 +      short ordinal = Version.readOrdinal(dis);
 +      
 +      if (ordinal < Version.CURRENT_ORDINAL) {
 +        dis = new VersionedDataInputStream(dis, Version.fromOrdinalNoThrow(
 +            ordinal, true));
 +      }
 +      
 +      GMSMember m = DataSerializer.readObject(dis);
 +
 +      result = DataSerializer.readObject(dis);
 +
 +      DistributionMessage dm = (DistributionMessage)result;
 +      
 +      // JoinRequestMessages are sent with an ID that may have been
 +      // reused from a previous life by way of auto-reconnect,
 +      // so we don't want to find a canonical reference for the
 +      // request's sender ID
 +      if (dm.getDSFID() == JOIN_REQUEST) {
 +        sender = ((JoinRequestMessage)dm).getMemberID();
 +      } else {
 +        sender = getMemberFromView(m, ordinal);
 +      }
 +      ((DistributionMessage)result).setSender(sender);
 +      
 +      services.getStatistics().endMsgDeserialization(start);
 +    }
 +    catch (ClassNotFoundException | IOException | RuntimeException e) {
 +      problem = e;
 +    }
 +    if (problem != null) {
 +      logger.error(LocalizedMessage.create(
 +            LocalizedStrings.GroupMembershipService_EXCEPTION_DESERIALIZING_MESSAGE_PAYLOAD_0, jgmsg), problem);
 +      return null;
 +    }
 +
 +    return result;
 +  }
 +  
 +  
 +  /** look for certain messages that may need to be altered before being sent */
 +  void filterOutgoingMessage(DistributionMessage m) {
 +    switch (m.getDSFID()) {
 +    case JOIN_RESPONSE:
 +      JoinResponseMessage jrsp = (JoinResponseMessage)m;
 +      
 +      if (jrsp.getRejectionMessage() == null
 +          &&  services.getConfig().getTransport().isMcastEnabled()) {
 +        // get the multicast message digest and pass it with the join response
 +        Digest digest = (Digest)this.myChannel.getProtocolStack()
 +            .getTopProtocol().down(Event.GET_DIGEST_EVT);
 +        HeapDataOutputStream hdos = new HeapDataOutputStream(500, Version.CURRENT);
 +        try {
 +          digest.writeTo(hdos);
 +        } catch (Exception e) {
 +          logger.fatal("Unable to serialize JGroups messaging digest", e);
 +        }
 +        jrsp.setMessengerData(hdos.toByteArray());
 +      }
 +      break;
 +    default:
 +      break;
 +    }
 +  }
 +  
 +  void filterIncomingMessage(DistributionMessage m) {
 +    switch (m.getDSFID()) {
 +    case JOIN_RESPONSE:
 +      JoinResponseMessage jrsp = (JoinResponseMessage)m;
 +      
 +      if (jrsp.getRejectionMessage() == null
 +          &&  services.getConfig().getTransport().isMcastEnabled()) {
 +        byte[] serializedDigest = jrsp.getMessengerData();
 +        ByteArrayInputStream bis = new ByteArrayInputStream(serializedDigest);
 +        DataInputStream dis = new DataInputStream(bis);
 +        try {
 +          Digest digest = new Digest();
 +          digest.readFrom(dis);
 +          if (digest != null) {
 +            logger.trace("installing JGroups message digest {}", digest);
 +            this.myChannel.getProtocolStack()
 +                .getTopProtocol().down(new Event(Event.SET_DIGEST, digest));
 +            jrsp.setMessengerData(null);
 +          }
 +        } catch (Exception e) {
 +          logger.fatal("Unable to read JGroups messaging digest", e);
 +        }
 +      }
 +      break;
 +    default:
 +      break;
 +    }
 +  }
 +  
 +  @Override
 +  public InternalDistributedMember getMemberID() {
 +    return localAddress;
 +  }
 +  
 +  /**
 +   * returns the JGroups configuration string, for testing
 +   */
 +  public String getJGroupsStackConfig() {
 +    return this.jgStackConfig;
 +  }
 +  
 +  /**
 +   * returns the pinger, for testing
 +   */
 +  public GMSPingPonger getPingPonger() {
 +    return this.pingPonger;
 +  }
 +  
 +  /**
 +   * for unit testing we need to replace UDP with a fake UDP protocol 
 +   */
 +  public void setJGroupsStackConfigForTesting(String config) {
 +    this.jgStackConfig = config;
 +  }
 +
 +  /**
 +   * returns the member ID for the given GMSMember object
 +   */
 +  private InternalDistributedMember getMemberFromView(GMSMember jgId, short version) {
 +    NetView v = services.getJoinLeave().getView();
 +    
 +    if (v != null) {
 +      for (InternalDistributedMember m: v.getMembers()) {
 +        if (((GMSMember)m.getNetMember()).equals(jgId)) {
 +          return m;
 +        }
 +      }
 +    }
 +    return new InternalDistributedMember(jgId);
 +  }
 +
 +
 +  @Override
 +  public void emergencyClose() {
 +    this.view = null;
 +    if (this.myChannel != null) {
 +      if ((services.isShutdownDueToForcedDisconnect() && services.isAutoReconnectEnabled()) || services.getManager().isReconnectingDS()) {
 +      }
 +      else {
 +        this.myChannel.disconnect();
 +      }
 +    }
 +  }
 +  
 +  public QuorumChecker getQuorumChecker() {    
 +    NetView view = this.view;
 +    if (view == null) {
 +      view = services.getJoinLeave().getView();
 +      if (view == null) {
 +        view = services.getJoinLeave().getPreviousView();
 +        if (view == null) {
 +          return null;
 +        }
 +      }
 +    }
 +    GMSQuorumChecker qc = new GMSQuorumChecker(
 +          view, services.getConfig().getLossThreshold(),
 +          this.myChannel);
 +    qc.initialize();
 +    return qc;
 +  }
 +  /**
 +   * JGroupsReceiver receives incoming JGroups messages and passes them to a handler.
 +   * It may be accessed through JChannel.getReceiver().
 +   */
 +  class JGroupsReceiver extends ReceiverAdapter  {
 +  
 +    @Override
 +    public void receive(Message jgmsg) {
-       if (services.getManager().shutdownInProgress()) {
-         return;
-       }
- 
-       if (logger.isTraceEnabled()) {
-         logger.trace("JGroupsMessenger received {} headers: {}", jgmsg, jgmsg.getHeaders());
-       }
-       
-       //Respond to ping messages sent from other systems that are in a auto reconnect state
-       byte[] contents = jgmsg.getBuffer();
-       if (contents == null) {
-         return;
-       }
-       if (pingPonger.isPingMessage(contents)) {
++      long startTime = DistributionStats.getStatTime();
++      try {
++        if (services.getManager().shutdownInProgress()) {
++          return;
++        }
++  
++        if (logger.isTraceEnabled()) {
++          logger.trace("JGroupsMessenger received {} headers: {}", jgmsg, jgmsg.getHeaders());
++        }
++        
++        //Respond to ping messages sent from other systems that are in a auto reconnect state
++        byte[] contents = jgmsg.getBuffer();
++        if (contents == null) {
++          return;
++        }
++        if (pingPonger.isPingMessage(contents)) {
++          try {
++            pingPonger.sendPongMessage(myChannel, jgAddress, jgmsg.getSrc());
++          }
++          catch (Exception e) {
++            logger.info("Failed sending Pong response to " + jgmsg.getSrc());
++          }
++          return;
++        } else if (pingPonger.isPongMessage(contents)) {
++          pongsReceived.incrementAndGet();
++          return;
++        }
++        
++        Object o = readJGMessage(jgmsg);
++        if (o == null) {
++          return;
++        }
++  
++        DistributionMessage msg = (DistributionMessage)o;
++        assert msg.getSender() != null;
++        
++        // admin-only VMs don't have caches, so we ignore cache operations
++        // multicast to them, avoiding deserialization cost and classpath
++        // problems
++        if ( (services.getConfig().getTransport().getVmKind() == DistributionManager.ADMIN_ONLY_DM_TYPE)
++             && (msg instanceof DistributedCacheOperation.CacheOperationMessage)) {
++          return;
++        }
++  
++        msg.resetTimestamp();
++        msg.setBytesRead(jgmsg.getLength());
++              
 +        try {
-           pingPonger.sendPongMessage(myChannel, jgAddress, jgmsg.getSrc());
++          logger.trace("JGroupsMessenger dispatching {} from {}", msg, msg.getSender());
++          filterIncomingMessage(msg);
++          getMessageHandler(msg).processMessage(msg);
 +        }
-         catch (Exception e) {
-           logger.info("Failed sending Pong response to " + jgmsg.getSrc());
++        catch (MemberShunnedException e) {
++          // message from non-member - ignore
 +        }
-         return;
-       } else if (pingPonger.isPongMessage(contents)) {
-         pongsReceived.incrementAndGet();
-         return;
-       }
-       
-       Object o = readJGMessage(jgmsg);
-       if (o == null) {
-         return;
-       }
- 
-       DistributionMessage msg = (DistributionMessage)o;
-       assert msg.getSender() != null;
-       
-       // admin-only VMs don't have caches, so we ignore cache operations
-       // multicast to them, avoiding deserialization cost and classpath
-       // problems
-       if ( (services.getConfig().getTransport().getVmKind() == DistributionManager.ADMIN_ONLY_DM_TYPE)
-            && (msg instanceof DistributedCacheOperation.CacheOperationMessage)) {
-         return;
-       }
- 
-       msg.resetTimestamp();
-       msg.setBytesRead(jgmsg.getLength());
-             
-       try {
-         logger.trace("JGroupsMessenger dispatching {} from {}", msg, msg.getSender());
-         filterIncomingMessage(msg);
-         getMessageHandler(msg).processMessage(msg);
-       }
-       catch (MemberShunnedException e) {
-         // message from non-member - ignore
++      }finally {
++        long delta = DistributionStats.getStatTime() - startTime ;
++        JGroupsMessenger.this.services.getStatistics().incUDPDispatchRequestTime(delta);
 +      }
 +    }
 +    
 +    /**
 +     * returns the handler that should process the given message.
 +     * The default handler is the membership manager
 +     * @param msg
 +     * @return
 +     */
 +    private MessageHandler getMessageHandler(DistributionMessage msg) {
 +      Class<?> msgClazz = msg.getClass();
 +      MessageHandler h = handlers.get(msgClazz);
 +      if (h == null) {
 +        for (Class<?> clazz: handlers.keySet()) {
 +          if (clazz.isAssignableFrom(msgClazz)) {
 +            h = handlers.get(clazz);
 +            handlers.put(msg.getClass(), h);
 +            break;
 +          }
 +        }
 +      }
 +      if (h == null) {
 +        h = (MessageHandler)services.getManager();
 +      }
 +      return h;
 +    }
 +  }
 +  
 +  
 +  
 +}



[031/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EventTracker.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EventTracker.java
index 83b00b4,0000000..3d6ce73
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EventTracker.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EventTracker.java
@@@ -1,811 -1,0 +1,812 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.DataInput;
 +import java.io.DataOutput;
 +import java.io.IOException;
 +import java.util.HashMap;
 +import java.util.Iterator;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentMap;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.DataSerializable;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.SystemTimer.SystemTimerTask;
 +import com.gemstone.gemfire.internal.cache.ha.ThreadIdentifier;
 +import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +import com.gemstone.gemfire.internal.util.concurrent.StoppableCountDownLatch;
 +
 +/**
 + * EventTracker tracks the last sequence number for a particular
 + * memberID:threadID.  It is used to avoid replaying events in
 + * client/server and partitioned-region configurations.
 + * 
 + * @author bruce
 + * @since 6.0
 + */
 +public class EventTracker
 +{
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  /**
 +   * a mapping of originator to the last event applied to this cache 
 +   *
 +   * Keys are instances of {@link ThreadIdentifier}, values are instances
 +   * of {@link com.gemstone.gemfire.internal.cache.EventTracker.EventSeqnoHolder}.
 +   */
 +  protected final ConcurrentMap<ThreadIdentifier, EventSeqnoHolder> recordedEvents 
 +      = new ConcurrentHashMap<ThreadIdentifier, EventSeqnoHolder>(100);
 + 
 +  /** a mapping of originator to bulkOp's last status (true means
 +   * finished processing) applied to this cache. 
 +   *
 +   * Keys are instances of @link {@link ThreadIdentifier}, values are instances
 +   * of {@link BulkOpProcessed}.
 +   */
 +  private final ConcurrentMap<ThreadIdentifier, BulkOpProcessed> recordedBulkOps 
 +      = new ConcurrentHashMap<ThreadIdentifier, BulkOpProcessed>(100);
 +  
 +  /** a mapping of originator to bulkOperation's last version tags. This map
 +   * differs from {@link #recordedBulkOps} in that the thread identifier used
 +   * here is the base member id and thread id of the bulk op, as opposed to the fake
 +   * thread id which is assigned for each bucket.
 +   * 
 +   * recordedBulkOps are also only tracked on the secondary for partitioned regions
 +   * recordedBulkOpVersionTags are tracked on both the primary and secondary.
 +   *
 +   * Keys are instances of @link {@link ThreadIdentifier}, values are instances
 +   * of {@link BulkOpHolder}.
 +   */
 +  private final ConcurrentMap<ThreadIdentifier, BulkOpHolder> recordedBulkOpVersionTags 
 +      = new ConcurrentHashMap<ThreadIdentifier, BulkOpHolder>(100);
 +  
 +  /**
 +   * The member that the region corresponding to this tracker (if any)
 +   * received its initial image from (if a replicate)
 +   */
 +  private volatile InternalDistributedMember initialImageProvider;
 +
 + 
 +  /**
 +   * The cache associated with this tracker
 +   */
 +  GemFireCacheImpl cache;
 + 
 +  /**
 +   * The name of this tracker
 +   */
 +  String name;
 +  
 +  /**
 +   * whether or not this tracker has been initialized with state from
 +   * another process
 +   */
 +  volatile boolean initialized;
 + 
 +  /**
 +   * object used to wait for initialization 
 +   */
 +  final StoppableCountDownLatch initializationLatch;
 +  
 +  /**
 +  * Initialize the EventTracker's timer task.  This is stored in the cache
 +  * for tracking and shutdown purposes
 +  * @param cache the cache to schedule tasks with
 +  */
 +  public static ExpiryTask startTrackerServices(GemFireCacheImpl cache) {
 +    long expiryTime = Long.getLong("gemfire.messageTrackingTimeout",
 +        PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT / 3).longValue();
 +    ExpiryTask result = new ExpiryTask(cache, expiryTime);
 +    cache.getCCPTimer().scheduleAtFixedRate(result,
 +        expiryTime, expiryTime);
 +    //schedule(result, expiryTime);
 +    return result;
 +  }
 +  
 +  /**
 +   * Terminate the tracker's timer task
 +   * @param cache the cache holding the tracker task
 +   */
 +  public static void stopTrackerServices(GemFireCacheImpl cache) {
 +    cache.getEventTrackerTask().cancel();
 +  }
 + 
 + /**
 +  * Create an event tracker
 +  * @param region the cache region to associate with this tracker
 +  */
 +  public EventTracker(LocalRegion region) {
 +   this.cache = region.cache;
 +   this.name = "Event Tracker for " + region.getName();
 +   this.initializationLatch = new StoppableCountDownLatch(region.stopper, 1);
 + }
 +
 +  /** start this event tracker */
 +  public void start() {
 +    if (this.cache.getEventTrackerTask() != null) {
 +      this.cache.getEventTrackerTask().addTracker(this);
 +    }
 +  }
 +  
 +  /** stop this event tracker */
 +  public void stop() {
 +    if (this.cache.getEventTrackerTask() != null) {
 +      this.cache.getEventTrackerTask().removeTracker(this);
 +    }
 +  }
 +  
 +  /**
 +   * retrieve a deep copy of the state of the event tracker.  Synchronization
 +   * is not used while copying the tracker's state.
 +   */
 +  public Map<ThreadIdentifier, EventSeqnoHolder> getState() {
 +    Map<ThreadIdentifier, EventSeqnoHolder> result = new HashMap<ThreadIdentifier, EventSeqnoHolder>(recordedEvents.size());
 +    for (Iterator<Map.Entry<ThreadIdentifier, EventSeqnoHolder>> it=recordedEvents.entrySet().iterator(); it.hasNext(); ) {
 +      Map.Entry<ThreadIdentifier, EventSeqnoHolder> entry = it.next();
 +      EventSeqnoHolder holder = entry.getValue();
 +      result.put(entry.getKey(), new EventSeqnoHolder(
 +          holder.lastSeqno, null)); // don't transfer version tags - adds too much bulk just so we can do client tag recovery
 +    }
 +    return result;
 +  }
 +  
 +  /**
 +   * record the given state in the tracker.
 +   * @param provider the member that provided this state
 +   * @param state a Map obtained from getState();
 +   */
 +  public void recordState(InternalDistributedMember provider, Map<ThreadIdentifier, EventSeqnoHolder> state) {
 +    this.initialImageProvider = provider;
 +    StringBuffer sb = null;
 +    if (logger.isDebugEnabled()) {
 +      sb = new StringBuffer(200);
 +      sb.append("Recording initial state for ")
 +        .append(this.name)
 +        .append(": ");
 +    }
 +    for (Iterator<Map.Entry<ThreadIdentifier, EventSeqnoHolder>> it=state.entrySet().iterator(); it.hasNext(); ) {
 +      Map.Entry<ThreadIdentifier, EventSeqnoHolder> entry = it.next();
 +      if (sb != null) {
 +        sb.append("\n  ")
 +          .append(entry.getKey().expensiveToString())
 +          .append("; sequenceID=")
 +          .append(entry.getValue()); 
 +      }
 +      // record only if we haven't received an event that is newer
 +      recordSeqno(entry.getKey(), entry.getValue(), true);
 +    }
 +    if (sb != null) {
 +      logger.debug(sb);
 +    }
 +    // fix for bug 41622 - hang in GII.  This keeps ops from waiting for the
 +    // full GII to complete
 +    setInitialized();
 +  }
 +  
 +  /**
 +   * Use this method to ensure that the tracker is put in an initialized state
 +   */
 +  public void setInitialized() {
 +    this.initializationLatch.countDown();
 +    this.initialized = true;
 +  }
 +  
 +  /**
 +   * Wait for the tracker to finishe being initialized
 +   */
 +  public void waitOnInitialization() throws InterruptedException {
 +    this.initializationLatch.await();
 +  }
 +  
 +  /**
 +   * Record an event sequence id if it is higher than what we currently have.
 +   * This is intended for use during initial image transfer.
 +   * @param membershipID the key of an entry in the map obtained from getEventState()
 +   * @param evhObj the value of an entry in the map obtained from getEventState()
 +   */
 +  protected void recordSeqno(ThreadIdentifier membershipID, EventSeqnoHolder evhObj){
 +    recordSeqno(membershipID, evhObj, false);
 +  }
 +  
 +  /**
 +   * Record an event sequence id if it is higher than what we currently have.
 +   * This is intended for use during initial image transfer.
 +   * @param threadID the key of an entry in the map obtained from getEventState()
 +   * @param evh the value of an entry in the map obtained from getEventState()
 +   * @param ifAbsent only record this state if there's not already an entry for this memberID
 +   */
 +  private void recordSeqno(ThreadIdentifier threadID, EventSeqnoHolder evh, boolean ifAbsent) {
 +    boolean removed;
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("recording {} {}", threadID.expensiveToString(), evh.toString());
 +    }
 +    do {
 +      removed = false;
 +      EventSeqnoHolder oldEvh = recordedEvents.putIfAbsent(
 +          threadID, evh);
 +      if (oldEvh != null) {
 +        synchronized(oldEvh) {
 +          if (oldEvh.removed) {
 +            // need to wait for an entry being removed by the sweeper to go away
 +            removed = true;
 +            continue;
 +          }
 +          else {
 +            if (ifAbsent) {
 +              break;
 +            }
 +            oldEvh.endOfLifeTimer = 0;
 +            if (oldEvh.lastSeqno < evh.lastSeqno) {
 +              oldEvh.lastSeqno = evh.lastSeqno;
 +              oldEvh.versionTag = evh.versionTag;
 +//              Exception e = oldEvh.context;
 +//              oldEvh.context = new Exception("stack trace");
 +//              oldEvh.context.initCause(e);
 +            }
 +          }
 +        }
 +      }
 +      else {
 +        evh.endOfLifeTimer = 0;
 +//        evh.context = new Exception("stack trace");
 +      }
 +    } while (removed);
 +  }
 +  
 +  /** record the event's threadid/sequenceid to prevent replay */
 +  public void recordEvent(InternalCacheEvent event) {
 +    EventID eventID = event.getEventId();
 +    if (ignoreEvent(event, eventID)) {
 +      return; // not tracked
 +    }
 +
 +    LocalRegion lr = (LocalRegion)event.getRegion();
 +
 +    ThreadIdentifier membershipID = new ThreadIdentifier(eventID.getMembershipID(),
 +        eventID.getThreadID());
 +
 +    VersionTag tag = null;
 +    if (lr.getServerProxy() == null/* && event.hasClientOrigin()*/) { // clients do not need to store version tags for replayed events
 +      tag = event.getVersionTag();
 +      RegionVersionVector v = ((LocalRegion)event.getRegion()).getVersionVector();
 +      // bug #46453 - make sure ID references are canonical before storing
 +      if (v != null && tag != null) {
 +        tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
 +        if (tag.getPreviousMemberID() != null) {
 +          tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
 +        }
 +      }
 +    }
-     EventSeqnoHolder newEvh = new EventSeqnoHolder(eventID.getSequenceID(), tag);
-     if (logger.isTraceEnabled()){
-       logger.trace("region event tracker recording {}", event);
-     }
-     recordSeqno(membershipID, newEvh);
 +    
 +    //If this is a bulkOp, and concurrency checks are enabled, we need to
 +    //save the version tag in case we retry.
 +    if (lr.concurrencyChecksEnabled 
 +        && (event.getOperation().isPutAll() || event.getOperation().isRemoveAll()) && lr.getServerProxy() == null) {
 +      recordBulkOpEvent(event, membershipID);
 +    }
++
++    EventSeqnoHolder newEvh = new EventSeqnoHolder(eventID.getSequenceID(), tag);
++    if (logger.isTraceEnabled()){
++      logger.trace("region event tracker recording {}", event);
++    }
++    recordSeqno(membershipID, newEvh);
 +  }
 +
 +  /**
 +   * Record a version tag for a bulk operation
 +   */
 +  private void recordBulkOpEvent(InternalCacheEvent event, ThreadIdentifier tid) {
 +    EventID eventID = event.getEventId();
 +    
 +    VersionTag tag = event.getVersionTag();
 +    if (tag == null) {
 +      return;
 +    }
 +    
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("recording bulkOp event {} {} {} op={}", tid.expensiveToString(),
 +          eventID, tag, event.getOperation());
 +    }
 +
 +    RegionVersionVector v = ((LocalRegion)event.getRegion()).getVersionVector();
 +    // bug #46453 - make sure ID references are canonical before storing
 +    if (v != null) {
 +      tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
 +      if (tag.getPreviousMemberID() != null) {
 +        tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
 +      }
 +    }
 +
 +    //Loop until we can successfully update the recorded bulk operations
 +    //For this thread id.
 +    boolean retry = false;
 +    do {
 +      BulkOpHolder bulkOpTracker = recordedBulkOpVersionTags.get(tid);
 +      if(bulkOpTracker == null) {
 +        bulkOpTracker = new BulkOpHolder();
 +        BulkOpHolder old = recordedBulkOpVersionTags.putIfAbsent(tid, bulkOpTracker);
 +        if(old != null) {
 +          retry = true;
 +          continue;
 +        }
 +      }
 +      synchronized(bulkOpTracker) {
 +        if(bulkOpTracker.removed) {
 +          retry = true;
 +          continue;
 +        }
 +        
 +        //Add the version tag for bulkOp event.
 +        bulkOpTracker.putVersionTag(eventID, event.getVersionTag());
 +        retry = false;
 +      }
 +    } while(retry);
 +  }
 +  
 +  public boolean hasSeenEvent(InternalCacheEvent event) {
 +//  ClientProxyMembershipID membershipID = event.getContext();
 +    EventID eventID = event.getEventId();
 +    if (ignoreEvent(event, eventID)) {
 +      return false; // not tracked
 +    }
 +    return hasSeenEvent(eventID, event);
 +  }
 +  
 +  public boolean hasSeenEvent(EventID eventID) {
 +    return hasSeenEvent(eventID, null);
 +  }
 +
 +  public boolean hasSeenEvent(EventID eventID, InternalCacheEvent tagHolder) {
 +    ThreadIdentifier membershipID = new ThreadIdentifier(
 +        eventID.getMembershipID(), eventID.getThreadID());
 +//  if (membershipID == null || eventID == null) {
 +//    return false;
 +//  }
 +        
 +    EventSeqnoHolder evh = recordedEvents.get(membershipID);
 +    if (evh == null) {
 +      return false;
 +    }
 +    
 +    synchronized (evh) {
 +      if (evh.removed || evh.lastSeqno < eventID.getSequenceID()) {
 +        return false;
 +      }
 +      // log at fine because partitioned regions can send event multiple times
 +      // during normal operation during bucket region initialization
 +      if (logger.isTraceEnabled(LogMarker.DISTRIBUTION_BRIDGE_SERVER)) {
 +        logger.trace(LogMarker.DISTRIBUTION_BRIDGE_SERVER, "Cache encountered replay of event with ID {}.  Highest recorded for this source is {}",
 +            eventID, evh.lastSeqno);
 +      }
 +      // bug #44956 - recover version tag for duplicate event
 +      if (evh.lastSeqno == eventID.getSequenceID() && tagHolder != null && evh.versionTag != null) {
 +        ((EntryEventImpl)tagHolder).setVersionTag(evh.versionTag);
 +      }
 +      return true;
 +    } // synchronized
 +  }
 +
 +  public VersionTag findVersionTag(EventID eventID) {
 +    ThreadIdentifier threadID = new ThreadIdentifier(
 +        eventID.getMembershipID(), eventID.getThreadID());
 +        
 +    EventSeqnoHolder evh = recordedEvents.get(threadID);
 +    if (evh == null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("search for version tag failed as no event is recorded for {}", threadID.expensiveToString());
 +      }
 +      return null;
 +    }
 +    
 +    synchronized (evh) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("search for version tag located last event for {}: {}",threadID.expensiveToString(), evh);
 +      }
 +      if (evh.lastSeqno != eventID.getSequenceID()) {
 +        return null;
 +      }
 +      // log at fine because partitioned regions can send event multiple times
 +      // during normal operation during bucket region initialization
 +      if (logger.isTraceEnabled(LogMarker.DISTRIBUTION_BRIDGE_SERVER) && evh.versionTag == null) {
 +        logger.trace(LogMarker.DISTRIBUTION_BRIDGE_SERVER, "Could not recover version tag.  Found event holder with no version tag for {}", eventID);
 +      }
 +      return evh.versionTag;
 +    } // synchronized
 +  }
 +  
 +  public VersionTag findVersionTagForGateway(EventID eventID) {
 +    ThreadIdentifier threadID = new ThreadIdentifier(
 +        eventID.getMembershipID(), eventID.getThreadID());
 +        
 +    EventSeqnoHolder evh = recordedEvents.get(threadID);
 +    if (evh == null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("search for version tag failed as no event is recorded for {}", threadID.expensiveToString());
 +      }
 +      return null;
 +    }
 +    
 +    synchronized (evh) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("search for version tag located last event for {}: {} {}",threadID.expensiveToString(), evh, eventID.getSequenceID() );
 +      }
 +      
 +      if (evh.lastSeqno < eventID.getSequenceID()) {
 +        return null;
 +      }
 +      // log at fine because partitioned regions can send event multiple times
 +      // during normal operation during bucket region initialization
 +      if (logger.isTraceEnabled(LogMarker.DISTRIBUTION_BRIDGE_SERVER) && evh.versionTag == null) {
 +        logger.trace(LogMarker.DISTRIBUTION_BRIDGE_SERVER, "Could not recover version tag.  Found event holder with no version tag for {}", eventID);
 +      }
 +      return evh.versionTag;
 +    } // synchronized
 +  }
 +  
 +  
 +  public VersionTag findVersionTagForBulkOp(EventID eventID) {
 +    ThreadIdentifier threadID = new ThreadIdentifier(
 +        eventID.getMembershipID(), eventID.getThreadID());
 +        
 +    BulkOpHolder evh = recordedBulkOpVersionTags.get(threadID);
 +    if (evh == null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("search for version tag failed as no events are recorded for {}", threadID.expensiveToString());
 +      }
 +      return null;
 +    }
 +    
 +    synchronized (evh) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("search for version tag located event holder for {}: {}", threadID.expensiveToString(), evh);
 +      }
 +      return evh.entryVersionTags.get(eventID);
 +    } // synchronized
 +  }
 +
 +  /**
 +   * @param event
 +   * @param eventID
 +   * @return true if the event should not be tracked, false otherwise
 +   */
 +  private boolean ignoreEvent(InternalCacheEvent event, EventID eventID) {
 +    if (eventID == null) {
 +      return true;
 +    } else {
 +      boolean isVersioned = (event.getVersionTag() != null);
 +      boolean isClient = event.hasClientOrigin();
 +      if (isVersioned && isClient) {
 +        return false; // version tags for client events are kept for retries by the client
 +      }
 +      boolean isEntry = event.getOperation().isEntry();
 +      boolean isPr = event.getRegion().getAttributes().getDataPolicy().withPartitioning()
 +                   || ((LocalRegion)event.getRegion()).isUsedForPartitionedRegionBucket();
 +      return (!isClient &&   // ignore if it originated on a server, and
 +           isEntry &&        // it affects an entry and
 +          !isPr);            // is not on a PR
 +    }
 +  }
 +
 +  /**
 +   * A routine to provide synchronization running based on <memberShipID, threadID> 
 +   * of the requesting client
 +   * @param r - a Runnable to wrap the processing of the bulk op
 +   * @param eventID - the base event ID of the bulk op
 +   *
 +   * @since 5.7
 +   */
 +  public void syncBulkOp(Runnable r, EventID eventID) {
 +    Assert.assertTrue(eventID != null);
 +    ThreadIdentifier membershipID = new ThreadIdentifier(
 +      eventID.getMembershipID(), eventID.getThreadID());
 +
 +    BulkOpProcessed opSyncObj = recordedBulkOps.putIfAbsent(membershipID, new BulkOpProcessed(false));
 +    if (opSyncObj == null) {
 +      opSyncObj = recordedBulkOps.get(membershipID);
 +    }
 +    synchronized (opSyncObj) {
 +      try {
 +        if (opSyncObj.getStatus() && logger.isDebugEnabled()) {
 +          logger.debug("SyncBulkOp: The operation was performed by another thread.");
 +        }
 +        else {
 +          recordBulkOpStart(membershipID);
 +          
 +          //Perform the bulk op
 +          r.run();
 +          // set to true in case another thread is waiting at sync 
 +          opSyncObj.setStatus(true);
 +          recordedBulkOps.remove(membershipID);
 +        }
 +      }
 +      finally {
 +        recordedBulkOps.remove(membershipID);
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Called when a bulkOp is started on the local region. Used to clear
 +   * event tracker state from the last bulkOp.
 +   */
 +  public void recordBulkOpStart(ThreadIdentifier tid) {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("recording bulkOp start for {}", tid.expensiveToString());
 +    }
 +    this.recordedBulkOpVersionTags.remove(tid);
 +  }
 +  
 +  /**
 +   * @return the initialized
 +   */
 +  public boolean isInitialized() {
 +    return this.initialized;
 +  }
 +  
 +  /**
 +   * @param mbr the member in question
 +   * @return true if the given member provided the initial image event state for this tracker
 +   */
 +  public boolean isInitialImageProvider(DistributedMember mbr) {
 +    return (this.initialImageProvider != null)
 +      && (mbr != null)
 +      && this.initialImageProvider.equals(mbr);
 +  }
 +  
 +  /**
 +   * Test method for getting the set of recorded version tags.
 +   */
 +  protected ConcurrentMap<ThreadIdentifier, BulkOpHolder> getRecordedBulkOpVersionTags() {
 +    return recordedBulkOpVersionTags;
 +  }
 +  
 +  @Override
 +  public String toString() {
 +    return ""+this.name+"(initialized=" + this.initialized+")";
 +  }
 +  
 +  /**
 +   * A sequence number tracker to keep events from clients from being
 +   * re-applied to the cache if they've already been seen.
 +   * @author bruce
 +   * @since 5.5
 +   */
 +  static class EventSeqnoHolder implements DataSerializable {
 +    private static final long serialVersionUID = 8137262960763308046L;
 +
 +    /** event sequence number.  These  */
 +    long lastSeqno = -1;
 +    
 +    /** millisecond timestamp */
 +    transient long endOfLifeTimer;
 +    
 +    /** whether this entry is being removed */
 +    transient boolean removed;
 +    
 +    /**
 +     * version tag, if any, for the operation
 +     */
 +    VersionTag versionTag;
 +    
 +    // for debugging
 +//    transient Exception context;
 +    
 +    EventSeqnoHolder(long id, VersionTag versionTag) {
 +      this.lastSeqno = id;
 +      this.versionTag = versionTag;
 +    }
 +    
 +    public EventSeqnoHolder() {
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      StringBuilder result = new StringBuilder();
 +      result.append("seqNo").append(this.lastSeqno);
 +      if (this.versionTag != null) {
 +        result.append(",").append(this.versionTag);
 +      }
 +      return result.toString();
 +    }
 +
 +    public void fromData(DataInput in) throws IOException,
 +        ClassNotFoundException {
 +      lastSeqno = in.readLong();
 +      versionTag = (VersionTag)DataSerializer.readObject(in);
 +    }
 +
 +    public void toData(DataOutput out) throws IOException {
 +      out.writeLong(lastSeqno);
 +      DataSerializer.writeObject(versionTag, out);
 +    }
 +  }
 +
 +  /**
 +   * A status tracker for each bulk operation (putAll or removeAll) from originators specified by
 +   * membershipID and threadID in the cache
 +   * processed is true means the bulk op is processed by one thread 
 +   * no need to redo it by other threads.
 +   * @author Gester
 +   * @since 5.7
 +   */
 +  static class BulkOpProcessed {
 +    /** whether the op is processed */
 +    private boolean processed;
 +  
 +    /**
 +     * creates a new instance to save status of a bulk op 
 +     * @param status true if the op has been processed 
 +     */
 +    BulkOpProcessed(boolean status) {
 +      this.processed = status;
 +    }
 +    
 +    /**
 +     * setter method to change the status
 +     * @param status true if the op has been processed 
 +     */
 +    void setStatus(boolean status) {
 +      this.processed = status;
 +    }
 +    
 +    /**
 +     * getter method to peek the current status
 +     * @return current status
 +     */
 +    boolean getStatus() {
 +      return this.processed;
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      return "BULKOP("+this.processed+")";
 +    }
 +  }
 +  
 +  /**
 +   * A holder for the version tags generated for a bulk operation (putAll or removeAll). These
 +   * version tags are retrieved when a bulk op is retried.
 +   * @author Dan
 +   * @since 7.0
 +   * protected for test purposes only.
 +   */
 +  protected static class BulkOpHolder {
 +    /**
 +     * Whether this object was removed by the cleanup thread.
 +     */
 +    public boolean removed;
 +    /**
 +     * public for tests only
 +     */
 +    public Map<EventID, VersionTag> entryVersionTags = new HashMap<EventID, VersionTag>();
 +    /** millisecond timestamp */
 +    transient long endOfLifeTimer;
 +  
 +    /**
 +     * creates a new instance to save status of a putAllOperation 
 +     */
 +    BulkOpHolder() {
 +    }
 +    
 +    public void putVersionTag(EventID eventId, VersionTag versionTag) {
 +      entryVersionTags.put(eventId, versionTag);
 +      this.endOfLifeTimer = 0;
 +    }
 +
 +    
 +    @Override
 +    public String toString() {
 +      return "BulkOpHolder tags=" + this.entryVersionTags;
 +    }
 +  }
 +  
 +  static class ExpiryTask extends SystemTimerTask {
 +    
 +    GemFireCacheImpl cache;
 +    long expiryTime;
 +    List trackers = new LinkedList();
 +    
 +    public ExpiryTask(GemFireCacheImpl cache, long expiryTime) {
 +      this.cache = cache;
 +      this.expiryTime = expiryTime;
 +    }
 +    void addTracker(EventTracker tracker) {
 +      synchronized(trackers) {
 +        trackers.add(tracker);
 +      }
 +    }
 +    void removeTracker(EventTracker tracker) {
 +      synchronized(trackers) {
 +        trackers.remove(tracker);
 +      }
 +    }
 +    int getNumberOfTrackers() {
 +      return trackers.size();
 +    }
 +    @Override
 +    public void run2() {
 +      long now = System.currentTimeMillis();
 +      long timeout = now - expiryTime;
 +      final boolean traceEnabled = logger.isTraceEnabled();
 +      synchronized(trackers) {
 +        for (Iterator it=trackers.iterator(); it.hasNext(); ) {
 +          EventTracker tracker = (EventTracker)it.next();
 +          if (traceEnabled) {
 +            logger.trace("{} sweeper: starting", tracker.name);
 +          }
 +          for (Iterator it2 = tracker.recordedEvents.entrySet().iterator(); it2.hasNext();) {
 +            Map.Entry e = (Map.Entry)it2.next();
 +            EventSeqnoHolder evh = (EventSeqnoHolder)e.getValue();
 +            synchronized(evh) {
 +              if (evh.endOfLifeTimer == 0) {
 +                evh.endOfLifeTimer = now; // a new holder - start the timer 
 +              }
 +              if (evh.endOfLifeTimer <= timeout) {
 +                evh.removed = true;
 +                evh.lastSeqno = -1;
 +                if (traceEnabled) {
 +                  logger.trace("{} sweeper: removing {}", tracker.name, e.getKey());
 +                }
 +                it2.remove();
 +              }
 +            }
 +          }
 +          
 +          //Remove bulk operations we're tracking
 +          for (Iterator<Map.Entry<ThreadIdentifier, BulkOpHolder>> it2 = tracker.recordedBulkOpVersionTags.entrySet().iterator(); it2.hasNext();) {
 +            Map.Entry<ThreadIdentifier, BulkOpHolder> e = it2.next();
 +            BulkOpHolder evh = e.getValue();
 +            synchronized(evh) {
 +              if (evh.endOfLifeTimer == 0) {
 +                evh.endOfLifeTimer = now; // a new holder - start the timer 
 +              }
 +              //Remove the PutAll tracker only if the put all is complete
 +              //and it has expired.
 +              if (evh.endOfLifeTimer <= timeout) {
 +                evh.removed = true;
 +                if (logger.isTraceEnabled()) {
 +                  logger.trace("{} sweeper: removing bulkOp {}", tracker.name, e.getKey());
 +                }
 +                it2.remove();
 +              }
 +            }
 +          }
 +          if (traceEnabled) {
 +            logger.trace("{} sweeper: done", tracker.name);
 +          }
 +        }
 +      }
 +    }
 +    
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
index 201acc0,0000000..201acc0
mode 100644,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/TXManagerImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/TXManagerImpl.java
index f4216ac,0000000..de49fea
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/TXManagerImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/TXManagerImpl.java
@@@ -1,1511 -1,0 +1,1511 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.DataInput;
 +import java.io.DataOutput;
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.LinkedHashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Map.Entry;
 +import java.util.Queue;
 +import java.util.Set;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentLinkedQueue;
 +import java.util.concurrent.ConcurrentMap;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.atomic.AtomicInteger;
 +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 +import java.util.concurrent.locks.LockSupport;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.GemFireException;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.CommitConflictException;
 +import com.gemstone.gemfire.cache.TransactionDataRebalancedException;
 +import com.gemstone.gemfire.cache.TransactionId;
 +import com.gemstone.gemfire.cache.TransactionInDoubtException;
 +import com.gemstone.gemfire.cache.TransactionListener;
 +import com.gemstone.gemfire.cache.TransactionWriter;
 +import com.gemstone.gemfire.cache.UnsupportedOperationInTransactionException;
 +import com.gemstone.gemfire.distributed.TXManagerCancelledException;
 +import com.gemstone.gemfire.distributed.internal.DM;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.distributed.internal.HighPriorityDistributionMessage;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.MembershipListener;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.SystemTimer.SystemTimerTask;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap;
 +import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap.HashEntry;
 +import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap.MapCallback;
 +
 +/** <p>The internal implementation of the {@link CacheTransactionManager}
 + * interface returned by {@link GemFireCacheImpl#getCacheTransactionManager}.
 + * Internal operations 
 +
 + </code>TransactionListener</code> invocation, Region synchronization, transaction statistics and
 +
 + * transaction logging are handled here 
 + * 
 + * @author Mitch Thomas
 + *
 + * @since 4.0
 + * 
 + * @see CacheTransactionManager
 + */
 +public final class TXManagerImpl implements CacheTransactionManager,
 +    MembershipListener {
 +
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  // Thread specific context container
 +  private final ThreadLocal<TXStateProxy> txContext;
 +  private static TXManagerImpl currentInstance = null;
 +  // The unique transaction ID for this Manager 
 +  private final AtomicInteger uniqId;
 +
 +  private final DM dm;
 +  private final Cache cache;
 +
 +  // The DistributionMemberID used to construct TXId's
 +  private final InternalDistributedMember distributionMgrId;
 +
 +  private final CachePerfStats cachePerfStats;
 +
 +  private static final TransactionListener[] EMPTY_LISTENERS =
 +    new TransactionListener[0];
 +
 +  /**
 +   * Default transaction id to indicate no transaction
 +   */
 +  public static final int NOTX = -1;
 +  
 +  private final ArrayList<TransactionListener> txListeners = new ArrayList<TransactionListener>(8);
 +  public TransactionWriter writer = null;
 +  private boolean closed = false;
 +
 +  private final Map<TXId, TXStateProxy> hostedTXStates;
 +
 +  /**
 +   * the number of client initiated transactions to store for client failover
 +   */
 +  public final static int FAILOVER_TX_MAP_SIZE = Integer.getInteger("gemfire.transactionFailoverMapSize", 1000);
 +  
 +  /**
 +   * used to store TXCommitMessages for client initiated transactions, so that when a client failsover,
 +   * (after the delegate dies) the commit message can be sent to client.
 +   * //TODO we really need to keep around only one msg for each thread on a client
 +   */
 +  @SuppressWarnings("unchecked")
 +  private Map<TXId ,TXCommitMessage> failoverMap = Collections.synchronizedMap(new LinkedHashMap<TXId, TXCommitMessage>() {
 +    private static final long serialVersionUID = -4156018226167594134L;
 +
 +    protected boolean removeEldestEntry(Entry eldest) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("TX: removing client initiated transaction from failover map:{} :{}", eldest.getKey(), (size()>FAILOVER_TX_MAP_SIZE));
 +      }
 +      return size() > FAILOVER_TX_MAP_SIZE;
 +    };
 +  });
 +
 +  /**
 +   * A flag to allow persistent transactions. public for testing.
 +   */
 +  public static boolean ALLOW_PERSISTENT_TRANSACTIONS = Boolean.getBoolean("gemfire.ALLOW_PERSISTENT_TRANSACTIONS");
 +
 +  /**
 +   * this keeps track of all the transactions that were initiated locally.
 +   */
 +  private ConcurrentMap<TXId, TXStateProxy> localTxMap = new ConcurrentHashMap<TXId, TXStateProxy>();
 +
 +  /**
 +   * the time in minutes after which any suspended transaction are rolled back. default is 30 minutes
 +   */
 +  private volatile long suspendedTXTimeout = Long.getLong("gemfire.suspendedTxTimeout", 30);
 +  
 +  /**
 +   * Thread-specific flag to indicate whether the transactions managed by this
 +   * CacheTransactionManager for this thread should be distributed
 +   */
 +  private final ThreadLocal<Boolean> isTXDistributed;
 +  
 +
 +  /** Constructor that implements the {@link CacheTransactionManager}
 +   * interface. Only only one instance per {@link com.gemstone.gemfire.cache.Cache}
 +   *
 +   * @param cachePerfStats 
 +   */
 +  public TXManagerImpl(
 +                       CachePerfStats cachePerfStats,
 +                       Cache cache) {
 +    this.cache = cache;
 +    this.dm = ((InternalDistributedSystem)cache.getDistributedSystem())
 +        .getDistributionManager();
 +    this.distributionMgrId = this.dm.getDistributionManagerId();
 +    this.uniqId = new AtomicInteger(0);
 +    this.cachePerfStats = cachePerfStats;
 +    this.hostedTXStates = new HashMap<TXId, TXStateProxy>();
 +    this.txContext = new ThreadLocal<TXStateProxy>();
 +    this.isTXDistributed = new ThreadLocal<Boolean>();
 +    currentInstance = this;
 +  }
 +
 +  final Cache getCache() {
 +    return this.cache;
 +  }
 +  
 +  
 +  /**
 +   * Get the TransactionWriter for the cache
 +   * 
 +   * @return the current TransactionWriter
 +   * @see TransactionWriter
 +   */
 +  public final TransactionWriter getWriter() {
 +    return writer;
 +  }
 +  
 +
 +  public final void setWriter(TransactionWriter writer) {
 +    if (((GemFireCacheImpl)this.cache).isClient()) {
 +      throw new IllegalStateException(LocalizedStrings.TXManager_NO_WRITER_ON_CLIENT.toLocalizedString());
 +    }
 +    this.writer = writer;
 +  }
 +  
 +
 +  public final TransactionListener getListener() {
 +    synchronized (this.txListeners) {
 +      if (this.txListeners.isEmpty()) {
 +      return null;
 +      } else if (this.txListeners.size() == 1) {
 +        return this.txListeners.get(0);
 +      } else {
 +        throw new IllegalStateException(LocalizedStrings.TXManagerImpl_MORE_THAN_ONE_TRANSACTION_LISTENER_EXISTS.toLocalizedString());
 +      }
 +    }
 +  }
 +  
 +  public TransactionListener[] getListeners() {
 +    synchronized (this.txListeners) {
 +      int size = this.txListeners.size();
 +      if (size == 0) {
 +        return EMPTY_LISTENERS;
 +      } else {
 +        TransactionListener[] result = new TransactionListener[size];
 +        this.txListeners.toArray(result);
 +        return result;
 +      }
 +    }
 +  }
 +  
 +  public TransactionListener setListener(TransactionListener newListener) {
 +    synchronized (this.txListeners) {
 +      TransactionListener result = getListener();
 +      this.txListeners.clear();
 +      if (newListener != null) {
 +        this.txListeners.add(newListener);
 +      }
 +      if (result != null) {
 +        closeListener(result);
 +      }
 +      return result;
 +    }
 +  }
 +  public void addListener(TransactionListener aListener) {
 +    if (aListener == null) {
 +      throw new IllegalArgumentException(LocalizedStrings.TXManagerImpl_ADDLISTENER_PARAMETER_WAS_NULL.toLocalizedString());
 +    }
 +    synchronized (this.txListeners) {
 +      if (!this.txListeners.contains(aListener)) {
 +        this.txListeners.add(aListener);
 +      }
 +    }
 +  }
 +  public void removeListener(TransactionListener aListener) {
 +    if (aListener == null) {
 +      throw new IllegalArgumentException(LocalizedStrings.TXManagerImpl_REMOVELISTENER_PARAMETER_WAS_NULL.toLocalizedString());
 +    }
 +    synchronized (this.txListeners) {
 +      if (this.txListeners.remove(aListener)) {
 +        closeListener(aListener);
 +      }
 +    }
 +  }
 +  public void initListeners(TransactionListener[] newListeners) {
 +    synchronized (this.txListeners) {
 +      if (!this.txListeners.isEmpty()) {
 +        Iterator<TransactionListener> it = this.txListeners.iterator();
 +        while (it.hasNext()) {
 +          closeListener(it.next());
 +        }
 +        this.txListeners.clear();
 +      }
 +      if (newListeners != null && newListeners.length > 0) {
 +        List<TransactionListener> nl = Arrays.asList(newListeners);
 +        if (nl.contains(null)) {
 +          throw new IllegalArgumentException(LocalizedStrings.TXManagerImpl_INITLISTENERS_PARAMETER_HAD_A_NULL_ELEMENT.toLocalizedString());
 +        }
 +        this.txListeners.addAll(nl);
 +      }
 +    }
 +  }
 +
 +  final CachePerfStats getCachePerfStats() {
 +    return this.cachePerfStats;
 +  }
 +
 +  /** Build a new {@link TXId}, use it as part of the transaction
 +   * state and associate with the current thread using a {@link
 +   * ThreadLocal}.
 +   */
 +  public void begin() {
 +    checkClosed();
 +    {
 +      TransactionId tid = getTransactionId();
 +      if (tid != null) {
 +        throw new java.lang.IllegalStateException(LocalizedStrings.TXManagerImpl_TRANSACTION_0_ALREADY_IN_PROGRESS.toLocalizedString(tid));
 +      }
 +    }
 +    TXId id = new TXId(this.distributionMgrId, this.uniqId.incrementAndGet());
 +    TXStateProxyImpl proxy = null;
 +    if (isDistributed()) {
 +      proxy = new DistTXStateProxyImplOnCoordinator(this, id, null);  
 +    } else {
 +      proxy = new TXStateProxyImpl(this, id, null);  
 +    }
 +    setTXState(proxy);
 +    this.localTxMap.put(id, proxy);
 +  }
 +
 +
 +  /** Build a new {@link TXId}, use it as part of the transaction
 +   * state and associate with the current thread using a {@link
 +   * ThreadLocal}. Flag the transaction to be enlisted with a JTA
 +   * Transaction.  Should only be called in a context where we know
 +   * there is no existing transaction.
 +   */
 +  public TXStateProxy beginJTA() {
 +    checkClosed();
 +    TXId id = new TXId(this.distributionMgrId, this.uniqId.incrementAndGet());
 +    TXStateProxy newState = null;
 +    
 +    if (isDistributed()) {
 +      newState = new DistTXStateProxyImplOnCoordinator(this, id, true);
 +    } else {
 +      newState = new TXStateProxyImpl(this, id, true);
 +    }
 +    setTXState(newState);
 +    return newState;
 +  }
 +
 +  /*
 +   * Only applicable for Distributed transaction.
 +   */
 +  public void precommit() throws CommitConflictException {
 +    checkClosed();
 +
 +    final TXStateProxy tx = getTXState();
 +    if (tx == null) {
 +      throw new IllegalStateException(LocalizedStrings.TXManagerImpl_THREAD_DOES_NOT_HAVE_AN_ACTIVE_TRANSACTION.toLocalizedString());
 +    }
 +    
 +    tx.checkJTA(LocalizedStrings.TXManagerImpl_CAN_NOT_COMMIT_THIS_TRANSACTION_BECAUSE_IT_IS_ENLISTED_WITH_A_JTA_TRANSACTION_USE_THE_JTA_MANAGER_TO_PERFORM_THE_COMMIT.toLocalizedString());
 +  
 +    tx.precommit();
 +  }
 +  
 +  /** Complete the transaction associated with the current
 +   *  thread. When this method completes, the thread is no longer
 +   *  associated with a transaction.
 +   *
 +   */
 +  public void commit() throws CommitConflictException {
 +    checkClosed();
 +
 +    final TXStateProxy tx = getTXState();
 +    if (tx == null) {
 +      throw new IllegalStateException(LocalizedStrings.TXManagerImpl_THREAD_DOES_NOT_HAVE_AN_ACTIVE_TRANSACTION.toLocalizedString());
 +    }
 +
 +    tx.checkJTA(LocalizedStrings.TXManagerImpl_CAN_NOT_COMMIT_THIS_TRANSACTION_BECAUSE_IT_IS_ENLISTED_WITH_A_JTA_TRANSACTION_USE_THE_JTA_MANAGER_TO_PERFORM_THE_COMMIT.toLocalizedString());
 +
 +    final long opStart = CachePerfStats.getStatTime();
 +    final long lifeTime = opStart - tx.getBeginTime();
 +    try {
 +      setTXState(null);
 +      tx.commit();
 +    } catch (CommitConflictException ex) {
 +      saveTXStateForClientFailover(tx, TXCommitMessage.CMT_CONFLICT_MSG); //fixes #43350
 +      noteCommitFailure(opStart, lifeTime, tx);
 +      cleanup(tx.getTransactionId()); // fixes #52086
 +      throw ex;
 +    } catch (TransactionDataRebalancedException reb) {
 +      saveTXStateForClientFailover(tx, TXCommitMessage.REBALANCE_MSG);
 +      cleanup(tx.getTransactionId()); // fixes #52086
 +      throw reb;
 +    } catch (UnsupportedOperationInTransactionException e) {
 +      // fix for #42490
 +      setTXState(tx);
 +      throw e;
 +    } catch (RuntimeException e) {
 +      saveTXStateForClientFailover(tx, TXCommitMessage.EXCEPTION_MSG);
 +      cleanup(tx.getTransactionId()); // fixes #52086
 +      throw e;
 +    }
 +    saveTXStateForClientFailover(tx);
 +    cleanup(tx.getTransactionId());
 +    noteCommitSuccess(opStart, lifeTime, tx);
 +  }
 +
 +  final void noteCommitFailure(long opStart, long lifeTime, TXStateInterface tx) {
 +    long opEnd = CachePerfStats.getStatTime();
 +    this.cachePerfStats.txFailure(opEnd - opStart,
 +                                  lifeTime, tx.getChanges());
 +    TransactionListener[] listeners = getListeners();
 +    if (tx.isFireCallbacks() && listeners.length > 0) {
 +      final TXEvent e = tx.getEvent();
 +      try {
 +      for (int i=0; i < listeners.length; i++) {
 +        try {
 +          listeners[i].afterFailedCommit(e);
 +        } 
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          logger.error(LocalizedMessage.create(LocalizedStrings.TXManagerImpl_EXCEPTION_OCCURRED_IN_TRANSACTIONLISTENER), t);
 +        }
 +      }
 +      } finally {
 +        e.release();
 +      }
 +    }
 +  }
 +
 +  final void noteCommitSuccess(long opStart, long lifeTime, TXStateInterface tx) {
 +    long opEnd = CachePerfStats.getStatTime();
 +    this.cachePerfStats.txSuccess(opEnd - opStart,
 +                                  lifeTime, tx.getChanges());
 +    TransactionListener[] listeners = getListeners();
 +    if (tx.isFireCallbacks() && listeners.length > 0) {
 +      final TXEvent e = tx.getEvent();
 +      try {
 +      for (final TransactionListener listener : listeners) {
 +        try {
 +          listener.afterCommit(e);
 +        } 
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          logger.error(LocalizedMessage.create(LocalizedStrings.TXManagerImpl_EXCEPTION_OCCURRED_IN_TRANSACTIONLISTENER), t);
 +        }
 +      }
 +      } finally {
 +        e.release();
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * prepare for transaction replay by assigning a new tx id to the current proxy
 +   */
 +  private void _incrementTXUniqueIDForReplay() {
 +    TXStateProxyImpl tx = (TXStateProxyImpl)getTXState();
 +    assert tx != null : "expected a transaction to be in progress";
 +    TXId id = new TXId(this.distributionMgrId, this.uniqId.incrementAndGet());
 +    tx.setTXIDForReplay(id);
 +  }
 +
 +
 +  /** Roll back the transaction associated with the current
 +   *  thread. When this method completes, the thread is no longer
 +   *  associated with a transaction.
 +   */
 +  public void rollback() {
 +    checkClosed();
 +    TXStateProxy tx = getTXState();
 +    if (tx == null) {
 +      throw new IllegalStateException(LocalizedStrings.TXManagerImpl_THREAD_DOES_NOT_HAVE_AN_ACTIVE_TRANSACTION.toLocalizedString());
 +    }
 +
 +    tx.checkJTA(LocalizedStrings.TXManagerImpl_CAN_NOT_ROLLBACK_THIS_TRANSACTION_IS_ENLISTED_WITH_A_JTA_TRANSACTION_USE_THE_JTA_MANAGER_TO_PERFORM_THE_ROLLBACK.toLocalizedString());
 +
 +    final long opStart = CachePerfStats.getStatTime();
 +    final long lifeTime = opStart - tx.getBeginTime();
 +    setTXState(null);
 +    tx.rollback();
 +    saveTXStateForClientFailover(tx);
 +    cleanup(tx.getTransactionId());
 +    noteRollbackSuccess(opStart, lifeTime, tx);
 +  }
 +  
 +  final void noteRollbackSuccess(long opStart, long lifeTime, TXStateInterface tx) {
 +    long opEnd = CachePerfStats.getStatTime();
 +    this.cachePerfStats.txRollback(opEnd - opStart,
 +                                   lifeTime, tx.getChanges());
 +    TransactionListener[] listeners = getListeners();
 +    if (tx.isFireCallbacks() && listeners.length > 0) {
 +      final TXEvent e = tx.getEvent();
 +      try {
 +      for (int i = 0; i < listeners.length; i++) {
 +        try {
 +          listeners[i].afterRollback(e);
 +        } 
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          logger.error(LocalizedMessage.create(LocalizedStrings.TXManagerImpl_EXCEPTION_OCCURRED_IN_TRANSACTIONLISTENER), t);
 +        }
 +      }
 +      } finally {
 +        e.release();
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Called from Commit and Rollback to unblock waiting threads
 +   */
 +  private void cleanup(TransactionId txId) {
 +    TXStateProxy proxy = this.localTxMap.remove(txId);
 +    if (proxy != null) {
 +      proxy.close();
 +    }
 +    Queue<Thread> waitingThreads = this.waitMap.get(txId);
 +    if (waitingThreads != null && !waitingThreads.isEmpty()) {
 +      for (Thread waitingThread : waitingThreads) {
 +        LockSupport.unpark(waitingThread);
 +      }
 +      waitMap.remove(txId);
 +    }
 +  }
 +  
 +  /** Reports the existance of a Transaction for this thread
 +   *
 +   */
 +  public boolean exists() {
 +    return null != getTXState();
 +  }
 +
 +  /** Gets the current transaction identifier or null if no transaction exists
 +   *
 +   */
 +  public TransactionId getTransactionId() {
 +    TXStateProxy t = getTXState();
 +    TransactionId ret = null;
 +    if (t!=null) {
 +      ret = t.getTransactionId();
 +    } 
 +    return ret;
 +  }
 +
 +  /** 
 +   * Returns the TXStateProxyInterface of the current thread; null if no transaction.
 +   */
 +  public final TXStateProxy getTXState() {
 +    TXStateProxy tsp = txContext.get();
 +    if (tsp != null && !tsp.isInProgress()) {
 +      this.txContext.set(null);
 +      tsp = null;
 +    }
 +    return tsp;
 +  }
 +
 +  /**
 +   * sets {@link TXStateProxy#setInProgress(boolean)} when a txContext is present.
 +   * This method must only be used in fail-over scenarios.
 +   * @param progress value of the progress flag to be set
 +   * @return the previous value of inProgress flag
 +   * @see TXStateProxy#setInProgress(boolean)
 +   */
 +  public boolean setInProgress(boolean progress) {
 +    boolean retVal = false;
 +    TXStateProxy tsp = txContext.get();
 +    if (tsp != null) {
 +      retVal = tsp.isInProgress();
 +      tsp.setInProgress(progress);
 +    }
 +    return retVal;
 +  }
 +
 +  public final void setTXState(TXStateProxy val) {
 +    txContext.set(val);
 +  }
 +
 +
 +  public void close() {
 +    if (isClosed()) {
 +      return;
 +    }
 +    this.closed = true;
 +    for (TXStateProxy proxy: this.hostedTXStates.values()) {
 +      proxy.close();
 +    }
 +    for (TXStateProxy proxy: this.localTxMap.values()) {
 +      proxy.close();
 +    }
 +    {
 +      TransactionListener[] listeners = getListeners();
 +      for (int i=0; i < listeners.length; i++) {
 +        closeListener(listeners[i]);
 +      }
 +    }
 +  }
 +  private void closeListener(TransactionListener tl) {
 +    try {
 +      tl.close();
 +    } 
 +    catch (VirtualMachineError err) {
 +      SystemFailure.initiateFailure(err);
 +      // If this ever returns, rethrow the error.  We're poisoned
 +      // now, so don't let this thread continue.
 +      throw err;
 +    }
 +    catch (Throwable t) {
 +      // Whenever you catch Error or Throwable, you must also
 +      // catch VirtualMachineError (see above).  However, there is
 +      // _still_ a possibility that you are dealing with a cascading
 +      // error condition, so you also need to check to see if the JVM
 +      // is still usable:
 +      SystemFailure.checkFailure();
 +      logger.error(LocalizedMessage.create(LocalizedStrings.TXManagerImpl_EXCEPTION_OCCURRED_IN_TRANSACTIONLISTENER), t);
 +    }
 +  }
 +  /**
 +   * If the current thread is in a transaction then suspend will
 +   * cause it to no longer be in a transaction.
 +   * @return the state of the transaction or null. Pass this value
 +   *  to {@link TXManagerImpl#resume} to reactivate the suspended transaction.
 +   */
 +  public final TXStateProxy internalSuspend() {
 +    TXStateProxy result = getTXState();
 +    if (result != null) {
 +      result.suspend();
 +      setTXState(null);
 +    }
 +    return result;
 +  }
 +  /**
 +   * Activates the specified transaction on the calling thread.
 +   * @param tx the transaction to activate.
 +   * @throws IllegalStateException if this thread already has an active transaction
 +   */
 +  public final void resume(TXStateProxy tx) {
 +    if (tx != null) {
 +      TransactionId tid = getTransactionId();
 +      if (tid != null) {
 +        throw new java.lang.IllegalStateException(LocalizedStrings.TXManagerImpl_TRANSACTION_0_ALREADY_IN_PROGRESS.toLocalizedString(tid));
 +      }
 +      if (tx instanceof TXState) {
 +        throw new java.lang.IllegalStateException("Found instance of TXState: " + tx);
 +      }
 +      setTXState(tx);
 +      tx.resume();
 +      SystemTimerTask task = this.expiryTasks.remove(tx.getTransactionId());
 +      if (task != null) {
 +        task.cancel();
 +      }
 +    }
 +  }
 +
 +  private final boolean isClosed() {
 +    return this.closed;
 +  }
 +  private final void checkClosed() {
 +    cache.getCancelCriterion().checkCancelInProgress(null);
 +    if (this.closed) {
 +      throw new TXManagerCancelledException("This transaction manager is closed.");
 +    }
 +  }
 +
 +  final DM getDM() {
 +    return this.dm;
 +  }
 +
 +  
 +  public static int getCurrentTXUniqueId() {
 +    if(currentInstance==null) {
 +      return NOTX;
 +    }
 +    return currentInstance.getMyTXUniqueId();
 +  }
 +  
 +  
 +  
 +  
 +  public final static TXStateProxy getCurrentTXState() {
 +    if(currentInstance==null) {
 +      return null;
 +    }
 +    return currentInstance.getTXState();
 +  }
 +  
 +  public static void incrementTXUniqueIDForReplay() {
 +    if(currentInstance != null) {
 +      currentInstance._incrementTXUniqueIDForReplay();
 +    }
 +  }
 +  
 +  public int getMyTXUniqueId() {
 +    TXStateProxy t = txContext.get();
 +    if (t != null) {
 +      return t.getTxId().getUniqId();
 +    } else {
 +      return NOTX;
 +    }
 +  }
 +
 +  /**
 +   * Associate the remote txState with the thread processing this message. Also,
 +   * we acquire a lock on the txState, on which this thread operates.
 +   * Some messages like SizeMessage should not create a new txState.
 +   * @param msg
 +   * @return {@link TXStateProxy} the txProxy for the transactional message
 +   * @throws InterruptedException 
 +   */
 +  public TXStateProxy masqueradeAs(TransactionMessage msg) throws InterruptedException {
 +    if (msg.getTXUniqId() == NOTX || !msg.canParticipateInTransaction()) {
 +      return null;
 +    }
 +    TXId key = new TXId(msg.getMemberToMasqueradeAs(), msg.getTXUniqId());
 +    TXStateProxy val;
 +    val = this.hostedTXStates.get(key);
 +    if (val == null) {
 +      synchronized(this.hostedTXStates) {
 +        val = this.hostedTXStates.get(key);
 +        if (val == null && msg.canStartRemoteTransaction()) {
 +          if (msg.isTransactionDistributed()) {
 +            val = new DistTXStateProxyImplOnDatanode(this, key, msg.getTXOriginatorClient());
 +            val.setLocalTXState(new DistTXState(val,true));
 +          } else {
 +            val = new TXStateProxyImpl(this, key, msg.getTXOriginatorClient());
 +            val.setLocalTXState(new TXState(val,true));
 +          }
 +          this.hostedTXStates.put(key, val);
 +        }
 +      }
 +    }
 +    if (val != null) {
 +      if (!val.getLock().isHeldByCurrentThread()) {
 +        val.getLock().lock();
 +      }
 +    }
 +
 +    setTXState(val);
 +    return val;
 +  }
 +  
 +  /**
 +   * Associate the remote txState with the thread processing this message. Also,
 +   * we acquire a lock on the txState, on which this thread operates.
 +   * Some messages like SizeMessage should not create a new txState.
 +   * @param msg
 +   * @param memberId
 +   * @param probeOnly - do not masquerade; just look up the TX state
 +   * @return {@link TXStateProxy} the txProxy for the transactional message
 +   * @throws InterruptedException 
 +   */
 +  public TXStateProxy masqueradeAs(Message msg,InternalDistributedMember memberId, boolean probeOnly) throws InterruptedException {
 +    if (msg.getTransactionId() == NOTX) {
 +      return null;
 +    }
 +    TXId key = new TXId(memberId, msg.getTransactionId());
 +    TXStateProxy val;
 +    val = this.hostedTXStates.get(key);
 +    if (val == null) {
 +      synchronized(this.hostedTXStates) {
 +        val = this.hostedTXStates.get(key);
-         if (val == null && msg.canStartRemoteTransaction()) {
++        if (val == null) {
 +          // [sjigyasu] TODO: Conditionally create object based on distributed or non-distributed tx mode 
 +          if (msg instanceof TransactionMessage && ((TransactionMessage)msg).isTransactionDistributed()) {
 +            val = new DistTXStateProxyImplOnDatanode(this, key, memberId);
 +            //val.setLocalTXState(new DistTXState(val,true));
 +          } else {
 +            val = new TXStateProxyImpl(this, key, memberId);
 +            //val.setLocalTXState(new TXState(val,true));
 +          }
 +          this.hostedTXStates.put(key, val);
 +        }
 +      }
 +    }
 +    if (!probeOnly) {
 +      if (val != null) {
 +        if (!val.getLock().isHeldByCurrentThread()) {
 +          val.getLock().lock();
 +          // add the TXStateProxy back to the map
 +          // in-case another thread removed it while we were waiting to lock.
 +          // This can happen during client transaction failover.
 +          synchronized (this.hostedTXStates) {
 +            this.hostedTXStates.put(key, val);
 +          }
 +        }
 +      }
 +      setTXState(val);
 +    }
 +    return val;
 +  }
 +  
 +  
 +  
 +  
 +  /**
 +   * Associate the transactional state with this thread.
 +   * @param txState the transactional state.
 +   */
 +  public void masqueradeAs(TXStateProxy txState) {
 +    assert txState != null;
 +    if (!txState.getLock().isHeldByCurrentThread()) {
 +      txState.getLock().lock();
 +    }
 +    setTXState(txState);
 +  }
 +
 +  /**
 +   * Remove the association created by {@link #masqueradeAs(TransactionMessage)}
 +   * @param tx
 +   */
 +  public void unmasquerade(TXStateProxy tx) {
 +    if (tx != null) {
 +      setTXState(null);
 +      tx.getLock().unlock();
 +    }
 +  }
 +
 +  /**
 +   * Cleanup the remote txState after commit and rollback
 +   * @param txId  
 +   * @return the TXStateProxy
 +   */
 +  public TXStateProxy removeHostedTXState(TXId txId) {
 +    synchronized (this.hostedTXStates) {
 +      TXStateProxy result = this.hostedTXStates.remove(txId);
 +      if (result != null) {
 +        result.close();
 +      }
 +      return result;
 +    }
 +  }
 +  
 +  /**
 +   * Called when the CacheServer is shutdown.
 +   * Removes txStates hosted on client's behalf
 +   */
 +  protected void removeHostedTXStatesForClients() {
 +    synchronized (this.hostedTXStates) {
 +      Iterator<Entry<TXId, TXStateProxy>> iterator = this.hostedTXStates.entrySet().iterator();
 +      while (iterator.hasNext()) {
 +        Entry<TXId, TXStateProxy> entry = iterator.next();
 +        if (entry.getValue().isOnBehalfOfClient()) {
 +          entry.getValue().close();
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Cleaning up TXStateProxy for {}", entry.getKey());
 +          }
 +          iterator.remove();
 +        }
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Used to verify if a transaction with a given id is hosted by this txManager.
 +   * @param txId
 +   * @return true if the transaction is in progress, false otherwise
 +   */
 +  public boolean isHostedTxInProgress(TXId txId) {
 +    synchronized (this.hostedTXStates) {
 +      TXStateProxy tx = this.hostedTXStates.get(txId);
 +      if (tx == null) {
 +        return false;
 +      }
 +      return tx.isRealDealLocal();
 +    }
 +  }
 +
 +  public TXStateProxy getHostedTXState(TXId txId) {
 +    synchronized (this.hostedTXStates) {
 +      return this.hostedTXStates.get(txId);
 +    }
 +  }
 +  
 +  /**
 +   * @return number of transaction in progress on behalf of remote nodes
 +   */
 +  public int hostedTransactionsInProgressForTest() {
 +    synchronized (this.hostedTXStates) {
 +      return this.hostedTXStates.size();
 +    }
 +  }
 +  public int localTransactionsInProgressForTest() {
 +    return this.localTxMap.size();
 +  }
 +
 +  public void memberDeparted(InternalDistributedMember id, boolean crashed) {
 +    synchronized (this.hostedTXStates) {
 +      Iterator<Map.Entry<TXId,TXStateProxy>> iterator = this.hostedTXStates.entrySet().iterator();
 +      while (iterator.hasNext()) {
 +        Map.Entry<TXId,TXStateProxy> me = iterator.next();
 +        TXId txId = me.getKey();
 +        if (txId.getMemberId().equals(id)) {
 +          me.getValue().close();
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Received memberDeparted, cleaning up txState:{}", txId);
 +          }
 +          iterator.remove();
 +        }
 +      }
 +    }
 +  }
 +
 +  public void memberJoined(InternalDistributedMember id) {
 +  }
 +
 +  public void quorumLost(Set<InternalDistributedMember> failures, List<InternalDistributedMember> remaining) {
 +  }
 +
 +  public void memberSuspect(InternalDistributedMember id,
 +      InternalDistributedMember whoSuspected, String reason) {
 +  }
 +  
 +
 +  /**
 +   * retrieve the transaction states for the given client
 +   * @param id the client's membership ID
 +   * @return a set of the currently open transaction states
 +   */
 +  public Set<TXId> getTransactionsForClient(InternalDistributedMember id) {
 +    Set<TXId> result = new HashSet<TXId>();
 +    synchronized (this.hostedTXStates) {
 +      for (Map.Entry<TXId, TXStateProxy> entry: this.hostedTXStates.entrySet()) {
 +        if (entry.getKey().getMemberId().equals(id)) {
 +          result.add(entry.getKey());
 +        }
 +      }
 +    }
 +    return result;
 +  }
 +
 +  /** remove the given TXStates */
 +  public void removeTransactions(Set<TXId> txIds, boolean distribute) {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("expiring the following transactions: {}", txIds);
 +    }
 +    synchronized (this.hostedTXStates) {
 +      Iterator<Map.Entry<TXId, TXStateProxy>> iterator = this.hostedTXStates.entrySet().iterator();
 +      while (iterator.hasNext()) {
 +        Map.Entry<TXId,TXStateProxy> entry = iterator.next();
 +        if (txIds.contains(entry.getKey())) {
 +          entry.getValue().close();
 +          iterator.remove();
 +        }
 +      }
 +    }
 +    if (distribute) {
 +      // tell other VMs to also remove the transactions
 +      TXRemovalMessage.send(this.dm, this.dm.getOtherDistributionManagerIds(), txIds);
 +    }
 +  }
 +
 +  private void saveTXStateForClientFailover(TXStateProxy tx) {
 +    if (tx.isOnBehalfOfClient() && tx.isRealDealLocal()) {
 +      failoverMap.put(tx.getTxId(), tx.getCommitMessage());
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("TX: storing client initiated transaction:{}; now there are {} entries in the failoverMap",
 +            tx.getTxId(), failoverMap.size());
 +      }
 +    }
 +  }
 +
 +  private void saveTXStateForClientFailover(TXStateProxy tx, TXCommitMessage msg) {
 +    if (tx.isOnBehalfOfClient() && tx.isRealDealLocal()) {
 +      failoverMap.put(tx.getTxId(), msg);
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("TX: storing client initiated transaction:{}; now there are {} entries in the failoverMap",
 +            tx.getTxId(), failoverMap.size());
 +      }
 +    }
 +  }
 +
 +  public void saveTXCommitMessageForClientFailover(TXId txId, TXCommitMessage msg) {
 +    failoverMap.put(txId, msg);
 +  }
 +  
 +  public boolean isHostedTxRecentlyCompleted(TXId txId) {
 +    // if someone is asking to see if we have the txId, they will come
 +    // back and ask for the commit message, this could take a long time
 +    // specially when called from TXFailoverCommand, so we move
 +    // the txId to the front of the queue
 +    TXCommitMessage msg = failoverMap.remove(txId);
 +    if (msg != null) {
 +      failoverMap.put(txId, msg);
 +      return true;
 +    }
 +    return false;
 +  }
 +  
 +  
 +  /**
 +   * If the given transaction is already being completed by another thread
 +   * this will wait for that completion to finish and will ensure that
 +   * the result is saved in the client failover map.
 +   * @param txId
 +   * @return true if a wait was performed
 +   */
 +  public boolean waitForCompletingTransaction(TXId txId) {
 +    TXStateProxy val;
 +    val = this.hostedTXStates.get(txId);
 +    if (val == null) {
 +      synchronized(this.hostedTXStates) {
 +        val = this.hostedTXStates.get(txId);
 +      }
 +    }
 +    if (val != null && val.isRealDealLocal()) {
 +      TXStateProxyImpl impl = (TXStateProxyImpl)val;
 +      TXState state = impl.getLocalRealDeal();
 +      if (state.waitForPreviousCompletion()) {
 +        // the thread we were waiting for would have put a TXCommitMessage
 +        // in the failover map, doing so here may replace an existing token
 +        // like TXCommitMessage.REBALANCE_MSG with null. fixes bug 42661
 +        //saveTXStateForClientFailover(impl);
 +        return true;
 +      }
 +    }
 +    return false;
 +  }
 +  
 +  /**
 +   * Returns the TXCommitMessage for a transaction that has been
 +   * successfully completed.
 +   * @param txId
 +   * @return the commit message or an exception token e.g 
 +   * {@link TXCommitMessage#CMT_CONFLICT_MSG} if the transaction
 +   * threw an exception
 +   * @see #isExceptionToken(TXCommitMessage)
 +   */
 +  public TXCommitMessage getRecentlyCompletedMessage(TXId txId) {
 +    return failoverMap.get(txId);
 +  }
 +
 +  /**
 +   * @param msg
 +   * @return true if msg is an exception token, false otherwise
 +   */
 +  public boolean isExceptionToken(TXCommitMessage msg) {
 +    if (msg == TXCommitMessage.CMT_CONFLICT_MSG
 +        || msg == TXCommitMessage.REBALANCE_MSG
 +        || msg == TXCommitMessage.EXCEPTION_MSG) {
 +      return true;
 +    }
 +    return false;
 +  }
 +  
 +  /**
 +   * Generates exception messages for the three TXCommitMessage tokens that represent
 +   * exceptions during transaction execution. 
 +   * @param msg the token that represents the exception
 +   * @param txId
 +   * @return the exception
 +   */
 +  public RuntimeException getExceptionForToken(TXCommitMessage msg, TXId txId) {
 +    if (msg == TXCommitMessage.CMT_CONFLICT_MSG) {
 +      return new CommitConflictException(LocalizedStrings.
 +            TXState_CONFLICT_DETECTED_IN_GEMFIRE_TRANSACTION_0.toLocalizedString(txId));
 +    }
 +    if (msg == TXCommitMessage.REBALANCE_MSG) {
 +      return new TransactionDataRebalancedException(LocalizedStrings.
 +          PartitionedRegion_TRANSACTIONAL_DATA_MOVED_DUE_TO_REBALANCING.toLocalizedString());
 +    }
 +    if (msg == TXCommitMessage.EXCEPTION_MSG) {
 +      return new TransactionInDoubtException(LocalizedStrings.
 +          ClientTXStateStub_COMMIT_FAILED_ON_SERVER.toLocalizedString());
 +    }
 +    throw new InternalGemFireError("the parameter TXCommitMessage is not an exception token");
 +  }
 +  
 +  public static class TXRemovalMessage extends HighPriorityDistributionMessage {
 +
 +    Set<TXId> txIds;
 +
 +    /** for deserialization */
 +    public TXRemovalMessage() {
 +    }
 +
 +    static void send(DM dm, Set recipients, Set<TXId> txIds) {
 +      TXRemovalMessage msg = new TXRemovalMessage();
 +      msg.txIds = txIds;
 +      msg.setRecipients(recipients);
 +      dm.putOutgoing(msg);
 +    }
 +    
 +    @Override
 +    public void toData(DataOutput out) throws IOException {
 +      DataSerializer.writeHashSet((HashSet<TXId>)this.txIds, out);
 +    }
 +    
 +    @Override
 +    public void fromData(DataInput in) throws IOException, ClassNotFoundException {
 +      this.txIds = DataSerializer.readHashSet(in);
 +    }
 +
 +    public int getDSFID() {
 +      return TX_MANAGER_REMOVE_TRANSACTIONS;
 +    }
 +
 +    @Override
 +    protected void process(DistributionManager dm) {
 +      GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
 +      if (cache != null) {
 +        TXManagerImpl mgr = cache.getTXMgr();
 +        mgr.removeTransactions(this.txIds, false);
 +      }
 +    }
 +    
 +  }
 +
 +  private ConcurrentMap<TransactionId, TXStateProxy> suspendedTXs = new ConcurrentHashMap<TransactionId, TXStateProxy>();
 +  
 +  public TransactionId suspend() {
 +    return suspend(TimeUnit.MINUTES);
 +  }
 +  
 +  TransactionId suspend(TimeUnit expiryTimeUnit) {
 +    TXStateProxy result = getTXState();
 +    if (result != null) {
 +      TransactionId txId = result.getTransactionId();
 +      internalSuspend();
 +      this.suspendedTXs.put(txId, result);
 +      // wake up waiting threads
 +      Queue<Thread> waitingThreads = this.waitMap.get(txId);
 +      if (waitingThreads != null) {
 +        Thread waitingThread = null;
 +        while (true) {
 +          waitingThread = waitingThreads.poll();
 +          if (waitingThread == null
 +              || !Thread.currentThread().equals(waitingThread)) {
 +            break;
 +          }
 +        }
 +        if (waitingThread != null) {
 +          LockSupport.unpark(waitingThread);
 +        }
 +      }
 +      scheduleExpiry(txId, expiryTimeUnit);
 +      return txId;
 +    }
 +    return null;
 +  }
 +
 +  public void resume(TransactionId transactionId) {
 +    if (transactionId == null) {
 +      throw new IllegalStateException(
 +          LocalizedStrings.TXManagerImpl_UNKNOWN_TRANSACTION_OR_RESUMED
 +              .toLocalizedString());
 +    }
 +    if (getTXState() != null) {
 +      throw new IllegalStateException(
 +          LocalizedStrings.TXManagerImpl_TRANSACTION_ACTIVE_CANNOT_RESUME
 +              .toLocalizedString());
 +    }
 +    TXStateProxy txProxy = this.suspendedTXs.remove(transactionId);
 +    if (txProxy == null) {
 +      throw new IllegalStateException(
 +          LocalizedStrings.TXManagerImpl_UNKNOWN_TRANSACTION_OR_RESUMED
 +              .toLocalizedString());
 +    }
 +    resume(txProxy);
 +  }
 +
 +  public boolean isSuspended(TransactionId transactionId) {
 +    return this.suspendedTXs.containsKey(transactionId);
 +  }
 +  
 +  public boolean tryResume(TransactionId transactionId) {
 +    if (transactionId == null || getTXState() != null) {
 +      return false;
 +    }
 +    TXStateProxy txProxy = this.suspendedTXs.remove(transactionId);
 +    if (txProxy != null) {
 +      resume(txProxy);
 +      return true;
 +    }
 +    return false;
 +  }
 +
 +  /**
 +   * this map keeps track of all the threads that are waiting in
 +   * {@link #tryResume(TransactionId, long, TimeUnit)} for a particular
 +   * transactionId
 +   */
 +  private ConcurrentMap<TransactionId, Queue<Thread>> waitMap = new ConcurrentHashMap<TransactionId, Queue<Thread>>();
 +  
 +  public boolean tryResume(TransactionId transactionId, long time, TimeUnit unit) {
 +    if (transactionId == null || getTXState() != null || !exists(transactionId)) {
 +      return false;
 +    }
 +    Thread currentThread = Thread.currentThread();
 +    long timeout = unit.toNanos(time);
 +    long startTime = System.nanoTime();
 +    Queue<Thread> threadq = null;
 +
 +    try {
 +      while (true) {
 +        threadq = waitMap.get(transactionId);
 +        if (threadq == null) {
 +          threadq = new ConcurrentLinkedQueue<Thread>();
 +          Queue<Thread> oldq = waitMap.putIfAbsent(transactionId, threadq);
 +          if (oldq != null) {
 +            threadq = oldq;
 +          }
 +        }
 +        threadq.add(currentThread);
 +        // after putting this thread in waitMap, we should check for
 +        // an entry in suspendedTXs. if no entry is found in suspendedTXs
 +        // next invocation of suspend() will unblock this thread
 +        if (tryResume(transactionId)) {
 +          return true;
 +        } else if (!exists(transactionId)) {
 +          return false;
 +        }
 +        LockSupport.parkNanos(timeout);
 +        long nowTime = System.nanoTime();
 +        timeout -= nowTime - startTime;
 +        startTime = nowTime;
 +        if (timeout <= 0) {
 +          break;
 +        }
 +      }
 +    } finally {
 +      threadq = waitMap.get(transactionId);
 +      if (threadq != null) {
 +        threadq.remove(currentThread);
 +        // the queue itself will be removed at commit/rollback
 +      }
 +    }
 +    return false;
 +  }
 +
 +  public boolean exists(TransactionId transactionId) {
 +    return isHostedTxInProgress((TXId) transactionId)
 +        || isSuspended(transactionId)
 +        || this.localTxMap.containsKey(transactionId);
 +  }
 +
 +  /**
 +   * The timeout after which any suspended transactions are
 +   * rolled back if they are not resumed. If a negative
 +   * timeout is passed, suspended transactions will never expire.
 +   * @param timeout the timeout in minutes
 +   */
 +  public void setSuspendedTransactionTimeout(long timeout) {
 +    this.suspendedTXTimeout = timeout;
 +  }
 +
 +  /**
 +   * Return the timeout after which suspended transactions
 +   * are rolled back.
 +   * @return the timeout in minutes
 +   * @see #setSuspendedTransactionTimeout(long)
 +   */
 +  public long getSuspendedTransactionTimeout() {
 +    return this.suspendedTXTimeout;
 +  }
 +  
 +  /**
 +   * map to track the scheduled expiry tasks of suspended transactions.
 +   */
 +  private ConcurrentMap<TransactionId, SystemTimerTask> expiryTasks = new ConcurrentHashMap<TransactionId, SystemTimerTask>();
 +  
 +  /**
 +   * schedules the transaction to expire after {@link #suspendedTXTimeout}
 +   * @param txId
 +   * @param expiryTimeUnit the time unit to use when scheduling the expiration
 +   */
 +  private void scheduleExpiry(TransactionId txId, TimeUnit expiryTimeUnit) {
 +    final GemFireCacheImpl cache = (GemFireCacheImpl) this.cache;
 +    if (suspendedTXTimeout < 0) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("TX: transaction: {} not scheduled to expire", txId);
 +      }
 +      return;
 +    }
 +    SystemTimerTask task = new TXExpiryTask(txId);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("TX: scheduling transaction: {} to expire after:{}", txId, suspendedTXTimeout);
 +    }
 +    cache.getCCPTimer().schedule(task, TimeUnit.MILLISECONDS.convert(suspendedTXTimeout, expiryTimeUnit));
 +    this.expiryTasks.put(txId, task);
 +  }
 +
 +  /**
 +   * Task scheduled to expire a transaction when it is suspended.
 +   * This task gets canceled if the transaction is resumed.
 +   * @author sbawaska
 +   */
 +  public static class TXExpiryTask extends SystemTimerTask {
 +
 +    /**
 +     * The txId to expire
 +     */
 +    private final TransactionId txId;
 +    
 +    public TXExpiryTask(TransactionId txId) {
 +      this.txId = txId;
 +    }
 +    @Override
 +    public void run2() {
 +      TXManagerImpl mgr = TXManagerImpl.currentInstance;
 +      TXStateProxy tx = mgr.suspendedTXs.remove(txId);
 +      if (tx != null) {
 +        try {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("TX: Expiry task rolling back transaction: {}", txId);
 +          }
 +          tx.rollback();
 +        } catch (GemFireException e) {
 +          logger.warn(LocalizedMessage.create(LocalizedStrings.TXManagerImpl_EXCEPTION_IN_TRANSACTION_TIMEOUT, txId), e);
 +        }
 +      }
 +    }
 +  }
 +  private static class RefCountMapEntryCreator implements CustomEntryConcurrentHashMap.HashEntryCreator<AbstractRegionEntry, RefCountMapEntry> {
 +    @Override
 +    public HashEntry<AbstractRegionEntry, RefCountMapEntry> newEntry(AbstractRegionEntry key, int hash,
 +        HashEntry<AbstractRegionEntry, RefCountMapEntry> next, RefCountMapEntry value) {
 +      value.setNextEntry(next);
 +      return value;
 +    }
 +
 +    @Override
 +    public int keyHashCode(Object key, boolean compareValues) {
 +      // key will always be an AbstractRegionEntry because our map is strongly typed.
 +      return ((AbstractRegionEntry) key).getEntryHash();
 +    }
 +  }
 +  private static class RefCountMapEntry implements HashEntry<AbstractRegionEntry, RefCountMapEntry> {
 +    private final AbstractRegionEntry key;
 +    private HashEntry<AbstractRegionEntry, RefCountMapEntry> next;
 +    private volatile int refCount;
 +    private static final AtomicIntegerFieldUpdater<RefCountMapEntry> refCountUpdater
 +      = AtomicIntegerFieldUpdater.newUpdater(RefCountMapEntry.class, "refCount");    
 +    public RefCountMapEntry(AbstractRegionEntry k) {
 +      this.key = k;
 +      this.refCount = 1;
 +    }
 +
 +    @Override
 +    public AbstractRegionEntry getKey() {
 +      return this.key;
 +    }
 +
 +    @Override
 +    public boolean isKeyEqual(Object k) {
 +      return this.key.equals(k);
 +    }
 +
 +    @Override
 +    public RefCountMapEntry getMapValue() {
 +      return this;
 +    }
 +
 +    @Override
 +    public void setMapValue(RefCountMapEntry newValue) {
 +      if (newValue != this) {
 +        throw new IllegalStateException("Expected newValue " + newValue + " to be this " + this);
 +      }
 +    }
 +
 +    @Override
 +    public int getEntryHash() {
 +      return this.key.getEntryHash();
 +    }
 +
 +    @Override
 +    public HashEntry<AbstractRegionEntry, RefCountMapEntry> getNextEntry() {
 +      return this.next;
 +    }
 +
 +    @Override
 +    public void setNextEntry(HashEntry<AbstractRegionEntry, RefCountMapEntry> n) {
 +      this.next = n;
 +    }
 +
 +    public void incRefCount() {
 +      refCountUpdater.addAndGet(this, 1);
 +    }
 +
 +    /**
 +     * Returns true if refCount goes to 0.
 +     */
 +    public boolean decRefCount() {
 +      int rc = refCountUpdater.decrementAndGet(this);
 +      if (rc < 0) {
 +        throw new IllegalStateException("rc=" + rc);
 +      }
 +      return rc == 0;
 +    }
 +  }
 +  
 +  private final CustomEntryConcurrentHashMap<AbstractRegionEntry, RefCountMapEntry> refCountMap
 +    = new CustomEntryConcurrentHashMap<AbstractRegionEntry, RefCountMapEntry>(
 +        CustomEntryConcurrentHashMap.DEFAULT_INITIAL_CAPACITY, 
 +        CustomEntryConcurrentHashMap.DEFAULT_LOAD_FACTOR,
 +        CustomEntryConcurrentHashMap.DEFAULT_CONCURRENCY_LEVEL,
 +        true,
 +        new RefCountMapEntryCreator());
 +  
 +  private static final MapCallback<AbstractRegionEntry, RefCountMapEntry, Object, Object> incCallback = new MapCallback<AbstractRegionEntry, RefCountMapEntry, Object, Object>() {
 +    @Override
 +    public RefCountMapEntry newValue(AbstractRegionEntry key, Object context,
 +        Object createParams) {
 +      return new RefCountMapEntry(key);
 +    }
 +    @Override
 +    public void oldValueRead(RefCountMapEntry value) {
 +      value.incRefCount();
 +    }
 +    @Override
 +    public boolean doRemoveValue(RefCountMapEntry value, Object context,
 +        Object removeParams) {
 +      throw new IllegalStateException("doRemoveValue should not be called from create");
 +    }
 +  };
 +  
 +  private static final MapCallback<AbstractRegionEntry, RefCountMapEntry, Object, Object> decCallback = new MapCallback<AbstractRegionEntry, RefCountMapEntry, Object, Object>() {
 +    @Override
 +    public RefCountMapEntry newValue(AbstractRegionEntry key, Object context,
 +        Object createParams) {
 +      throw new IllegalStateException("newValue should not be called from remove");
 +    }
 +    @Override
 +    public void oldValueRead(RefCountMapEntry value) {
 +      throw new IllegalStateException("oldValueRead should not be called from remove");
 +    }
 +    @Override
 +    public boolean doRemoveValue(RefCountMapEntry value, Object context,
 +        Object removeParams) {
 +      return value.decRefCount();
 +    }
 +  };
 +  
 +  public static final void incRefCount(AbstractRegionEntry re) {
 +    TXManagerImpl mgr = currentInstance;
 +    if (mgr != null) {
 +      mgr.refCountMap.create(re, incCallback, null, null, true);
 +    }
 +  }
 +  /**
 +   * Return true if refCount went to zero.
 +   */
 +  public static final boolean decRefCount(AbstractRegionEntry re) {
 +    TXManagerImpl mgr = currentInstance;
 +    if (mgr != null) {
 +      return mgr.refCountMap.removeConditionally(re, decCallback, null, null) != null;
 +    } else {
 +      return true;
 +    }
 +  }
 +
 +  // Used by tests
 +  public Set<TXId> getLocalTxIds() {
 +    return this.localTxMap.keySet();
 +  }
 +
 +  // Used by tests
 +  public ArrayList<TXId> getHostedTxIds() {
 +    synchronized (this.hostedTXStates) {
 +      return new ArrayList<TXId>(this.hostedTXStates.keySet());
 +    }
 +  }
 +  
 +  public void setDistributed(boolean flag) {
 +    checkClosed();
 +    TXStateProxy tx = getTXState();
 +    // Check whether given flag and current flag are different and whether a transaction is in progress
 +    if (tx != null && flag != isDistributed()) {
 +      // Cannot change mode in the middle of a transaction
 +      throw new java.lang.IllegalStateException(
 +          LocalizedStrings.TXManagerImpl_CANNOT_CHANGE_TRANSACTION_MODE_WHILE_TRANSACTIONS_ARE_IN_PROGRESS
 +              .toLocalizedString());
 +    } else {
 +      isTXDistributed.set(new Boolean(flag));
 +    }
 +  }
 +
 +  /*
 +   * If explicitly set using setDistributed, this returns that value.
 +   * If not, it returns the value of gemfire property "distributed-transactions" if set.
 +   * If this is also not set, it returns the default value of this property.
 +   */
 +  public boolean isDistributed() {
 +    
 +     Boolean value = isTXDistributed.get();
 +    // This can be null if not set in setDistributed().
 +    if (value == null) {
 +      return InternalDistributedSystem.getAnyInstance().getOriginalConfig().getDistributedTransactions();
 +    } else {
 +      return value.booleanValue();
 +    }
 +  }
 +  
 +}


[003/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/SearchAndLoadDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/SearchAndLoadDUnitTest.java
index 01aa205,0000000..f26f94a
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/SearchAndLoadDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/SearchAndLoadDUnitTest.java
@@@ -1,1017 -1,0 +1,1017 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.concurrent.CountDownLatch;
 +import java.util.concurrent.TimeUnit;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionEvent;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * This class tests various search load and write scenarios for distributed regions
 + */
 +@SuppressWarnings({"deprecation", "unchecked", "rawtypes", "serial"})
 +public class SearchAndLoadDUnitTest extends CacheTestCase {
 +
 +  static boolean loaderInvoked;
 +  static boolean  remoteLoaderInvoked;
 +  static int remoteLoaderInvokedCount;
 +  static boolean netSearchCalled;
 +  static boolean netSearchHit;
 +  static boolean netWriteInvoked;
 +  static boolean operationWasCreate;
 +  static boolean originWasRemote;
 +  static int writerInvocationCount;
 +
 +  /** A <code>CacheListener</code> used by a test */
 +  protected static TestCacheListener listener;
 +
 +  /** A <code>CacheLoader</code> used by a test */
 +  protected static TestCacheLoader loader;
 +
 +  /** A <code>CacheWriter</code> used by a test */
 +  protected static TestCacheWriter writer;
 +
 +  static boolean exceptionThrown;
 +  static final CountDownLatch readyForExceptionLatch = new CountDownLatch(1);
 +  static final CountDownLatch loaderInvokedLatch = new CountDownLatch(1);
 +
 +  public SearchAndLoadDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  @Override
 +  protected final void preTearDownCacheTestCase() throws Exception {
 +    for (int h = 0; h < Host.getHostCount(); h++) {
 +      Host host = Host.getHost(h);
 +      for (int v = 0; v < host.getVMCount(); v++) {
 +        host.getVM(v).invoke(new SerializableRunnable("Clean up") {
 +            public void run() {
 +              cleanup();
 +            }
 +          });
 +      }
 +    }
 +    cleanup();
 +  }
 +
 +  /**
 +   * Clears fields used by a test
 +   */
 +  protected static void cleanup() {
 +    listener = null;
 +    loader = null;
 +    writer = null;
 +  }
 +
 +  /**
 +   * Returns region attributes for a <code>GLOBAL</code> region
 +   */
 +  protected RegionAttributes getRegionAttributes() {
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setEarlyAck(false);
 +    return factory.create();
 +  }
 +
 +  public void testNetSearch()
 +  throws CacheException, InterruptedException {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final String name = this.getUniqueName() + "-ACK";
 +    final String objectName = "NetSearchKey";
 +    final Integer value = new Integer(440);
 +    vm0.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        try {
 +
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setStatisticsEnabled(true);
 +          Region region = createRegion(name,factory.create());
 +          region.create(objectName,null);
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        try {
 +
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setStatisticsEnabled(true);
 +          Region region = createRegion(name,factory.create());
 +          region.put(objectName,value);
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +
 +    vm2.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        try {
 +
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setStatisticsEnabled(true);
 +          Region region = createRegion(name,factory.create());
 +          region.create(objectName,null);
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +
 +    vm0.invoke(new SerializableRunnable("Get a value") {
 +      public void run() {
 +        try {
 +          Object result = null;
 +          result = getRootRegion().getSubregion(name).get(objectName);
 +          assertEquals(value,result);
 +
 +//         System.err.println("Results is " + result.toString() + " Key is " + objectName.toString());
 +        }
 +        catch(CacheLoaderException cle) {
 +          Assert.fail("While Get a value", cle);
 +        }
 +        catch(TimeoutException te) {
 +          Assert.fail("While Get a value", te);
 +        }
 +      }
 +
 +    });
 +  }
 +
 +
 +  /**
 +   * This test is for a bug in which a cache loader threw an exception
 +   * that caused the wrong value to be put in a Future in nonTxnFindObject.  This
 +   * in turn caused a concurrent search for the object to not invoke the loader a
 +   * second time.
 +   * 
 +   * VM0 is used to create a cache and a region having a loader that simulates the
 +   * conditions that caused the bug.  One async thread then does a get() which invokes
 +   * the loader.  Another async thread does a get() which reaches nonTxnFindObject
 +   * and blocks waiting for the first thread's load to complete.  The loader then
 +   * throws an exception that is sent back to the first thread.  The second thread
 +   * should then cause the loader to be invoked again, and this time the loader will
 +   * return a value.  Both threads then validate that they received the expected
 +   * result.
 +   */
 +  public void testConcurrentLoad() throws Throwable {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    
 +    final String name = this.getUniqueName() + "Region";
 +    final String objectName = "theKey";
 +    final Integer value = new Integer(44);
 +    final String exceptionString = "causing first cache-load to fail";
 +
 +    remoteLoaderInvoked = false;
 +    loaderInvoked = false;
 +    
 +    vm0.invoke(new CacheSerializableRunnable("create region " + name + " in vm0") {
 +      public void run2() {
 +        remoteLoaderInvoked = false;
 +        loaderInvoked = false;
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.DISTRIBUTED_ACK);
 +        factory.setConcurrencyChecksEnabled(true);
 +        factory.setCacheLoader(new CacheLoader() {
 +          boolean firstInvocation = true;
 +          public synchronized Object load(LoaderHelper helper) {
 +            System.out.println("invoked cache loader for " + helper.getKey());
 +            loaderInvoked = true;
 +            loaderInvokedLatch.countDown();
 +            if (firstInvocation) {
 +              firstInvocation = false;
 +              try { 
 +                // wait for both threads to be ready for the exception to be thrown
 +                System.out.println("waiting for vm0t2 to be ready before throwing exception");
 +                readyForExceptionLatch.await(30, TimeUnit.SECONDS);
 +                // give the second thread time to get into loader code
 +                Thread.sleep(5000);
 +              } catch (InterruptedException e) {
 +                fail("interrupted");
 +              }
 +              System.out.println("throwing exception");
 +              exceptionThrown = true;
 +              throw new RuntimeException(exceptionString);
 +            }
 +            System.out.println("returning value="+value);
 +            return value;
 +          }
 +
 +          public void close() {
 +
 +          }
 +        });
 +
 +        Region region = createRegion(name,factory.create());
 +        region.create(objectName, null);
 +        IgnoredException.addIgnoredException(exceptionString);
 +      }
 +    });
 +
 +    AsyncInvocation async1 = null;
 +    try {
 +      async1 = vm0.invokeAsync(new CacheSerializableRunnable("Concurrently invoke the remote loader on the same key - t1") {
 +        public void run2() {
 +          Region region = getCache().getRegion("root/"+name);
 +  
 +          LogWriterUtils.getLogWriter().info("t1 is invoking get("+objectName+")");
 +          try {
 +            LogWriterUtils.getLogWriter().info("t1 retrieved value " + region.get(objectName));
 +            fail("first load should have triggered an exception");
 +          } catch (RuntimeException e) {
 +            if (!e.getMessage().contains(exceptionString)) {
 +              throw e;
 +            }
 +          }
 +        }
 +      });
 +      vm0.invoke(new CacheSerializableRunnable("Concurrently invoke the loader on the same key - t2") {
 +        public void run2() {
 +          final Region region = getCache().getRegion("root/"+name);
 +          final Object[] valueHolder = new Object[1];
 +  
 +          // wait for vm1 to cause the loader to be invoked
 +          LogWriterUtils.getLogWriter().info("t2 is waiting for loader to be invoked by t1");
 +          try {
 +            loaderInvokedLatch.await(30, TimeUnit.SECONDS);
 +          } catch (InterruptedException e) {
 +            fail("interrupted");
 +          }
 +          assertTrue(loaderInvoked);
 +          
 +          Thread t = new Thread("invoke get()") {
 +            public void run() {
 +              try {
 +                valueHolder[0] = region.get(objectName);
 +              } catch (RuntimeException e) {
 +                valueHolder[0] = e;
 +              }
 +            }
 +          };
 +          
 +          t.setDaemon(true);
 +          t.start();
 +          try {
 +            // let the thread get to the point of blocking on vm1's Future
 +            // in LocalRegion.nonTxnFindObject()
 +            Thread.sleep(5000);
 +          } catch (InterruptedException e) {
 +            fail("interrupted");
 +          }
 +          
 +          readyForExceptionLatch.countDown();
 +          try {
 +            t.join(30000);
 +          } catch (InterruptedException e) {
 +            fail("interrupted");
 +          }
 +          if (t.isAlive()) {
 +            t.interrupt();
 +            fail("get() operation blocked for too long - test needs some work");
 +          }
 +          
 +          LogWriterUtils.getLogWriter().info("t2 is invoking get("+objectName+")");
 +          Object value = valueHolder[0];
 +          if (value instanceof RuntimeException) {
 +            if ( ((Exception)value).getMessage().contains(exceptionString) ) {
 +              fail("second load should not have thrown an exception");
 +            } else {
 +              throw (RuntimeException)value;
 +            }
 +          } else {
 +            LogWriterUtils.getLogWriter().info("t2 retrieved value " + value);
 +            assertNotNull(value);
 +          }
 +        }
 +      });
 +    } finally {
 +      if (async1 != null) {
 +        async1.join();
 +        if (async1.exceptionOccurred()) {
 +          throw async1.getException();
 +        }
 +      }
 +    }
 +  }
 +  
 +  
 +  public void testNetLoadNoLoaders() throws CacheException, InterruptedException {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final String name = this.getUniqueName() + "-ACK";
 +    final String objectName = "B";
 +    SerializableRunnable create =
 +          new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory =
 +          new AttributesFactory();
 +        factory.setScope(Scope.DISTRIBUTED_ACK);
 +        factory.setEarlyAck(false);
 +        createRegion(name,factory.create());
 +
 +      }
 +    };
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm0.invoke(new SerializableRunnable("Get with No Loaders defined") {
 +      public void run() {
 +        try {
 +          Object result = getRootRegion().getSubregion(name).get(objectName);
 +          assertNull(result);
 +        }
 +        catch(CacheLoaderException cle) {
 +          Assert.fail("While getting value for ACK region", cle);
 +        }
 +        catch(TimeoutException te) {
 +          Assert.fail("While getting value for ACK region", te);
 +        }
 +
 +      }
 +    });
 +
 +
 +  }
 +
 +  public void testNetLoad()
 +  throws CacheException, InterruptedException {
 +    Invoke.invokeInEveryVM(DistributedTestCase.class,
 +        "disconnectFromDS");
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final String name = this.getUniqueName() + "-ACK";
 +    final String objectName = "B";
 +    final Integer value = new Integer(43);
 +    loaderInvoked = false;
 +    remoteLoaderInvoked = false;
 +    vm0.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        try {
 +          loaderInvoked = false;
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +      //  factory.setCacheLoader(new CacheLoader() {
 +      //      public Object load(LoaderHelper helper) {
 +      ///        loaderInvoked = true;
 +      //        return value;
 +      //      }
 +//
 +      //      public void close() {
 +//
 +      //      }
 +      //    });
 +
 +          Region region = createRegion(name,factory.create());
 +          region.create(objectName,null);
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setCacheLoader(new CacheLoader() {
 +            public Object load(LoaderHelper helper) {
 +              remoteLoaderInvoked = true;
 +              return value;
 +            }
 +            public void close() {
 +
 +            }
 +          });
 +          createRegion(name,factory.create());
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +    vm0.invoke(new SerializableRunnable("Get a value from remote loader") {
 +      public void run() {
 +        for (int i=0;i< 1;i++) {
 +          try {
 +            Object result = getRootRegion().getSubregion(name).get(objectName);
 +            assertEquals(value,result);
 +            assertEquals(new Boolean(loaderInvoked),Boolean.FALSE);
 +           // getRootRegion().getSubregion(name).invalidate(objectName);
 +
 +          }
 +          catch(CacheLoaderException cle) {
 +            Assert.fail("While getting value for ACK region", cle);
 +
 +          }
 +/*        catch(EntryNotFoundException enfe) {
 +            fail("While getting value for ACK region", enfe);
 +
 +          }*/
 +          catch(TimeoutException te) {
 +            Assert.fail("While getting value for ACK region", te);
 +
 +          }
 +        }
 +      }
 +
 +    });
 +  }
 +
 +  /**
 +   * Confirm that a netLoad that returns null will NOT allow other netLoad methods
 +   * to be called.
 +   */
 +  public void testEmptyNetLoad()
 +  throws CacheException, InterruptedException {
 +    Invoke.invokeInEveryVM(DistributedTestCase.class,
 +        "disconnectFromDS");
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final String name = this.getUniqueName() + "-ACK";
 +    final String objectName = "B";
 +    loaderInvoked = false;
 +    remoteLoaderInvoked = false;
 +    remoteLoaderInvokedCount = 0;
 +    vm0.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        loaderInvoked = false;
 +        remoteLoaderInvoked = false;
 +        remoteLoaderInvokedCount = 0;
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +      //  factory.setCacheLoader(new CacheLoader() {
 +      //      public Object load(LoaderHelper helper) {
 +      ///        loaderInvoked = true;
 +      //        return value;
 +      //      }
 +//
 +      //      public void close() {
 +//
 +      //      }
 +      //    });
 +          Region region = createRegion(name,factory.create());
 +          region.create(objectName,null);
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +
 +    SerializableRunnable installLoader = new SerializableRunnable("Create ACK Region") {
 +        public void run() {
 +          loaderInvoked = false;
 +          remoteLoaderInvoked = false;
 +          remoteLoaderInvokedCount = 0;
 +          try {
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setEarlyAck(false);
 +            factory.setCacheLoader(new CacheLoader() {
 +                public Object load(LoaderHelper helper) {
 +                  remoteLoaderInvoked = true;
 +                  remoteLoaderInvokedCount++;
 +                  return null;
 +                }
 +                public void close() {
 +
 +                }
 +              });
 +            createRegion(name,factory.create());
 +          }
 +          catch (CacheException ex) {
 +            Assert.fail("While creating ACK region", ex);
 +          }
 +        }
 +      };
 +    vm1.invoke(installLoader);
 +    vm2.invoke(installLoader);
 +    vm0.invoke(new SerializableRunnable("Get a value from remote loader") {
 +      public void run() {
 +        for (int i=0;i< 1;i++) {
 +          try {
 +            Object result = getRootRegion().getSubregion(name).get(objectName);
 +            assertEquals(null,result);
 +            assertEquals(false, loaderInvoked);
 +           // getRootRegion().getSubregion(name).invalidate(objectName);
 +
 +          }
 +          catch(CacheLoaderException cle) {
 +            Assert.fail("While getting value for ACK region", cle);
 +
 +          }
 +/*        catch(EntryNotFoundException enfe) {
 +            fail("While getting value for ACK region", enfe);
 +
 +          }*/
 +          catch(TimeoutException te) {
 +            Assert.fail("While getting value for ACK region", te);
 +
 +          }
 +        }
 +      }
 +
 +    });
 +    // we only invoke one netLoad loader even when they return null.
 +    boolean xor = vmRemoteLoaderInvoked(vm1) ^ vmRemoteLoaderInvoked(vm2);
 +    assertEquals("vm1=" + vmRemoteLoaderInvoked(vm1) + " vm2=" + vmRemoteLoaderInvoked(vm2)
 +                 + " vm1Count=" + vmRemoteLoaderInvokedCount(vm1) + " vm2Count=" + vmRemoteLoaderInvokedCount(vm2), true, xor);
 +    int total = vmRemoteLoaderInvokedCount(vm1) + vmRemoteLoaderInvokedCount(vm2);
 +    assertEquals("vm1=" + vmRemoteLoaderInvokedCount(vm1) + " vm2=" + vmRemoteLoaderInvokedCount(vm2), 1, total);
 +  }
 +
 +  public static boolean vmRemoteLoaderInvoked(VM vm) {
-     Boolean v = (Boolean)vm.invoke(SearchAndLoadDUnitTest.class, "fetchRemoteLoaderInvoked");
++    Boolean v = (Boolean)vm.invoke(() -> SearchAndLoadDUnitTest.fetchRemoteLoaderInvoked());
 +    return v.booleanValue();
 +  }
 +  public static int vmRemoteLoaderInvokedCount(VM vm) {
-     Integer v = (Integer)vm.invoke(SearchAndLoadDUnitTest.class, "fetchRemoteLoaderInvokedCount");
++    Integer v = (Integer)vm.invoke(() -> SearchAndLoadDUnitTest.fetchRemoteLoaderInvokedCount());
 +    return v.intValue();
 +  }
 +
 +  public static Boolean fetchRemoteLoaderInvoked() {
 +    return Boolean.valueOf(remoteLoaderInvoked);
 +  }
 +  public static Integer fetchRemoteLoaderInvokedCount() {
 +    return new Integer(remoteLoaderInvokedCount);
 +  }
 +  
 +  public void testLocalLoad()
 +  throws CacheException, InterruptedException {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final String name = this.getUniqueName() + "-ACK";
 +    final String objectName = "C";
 +    final Integer value = new Integer(44);
 +    remoteLoaderInvoked = false;
 +    loaderInvoked = false;
 +    vm0.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        remoteLoaderInvoked = false;
 +        loaderInvoked = false;
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setCacheLoader(new CacheLoader() {
 +            public Object load(LoaderHelper helper) {
 +              loaderInvoked = true;
 +              return value;
 +            }
 +
 +            public void close() {
 +
 +            }
 +          });
 +
 +          Region region = createRegion(name,factory.create());
 +          region.create(objectName,null);
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("Create ACK Region") {
 +      public void run() {
 +        remoteLoaderInvoked = false;
 +        loaderInvoked = false;
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setCacheLoader(new CacheLoader() {
 +            public Object load(LoaderHelper helper) {
 +              remoteLoaderInvoked = true;
 +              return value;
 +            }
 +            public void close() {
 +
 +            }
 +          });
 +          createRegion(name,factory.create());
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +    vm0.invoke(new SerializableRunnable("Get a value from local loader") {
 +      public void run() {
 +        try {
 +          Object result = getRootRegion().getSubregion(name).get(objectName);
 +          assertEquals(value,result);
 +          assertEquals(new Boolean(loaderInvoked),Boolean.TRUE);
 +          assertEquals(new Boolean(remoteLoaderInvoked),Boolean.FALSE);
 +
 +        }
 +        catch(CacheLoaderException cle) {
 +
 +        }
 +        catch(TimeoutException te) {
 +        }
 +      }
 +
 +    });
 +  }
 +
 +
 +  public void testNetWrite()
 +  throws CacheException, InterruptedException {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final String name = this.getUniqueName() + "-ACK";
 +    final String objectName = "Gemfire7";
 +    final Integer value = new Integer(483);
 +
 +    vm0.invoke(new SerializableRunnable("Create ACK Region with cacheWriter") {
 +      public void run() {
 +        netWriteInvoked = false;
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setCacheWriter(new CacheWriter() {
 +            public void beforeCreate(EntryEvent e) throws CacheWriterException {
 +              netWriteInvoked = true;
 +              return;
 +            }
 +            public void beforeUpdate(EntryEvent e) throws CacheWriterException {
 +              netWriteInvoked = true;
 +              return;
 +            }
 +            public void beforeDestroy(EntryEvent e) throws CacheWriterException {
 +              return;
 +            }
 +            public void beforeRegionDestroy(RegionEvent e) throws CacheWriterException {
 +              return;
 +            }
 +            public void beforeRegionClear(RegionEvent e) throws CacheWriterException {
 +              return;
 +            }
 +            public void close() {
 +            }
 +          });
 +
 +          createRegion(name,factory.create());
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating ACK region", ex);
 +        }
 +      }
 +    });
 +    vm1.invoke(new SerializableRunnable("Create ACK Region") {
 +        public void run() {
 +          loaderInvoked = false;
 +          remoteLoaderInvoked = false;
 +          netWriteInvoked = false;
 +          try {
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            createRegion(name,factory.create());
 +          }
 +          catch (CacheException ex) {
 +            Assert.fail("While creating ACK region", ex);
 +          }
 +        }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("Do a put operation resulting in cache writer notification in other vm") {
 +      public void run() {
 +        try {
 +          getRootRegion().getSubregion(name).put(objectName,value);
 +          try {
 +            Object result = getRootRegion().getSubregion(name).get(objectName);
 +            assertEquals(result,value);
 +           }
 +           catch(CacheLoaderException cle) {
 +           }
 +           catch(TimeoutException te) {
 +           }
 +        }
 +        catch(CacheWriterException cwe) {
 +
 +        }
 +        catch(TimeoutException te) {
 +        }
 +      }
 +
 +    });
 +
 +    vm0.invoke(new SerializableRunnable("ensure that cache writer was invoked") {
 +      public void run() {
 +        assertTrue("expected cache writer to be invoked", netWriteInvoked);
 +      }
 +    });
 +  }
 +
 +  
 +  public void testOneHopNetWrite() throws CacheException, InterruptedException {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final String name = this.getUniqueName() + "Region";
 +    final String objectName = "Object7";
 +    final Integer value = new Integer(483);
 +    final Integer updateValue = new Integer(484);
 +
 +    vm0.invoke(new SerializableRunnable("Create replicated region with cacheWriter") {
 +      public void run() {
 +        netWriteInvoked = false;
 +        operationWasCreate = false;
 +        originWasRemote = false;
 +        writerInvocationCount = 0;
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
 +          factory.setCacheWriter(new CacheWriter() {
 +            public void beforeCreate(EntryEvent e) throws CacheWriterException {
 +              e.getRegion().getCache().getLogger().info("cache writer beforeCreate invoked for " + e);
 +              netWriteInvoked = true;
 +              operationWasCreate = true;
 +              originWasRemote = e.isOriginRemote();
 +              writerInvocationCount++;
 +              return;
 +            }
 +            public void beforeUpdate(EntryEvent e) throws CacheWriterException {
 +              e.getRegion().getCache().getLogger().info("cache writer beforeUpdate invoked for " + e);
 +              netWriteInvoked = true;
 +              operationWasCreate = false;
 +              originWasRemote = e.isOriginRemote();
 +              writerInvocationCount++;
 +              return;
 +            }
 +            public void beforeDestroy(EntryEvent e) throws CacheWriterException {  }
 +            public void beforeRegionDestroy(RegionEvent e) throws CacheWriterException {   }
 +            public void beforeRegionClear(RegionEvent e) throws CacheWriterException {   }
 +            public void close() { }
 +          });
 +
 +          createRegion(name,factory.create());
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating replicated region", ex);
 +        }
 +      }
 +    });
 +    vm1.invoke(new SerializableRunnable("Create empty Region") {
 +        public void run() {
 +          try {
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setDataPolicy(DataPolicy.EMPTY);
 +            createRegion(name,factory.create());
 +          }
 +          catch (CacheException ex) {
 +            Assert.fail("While creating empty region", ex);
 +          }
 +        }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("do a put that should be proxied in the other vm and invoke its cache writer") {
 +      public void run() {
 +        try {
 +          getRootRegion().getSubregion(name).put(objectName,value);
 +        } catch(CacheWriterException cwe) {
 +        } catch(TimeoutException te) {
 +        }
 +      }
 +    });
 +
 +    vm0.invoke(new SerializableRunnable("ensure that cache writer was invoked with correct settings in event") {
 +      public void run() {
 +        assertTrue("expected cache writer to be invoked", netWriteInvoked);
 +        assertTrue("expected originRemote to be true", originWasRemote);
 +        assertTrue("expected event to be create", operationWasCreate);
 +        assertEquals("expected only one cache writer invocation", 1, writerInvocationCount);
 +        // set flags for the next test - updating the same key
 +        netWriteInvoked = false;
 +        writerInvocationCount = 0;
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("do an update that should be proxied in the other vm and invoke its cache writer") {
 +      public void run() {
 +        try {
 +          getRootRegion().getSubregion(name).put(objectName,updateValue);
 +        } catch(CacheWriterException cwe) {
 +        } catch(TimeoutException te) {
 +        }
 +      }
 +    });
 +
 +    vm0.invoke(new SerializableRunnable("ensure that cache writer was invoked with correct settings in event") {
 +      public void run() {
 +        assertTrue("expected cache writer to be invoked", netWriteInvoked);
 +        assertTrue("expected originRemote to be true", originWasRemote);
 +        assertTrue("expected event to be create", operationWasCreate);
 +        assertEquals("expected only one cache writer invocation", 1, writerInvocationCount);
 +      }
 +    });
 +  }
 +
 +
 +  /** same as the previous test but the cache writer is in a third, non-replicated, vm */
 +  public void testOneHopNetWriteRemoteWriter() throws CacheException, InterruptedException {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final String name = this.getUniqueName() + "Region";
 +    final String objectName = "Object7";
 +    final Integer value = new Integer(483);
 +    final Integer updateValue = new Integer(484);
 +
 +    vm0.invoke(new SerializableRunnable("Create replicate Region") {
 +      public void run() {
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
 +          createRegion(name,factory.create());
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating empty region", ex);
 +        }
 +      }
 +    });
 +    vm1.invoke(new SerializableRunnable("Create empty Region") {
 +        public void run() {
 +          try {
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setDataPolicy(DataPolicy.EMPTY);
 +            createRegion(name,factory.create());
 +          }
 +          catch (CacheException ex) {
 +            Assert.fail("While creating empty region", ex);
 +          }
 +        }
 +    });
 +    vm2.invoke(new SerializableRunnable("Create replicated region with cacheWriter") {
 +      public void run() {
 +        netWriteInvoked = false;
 +        operationWasCreate = false;
 +        originWasRemote = false;
 +        writerInvocationCount = 0;
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setDataPolicy(DataPolicy.EMPTY);
 +          factory.setCacheWriter(new CacheWriter() {
 +            public void beforeCreate(EntryEvent e) throws CacheWriterException {
 +              e.getRegion().getCache().getLogger().info("cache writer beforeCreate invoked for " + e);
 +              netWriteInvoked = true;
 +              operationWasCreate = true;
 +              originWasRemote = e.isOriginRemote();
 +              writerInvocationCount++;
 +              return;
 +            }
 +            public void beforeUpdate(EntryEvent e) throws CacheWriterException {
 +              e.getRegion().getCache().getLogger().info("cache writer beforeUpdate invoked for " + e);
 +              netWriteInvoked = true;
 +              operationWasCreate = false;
 +              originWasRemote = e.isOriginRemote();
 +              writerInvocationCount++;
 +              return;
 +            }
 +            public void beforeDestroy(EntryEvent e) throws CacheWriterException {  }
 +            public void beforeRegionDestroy(RegionEvent e) throws CacheWriterException {   }
 +            public void beforeRegionClear(RegionEvent e) throws CacheWriterException {   }
 +            public void close() { }
 +          });
 +
 +          createRegion(name,factory.create());
 +
 +        }
 +        catch (CacheException ex) {
 +          Assert.fail("While creating replicated region", ex);
 +        }
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("do a put that should be proxied in the other vm and invoke its cache writer") {
 +      public void run() {
 +        try {
 +          getRootRegion().getSubregion(name).put(objectName,value);
 +        } catch(CacheWriterException cwe) {
 +        } catch(TimeoutException te) {
 +        }
 +      }
 +    });
 +
 +    vm2.invoke(new SerializableRunnable("ensure that cache writer was invoked with correct settings in event") {
 +      public void run() {
 +        assertTrue("expected cache writer to be invoked", netWriteInvoked);
 +        assertTrue("expected originRemote to be true", originWasRemote);
 +        assertTrue("expected event to be create", operationWasCreate);
 +        assertEquals("expected only one cache writer invocation", 1, writerInvocationCount);
 +        // set flags for the next test - updating the same key
 +        netWriteInvoked = false;
 +        writerInvocationCount = 0;
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableRunnable("do an update that should be proxied in the other vm and invoke its cache writer") {
 +      public void run() {
 +        try {
 +          getRootRegion().getSubregion(name).put(objectName,updateValue);
 +        } catch(CacheWriterException cwe) {
 +        } catch(TimeoutException te) {
 +        }
 +      }
 +    });
 +
 +    vm2.invoke(new SerializableRunnable("ensure that cache writer was invoked with correct settings in event") {
 +      public void run() {
 +        assertTrue("expected cache writer to be invoked", netWriteInvoked);
 +        assertTrue("expected originRemote to be true", originWasRemote);
 +        assertTrue("expected event to be create", operationWasCreate);
 +        assertEquals("expected only one cache writer invocation", 1, writerInvocationCount);
 +      }
 +    });
 +  }
 +}
 +
 +



[084/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
index 0000000,f3e730a..021eba6
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
@@@ -1,0 -1,4311 +1,4311 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ABSTRACT_REGION_ENTRY_FILL_IN_VALUE;
+ 
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.CopyOnWriteArraySet;
+ import java.util.concurrent.RejectedExecutionException;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ import java.util.concurrent.locks.Condition;
+ import java.util.concurrent.locks.Lock;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.InternalGemFireError;
+ import com.gemstone.gemfire.InvalidDeltaException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.cache.CacheListener;
+ import com.gemstone.gemfire.cache.CacheLoader;
+ import com.gemstone.gemfire.cache.CacheLoaderException;
+ import com.gemstone.gemfire.cache.CacheWriter;
+ import com.gemstone.gemfire.cache.CacheWriterException;
+ import com.gemstone.gemfire.cache.DataPolicy;
+ import com.gemstone.gemfire.cache.DiskAccessException;
+ import com.gemstone.gemfire.cache.EntryNotFoundException;
+ import com.gemstone.gemfire.cache.LossAction;
+ import com.gemstone.gemfire.cache.MembershipAttributes;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.RegionAccessException;
+ import com.gemstone.gemfire.cache.RegionAttributes;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.RegionDistributionException;
+ import com.gemstone.gemfire.cache.RegionMembershipListener;
+ import com.gemstone.gemfire.cache.ResumptionAction;
+ import com.gemstone.gemfire.cache.RoleException;
+ import com.gemstone.gemfire.cache.TimeoutException;
+ import com.gemstone.gemfire.cache.TransactionId;
+ import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueImpl;
+ import com.gemstone.gemfire.cache.execute.Function;
+ import com.gemstone.gemfire.cache.execute.FunctionException;
+ import com.gemstone.gemfire.cache.execute.ResultCollector;
+ import com.gemstone.gemfire.cache.execute.ResultSender;
+ import com.gemstone.gemfire.cache.persistence.PersistentReplicatesOfflineException;
+ import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
+ import com.gemstone.gemfire.cache.wan.GatewaySender;
+ import com.gemstone.gemfire.distributed.DistributedLockService;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.LockServiceDestroyedException;
+ import com.gemstone.gemfire.distributed.Role;
+ import com.gemstone.gemfire.distributed.internal.DM;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisee;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.ProfileVisitor;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.distributed.internal.MembershipListener;
+ import com.gemstone.gemfire.distributed.internal.ReplyProcessor21;
+ import com.gemstone.gemfire.distributed.internal.locks.DLockRemoteToken;
+ import com.gemstone.gemfire.distributed.internal.locks.DLockService;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.CacheProfile;
+ import com.gemstone.gemfire.internal.cache.InitialImageOperation.GIIStatus;
+ import com.gemstone.gemfire.internal.cache.RemoteFetchVersionMessage.FetchVersionResponse;
+ import com.gemstone.gemfire.internal.cache.control.InternalResourceManager.ResourceType;
+ import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
+ import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionExecutor;
+ import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionResultSender;
+ import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionResultWaiter;
+ import com.gemstone.gemfire.internal.cache.execute.FunctionStats;
+ import com.gemstone.gemfire.internal.cache.execute.LocalResultCollector;
+ import com.gemstone.gemfire.internal.cache.execute.RegionFunctionContextImpl;
+ import com.gemstone.gemfire.internal.cache.execute.ServerToClientFunctionResultSender;
+ import com.gemstone.gemfire.internal.cache.lru.LRUEntry;
+ import com.gemstone.gemfire.internal.cache.persistence.CreatePersistentRegionProcessor;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistenceAdvisor;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistenceAdvisorImpl;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberID;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberManager;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberView;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+ import com.gemstone.gemfire.internal.cache.versions.ConcurrentCacheModificationException;
+ import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
+ import com.gemstone.gemfire.internal.cache.versions.VersionSource;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
+ import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
+ import com.gemstone.gemfire.internal.cache.wan.AsyncEventQueueConfigurationException;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderConfigurationException;
+ import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewaySenderQueue;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.sequencelog.RegionLogger;
+ import com.gemstone.gemfire.internal.util.concurrent.StoppableCountDownLatch;
+ import com.gemstone.gemfire.i18n.StringId;
+ /**
+  * 
+  * @author Eric Zoerner
+  * @author Sudhir Menon
+  */
+ @SuppressWarnings("deprecation")
+ public class DistributedRegion extends LocalRegion implements 
+     CacheDistributionAdvisee
+ {
+   private static final Logger logger = LogService.getLogger();
+   
+   /** causes cache profile to be added to afterRemoteRegionCreate notification for testing */
+   public static boolean TEST_HOOK_ADD_PROFILE = false;
+   
+   /** Used to sync accesses to this.dlockService to allow lazy construction */
+   private final Object dlockMonitor = new Object();
+ 
+   final CacheDistributionAdvisor distAdvisor;
+ 
+   /**
+    * @guarded.By {@link #dlockMonitor}
+    */
+   private DistributedLockService dlockService;
+ 
+   protected final AdvisorListener advisorListener = new AdvisorListener();
+ 
+   /** Set of currently missing required roles */
+   protected final HashSet missingRequiredRoles = new HashSet();
+ 
+   /** True if this region is currently missing any required roles */
+   protected volatile boolean isMissingRequiredRoles = false;
+   
+   /**
+    * True if this region is has any required roles defined and the LossAction is
+    * either NO_ACCESS or LIMITED_ACCESS. Reliability checks will only happen if
+    * this is true.
+    */
+   private final boolean requiresReliabilityCheck;
+ 
+   /**
+    * Provides a queue for reliable message delivery
+    * 
+    * @since 5.0
+    */
+   protected final ReliableMessageQueue rmq;
+ 
+   /**
+    * Latch that is opened after initialization waits for required roles up to
+    * the <a href="DistributedSystem#member-timeout">member-timeout </a>.
+    */
+   protected final StoppableCountDownLatch initializationLatchAfterMemberTimeout; 
+ 
+   private final PersistenceAdvisor persistenceAdvisor;
+   
+   private final PersistentMemberID persistentId;
+ 
+   /**
+    * This boolean is set to false when this region
+    * is non-persistent, but there are persistent members in the distributed system
+    * to which all region modifications should be forwarded
+    * see bug 45186
+    */
+   private volatile boolean generateVersionTag = true;
+ 
+   /** Tests can set this to true and ignore reliability triggered reconnects */
+   public static boolean ignoreReconnect = false;
+   
+   /**
+    * Lock to prevent multiple threads on this member from performing
+    * a clear at the same time.
+    */
+   private final Object clearLock = new Object();
+ 
+   private static AtomicBoolean loggedNetworkPartitionWarning = new AtomicBoolean(false);
+ 
+   /** Creates a new instance of DistributedRegion */
+   protected DistributedRegion(String regionName, RegionAttributes attrs,
+       LocalRegion parentRegion, GemFireCacheImpl cache,
+       InternalRegionArguments internalRegionArgs) {
+     super(regionName, attrs, parentRegion, cache, internalRegionArgs);
+     this.initializationLatchAfterMemberTimeout = new StoppableCountDownLatch(
+         getCancelCriterion(), 1);
+     this.distAdvisor = createDistributionAdvisor(internalRegionArgs);
+     
+     if (getDistributionManager().getConfig().getEnableNetworkPartitionDetection()
+         && !isInternalRegion() && !attrs.getScope().isAck() && !doesNotDistribute() && attrs.getDataPolicy().withStorage()) {
+       logger.warn(LocalizedMessage.create(LocalizedStrings.DistributedRegion_REGION_0_1_SPLITBRAIN_CONFIG_WARNING,
+           new Object[] { regionName, attrs.getScope() })); 
+     }
+     if (!getDistributionManager().getConfig().getEnableNetworkPartitionDetection() 
+         && attrs.getDataPolicy().withPersistence() && !loggedNetworkPartitionWarning.getAndSet(true)) {
+       logger.warn(LocalizedMessage.create(
+           LocalizedStrings.DistributedRegion_REGION_0_ENABLE_NETWORK_PARTITION_WARNING,
+           new Object[] { regionName, attrs.getScope() }));
+     }
+ 
+     boolean setRequiresReliabilityCheck = attrs.getMembershipAttributes()
+         .hasRequiredRoles()
+         &&
+         // note that the following includes NO_ACCESS, LIMITED_ACCESS,
+         !attrs.getMembershipAttributes().getLossAction().isAllAccess()
+         && !attrs.getMembershipAttributes().getLossAction().isReconnect();
+ 
+     // this optimization is safe for as long as Roles and Required Roles are
+     // immutable
+     // if this VM fulfills all required roles, make requiresReliabilityCheck
+     // false
+     Set reqRoles = new HashSet(attrs.getMembershipAttributes()
+         .getRequiredRoles());
+     reqRoles.removeAll(getSystem().getDistributedMember().getRoles());
+     if (reqRoles.isEmpty()) {
+       setRequiresReliabilityCheck = false;
+     }
+ 
+     this.requiresReliabilityCheck = setRequiresReliabilityCheck;
+ 
+     {
+       ReliableMessageQueue tmp = null;
+       if (this.requiresReliabilityCheck) {
+         //         if
+         // (attrs.getMembershipAttributes().getLossAction().isAllAccessWithQueuing())
+         // {
+         //           tmp = cache.getReliableMessageQueueFactory().create(this);
+         //         }
+       }
+       this.rmq = tmp;
+     }
+ 
+     if(internalRegionArgs.isUsedForPartitionedRegionBucket()) {
+       this.persistenceAdvisor = internalRegionArgs.getPersistenceAdvisor();
+     } else if (this.allowsPersistence()){
+       //TODO prpersist - using this lock service is a hack. Maybe? Or maybe
+       //it's ok if we have one (rarely used) lock service for many operations?
+       //What does the resource manager do?
+       DistributedLockService dl = cache.getPartitionedRegionLockService();
+       try {
+         //TODO prpersist - this is just a quick and dirty storage mechanism so that
+         //I can test the storage.
+         DiskRegionStats diskStats;
+         PersistentMemberView storage;
+         if(getDataPolicy().withPersistence()) {
+           storage = getDiskRegion();
+           diskStats = getDiskRegion().getStats();
+         } else {
+           storage = new InMemoryPersistentMemberView();
+           diskStats = null;
+         }
+         PersistentMemberManager memberManager = cache.getPersistentMemberManager();
+         this.persistenceAdvisor = new PersistenceAdvisorImpl(distAdvisor, dl, storage, this.getFullPath(), diskStats, memberManager);
+       } catch (Exception e) {
+         throw new InternalGemFireError("Couldn't recover persistence");
+       }
+     } else {
+       this.persistenceAdvisor = null;
+     }
+     if(this.persistenceAdvisor != null) {
+       this.persistentId = persistenceAdvisor.generatePersistentID();
+     } else {
+       this.persistentId = null;
+     }
+     
+   }
+   
+   @Override
+   public void createEventTracker() {
+     this.eventTracker = new EventTracker(this);
+     this.eventTracker.start();
+   }
+   
+   /**
+    * Intended for used during construction of a DistributedRegion
+    *  
+    * @return the advisor to be used by the region
+    */
+   protected CacheDistributionAdvisor createDistributionAdvisor(InternalRegionArguments internalRegionArgs) {
+     return CacheDistributionAdvisor.createCacheDistributionAdvisor(this);  // Warning: potential early escape of object before full construction
+   }
+   
+   /**
+    * Does this region support persistence?
+    */
+   public boolean allowsPersistence() {
+     return true;
+   }
+ 
+   @Override
+   public boolean requiresOneHopForMissingEntry(EntryEventImpl event) {
+     // received from another member - don't use one-hop
+     if (event.isOriginRemote()) {
+       return false; 
+     }
+     // local ops aren't distributed
+     if (event.getOperation().isLocal()) {
+       return false;
+     }
+     // if it already has a valid version tag it can go out with a DistributedCacheOperation
+     if (event.getVersionTag() != null && event.getVersionTag().getRegionVersion() > 0) {
+       return false;
+     }
+     // if we're not allowed to generate a version tag we need to send it to someone who can
+     if (!this.generateVersionTag) {
+       return true;
+     }
+     return this.concurrencyChecksEnabled &&
+         (this.srp == null) &&
+         !isTX() &&
+         this.scope.isDistributed() &&
+         !this.dataPolicy.withReplication();
+   }
+   
+   
+   /**
+    * @see LocalRegion#virtualPut(EntryEventImpl, boolean, boolean, Object, 
+    * boolean, long, boolean)
+    */
+   @Override
+   protected
+   boolean virtualPut(EntryEventImpl event,
+                      boolean ifNew,
+                      boolean ifOld,
+                      Object expectedOldValue,
+                      boolean requireOldValue,
+                      long lastModified,
+                      boolean overwriteDestroyed)
+   throws TimeoutException,
+          CacheWriterException {
+     final boolean isTraceEnabled = logger.isTraceEnabled();
+     
+     Lock dlock = null;
+     if (this.scope.isGlobal() && // lock only applies to global scope
+         !event.isOriginRemote() && // only if operation originating locally
+         !event.isNetSearch() && // search and load processor handles own locking
+         !event.isNetLoad() &&
+         // @todo darrel/kirk: what about putAll?
+         !event.isLocalLoad() &&
+         !event.isSingleHopPutOp()) { // Single Hop Op means dlock is already taken at origin node.
+       dlock = this.getDistributedLockIfGlobal(event.getKey());
+     }
+     if (isTraceEnabled) {
+       logger.trace("virtualPut invoked for event {}", event);
+     }
+     try {
+       if (!hasSeenEvent(event)) {
+         if (this.requiresOneHopForMissingEntry(event)) {
+           // bug #45704: see if a one-hop must be done for this operation
+           RegionEntry re = getRegionEntry(event.getKey());
+           if (re == null /*|| re.isTombstone()*/ || !this.generateVersionTag) {
+             if (!event.isBulkOpInProgress() || this.dataPolicy.withStorage()) {
+               // putAll will send a single one-hop for empty regions.  for other missing entries
+               // we need to get a valid version number before modifying the local cache 
+               boolean didDistribute = RemotePutMessage.distribute(event, lastModified,
+                   false, false, expectedOldValue, requireOldValue, !this.generateVersionTag);
+ 
+               if (!didDistribute && isTraceEnabled) {
+                 logger.trace("Unable to perform one-hop messaging");
+               }
+               if (!this.generateVersionTag && !didDistribute) {
+                 throw new PersistentReplicatesOfflineException();
+               }
+               if (didDistribute) {
+                 if (isTraceEnabled) {
+                   logger.trace("Event after remotePut operation: {}", event);
+                 }
+                 if (event.getVersionTag() == null) {
+                   // if the event wasn't applied by the one-hop replicate it will not have a version tag
+                   // and so should not be applied to this cache
+                   return false;
+                 }
+               }
+             }
+           }
+         }
+         return super.virtualPut(event,
+                                 ifNew,
+                                 ifOld,
+                                 expectedOldValue,
+                                 requireOldValue,
+                                 lastModified,
+                                 overwriteDestroyed);
+       }
+       else {
+         if (event.getDeltaBytes() != null && event.getRawNewValue() == null) {
+           // This means that this event has delta bytes but no full value.
+           // Request the full value of this event.
+           // The value in this vm may not be same as this event's value.
+           throw new InvalidDeltaException(
+               "Cache encountered replay of event containing delta bytes for key "
+                   + event.getKey());
+         }
+         // if the listeners have already seen this event, then it has already
+         // been successfully applied to the cache.  Distributed messages and
+         // return
+         if (isTraceEnabled) {
+           logger.trace("DR.virtualPut: this cache has already seen this event {}", event);
+         }
+         
+         // Gester, Fix 39014: when hasSeenEvent, put will still distribute
+         // event, but putAll did not. We add the logic back here, not to put 
+         // back into DR.distributeUpdate() because we moved this part up into 
+         // LR.basicPutPart3 in purpose. Reviewed by Bruce.  
+         if (event.isBulkOpInProgress() && !event.isOriginRemote()) {
+           event.getPutAllOperation().addEntry(event, true);
+         }
+ 
+         /* doing this so that other VMs will apply this no matter what. If it 
+          * is an "update" they will not apply it if they don't have the key.
+          * Because this is probably a retry, it will never get applied to this 
+          * local AbstractRegionMap, and so will never be flipped to a 'create'
+          */
+         event.makeCreate();
+         if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
+           distributeUpdate(event, lastModified, ifNew, ifOld, expectedOldValue, requireOldValue);
+           event.invokeCallbacks(this,true, true);
+         }
+         return true;
+       }
+     }
+     finally {
+       if (dlock != null) {
+         dlock.unlock();
+       }
+     }
+   }
+   
+   @Override
+   protected RegionEntry basicPutEntry(EntryEventImpl event, long lastModified)
+       throws TimeoutException, CacheWriterException {
+     
+     final boolean isTraceEnabled = logger.isTraceEnabled();
+     
+     if (isTraceEnabled) {
+       logger.trace("basicPutEntry invoked for event {}", event);
+     }
+     if (this.requiresOneHopForMissingEntry(event)) {
+       // bug #45704: see if a one-hop must be done for this operation
+       RegionEntry re = getRegionEntry(event.getKey());
+       if (re == null /*|| re.isTombstone()*/ || !this.generateVersionTag) {
+         final boolean ifNew = false;
+         final boolean ifOld = false;
+         boolean didDistribute = RemotePutMessage.distribute(event, lastModified,
+             ifNew, ifOld, null, false, !this.generateVersionTag);
+         if (!this.generateVersionTag && !didDistribute) {
+           throw new PersistentReplicatesOfflineException();
+         }
+         if (didDistribute && isTraceEnabled) {
+           logger.trace("Event after remotePut for basicPutEntry: {}", event);
+         }
+       }
+     }
+     return super.basicPutEntry(event, lastModified);
+   }
+ 
+   @Override
+   public void performPutAllEntry(EntryEventImpl event) {
+ 	  /*
+ 	   * force shared data view so that we just do the virtual op, accruing things in the put all operation for later
+ 	   */
+ 	if(isTX()) {
+ 		event.getPutAllOperation().addEntry(event);
+ 	} else {
+ 		getSharedDataView().putEntry(event, false, false, null, false, 0L, false);
+ 	}
+   }
+   
+   @Override
+   public void performRemoveAllEntry(EntryEventImpl event) {
+     // force shared data view so that we just do the virtual op, accruing things in the bulk operation for later
+     if(isTX()) {
+       event.getRemoveAllOperation().addEntry(event);
+     } else {
+       basicDestroy(event, true, null);
+       //getSharedDataView().destroyExistingEntry(event, true, null);
+     }
+   }
+   
+   /**
+    * distribution and listener notification
+    */
+   @Override
+   public void basicPutPart3(EntryEventImpl event, RegionEntry entry,
+       boolean isInitialized, long lastModified, boolean invokeCallbacks,
+       boolean ifNew, boolean ifOld, Object expectedOldValue,
+       boolean requireOldValue) {
+     
+     distributeUpdate(event, lastModified, false, false, null, false);
+     super.basicPutPart3(event, entry, isInitialized, lastModified,
+         invokeCallbacks, ifNew, ifOld, expectedOldValue, requireOldValue);
+   }
+ 
+   /** distribute an update operation */
+   protected void distributeUpdate(EntryEventImpl event, long lastModified, boolean ifNew, boolean ifOld, Object expectedOldValue, boolean requireOldValue) {
+     // an update from a netSearch is not distributed
+     if (!event.isOriginRemote() && !event.isNetSearch() && !event.isBulkOpInProgress()) {
+       boolean distribute = true;
+         if (event.getInhibitDistribution()) {
+           // this has already been distributed by a one-hop operation
+           distribute = false;
+         }
+         if (distribute) {
+           UpdateOperation op = new UpdateOperation(event, lastModified);
+           if (logger.isTraceEnabled()) {
+             logger.trace("distributing operation for event : {} : for region : {}", event, this.getName());
+           }
+           op.distribute();
+         }
+     }
+   }
+ 
+   protected void setGeneratedVersionTag(boolean generateVersionTag) {
+     // there is at-least one other persistent member, so turn on concurrencyChecks
+     enableConcurrencyChecks();
+     
+     this.generateVersionTag = generateVersionTag;
+   }
+ 
+   protected boolean getGenerateVersionTag() {
+     return this.generateVersionTag;
+   }
+ 
+   @Override
+   protected boolean shouldGenerateVersionTag(RegionEntry entry, EntryEventImpl event) {
+     if (logger.isTraceEnabled()) {
+       logger.trace("shouldGenerateVersionTag this.generateVersionTag={} ccenabled={} dataPolicy={} event:{}",
+           this.generateVersionTag, this.concurrencyChecksEnabled, this.dataPolicy, event);
+     }
+     if (!this.concurrencyChecksEnabled || this.dataPolicy == DataPolicy.EMPTY || !this.generateVersionTag) {
+       return false;
+     }
+     if (this.srp != null) { // client
+       return false;
+     }
+     if (event.getVersionTag() != null && !event.getVersionTag().isGatewayTag()) {
+       return false;
+     }
+     if (event.getOperation().isLocal()) { // bug #45402 - localDestroy generated a version tag
+       return false;
+     }
+     if (!event.isOriginRemote() && this.dataPolicy.withReplication()) {
+       return true;
+     }
+     if (!this.dataPolicy.withReplication() && !this.dataPolicy.withPersistence()) {
+       if (!entry.getVersionStamp().hasValidVersion()) {
+         // do not generate a version stamp in a region that has no replication if it's not based
+         // on an existing version from a replicate region
+         return false;
+       }
+       return true;
+     }
+     if (!event.isOriginRemote() && event.getDistributedMember() != null) {
+       if (!event.getDistributedMember().equals(this.getMyId())) {
+         return event.getVersionTag() == null; // one-hop remote message
+       }
+     }
+     return false;
+   }
+   /**
+    * Throws RegionAccessException if required roles are missing and the
+    * LossAction is NO_ACCESS
+    * 
+    * @throws RegionAccessException
+    *           if required roles are missing and the LossAction is NO_ACCESS
+    */
+   @Override
+   protected void checkForNoAccess()
+   {
+     if (this.requiresReliabilityCheck && this.isMissingRequiredRoles) {
+       if (getMembershipAttributes().getLossAction().isNoAccess()) {
+         synchronized (this.missingRequiredRoles) {
+           if (!this.isMissingRequiredRoles)
+             return;
+           Set roles = Collections.unmodifiableSet(new HashSet(
+               this.missingRequiredRoles));
+           throw new RegionAccessException(LocalizedStrings.DistributedRegion_OPERATION_IS_DISALLOWED_BY_LOSSACTION_0_BECAUSE_THESE_REQUIRED_ROLES_ARE_MISSING_1.toLocalizedString(new Object[] {getMembershipAttributes().getLossAction(), roles}), getFullPath(), roles);
+         }
+       }
+     }
+   }
+ 
+   /**
+    * Throws RegionAccessException is required roles are missing and the
+    * LossAction is either NO_ACCESS or LIMITED_ACCESS.
+    * 
+    * @throws RegionAccessException
+    *           if required roles are missing and the LossAction is either
+    *           NO_ACCESS or LIMITED_ACCESS
+    */
+   @Override
+   protected void checkForLimitedOrNoAccess()
+   {
+     if (this.requiresReliabilityCheck && this.isMissingRequiredRoles) {
+       if (getMembershipAttributes().getLossAction().isNoAccess()
+           || getMembershipAttributes().getLossAction().isLimitedAccess()) {
+         synchronized (this.missingRequiredRoles) {
+           if (!this.isMissingRequiredRoles)
+             return;
+           Set roles = Collections.unmodifiableSet(new HashSet(
+               this.missingRequiredRoles));
+           Assert.assertTrue(!roles.isEmpty());
+           throw new RegionAccessException(LocalizedStrings.DistributedRegion_OPERATION_IS_DISALLOWED_BY_LOSSACTION_0_BECAUSE_THESE_REQUIRED_ROLES_ARE_MISSING_1
+               .toLocalizedString(new Object[] { getMembershipAttributes().getLossAction(), roles}), getFullPath(), roles);
+         }
+       }
+     }
+   }
+   
+   @Override
+   protected void handleReliableDistribution(ReliableDistributionData data,
+       Set successfulRecipients) {
+     handleReliableDistribution(data, successfulRecipients,
+         Collections.EMPTY_SET, Collections.EMPTY_SET);
+   }
+ 
+   protected void handleReliableDistribution(ReliableDistributionData data,
+       Set successfulRecipients, Set otherRecipients1, Set otherRecipients2)
+   {
+     if (this.requiresReliabilityCheck) {
+       MembershipAttributes ra = getMembershipAttributes();
+       Set recipients = successfulRecipients;
+       // determine the successful roles
+       Set roles = new HashSet();
+       for (Iterator iter = recipients.iterator(); iter.hasNext();) {
+         InternalDistributedMember mbr = (InternalDistributedMember)iter.next();
+         if (mbr != null) {
+           roles.addAll(mbr.getRoles());
+         }
+       }
+       for (Iterator iter = otherRecipients1.iterator(); iter.hasNext();) {
+         InternalDistributedMember mbr = (InternalDistributedMember)iter.next();
+         if (mbr != null) {
+           roles.addAll(mbr.getRoles());
+         }
+       }
+       for (Iterator iter = otherRecipients2.iterator(); iter.hasNext();) {
+         InternalDistributedMember mbr = (InternalDistributedMember)iter.next();
+         if (mbr != null) {
+           roles.addAll(mbr.getRoles());
+         }
+       }
+       // determine the missing roles
+       Set failedRoles = new HashSet(ra.getRequiredRoles());
+       failedRoles.removeAll(roles);
+       if (failedRoles.isEmpty())
+         return;
+ //       if (rp.isAllAccessWithQueuing()) {
+ //         this.rmq.add(data, failedRoles);
+ //       } else {
+ 
+       throw new RegionDistributionException(LocalizedStrings.DistributedRegion_OPERATION_DISTRIBUTION_MAY_HAVE_FAILED_TO_NOTIFY_THESE_REQUIRED_ROLES_0.toLocalizedString(failedRoles), getFullPath(), failedRoles);
+ //       }
+     }
+   }
+ 
+   /**
+    * 
+    * Called when we do a distributed operation and don't have anyone to
+    * distributed it too. Since this is only called when no distribution was done
+    * (i.e. no recipients) we do not check isMissingRequiredRoles because it
+    * might not longer be true due to race conditions
+    * 
+    * @return false if this region has at least one required role and queuing is
+    *         configured. Returns true if sending to no one is ok.
+    * @throws RoleException
+    *           if a required role is missing and the LossAction is either
+    *           NO_ACCESS or LIMITED_ACCESS.
+    * @since 5.0
+    */
+   protected boolean isNoDistributionOk()
+   {
+     if (this.requiresReliabilityCheck) {
+       MembershipAttributes ra = getMembershipAttributes();
+       //       if (ra.getLossAction().isAllAccessWithQueuing()) {
+       //         return !ra.hasRequiredRoles();
+       //       } else {
+       Set failedRoles = ra.getRequiredRoles();
+       throw new RegionDistributionException(LocalizedStrings.DistributedRegion_OPERATION_DISTRIBUTION_WAS_NOT_DONE_TO_THESE_REQUIRED_ROLES_0.toLocalizedString(failedRoles), getFullPath(), failedRoles);
+       //       }
+     }
+     return true;
+   }
+   
+   /**
+    * returns true if this Region does not distribute its operations to other
+    * members.
+    * @since 6.0
+    * @see HARegion#localDestroyNoCallbacks(Object)
+    */
+   public boolean doesNotDistribute() {
+     return false;
+   }
+ 
+   
+   @Override
+   public boolean shouldSyncForCrashedMember(InternalDistributedMember id) {
+     return !doesNotDistribute() && super.shouldSyncForCrashedMember(id);
+   }
+   
+   
+   /**
+    * Adjust the specified set of recipients by removing any of them that are
+    * currently having their data queued.
+    * 
+    * @param recipients
+    *          the set of recipients that a message is to be distributed too.
+    *          Recipients that are currently having their data queued will be
+    *          removed from this set.
+    * @return the set, possibly null, of recipients that are currently having
+    *         their data queued.
+    * @since 5.0
+    */
+   protected Set adjustForQueuing(Set recipients)
+   {
+     Set result = null;
+     //     if (this.requiresReliabilityCheck) {
+     //       MembershipAttributes ra = getMembershipAttributes();
+     //       if (ra.getLossAction().isAllAccessWithQueuing()) {
+     //         Set currentQueuedRoles = this.rmq.getQueuingRoles();
+     //         if (currentQueuedRoles != null) {
+     //           // foreach recipient see if any of his roles are queued and if
+     //           // they are remove him from recipients and add him to result
+     //           Iterator it = recipients.iterator();
+     //           while (it.hasNext()) {
+     //             DistributedMember dm = (DistributedMember)it.next();
+     //             Set dmRoles = dm.getRoles();
+     //             if (!dmRoles.isEmpty()) {
+     //               if (intersects(dmRoles, currentQueuedRoles)) {
+     //                 it.remove(); // fix for bug 34447
+     //                 if (result == null) {
+     //                   result = new HashSet();
+     //                 }
+     //                 result.add(dm);
+     //               }
+     //             }
+     //           }
+     //         }
+     //       }
+     //     }
+     return result;
+   }
+ 
+   /**
+    * Returns true if the two sets intersect
+    * 
+    * @param a
+    *          a non-null non-empty set
+    * @param b
+    *          a non-null non-empty set
+    * @return true if sets a and b intersect; false if not
+    * @since 5.0
+    */
+   public static boolean intersects(Set a, Set b)
+   {
+     Iterator it;
+     Set target;
+     if (a.size() <= b.size()) {
+       it = a.iterator();
+       target = b;
+     }
+     else {
+       it = b.iterator();
+       target = a;
+     }
+     while (it.hasNext()) {
+       if (target.contains(it.next()))
+         return true;
+     }
+     return false;
+   }
+ 
+   @Override
+   public boolean requiresReliabilityCheck()
+   {
+     return this.requiresReliabilityCheck;
+   }
+ 
+   /**
+    * Returns true if the ExpiryTask is currently allowed to expire.
+    * <p>
+    * If the region is in NO_ACCESS due to reliability configuration, then no
+    * expiration actions are allowed.
+    * <p>
+    * If the region is in LIMITED_ACCESS due to reliability configuration, then
+    * only non-distributed expiration actions are allowed.
+    */
+   @Override
+   protected boolean isExpirationAllowed(ExpiryTask expiry)
+   {
+     if (this.requiresReliabilityCheck && this.isMissingRequiredRoles) {
+       if (getMembershipAttributes().getLossAction().isNoAccess()) {
+         return false;
+       }
+       if (getMembershipAttributes().getLossAction().isLimitedAccess()
+           && expiry.isDistributedAction()) {
+         return false;
+       }
+     }
+     return true;
+   }
+ 
+   /**
+    * Performs the resumption action when reliability is resumed.
+    * 
+    * @return true if asynchronous resumption is triggered
+    */
+   protected boolean resumeReliability(InternalDistributedMember id,
+       Set newlyAcquiredRoles)
+   {
+     boolean async = false;
+     try {
+       ResumptionAction ra = getMembershipAttributes().getResumptionAction();
+       if (ra.isNone()) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("Reliability resumption for action of none");
+         }
+         resumeExpiration();
+       }
+       else if (ra.isReinitialize()) {
+         async = true;
+         asyncResumeReliability(id, newlyAcquiredRoles);
+       }
+     }
+     catch (Exception e) {
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
+     }
+     return async;
+   }
+ 
+   /**
+    * Handles asynchronous ResumptionActions such as region reinitialize.
+    */
+   private void asyncResumeReliability(final InternalDistributedMember id,
+                                       final Set newlyAcquiredRoles)
+                                throws RejectedExecutionException {
+     final ResumptionAction ra = getMembershipAttributes().getResumptionAction();
+     getDistributionManager().getWaitingThreadPool().execute(new Runnable() {
+       public void run()
+       {
+         try {
+           if (ra.isReinitialize()) {
+             if (logger.isDebugEnabled()) {
+               logger.debug("Reliability resumption for action of reinitialize");
+             }
+             if (!isDestroyed() && !cache.isClosed()) {
+               RegionEventImpl event = new RegionEventImpl(
+                   DistributedRegion.this, Operation.REGION_REINITIALIZE, null,
+                   false, getMyId(), generateEventID());
+               reinitialize(null, event);
+             }
+             synchronized (missingRequiredRoles) {
+               // any number of threads may be waiting on missingRequiredRoles
+               missingRequiredRoles.notifyAll();
+               if (hasListener() && id != null) {
+                 // fire afterRoleGain event
+                 RoleEventImpl relEvent = new RoleEventImpl(
+                     DistributedRegion.this, Operation.REGION_CREATE, null,
+                     true, id, newlyAcquiredRoles);
+                 dispatchListenerEvent(EnumListenerEvent.AFTER_ROLE_GAIN,
+                     relEvent);
+               }
+             }
+           }
+         }
+         catch (Exception e) {
+           logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
+         }
+       }
+     });
+   }
+ 
+   /** Reschedules expiry tasks when reliability is resumed. */
+   private void resumeExpiration()
+   {
+     boolean isNoAccess = getMembershipAttributes().getLossAction().isNoAccess();
+     boolean isLimitedAccess = getMembershipAttributes().getLossAction()
+         .isLimitedAccess();
+     if (!(isNoAccess || isLimitedAccess)) {
+       return; // early out: expiration was never affected by reliability
+     }
+ 
+     if (getEntryTimeToLive().getTimeout() > 0
+         && (isNoAccess || (isLimitedAccess && getEntryTimeToLive().getAction()
+             .isDistributed()))) {
+       rescheduleEntryExpiryTasks();
+     }
+     else 
+     if (getEntryIdleTimeout().getTimeout() > 0
+         && (isNoAccess || (isLimitedAccess && getEntryIdleTimeout().getAction()
+             .isDistributed()))) {
+       rescheduleEntryExpiryTasks();
+     }
+     else
+     if (getCustomEntryTimeToLive() != null || getCustomEntryIdleTimeout() != null) {
+       // Force all entries to be rescheduled
+       rescheduleEntryExpiryTasks();
+     }
+ 
+     if (getRegionTimeToLive().getTimeout() > 0
+         && (isNoAccess || (isLimitedAccess && getRegionTimeToLive().getAction()
+             .isDistributed()))) {
+       addTTLExpiryTask();
+     }
+     if (getRegionIdleTimeout().getTimeout() > 0
+         && (isNoAccess || (isLimitedAccess && getRegionIdleTimeout()
+             .getAction().isDistributed()))) {
+       addIdleExpiryTask();
+     }
+   }
+ 
+   /**
+    * A boolean used to indicate if its the intialization time i.e the
+    * distributed Region is created for the first time. The variable is used at
+    * the time of lost reliablility.
+    */
+   private boolean isInitializingThread = false;
+ 
+   /**
+    * Called when reliability is lost. If MembershipAttributes are configured
+    * with {@link LossAction#RECONNECT}then DistributedSystem reconnect will be
+    * called asynchronously.
+    * 
+    * @return true if asynchronous resumption is triggered
+    */
+   protected boolean lostReliability(final InternalDistributedMember id,
+       final Set newlyMissingRoles)
+   {
+     if (DistributedRegion.ignoreReconnect)
+       return false;
+     boolean async = false;
+     try {
+       if (getMembershipAttributes().getLossAction().isReconnect()) {
+         async = true;
+         if (isInitializingThread) {
+           doLostReliability(true, id, newlyMissingRoles);
+         }
+         else {
+           doLostReliability(false, id, newlyMissingRoles);
+         }
+         // we don't do this in the waiting pool because we're going to
+         // disconnect
+         // the distributed system, and it will wait for the pool to empty
+         /*
+          * moved to a new method called doLostReliablity. Thread t = new
+          * Thread("Reconnect Distributed System") { public void run() { try { //
+          * TODO: may need to check isReconnecting and checkReadiness...
+          * initializationLatchAfterMemberTimeout.await(); // TODO:
+          * call reconnect here
+          * getSystem().tryReconnect((GemFireCache)getCache()); // added for
+          * reconnect. synchronized (missingRequiredRoles) { // any number of
+          * threads may be waiting on missingRequiredRoles
+          * missingRequiredRoles.notifyAll(); // need to fire an event if id is
+          * not null if (hasListener() && id != null) { RoleEventImpl relEvent =
+          * new RoleEventImpl( DistributedRegion.this, Operation.CACHE_RECONNECT,
+          * null, true, id, newlyMissingRoles); dispatchListenerEvent(
+          * EnumListenerEvent.AFTER_ROLE_LOSS, relEvent); } } } catch (Exception
+          * e) { } } };
+          * t.setDaemon(true); t.start();
+          */
+       }
+     }
+     catch (CancelException cce) {
+       throw cce;
+     }
+     catch (Exception e) {
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
+     }
+     return async;
+   }
+ 
+   private void doLostReliability(boolean isInitializing,
+       final InternalDistributedMember id, final Set newlyMissingRoles)
+   {
+     try {
+       if (!isInitializing) {
+         // moved code to a new thread.
+         Thread t = new Thread(LocalizedStrings.DistributedRegion_RECONNECT_DISTRIBUTED_SYSTEM.toLocalizedString()) {
+           @Override
+           public void run()
+           {
+             try {
+               // TODO: may need to check isReconnecting and checkReadiness...
+               if (logger.isDebugEnabled()) {
+                 logger.debug("Reliability loss with policy of reconnect and membership thread doing reconnect");
+               }
+               initializationLatchAfterMemberTimeout.await();
+               getSystem().tryReconnect(false, "Role Loss", getCache());
+               synchronized (missingRequiredRoles) {
+                 // any number of threads may be waiting on missingRequiredRoles
+                 missingRequiredRoles.notifyAll();
+                 // need to fire an event if id is not null
+                 if (hasListener() && id != null) {
+                   RoleEventImpl relEvent = new RoleEventImpl(
+                       DistributedRegion.this, Operation.CACHE_RECONNECT, null,
+                       true, id, newlyMissingRoles);
+                   dispatchListenerEvent(EnumListenerEvent.AFTER_ROLE_LOSS,
+                       relEvent);
+                 }
+               }
+             }
+             catch (Exception e) {
+               logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
+             }
+           }
+         };
+         t.setDaemon(true);
+         t.start();
+ 
+       }
+       else {
+         getSystem().tryReconnect(false, "Role Loss", getCache()); // added for
+         // reconnect.
+         synchronized (missingRequiredRoles) {
+           // any number of threads may be waiting on missingRequiredRoles
+           missingRequiredRoles.notifyAll();
+           // need to fire an event if id is not null
+           if (hasListener() && id != null) {
+             RoleEventImpl relEvent = new RoleEventImpl(DistributedRegion.this,
+                 Operation.CACHE_RECONNECT, null, true, id, newlyMissingRoles);
+             dispatchListenerEvent(EnumListenerEvent.AFTER_ROLE_LOSS, relEvent);
+           }
+         }
+         // } catch (CancelException cce){
+ 
+         // }
+ 
+       }
+     }
+     catch (CancelException ignor) {
+       throw ignor;
+     }
+     catch (Exception e) {
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
+     }
+ 
+   }
+ 
+   protected void lockCheckReadiness()
+   {
+     // fix for bug 32610
+     cache.getCancelCriterion().checkCancelInProgress(null);
+     checkReadiness();
+   }
+ 
+   @Override
+   public final Object validatedDestroy(Object key, EntryEventImpl event)
+       throws TimeoutException, EntryNotFoundException, CacheWriterException {
+     Lock dlock = this.getDistributedLockIfGlobal(key);
+     try {
+       return super.validatedDestroy(key, event);
+     } finally {
+       if (dlock != null) {
+         dlock.unlock();
+       }
+     }
+   }
+ 
+   /**
+    * @see LocalRegion#localDestroyNoCallbacks(Object)
+    */
+   @Override
+   public void localDestroyNoCallbacks(Object key)
+   {
+     super.localDestroyNoCallbacks(key);
+     if (getScope().isGlobal()) {
+       try {
+         this.getLockService().freeResources(key);
+       }
+       catch (LockServiceDestroyedException ignore) {
+       }
+     }
+   }
+ 
+   /**
+    * @see LocalRegion#localDestroy(Object, Object)
+    */
+   @Override
+   public void localDestroy(Object key, Object aCallbackArgument)
+       throws EntryNotFoundException
+   {
+     super.localDestroy(key, aCallbackArgument);
+     if (getScope().isGlobal()) {
+       try {
+         this.getLockService().freeResources(key);
+       }
+       catch (LockServiceDestroyedException ignore) {
+       }
+     }
+   }
+ 
+   /**
+    * @see LocalRegion#invalidate(Object, Object)
+    */
+   @Override
+   public void invalidate(Object key, Object aCallbackArgument)
+       throws TimeoutException, EntryNotFoundException
+   {
+     validateKey(key);
+     validateCallbackArg(aCallbackArgument);
+     checkReadiness();
+     checkForLimitedOrNoAccess();
+     Lock dlock = this.getDistributedLockIfGlobal(key);
+     try {
+       super.validatedInvalidate(key, aCallbackArgument);
+     }
+     finally {
+       if (dlock != null)
+         dlock.unlock();
+     }
+   }
+ 
+   @Override
+   public Lock getRegionDistributedLock() throws IllegalStateException
+   {
+     lockCheckReadiness();
+     checkForLimitedOrNoAccess();
+     if (!this.scope.isGlobal()) {
+       throw new IllegalStateException(LocalizedStrings.DistributedRegion_DISTRIBUTION_LOCKS_ARE_ONLY_SUPPORTED_FOR_REGIONS_WITH_GLOBAL_SCOPE_NOT_0.toLocalizedString(this.scope));
+     }
+     return new RegionDistributedLock();
+   }
+ 
+   @Override
+   public Lock getDistributedLock(Object key) throws IllegalStateException
+   {
+     validateKey(key);
+     lockCheckReadiness();
+     checkForLimitedOrNoAccess();
+     if (!this.scope.isGlobal()) {
+       throw new IllegalStateException(LocalizedStrings.DistributedRegion_DISTRIBUTION_LOCKS_ARE_ONLY_SUPPORTED_FOR_REGIONS_WITH_GLOBAL_SCOPE_NOT_0.toLocalizedString(this.scope));
+     }
+     if (isLockingSuspendedByCurrentThread()) {
+       throw new IllegalStateException(LocalizedStrings.DistributedRegion_THIS_THREAD_HAS_SUSPENDED_ALL_LOCKING_FOR_THIS_REGION.toLocalizedString());
+     }
+     return new DistributedLock(key);
+   }
+ 
+   /**
+    * Called while NOT holding lock on parent's subregions
+    * 
+    * @throws IllegalStateException
+    *           if region is not compatible with a region in another VM.
+    * 
+    * @see LocalRegion#initialize(InputStream, InternalDistributedMember, InternalRegionArguments)
+    */
+   @Override
+   protected void initialize(InputStream snapshotInputStream,
+       InternalDistributedMember imageTarget, InternalRegionArguments internalRegionArgs) throws TimeoutException,
+       IOException, ClassNotFoundException
+   {
+     Assert.assertTrue(!isInitialized());
+     if (logger.isDebugEnabled()) {
+       logger.debug("DistributedRegion.initialize BEGIN: {}", getFullPath());
+     }
+ 
+     // if we're versioning entries we need a region-level version vector
+     if (this.scope.isDistributed() && this.concurrencyChecksEnabled) {
+       createVersionVector();
+     }
+ 
+     if (this.scope.isGlobal()) {
+       getLockService(); // create lock service eagerly now
+     }
+ 
+     final IndexUpdater indexUpdater = getIndexUpdater();
+     boolean sqlfGIILockTaken = false;
+     // this try block is to release the SQLF GII lock in finally
+     // which should be done after bucket status will be set
+     // properly in LocalRegion#initialize()
+     try {
+      try {
+       try {
+         // take the GII lock to avoid missing entries while updating the
+         // index list for SQLFabric (#41330 and others)
+         if (indexUpdater != null) {
+           indexUpdater.lockForGII();
+           sqlfGIILockTaken = true;
+         }
+         
+         PersistentMemberID persistentId = null;
+         boolean recoverFromDisk = isRecoveryNeeded();
+         DiskRegion dskRgn = getDiskRegion();
+         if (recoverFromDisk) {
+           if (logger.isDebugEnabled()) {
+             logger.debug("DistributedRegion.getInitialImageAndRecovery: Starting Recovery");
+           }
+           dskRgn.initializeOwner(this); // do recovery
+           if (logger.isDebugEnabled()) {
+             logger.debug("DistributedRegion.getInitialImageAndRecovery: Finished Recovery");
+           }
+           persistentId = dskRgn.getMyPersistentID();
+         }
+         
+         // Create OQL indexes before starting GII.
+         createOQLIndexes(internalRegionArgs, recoverFromDisk);
+  
+         if (getDataPolicy().withReplication()
+             || getDataPolicy().withPreloaded()) {
+           getInitialImageAndRecovery(snapshotInputStream, imageTarget,
+               internalRegionArgs, recoverFromDisk, persistentId);
+         }
+         else {
+           new CreateRegionProcessor(this).initializeRegion();
+           if (snapshotInputStream != null) {
+             releaseBeforeGetInitialImageLatch();
+             loadSnapshotDuringInitialization(snapshotInputStream);
+           }
+         }
+       }
+       catch (DiskAccessException dae) {
+         this.handleDiskAccessException(dae, true);
+         throw dae;
+       }
+ 
+       initMembershipRoles();
+       isInitializingThread = false;
+       super.initialize(null, null, null); // makes sure all latches are released if they haven't been already
+      } finally {
+       if (this.eventTracker != null) {
+         this.eventTracker.setInitialized();
+       }
+      }
+     } finally {
+       if (sqlfGIILockTaken) {
+         indexUpdater.unlockForGII();
+       }
+     }
+   }
+ 
+   @Override
+   public void initialized() {
+     new UpdateAttributesProcessor(this).distribute(false);
+   }
+ 
+   /** True if GII was impacted by missing required roles */
+   private boolean giiMissingRequiredRoles = false;
+ 
+   /**
+    * A reference counter to protected the memoryThresholdReached boolean
+    */
+   private final Set<DistributedMember> memoryThresholdReachedMembers =
+     new CopyOnWriteArraySet<DistributedMember>();
+ 
+   private ConcurrentParallelGatewaySenderQueue hdfsQueue;
+ 
+   /** Sets and returns giiMissingRequiredRoles */
+   private boolean checkInitialImageForReliability(
+       InternalDistributedMember imageTarget,
+       CacheDistributionAdvisor.InitialImageAdvice advice)
+   {
+     // assumption: required roles are interesting to GII only if Reinitialize...
+ //    if (true)
+       return false;
+ //    if (getMembershipAttributes().hasRequiredRoles()
+ //        && getMembershipAttributes().getResumptionAction().isReinitialize()) {
+ //      // are any required roles missing for GII with Reinitialize?
+ //      Set missingRR = new HashSet(getMembershipAttributes().getRequiredRoles());
+ //      missingRR.removeAll(getSystem().getDistributedMember().getRoles());
+ //      for (Iterator iter = advice.replicates.iterator(); iter.hasNext();) {
+ //        DistributedMember member = (DistributedMember)iter.next();
+ //        missingRR.removeAll(member.getRoles());
+ //      }
+ //      for (Iterator iter = advice.others.iterator(); iter.hasNext();) {
+ //        DistributedMember member = (DistributedMember)iter.next();
+ //        missingRR.removeAll(member.getRoles());
+ //      }
+ //      for (Iterator iter = advice.preloaded.iterator(); iter.hasNext();) {
+ //        DistributedMember member = (DistributedMember)iter.next();
+ //        missingRR.removeAll(member.getRoles());
+ //      }
+ //      if (!missingRR.isEmpty()) {
+ //        // entering immediate loss condition, which will cause reinit on resume
+ //        this.giiMissingRequiredRoles = true;
+ //      }
+ //    }
+ //    return this.giiMissingRequiredRoles;
+   }
+ 
+   private void getInitialImageAndRecovery(InputStream snapshotInputStream,
+       InternalDistributedMember imageSrc, InternalRegionArguments internalRegionArgs,
+       boolean recoverFromDisk, PersistentMemberID persistentId) throws TimeoutException
+   {
+     logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_0, this.getName()));
+   
+     ImageState imgState = getImageState();
+     imgState.init();
+     boolean targetRecreated = internalRegionArgs.getRecreateFlag();
+     Boolean isCBool = (Boolean)isConversion.get();
+     boolean isForConversion = isCBool!=null?isCBool.booleanValue():false;
+ 
+     if (recoverFromDisk && snapshotInputStream != null && !isForConversion) {
+       throw new InternalGemFireError(LocalizedStrings.DistributedRegion_IF_LOADING_A_SNAPSHOT_THEN_SHOULD_NOT_BE_RECOVERING_ISRECOVERING_0_SNAPSHOTSTREAM_1.toLocalizedString(new Object[] {Boolean.valueOf(recoverFromDisk), snapshotInputStream}));
+     }
+ 
+     ProfileExchangeProcessor targetProvider;
+     if (dataPolicy.withPersistence()) {
+       targetProvider = new CreatePersistentRegionProcessor(this,
+           getPersistenceAdvisor(), recoverFromDisk);
+     }
+     else {
+       // this will go in the advisor profile
+       targetProvider = new CreateRegionProcessor(this);
+     }
+     imgState.setInRecovery(false);
+     RegionVersionVector recovered_rvv = null;
+     if (dataPolicy.withPersistence()) {
+       recovered_rvv = (this.getVersionVector()==null?null:this.getVersionVector().getCloneForTransmission());
+     }
+       // initializeRegion will send out our profile
+     targetProvider.initializeRegion();
+     
+     if(persistenceAdvisor != null) {
+       persistenceAdvisor.initialize();
+     }
+     
+     // Register listener here so that the remote members are known
+     // since registering calls initializeCriticalMembers (which needs to know about
+     // remote members
+     if (!isInternalRegion()) {
+       if (!this.isDestroyed) {
+         cache.getResourceManager().addResourceListener(ResourceType.MEMORY, this);
+       }
+     }
+     
+     releaseBeforeGetInitialImageLatch();
+ 
+     // allow GII to invoke test hooks.  Do this just after releasing the
+     // before-gii latch for bug #48962.  See ConcurrentLeaveDuringGIIDUnitTest
+     InitialImageOperation.beforeGetInitialImage(this);
+     
+     if (snapshotInputStream != null) {
+       try {
+         if (logger.isDebugEnabled()) {
+           logger.debug("DistributedRegion.getInitialImageAndRecovery: About to load snapshot, isInitialized={}; {}",
+               isInitialized(), getFullPath());
+         }
+         loadSnapshotDuringInitialization(snapshotInputStream);
+       }
+       catch (IOException e) {
+         throw new RuntimeException(e); // @todo change this exception?
+       }
+       catch (ClassNotFoundException e) {
+         throw new RuntimeException(e); // @todo change this exception?
+       }
+       cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
+       return;
+     }
+     
+     // No snapshot provided, use the imageTarget(s)
+ 
+     // if we were given a recommended imageTarget, use that first, and
+     // treat it like it is a replicate (regardless of whether it actually is
+     // or not)
+ 
+     InitialImageOperation iiop = new InitialImageOperation(this, this.entries);
+     // [defunct] Special case GII for PR admin regions (which are always
+     // replicates and always writers
+     // bruce: this was commented out after adding the GIIAckRequest logic to
+     // force
+     //        consistency before the gii operation begins
+     //      if (isUsedForPartitionedRegionAdmin() ||
+     // isUsedForPartitionedRegionBucket()) {
+     //        releaseBeforeGetInitialImageLatch();
+     //        iiop.getFromAll(this.distAdvisor.adviseGeneric(), false);
+     //        cleanUpDestroyedTokens();
+     //        return;
+     //      }
+ 
+ 
+     CacheDistributionAdvisor.InitialImageAdvice advice = null;
+     boolean done = false;
+     while(!done && !isDestroyed()) {
+       advice = targetProvider.getInitialImageAdvice(advice);
+       checkInitialImageForReliability(imageSrc, advice);
+       boolean attemptGetFromOne = 
+         imageSrc != null // we were given a specific member
+         || this.dataPolicy.withPreloaded()
+            && !advice.preloaded.isEmpty() // this is a preloaded region
+         || (!advice.replicates.isEmpty());
+       // That is: if we have 0 or 1 giiProvider then we can do a getFromOne gii;
+       // if we have 2 or more giiProviders then we must do a getFromAll gii.
+ 
+       if (attemptGetFromOne) {
+         if (recoverFromDisk) {
+           if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER){
+             CacheObserverHolder.getInstance().afterMarkingGIIStarted();
+           }
+         }
+         {
+           // If we have an imageSrc and the target is reinitializing mark the
+           // getInitialImage so that it will wait until the target region is fully initialized
+           // before responding to the get image request. Otherwise, the
+           // source may respond with no data because it is still initializing,
+           // e.g. loading a snapshot.
+ 
+           // Plan A: use specified imageSrc, if specified
+           if (imageSrc != null) {
+             try {
+               GIIStatus ret = iiop.getFromOne(Collections.singleton(imageSrc),
+                   targetRecreated, advice, recoverFromDisk, recovered_rvv);
+               if (GIIStatus.didGII(ret)) {
+                 this.giiMissingRequiredRoles = false;
+                 cleanUpDestroyedTokensAndMarkGIIComplete(ret);
+                 done = true;
+                 return;
+               }
+             } finally {
+               imageSrc = null;
+             }
+           }
+ 
+           // Plan C: use a replicate, if one exists
+           GIIStatus ret = iiop.getFromOne(advice.replicates, false, advice, recoverFromDisk, recovered_rvv);
+           if (GIIStatus.didGII(ret)) {
+             cleanUpDestroyedTokensAndMarkGIIComplete(ret);
+             done = true;
+             return;
+           }
+ 
+           // Plan D: if this is a PRELOADED region, fetch from another PRELOADED
+           if (this.dataPolicy.isPreloaded()) {
+             GIIStatus ret_preload = iiop.getFromOne(advice.preloaded, false, advice, recoverFromDisk, recovered_rvv);
+             if (GIIStatus.didGII(ret_preload)) {
+               cleanUpDestroyedTokensAndMarkGIIComplete(ret_preload);
+               done = true;
+               return;
+             }
+           } // isPreloaded
+         }
+ 
+         //If we got to this point, we failed in the GII. Cleanup
+         //any partial image we received
+         cleanUpAfterFailedGII(recoverFromDisk);
+ 
+       } // attemptGetFromOne
+       else {
+         if(!isDestroyed()) {
+           if(recoverFromDisk) {
+             logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZED_FROM_DISK,
+                 new Object[] {this.getFullPath(), persistentId, getPersistentID()}));
+             if(persistentId != null) {
+               RegionLogger.logRecovery(this.getFullPath(), persistentId,
+                   getDistributionManager().getDistributionManagerId());
+             }
+           } else {
+             RegionLogger.logCreate(this.getFullPath(),
+                 getDistributionManager().getDistributionManagerId());
+             
+             if (getPersistentID() != null) {
+               RegionLogger.logPersistence(this.getFullPath(),
+                   getDistributionManager().getDistributionManagerId(),
+                   getPersistentID());
+               logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_NEW_PERSISTENT_REGION_CREATED,
+                   new Object[] {this.getFullPath(), getPersistentID()}));
+             }
+           }
+           
+           /* no more union GII
+             // do union getInitialImage
+             Set rest = new HashSet();
+             rest.addAll(advice.others);
+             rest.addAll(advice.preloaded);
+             // push profile w/ recovery flag turned off at same time that we
+             // do a union getInitialImage
+             boolean pushProfile = recoverFromDisk;
+             iiop.getFromAll(rest, pushProfile);
+            */
+           cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
+           done = true;
+           return;
+         }
+         break;
+       }
+     }
+ 
+     return;
+   }
+   
+   private void synchronizeWith(InternalDistributedMember target, 
+       VersionSource idToRecover) {
+     InitialImageOperation op = new InitialImageOperation(this, this.entries);
+     op.synchronizeWith(target, idToRecover, null);
+   }
+   
+   /**
+    * If this region has concurrency controls enabled this will pull any missing
+    * changes from other replicates using InitialImageOperation and a filtered
+    * chunking protocol.
+    */
+   public void synchronizeForLostMember(InternalDistributedMember
+       lostMember, VersionSource lostVersionID) {
+     if (this.concurrencyChecksEnabled == false) {
+       return;
+     }
+     CacheDistributionAdvisor advisor = getCacheDistributionAdvisor();
+     Set<InternalDistributedMember> targets = advisor.adviseInitializedReplicates();
+     for (InternalDistributedMember target: targets) {
+       synchronizeWith(target, lostVersionID, lostMember);
+     }
+   }
+   
+   /**
+    * synchronize with another member wrt messages from the given "lost" member.
+    * This can be used when a primary bucket crashes to ensure that interrupted
+    * message distribution is mended.
+    */
+   private void synchronizeWith(InternalDistributedMember target,
+       VersionSource versionMember, InternalDistributedMember lostMember) {
+     InitialImageOperation op = new InitialImageOperation(this, this.entries);
+     op.synchronizeWith(target, versionMember, lostMember);
+   }
+ 
+   /**
+    * invoked just before an initial image is requested from another member
+    */
+   /** remove any partial entries received in a failed GII */
+   protected void cleanUpAfterFailedGII(boolean recoverFromDisk) {
+     DiskRegion dskRgn = getDiskRegion();
+     //if we have a persistent region, instead of deleting everything on disk,
+     //we will just reset the "recovered from disk" flag. After
+     //the next GII we will delete these entries if they do not come
+     //in as part of the GII.
+     if (recoverFromDisk && dskRgn != null && dskRgn.isBackup()) {
+       dskRgn.resetRecoveredEntries(this);
+       return;
+     }
+ 
+     if (!this.entries.isEmpty()) {
+       closeEntries();
+       if (getDiskRegion() != null) {
+         getDiskRegion().clear(this, null);
+       }
+       // clear the left-members and version-tags sets in imageState
+       getImageState().getLeftMembers();
+       getImageState().getVersionTags();
+       // Clear OQL indexes
+       if (this.indexManager != null) {
+         try {
+           this.indexManager.rerunIndexCreationQuery();
+         } catch (Exception ex){
+           if (logger.isDebugEnabled()) {
+             logger.debug("Exception while clearing indexes after GII failure.", ex);
+           }
+         }
+       }
+     }
+   }
+ 
+   private void initMembershipRoles()
+   {
+     synchronized (this.advisorListener) {
+       // hold sync to prevent listener from changing initial members
+       Set others = this.distAdvisor
+           .addMembershipListenerAndAdviseGeneric(this.advisorListener);
+       this.advisorListener.addMembers(others);
+       // initialize missing required roles with initial member info
+       if (getMembershipAttributes().hasRequiredRoles()) {
+         // AdvisorListener will also sync on missingRequiredRoles
+         synchronized (this.missingRequiredRoles) {
+           this.missingRequiredRoles.addAll(getMembershipAttributes()
+               .getRequiredRoles());
+           // remove all the roles we are playing since they will never be
+           // missing
+           this.missingRequiredRoles.removeAll(getSystem()
+               .getDistributedMember().getRoles());
+           for (Iterator iter = others.iterator(); iter.hasNext();) {
+             DistributedMember other = (DistributedMember)iter.next();
+             this.missingRequiredRoles.removeAll(other.getRoles());
+           }
+         }
+       }
+     }
+     if (getMembershipAttributes().hasRequiredRoles()) {
+       // wait up to memberTimeout for required roles...
+ //      boolean requiredRolesAreMissing = false;
+       int memberTimeout = getSystem().getConfig().getMemberTimeout();
+       if (logger.isDebugEnabled()) {
+         logger.debug("Waiting up to {} for required roles.", memberTimeout);
+       }
+       try {
+         if (this.giiMissingRequiredRoles) {
+           // force reliability loss and possibly resumption
+           isInitializingThread = true;
+           synchronized (this.advisorListener) {
+             synchronized (this.missingRequiredRoles) {
+               // forcing state of loss because of bad GII
+               this.isMissingRequiredRoles = true;
+               getCachePerfStats().incReliableRegionsMissing(1);
+               if (getMembershipAttributes().getLossAction().isAllAccess())
+                 getCachePerfStats().incReliableRegionsMissingFullAccess(1); // rahul
+               else if (getMembershipAttributes().getLossAction()
+                   .isLimitedAccess())
+                 getCachePerfStats().incReliableRegionsMissingLimitedAccess(1);
+               else if (getMembershipAttributes().getLossAction().isNoAccess())
+                 getCachePerfStats().incReliableRegionsMissingNoAccess(1);
+               // pur code to increment the stats.
+               if (logger.isDebugEnabled()) {
+                 logger.debug("GetInitialImage had missing required roles.");
+               }
+               // TODO: will this work with RECONNECT and REINITIALIZE?
+               isInitializingThread = true;
+               lostReliability(null, null);
+               if (this.missingRequiredRoles.isEmpty()) {
+                 // all required roles are present so force resumption
+                 this.isMissingRequiredRoles = false;
+                 getCachePerfStats().incReliableRegionsMissing(-1);
+                 if (getMembershipAttributes().getLossAction().isAllAccess())
+                   getCachePerfStats().incReliableRegionsMissingFullAccess(-1); // rahul
+                 else if (getMembershipAttributes().getLossAction()
+                     .isLimitedAccess())
+                   getCachePerfStats()
+                       .incReliableRegionsMissingLimitedAccess(-1);
+                 else if (getMembershipAttributes().getLossAction().isNoAccess())
+                   getCachePerfStats().incReliableRegionsMissingNoAccess(-1);
+                 // pur code to increment the stats.
+                 boolean async = resumeReliability(null, null);
+                 if (async) {
+                   advisorListener.destroyed = true;
+                 }
+               }
+             }
+           }
+         }
+         else {
+           if (!getSystem().isLoner()) {
+             waitForRequiredRoles(memberTimeout);
+           }
+           synchronized (this.advisorListener) {
+             synchronized (this.missingRequiredRoles) {
+               if (this.missingRequiredRoles.isEmpty()) {
+                 Assert.assertTrue(!this.isMissingRequiredRoles);
+                 if (logger.isDebugEnabled()) {
+                   logger.debug("Initialization completed with all required roles present.");
+                 }
+               }
+               else {
+                 // starting in state of loss...
+                 this.isMissingRequiredRoles = true;
+                 getCachePerfStats().incReliableRegionsMissing(1);
+                 if (getMembershipAttributes().getLossAction().isAllAccess())
+                   getCachePerfStats().incReliableRegionsMissingFullAccess(1); // rahul
+                 else if (getMembershipAttributes().getLossAction()
+                     .isLimitedAccess())
+                   getCachePerfStats().incReliableRegionsMissingLimitedAccess(1);
+                 else if (getMembershipAttributes().getLossAction().isNoAccess())
+                   getCachePerfStats().incReliableRegionsMissingNoAccess(1);
+                 
+                 if (logger.isDebugEnabled()) {
+                   logger.debug("Initialization completed with missing required roles: {}", this.missingRequiredRoles);
+                 }
+                 isInitializingThread = true;
+                 lostReliability(null, null);
+               }
+             }
+           }
+         }
+       }
+       catch (RegionDestroyedException ignore) {
+         // ignore to fix bug 34639 may be thrown by waitForRequiredRoles
+       }
+       catch (CancelException ignore) {
+         // ignore to fix bug 34639 may be thrown by waitForRequiredRoles
+         if (isInitializingThread) {
+           throw ignore;
+         }
+       }
+       catch (Exception e) {
+         logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
+       }
+ 
+     }
+     // open latch which will allow any threads in lostReliability to proceed
+     this.initializationLatchAfterMemberTimeout.countDown();
+   }
+   private boolean isRecoveryNeeded() {
+     return getDataPolicy().withPersistence()
+       && getDiskRegion().isRecreated();
+   }
+ 
+   // called by InitialImageOperation to clean up destroyed tokens
+   // release afterGetInitialImageInitializationLatch before unlocking
+   // cleanUpLock
+   @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UL_UNRELEASED_LOCK")
+   private void cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus giiStatus)
+   {
+     //We need to clean up the disk before we release the after get initial image latch
+     DiskRegion dskRgn = getDiskRegion();
+     if (dskRgn != null && dskRgn.isBackup()) {
+       dskRgn.finishInitializeOwner(this, giiStatus);
+     }
+     ImageState is = getImageState();
+     is.lockGII();
+     // clear the version tag and left-members sets
+     is.getVersionTags();
+     is.getLeftMembers();
+     // remove DESTROYED tokens
+     RegionVersionVector rvv = is.getClearRegionVersionVector();
+     try {
+       Iterator/*<Object>*/ keysIt = getImageState().getDestroyedEntries();
+       while (keysIt.hasNext()) {
+         this.entries.removeIfDestroyed(keysIt.next());
+       }
+       if (rvv != null) {
+         // clear any entries received in the GII that are older than the RVV versions.
+         // this can happen if entry chunks were received prior to the clear() being
+         // processed
+         clearEntries(rvv);
+       }
+       //need to do this before we release the afterGetInitialImageLatch
+       if(persistenceAdvisor != null) {
+         persistenceAdvisor.setOnline(GIIStatus.didGII(giiStatus), false, getPersistentID());
+       }
+     }
+     finally {
+       // release after gii lock first so basicDestroy will see isInitialized()
+       // be true
+       // when they get the cleanUp lock.
+         try {
+           releaseAfterGetInitialImageLatch();
+         } finally { // make sure unlockGII is done for bug 40001
+           is.unlockGII();
+         }
+     }
+     
+     if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER){
+       CacheObserverHolder.getInstance().afterMarkingGIICompleted();
+     }
+     
+     //"Initializing region {0}" which is not acompanied by a completed message. Users think thread is stuck in some operation. Hence adding this log
+     logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_COMPLETED_0, this.getName()));
+   }
+ 
+   /**
+    * @see LocalRegion#basicDestroy(EntryEventImpl, boolean, Object)
+    */
+   @Override
+   protected
+   void basicDestroy(EntryEventImpl event,
+                        boolean cacheWrite,
+                        Object expectedOldValue)
+   throws EntryNotFoundException, CacheWriterException, TimeoutException {
+     //  disallow local destruction for mirrored keysvalues regions
+     boolean invokeWriter = cacheWrite;
+     boolean hasSeen = false;
+     if (hasSeenEvent(event)) {
+       hasSeen = true;
+     }
+     checkIfReplicatedAndLocalDestroy(event);
+     
+     try {
+       if (this.requiresOneHopForMissingEntry(event)) {
+         // bug #45704: see if a one-hop must be done for this operation
+         RegionEntry re = getRegionEntry(event.getKey());
+         if (re == null /*|| re.isTombstone()*/ || !this.generateVersionTag) {
+           if (this.srp == null) {
+             // only assert for non-client regions.
+             Assert.assertTrue(!this.dataPolicy.withReplication() || !this.generateVersionTag);
+           }
+           if (!event.isBulkOpInProgress() || this.dataPolicy.withStorage()) {
+             // removeAll will send a single one-hop for empty regions.  for other missing entries
+             // we need to get a valid version number before modifying the local cache 
+           // TODO: deltaGII: verify that delegating to a peer when this region is also a client is acceptable
+           boolean didDistribute = RemoteDestroyMessage.distribute(event, expectedOldValue, !this.generateVersionTag);
+ 
+           if (!this.generateVersionTag && !didDistribute) {
+             throw new PersistentReplicatesOfflineException();
+           }
+           
+           if (didDistribute) {
+             if (logger.isTraceEnabled()) {
+               logger.trace("Event after remoteDestroy operation: {}", event);
+             }
+             invokeWriter = false; // remote cache invoked the writer
+             if (event.getVersionTag() == null) {
+               // if the event wasn't applied by the one-hop replicate it will not have a version tag
+               // and so should not be applied to this cache
+               return;
+             }
+           }
+           }
+         }
+       }
+       
+       super.basicDestroy(event, invokeWriter, expectedOldValue);
+ 
+       // if this is a destroy coming in from remote source, free up lock resources
+       // if this is a local origin destroy, this will happen after lock is
+       // released
+       if (this.scope.isGlobal() && event.isOriginRemote()) {
+         try {
+           getLockService().freeResources(event.getKey());
+         }
+         catch (LockServiceDestroyedException ignore) {
+         }
+       }
+   
+       return;
+     } 
+     finally {
+       if (hasSeen) {
+         if (event.isBulkOpInProgress() && !event.isOriginRemote()) {
+           event.getRemoveAllOperation().addEntry(event, true);
+         }
+         if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
+           distributeDestroy(event, expectedOldValue);
+           event.invokeCallbacks(this,true, false);
+         }
+       }
+     }
+   }
+ 
+   @Override
+   void basicDestroyPart3(RegionEntry re, EntryEventImpl event,
+       boolean inTokenMode, boolean duringRI, boolean invokeCallbacks, Object expectedOldValue) {
+   
+     distributeDestroy(event, expectedOldValue);
+     super.basicDestroyPart3(re, event, inTokenMode, duringRI, invokeCallbacks, expectedOldValue);
+   }
+   
+   void distributeDestroy(EntryEventImpl event, Object expectedOldValue) {
+     if (event.isDistributed() && !event.isOriginRemote() && !event.isBulkOpInProgress()) {
+       boolean distribute = !event.getInhibitDistribution();
+       if (distribute) {
+         DestroyOperation op =  new DestroyOperation(event);
+         op.distribute();
+       }
+     }
+   }
+   
+   @Override
+   boolean evictDestroy(LRUEntry entry) {
+     boolean evictDestroyWasDone = super.evictDestroy(entry);
+     if (evictDestroyWasDone) {
+       if (this.scope.isGlobal()) {
+         try {
+           getLockService().freeResources(entry.getKey());
+         }
+         catch (LockServiceDestroyedException ignore) {
+         }
+       }
+     }
+     return evictDestroyWasDone;
+   }
+ 
+ 
+   /**
+    * @see LocalRegion#basicInvalidateRegion(RegionEventImpl)
+    */
+   @Override
+   void basicInvalidateRegion(RegionEventImpl event)
+   {
+     // disallow local invalidation for replicated regions
+     if (!event.isDistributed() && getScope().isDistributed()
+         && getDataPolicy().withReplication()) {
+       throw new IllegalStateException(LocalizedStrings.DistributedRegion_NOT_ALLOWED_TO_DO_A_LOCAL_INVALIDATION_ON_A_REPLICATED_REGION.toLocalizedString());
+     }
+     if (shouldDistributeInvalidateRegion(event)) {
+       distributeInvalidateRegion(event);
+     }
+     super.basicInvalidateRegion(event);
+   }
+ 
+   /**
+    * decide if InvalidateRegionOperation should be sent to peers. broken out so
+    * that BucketRegion can override
+    * @param event
+    * @return true if {@link InvalidateRegionOperation} should be distributed, false otherwise
+    */
+   protected boolean shouldDistributeInvalidateRegion(RegionEventImpl event) {
+     return event.isDistributed() && !event.isOriginRemote();
+   }
+ 
+   /**
+    * Distribute the invalidate of a region given its event.
+    * This implementation sends the invalidate to peers.
+    * @since 5.7
+    */
+   protected void distributeInvalidateRegion(RegionEventImpl event) {
+     new InvalidateRegionOperation(event).distribute();
+   }
+ 
+   /**
+    * @see LocalRegion#basicDestroyRegion(RegionEventImpl, boolean, boolean,
+    *      boolean)
+    */
+   @Override
+   void basicDestroyRegion(RegionEventImpl event, boolean cacheWrite,
+       boolean lock, boolean callbackEvents) throws CacheWriterException,
+       TimeoutException
+   {
+     final String path = getFullPath();
+     //Keep track of regions that are being destroyed. This helps avoid a race
+     //when another member concurrently creates this region. See bug 42051.
+     boolean isClose = event.getOperation().isClose();
+     if(!isClose) {
+       cache.beginDestroy(path, this);
+     }
+     try {
+       super.basicDestroyRegion(event, cacheWrite, lock, callbackEvents);
+       // send destroy region operation even if this is a localDestroyRegion (or
+       // close)
+       if (!event.isOriginRemote()) {
+         distributeDestroyRegion(event, true);
+       } else {
+         if(!event.isReinitializing()) {
+           RegionEventImpl localEvent = new RegionEventImpl(this,
+               Operation.REGION_LOCAL_DESTROY, event.getCallbackArgument(), false, getMyId(),
+               generateEventID()/* generate EventID */);
+           distributeDestroyRegion(localEvent, false/*fixes bug 41111*/);
+         }
+       }
+       notifyBridgeClients(event);
+     }
+     catch (CancelException e) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("basicDestroyRegion short-circuited due to cancellation");
+       }
+     }
+     finally {
+       if(!isClose) {
+         cache.endDestroy(path, this);
+       }
+       RegionLogger.logDestroy(path, getMyId(), getPersistentID(), isClose);
+     }
+  }
+ 
+ 
+   @Override
+   protected void distributeDestroyRegion(RegionEventImpl event,
+                                          boolean notifyOfRegionDeparture) {
+     if(persistenceAdvisor != null) {
+       persistenceAdvisor.releaseTieLock();
+     }
+     new DestroyRegionOperation(event, notifyOfRegionDeparture).distribute();
+   }
+ 
+   /**
+    * Return true if invalidation occurred; false if it did not, for example if
+    * it was already invalidated
+    * 
+    * @see LocalRegion#basicInvalidate(EntryEventImpl)
+    */
+   @Override
+   void basicInvalidate(EntryEventImpl event) throws EntryNotFoundException
+   {
+     
+     boolean hasSeen = false;
+     if (hasSeenEvent(event)) {
+       hasSeen = true;
+     }
+     try {
+       // disallow local invalidation for replicated regions
+       if (event.isLocalInvalid() && !event.getOperation().isLocal() && getScope().isDistributed()
+           && getDataPolicy().withReplication()) {
+         throw new IllegalStateException(LocalizedStrings.DistributedRegion_NOT_ALLOWED_TO_DO_A_LOCAL_INVALIDATION_ON_A_REPLICATED_REGION.toLocalizedString());
+       }
+       if (this.requiresOneHopForMissingEntry(event)) {
+         // bug #45704: see if a one-hop must be done for this operation
+         RegionEntry re = getRegionEntry(event.getKey());
+         if (re == null/* || re.isTombstone()*/ || !this.generateVersionTag) {
+           if (this.srp == null) {
+             // only assert for non-client regions.
+             Assert.assertTrue(!this.dataPolicy.withReplication() || !this.generateVersionTag);
+           }
+           // TODO: deltaGII: verify that delegating to a peer when this region is also a client is acceptable
+           boolean didDistribute = RemoteInvalidateMessage.distribute(event, !this.generateVersionTag);
+           if (!this.generateVersionTag && !didDistribute) {
+             throw new PersistentReplicatesOfflineException();
+           }
+           if (didDistribute) {
+             if (logger.isDebugEnabled()) {
+               logger.debug("Event after remoteInvalidate operation: {}", event);
+             }
+             if (event.getVersionTag() == null) {
+               // if the event wasn't applied by the one-hop replicate it will not have a version tag
+               // and so should not be applied to this cache
+               return;
+             }
+           }
+         }
+       }
+   
+       super.basicInvalidate(event);
+ 
+       return;
+     } finally {
+       if (hasSeen) {
+     	if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
+           distributeInvalidate(event);
+           event.invokeCallbacks(this,true, false);
+     	}
+       }
+     }
+   }
+ 
+   @Override
+   void basicInvalidatePart3(RegionEntry re, EntryEventImpl event,
+       boolean invokeCallbacks) {
+     distributeInvalidate(event);
+     super.basicInvalidatePart3(re, event, invokeCallbacks);
+   }
+   
+   void distributeInvalidate(EntryEventImpl event) {
+     if (!this.regionInvalid && event.isDistributed() && !event.isOriginRemote()
+         && !isTX() /* only distribute if non-tx */) {
+       if (event.isDistributed() && !event.isOriginRemote()) {
+         boolean distribute = !event.getInhibitDistribution();
+         if (distribute) {
+           InvalidateOperation op = new InvalidateOperation(event);
+           op.distribute();
+         }
+       }
+     }
+   }
+ 
+   
+   @Override
+   void basicUpdateEntryVersion(EntryEventImpl event)
+       throws EntryNotFoundException {
+ 
+     try {
+       if (!hasSeenEvent(event)) {
+         super.basicUpdateEntryVersion(event);
+       }
+       return;
+     } finally {
+       if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
+         distributeUpdateEntryVersion(event);
+       }
+     }
+   }
+ 
+   private void distributeUpdateEntryVersion(EntryEventImpl event) {
+     if (!this.regionInvalid && event.isDistributed() && !event.isOriginRemote()
+         && !isTX() /* only distribute if non-tx */) {
+       if (event.isDistributed() && !event.isOriginRemote()) {
+         UpdateEntryVersionOperation op = new UpdateEntryVersionOperation(event);
+         op.distribute();
+       }
+     }
+   }
+ 
+   @Override
+   protected void basicClear(RegionEventImpl ev)
+   {
+     Lock dlock = this.getRegionDistributedLockIfGlobal();
+     try {
+       super.basicClear(ev);
+     }
+     finally {
+       if (dlock != null)
+         dlock.unlock();
+     }
+   }
+   
+   @Override
+   void basicClear(RegionEventImpl regionEvent, boolean cacheWrite)  {
+     if (this.concurrencyChecksEnabled && !this.dataPolicy.withReplication()) {
+       boolean retry = false;
+       do {
+         // non-replicate regions must defer to a replicate for clear/invalidate of region
+         Set<InternalDistributedMember> repls = this.distAdvisor.adviseReplicates();
+         if (repls.size() > 0) {
+           InternalDistributedMember mbr = repls.iterator().next();
+           RemoteRegionOperation op = RemoteRegionOperation.clear(mbr, this);
+           try {
+             op.distribute();
+             return;
+           } catch (CancelException e) {
+             this.stopper.checkCancelInProgress(e);
+             retry = true;
+           } catch (RemoteOperationException e) {
+             this.stopper.checkCancelInProgress(e);
+             retry = true;
+           }
+         }
+       } while (retry);
+     }
+     // if no version vector or if no replicates are around, use the default mechanism
+     super.basicClear(regionEvent, cacheWrite);
+   }
+   
+   
+   @Override
+   void cmnClearRegion(RegionEventImpl regionEvent, boolean cacheWrite, boolean useRVV) {
+     boolean enableRVV = useRVV && this.dataPolicy.withReplication() && this.concurrencyChecksEnabled && !getDistributionManager().isLoner(); 
+     
+     //Fix for 46338 - apparently multiple threads from the same VM are allowed
+     //to suspend locking, which is what distributedLockForClear() does. We don't
+     //want that to happen, so we'll synchronize to make sure only one thread on
+     //this member performs a clear.
+     synchronized(clearLock) {
+       if (enableRVV) {
+ 
+         distributedLockForClear();
+         try {
+           Set<InternalDistributedMember> participants = getCacheDistributionAdvisor().adviseInvalidateRegion();
+           // pause all generation of versions and flush from the other members to this one
+           try {
+             obtainWriteLocksForClear(regionEvent, participants);
+             clearRegionLocally(regionEvent, cacheWrite, null);
+             if (!regionEvent.isOriginRemote() && regionEvent.isDistributed()) {
+               DistributedClearOperation.clear(regionEvent, null, participants);
+             }
+           } finally {
+             releaseWriteLocksForClear(regionEvent, participants);
+           }
+         }
+         finally {
+           distributedUnlockForClear();
+         }
+       } else {
+         Set<InternalDistributedMember> participants = getCacheDistributionAdvisor().adviseInvalidateRegion();
+         clearRegionLocally(regionEvent, cacheWrite, null);
+         if (!regionEvent.isOriginRemote() && regionEvent.isDistributed()) {
+           DistributedClearOperation.clear(regionEvent, null, participants);
+         }
+       }
+     }
+     
+     // since clients do not maintain RVVs except for tombstone GC
+     // we need to ensure that current ops reach the client queues
+     // before queuing a clear, but there is no infrastructure for doing so
+     notifyBridgeClients(regionEvent);
+   }
+ 
+   /**
+    * Obtain a distributed lock for the clear operation.
+    */
+   private void distributedLockForClear() {
+     if (!this.scope.isGlobal()) {  // non-global regions

<TRUNCATED>


[015/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryDataInconsistencyDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryDataInconsistencyDUnitTest.java
index aeb4343,0000000..0227836
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryDataInconsistencyDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryDataInconsistencyDUnitTest.java
@@@ -1,580 -1,0 +1,576 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.dunit;
 +
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.PartitionResolver;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.IndexType;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.data.Portfolio;
 +import com.gemstone.gemfire.cache.query.data.Position;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
 +import com.gemstone.gemfire.cache.query.partitioned.PRQueryDUnitHelper;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.internal.cache.execute.PRClientServerTestBase;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +
 +/**
 + * This tests the data inconsistency during update on an index and querying the
 + * same UNLOCKED index.
 + * 
 + * @author shobhit
 + * 
 + */
 +public class QueryDataInconsistencyDUnitTest extends CacheTestCase {
 +
 +  private static final int cnt = 0;
 +
 +  private static final int cntDest = 10;
 +
 +  static VM server = null;
 +
 +  static VM client = null;
 +
 +  static Cache cache = null;
 +
 +  static String PartitionedRegionName1 = "TestPartitionedRegion1"; // default
 +                                                                   // name
 +  static String repRegionName = "TestRepRegion"; // default name
 +  
 +  static Integer serverPort1 = null;
 +
 +  public static int numOfBuckets = 20;
 +
 +  public static String[] queries = new String[] {
 +      "select * from /" + PartitionedRegionName1 + " where ID=1",
 +      };
 +
 +  public static String[] queriesForRR = new String[] { "<trace> select * from /"
 +      + repRegionName + " where ID=1" };
 +
 +  private static PRQueryDUnitHelper PRQHelp = new PRQueryDUnitHelper("");
 +
 +  public static volatile boolean hooked = false;
 +  /**
 +   * @param name
 +   */
 +  public QueryDataInconsistencyDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  @Override
 +  protected final void preTearDownCacheTestCase() throws Exception {
 +    Invoke.invokeInEveryVM(CacheTestCase.class, "disconnectFromDS");
 +  }
 +  
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    Invoke.invokeInEveryVM(QueryObserverHolder.class, "reset");
 +  }
 +
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    Host host = Host.getHost(0);
 +    server = host.getVM(0);
 +  }
 +
 +  public void testCompactRangeIndex() {
 +    // Create caches
 +    Properties props = new Properties();
-     server.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
++    server.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
 +
 +    server.invoke(new CacheSerializableRunnable("create indexes") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        cache = CacheFactory.getAnyInstance();
 +        Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(repRegionName);
 +        
 +        // Create common Portflios and NewPortfolios
 +        for (int j = cnt; j < cntDest; j++) {
 +          region.put(new Integer(j), new Portfolio(j));
 +        }
 +        
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        try {
 +          Index index = qs.createIndex("idIndex", "ID", "/"+repRegionName);
 +          assertEquals(10, index.getStatistics().getNumberOfKeys());
 +        } catch (Exception e) {
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +    //Invoke update from client and stop in updateIndex
 +    //first before updating the RegionEntry and second after updating
 +    //the RegionEntry.
 +    AsyncInvocation putThread = server.invokeAsync(new CacheSerializableRunnable("update a Region Entry") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region repRegion = CacheFactory.getAnyInstance().getRegion(repRegionName);
 +        IndexManager.testHook = new IndexManagerTestHook();
 +        repRegion.put(new Integer("1"), new Portfolio(cntDest+1));
 +        //above call must be hooked in BEFORE_UPDATE_OP call.
 +      }
 +    });
 +    server.invoke(new CacheSerializableRunnable("query on server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        while (!hooked){Wait.pause(100);}
 +        Object rs = null;
 +        try {
 +          rs = qs.newQuery("<trace> select * from /"+repRegionName+" where ID = 1").execute();          
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          fail("Query execution failed on server.");
 +          IndexManager.testHook = null;
 +        }
 +        assertTrue(rs instanceof SelectResults);
 +        assertEquals(1, ((SelectResults)rs).size());
 +        Portfolio p1 = (Portfolio) ((SelectResults)rs).asList().get(0);
 +        if (p1.getID() != 1) {
 +          fail("Query thread did not verify index results even when RE is under update");
 +          IndexManager.testHook = null;
 +        }
 +        hooked = false;//Let client put go further.
 +      }
 +    });
 +
 +    //Client put is again hooked in AFTER_UPDATE_OP call in updateIndex.
 +    server.invoke(new CacheSerializableRunnable("query on server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        while (!hooked){Wait.pause(100);}
 +        Object rs = null;
 +        try {
 +          rs = qs.newQuery("<trace> select * from /"+repRegionName+" where ID = 1").execute();          
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          fail("Query execution failed on server."+e.getMessage());
 +        } finally {
 +          IndexManager.testHook = null;
 +        }
 +        assertTrue(rs instanceof SelectResults);
 +        if (((SelectResults)rs).size() > 0) {
 +          Portfolio p1 = (Portfolio) ((SelectResults)rs).iterator().next();
 +          if (p1.getID() != 1) {
 +            fail("Query thread did not verify index results even when RE is under update and " +
 +                      "RegionEntry value has been modified before releasing the lock");
 +            IndexManager.testHook = null;
 +          }
 +        }
 +        hooked = false;//Let client put go further.
 +      }
 +    });
 +    ThreadUtils.join(putThread, 200);
 +  }
 +
 +  public void testRangeIndex() {
 +    // Create caches
 +    Properties props = new Properties();
-     server.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
++    server.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
 +
 +    server.invoke(new CacheSerializableRunnable("create indexes") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        cache = CacheFactory.getAnyInstance();
 +        Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(repRegionName);
 +        IndexManager.testHook = null;
 +        // Create common Portfolios and NewPortfolios
 +        Position.cnt = 0;
 +        for (int j = cnt; j < cntDest; j++) {
 +          Portfolio p = new Portfolio(j);
 +          CacheFactory.getAnyInstance().getLogger().fine("Shobhit: portfolio "+j+ " : "+p);
 +          region.put(new Integer(j), p);
 +        }
 +        
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        try {
 +          Index index = qs.createIndex("posIndex", "pos.secId", "/"+repRegionName+" p, p.positions.values pos");
 +          assertEquals(12, index.getStatistics().getNumberOfKeys());
 +        } catch (Exception e) {
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +    //Invoke update from client and stop in updateIndex
 +    //first before updating the RegionEntry and second after updating
 +    //the RegionEntry.
 +    AsyncInvocation putThread = server.invokeAsync(new CacheSerializableRunnable("update a Region Entry") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region repRegion = CacheFactory.getAnyInstance().getRegion(repRegionName);
 +        IndexManager.testHook = new IndexManagerTestHook();
 +        Portfolio newPort = new Portfolio(cntDest+1);
 +        CacheFactory.getAnyInstance().getLogger().fine("Shobhit: New Portfolio"+newPort);
 +        repRegion.put(new Integer("1"), newPort);
 +        //above call must be hooked in BEFORE_UPDATE_OP call.
 +      }
 +    });
 +
 +    server.invoke(new CacheSerializableRunnable("query on server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        Position pos1 = null;
 +        while (!hooked){Wait.pause(100);}
 +        try {
 +          Object rs = qs.newQuery("<trace> select pos from /"+repRegionName+" p, p.positions.values pos where pos.secId = 'APPL' AND p.ID = 1").execute();
 +          CacheFactory.getAnyInstance().getLogger().fine("Shobhit: "+rs);
 +          assertTrue(rs instanceof SelectResults);
 +          pos1 = (Position) ((SelectResults)rs).iterator().next();
 +          if (!pos1.secId.equals("APPL")) {
 +            fail("Query thread did not verify index results even when RE is under update");
 +            IndexManager.testHook = null;       
 +          }          
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          Assert.fail("Query execution failed on server.", e);
 +          IndexManager.testHook = null;
 +        } finally {
 +          hooked = false;//Let client put go further.
 +        }
 +        while (!hooked) {
 +          Wait.pause(100);
 +        }
 +        try {
 +          Object rs = qs.newQuery("<trace> select pos from /"+repRegionName+" p, p.positions.values pos where pos.secId = 'APPL' AND p.ID = 1").execute();
 +          CacheFactory.getAnyInstance().getLogger().fine("Shobhit: "+rs);
 +          assertTrue(rs instanceof SelectResults);
 +          if (((SelectResults)rs).size() > 0) {
 +            Position pos2 = (Position) ((SelectResults)rs).iterator().next();
 +            if (pos2.equals(pos1)) {
 +              fail("Query thread did not verify index results even when RE is under update and " +
 +              "RegionEntry value has been modified before releasing the lock");
 +            }
 +          }
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          fail("Query execution failed on server.");
 +        } finally {
 +          hooked = false;//Let client put go further.
 +          IndexManager.testHook = null;
 +        }
 +      }
 +    });
 +    ThreadUtils.join(putThread, 200);
 +  }
 +  
 +  public void testRangeIndexWithIndexAndQueryFromCluaseMisMatch() {
 +    // Create caches
 +    Properties props = new Properties();
-     server.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
++    server.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
 +
 +    server.invoke(new CacheSerializableRunnable("create indexes") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        cache = CacheFactory.getAnyInstance();
 +        Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(repRegionName);
 +        IndexManager.testHook = null;
 +        // Create common Portfolios and NewPortfolios
 +        Position.cnt = 0;
 +        for (int j = cnt; j < cntDest; j++) {
 +          region.put(new Integer(j), new Portfolio(j));
 +        }
 +        
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        try {
 +          Index index = qs.createIndex("posIndex", "pos.secId", "/"+repRegionName+" p, p.collectionHolderMap.values coll, p.positions.values pos");
 +          assertEquals(12, index.getStatistics().getNumberOfKeys());
 +        } catch (Exception e) {
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +    //Invoke update from client and stop in updateIndex
 +    //first before updating the RegionEntry and second after updating
 +    //the RegionEntry.
 +    AsyncInvocation putThread = server.invokeAsync(new CacheSerializableRunnable("update a Region Entry") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region repRegion = CacheFactory.getAnyInstance().getRegion(repRegionName);
 +        IndexManager.testHook = new IndexManagerTestHook();
 +        // This portfolio with same ID must have different positions.
 +        repRegion.put(new Integer("1"), new Portfolio(1));
 +        //above call must be hooked in BEFORE_UPDATE_OP call.
 +      }
 +    });
 +
 +    server.invoke(new CacheSerializableRunnable("query on server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        Position pos1 = null;
 +        while (!hooked){Wait.pause(100);}
 +        try {
 +          Object rs = qs.newQuery("<trace> select pos from /"+repRegionName+" p, p.positions.values pos where pos.secId = 'APPL' AND p.ID = 1").execute();
 +          CacheFactory.getAnyInstance().getLogger().fine("Shobhit: "+rs);
 +          assertTrue(rs instanceof SelectResults);
 +          pos1 = (Position) ((SelectResults)rs).iterator().next();
 +          if (!pos1.secId.equals("APPL")) {
 +            fail("Query thread did not verify index results even when RE is under update");
 +            IndexManager.testHook = null;       
 +          }          
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          Assert.fail("Query execution failed on server.", e);
 +          IndexManager.testHook = null;
 +        } finally {
 +          hooked = false;//Let client put go further.
 +        }
 +        while (!hooked) {
 +          Wait.pause(100);
 +        }
 +        try {
 +          Object rs = qs.newQuery("select pos from /"+repRegionName+" p, p.positions.values pos where pos.secId = 'APPL' AND p.ID = 1").execute();
 +          assertTrue(rs instanceof SelectResults);
 +          if (((SelectResults)rs).size() > 0) {
 +            Position pos2 = (Position) ((SelectResults)rs).iterator().next();
 +            if (pos2.equals(pos1)) {
 +              fail("Query thread did not verify index results even when RE is under update and " +
 +              "RegionEntry value has been modified before releasing the lock");
 +            }
 +          }
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          fail("Query execution failed on server.");
 +        } finally {
 +          hooked = false;//Let client put go further.
 +          IndexManager.testHook = null;
 +        }
 +      }
 +    });
 +    ThreadUtils.join(putThread, 200);
 +  }
 +
 +  public void testRangeIndexWithIndexAndQueryFromCluaseMisMatch2() {
 +    // Create caches
 +    Properties props = new Properties();
-     server.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
++    server.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
 +
 +    server.invoke(new CacheSerializableRunnable("create indexes") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        cache = CacheFactory.getAnyInstance();
 +        Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(repRegionName);
 +        IndexManager.testHook = null;
 +        // Create common Portfolios and NewPortfolios
 +        Position.cnt = 0;
 +        for (int j = cnt; j < cntDest; j++) {
 +          region.put(new Integer(j), new Portfolio(j));
 +        }
 +        
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        try {
 +          Index index = qs.createIndex("posIndex", "pos.secId", "/"+repRegionName+" p, p.positions.values pos");
 +          assertEquals(12, index.getStatistics().getNumberOfKeys());
 +        } catch (Exception e) {
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +    //Invoke update from client and stop in updateIndex
 +    //first before updating the RegionEntry and second after updating
 +    //the RegionEntry.
 +    AsyncInvocation putThread = server.invokeAsync(new CacheSerializableRunnable("update a Region Entry") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region repRegion = CacheFactory.getAnyInstance().getRegion(repRegionName);
 +        IndexManager.testHook = new IndexManagerTestHook();
 +        // This portfolio with same ID must have different positions.
 +        repRegion.put(new Integer("1"), new Portfolio(1));
 +        //above call must be hooked in BEFORE_UPDATE_OP call.
 +      }
 +    });
 +
 +    server.invoke(new CacheSerializableRunnable("query on server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +        Position pos1 = null;
 +        while (!hooked){Wait.pause(100);}
 +        try {
 +          Object rs = qs.newQuery("<trace> select pos from /"+repRegionName+" p, p.collectionHolderMap.values coll, p.positions.values pos where pos.secId = 'APPL' AND p.ID = 1").execute();
 +          CacheFactory.getAnyInstance().getLogger().fine("Shobhit: "+rs);
 +          assertTrue(rs instanceof SelectResults);
 +          pos1 = (Position) ((SelectResults)rs).iterator().next();
 +          if (!pos1.secId.equals("APPL")) {
 +            fail("Query thread did not verify index results even when RE is under update");
 +            IndexManager.testHook = null;       
 +          }          
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          Assert.fail("Query execution failed on server.", e);
 +          IndexManager.testHook = null;
 +        } finally {
 +          hooked = false;//Let client put go further.
 +        }
 +        while (!hooked) {
 +          Wait.pause(100);
 +        }
 +        try {
 +          Object rs = qs.newQuery("select pos from /"+repRegionName+" p, p.collectionHolderMap.values coll, p.positions.values pos where pos.secId = 'APPL' AND p.ID = 1").execute();
 +          assertTrue(rs instanceof SelectResults);
 +          if (((SelectResults)rs).size() > 0) {
 +            Position pos2 = (Position) ((SelectResults)rs).iterator().next();
 +            if (pos2.equals(pos1)) {
 +              fail("Query thread did not verify index results even when RE is under update and " +
 +              "RegionEntry value has been modified before releasing the lock");
 +            }
 +          }
 +        } catch (Exception e) {
 +          e.printStackTrace();
 +          fail("Query execution failed on server.");
 +        } finally {
 +          IndexManager.testHook = null;
 +          hooked = false;//Let client put go further.
 +        }
 +      }
 +    });
 +    ThreadUtils.join(putThread, 200);
 +  }
 +  
 +  public static void createProxyRegions() {
 +    new QueryDataInconsistencyDUnitTest("temp").createProxyRegs();
 +  }
 +
 +  private void createProxyRegs() {
 +    ClientCache cache = (ClientCache) CacheFactory.getAnyInstance();
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(
 +        repRegionName);
 +
 +    /*cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(
 +        PartitionedRegionName1);*/
 +  }
 +
 +  public static void createNewPR() {
 +    new QueryDataInconsistencyDUnitTest("temp").createPR();
 +  }
 +  public void createPR() {
 +    PartitionResolver testKeyBasedResolver = new QueryAPITestPartitionResolver();
 +    cache = CacheFactory.getAnyInstance();
 +    cache
 +        .createRegionFactory(RegionShortcut.PARTITION_REDUNDANT)
 +        .setPartitionAttributes(
 +            new PartitionAttributesFactory()
 +                .setTotalNumBuckets(numOfBuckets)
 +                .setPartitionResolver(testKeyBasedResolver)
 +                .create())
 +        .create(PartitionedRegionName1);
 +  }
 +
 +  public static void createCacheClientWithoutRegion(String host, Integer port1) {
 +    new QueryDataInconsistencyDUnitTest("temp").createCacheClientWithoutReg(
 +        host, port1);
 +  }
 +
 +  private void createCacheClientWithoutReg(String host, Integer port1) {
 +    this.disconnectFromDS();
 +    ClientCache cache = new ClientCacheFactory().addPoolServer(host, port1)
 +        .create();
 +  }
 +
 +  /**
 +   * This function puts portfolio objects into the created Region (PR or Local)
 +   * *
 +   * 
 +   * @param regionName
 +   * @param portfolio
 +   * @param to
 +   * @param from
 +   * @return cacheSerializable object
 +   */
 +  public CacheSerializableRunnable getCacheSerializableRunnableForPRPuts(
 +      final String regionName, final Object[] portfolio, final int from,
 +      final int to) {
 +    SerializableRunnable puts = new CacheSerializableRunnable("Region Puts") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = CacheFactory.getAnyInstance();
 +        Region region = cache.getRegion(repRegionName);
 +        for (int j = from; j < to; j++)
 +          region.put(new Integer(j), portfolio[j]);
 +          LogWriterUtils.getLogWriter()
 +            .info(
 +                "PRQueryDUnitHelper#getCacheSerializableRunnableForPRPuts: Inserted Portfolio data on Region "
 +                    + regionName);
 +      }
 +    };
 +    return (CacheSerializableRunnable) puts;
 +  }
 +
 +  public class IndexManagerTestHook implements com.gemstone.gemfire.cache.query.internal.index.IndexManager.TestHook{
 +    public void hook(final int spot) throws RuntimeException {
 +      switch (spot) {
 +      case 9: //Before Index update and after region entry lock.
 +        hooked  = true;
 +        LogWriterUtils.getLogWriter().info("QueryDataInconsistency.IndexManagerTestHook is hooked in Update Index Entry.");
 +        while(hooked) {
 +          Wait.pause(100);
 +        }
 +        assertEquals(hooked, false);
 +        break;
 +      case 10: //Before Region update and after Index Remove call.
 +        hooked  = true;
 +        LogWriterUtils.getLogWriter().info("QueryDataInconsistency.IndexManagerTestHook is hooked in Remove Index Entry.");
 +        while(hooked) {
 +          Wait.pause(100);
 +        }
 +        assertEquals(hooked, false);
 +        break;
 +      default:
 +        break;
 +      }
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingFunctionContextDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingFunctionContextDUnitTest.java
index fcc96dc,0000000..1e3e973
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingFunctionContextDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingFunctionContextDUnitTest.java
@@@ -1,1048 -1,0 +1,1041 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.dunit;
 +
 +import java.util.ArrayList;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.PartitionResolver;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.client.ServerConnectivityException;
 +import com.gemstone.gemfire.cache.execute.Function;
 +import com.gemstone.gemfire.cache.execute.FunctionAdapter;
 +import com.gemstone.gemfire.cache.execute.FunctionContext;
 +import com.gemstone.gemfire.cache.execute.FunctionException;
 +import com.gemstone.gemfire.cache.execute.FunctionService;
 +import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
 +import com.gemstone.gemfire.cache.execute.ResultCollector;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.data.Portfolio;
 +import com.gemstone.gemfire.cache.query.functional.StructSetOrResultsSet;
 +import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
 +import com.gemstone.gemfire.cache.query.internal.IndexTrackingQueryObserver;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
 +import com.gemstone.gemfire.cache.query.partitioned.PRQueryDUnitHelper;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.internal.cache.LocalDataSet;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.execute.PRClientServerTestBase;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * This tests the querying using a RegionFunctionContext which provides a filter
 + * (routing keys) to run the query on subset of buckets "locally". If query
 + * includes buckets
 + *
 + * @author shobhit
 + *
 + */
 +public class QueryUsingFunctionContextDUnitTest extends CacheTestCase {
 +
 +  private static final int cnt = 0;
 +
 +  private static final int cntDest = 100;
 +
-   static VM server1 = null;
++  VM server1 = null;
 +
 +  static VM server2 = null;
 +
 +  static VM server3 = null;
 +
 +  static VM client = null;
 +
 +  static Cache cache = null;
 +
 +  static Function function = null;
 +  // PR 2 is co-located with 1 and 3 is co-located with 2
 +  // PR 5 is co-located with 4
 +  static String PartitionedRegionName1 = "TestPartitionedRegion1"; //default name
 +  static String PartitionedRegionName2 = "TestPartitionedRegion2"; //default name
 +  static String PartitionedRegionName3 = "TestPartitionedRegion3"; //default name
 +  static String PartitionedRegionName4 = "TestPartitionedRegion4"; //default name
 +  static String PartitionedRegionName5 = "TestPartitionedRegion5"; //default name
 +
 +  static String repRegionName = "TestRepRegion"; //default name
 +  static String localRegionName = "TestLocalRegion"; //default name
 +
 +  static Integer serverPort1 = null;
 +
 +  static Integer serverPort2 = null;
 +
 +  static Integer serverPort3 = null;
 +
 +  public static int numOfBuckets = 20;
 +
 +  public static String[] queries = new String[] {
 +      "select * from /" + PartitionedRegionName1 + " where ID>=0",
 +      "Select * from /" + PartitionedRegionName1 + " r1, /" + PartitionedRegionName2 + " r2 where r1.ID = r2.ID",
 +      "Select * from /" + PartitionedRegionName1 + " r1, /" + PartitionedRegionName2 + " r2 where r1.ID = r2.ID AND r1.status = r2.status",
 +      "Select * from /" + PartitionedRegionName1 + " r1, /" + PartitionedRegionName2 + " r2, /" + PartitionedRegionName3 + " r3 where r1.ID = r2.ID and r2.ID = r3.ID",
 +      "Select * from /" + PartitionedRegionName1 + " r1, /" + PartitionedRegionName2 + " r2, /" + PartitionedRegionName3
 +          + " r3  , /" + repRegionName + " r4 where r1.ID = r2.ID and r2.ID = r3.ID and r3.ID = r4.ID",
 +     // "Select * from /" + PartitionedRegionName4 + " r4 , /" + PartitionedRegionName5 + " r5 where r4.ID = r5.ID"
 +      };
 +
 +  public static String[] nonColocatedQueries = new String[]{
 +    "Select * from /" + PartitionedRegionName1 + " r1, /" + PartitionedRegionName4 + " r4 where r1.ID = r4.ID",
 +    "Select * from /" + PartitionedRegionName1 + " r1, /" + PartitionedRegionName4 + " r4 , /" + PartitionedRegionName5 + " r5 where r1.ID = r4.ID and r4.ID = r5.ID"
 +  };
 +  
 +  public static String[] queriesForRR = new String[]{"<trace> select * from /"+repRegionName+" where ID>=0"};
 +
 +  private static PRQueryDUnitHelper PRQHelp = new PRQueryDUnitHelper("");
 +  /**
 +   * @param name
 +   */
 +  public QueryUsingFunctionContextDUnitTest(String name) {
 +    super(name);
 +
 +  }
 +
 +  @Override
 +  protected final void preTearDownCacheTestCase() throws Exception {
 +    Invoke.invokeInEveryVM(CacheTestCase.class, "disconnectFromDS");
 +  }
 +  
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    Invoke.invokeInEveryVM(QueryObserverHolder.class, "reset");
 +    cache = null;
 +    Invoke.invokeInEveryVM(new SerializableRunnable() { public void run() { cache = null; } });
 +  }
 +
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    Host host = Host.getHost(0);
 +    server1 = host.getVM(0);
 +    server2 = host.getVM(1);
 +    server3 = host.getVM(2);
 +    client = host.getVM(3);
 +    createServersWithRegions();
 +    fillValuesInRegions();
 +    registerFunctionOnServers();
 +  }
 +
 +
 +  /**
 +   * Test on Replicated Region.
 +   */
 +  public void testQueriesWithFilterKeysOnReplicatedRegion() {
 +    IgnoredException.addIgnoredException("IllegalArgumentException");
 +
 +    Object[][] r = new Object[queriesForRR.length][2];
 +
 +    client.invoke(new CacheSerializableRunnable("Run function on RR") {
 +      @Override
 +      public void run2() throws CacheException {
 +
 +        ResultCollector rcollector = null;
 +
 +        for (int i = 0; i < queriesForRR.length; i++) {
 +
 +          try {
 +            function = new TestQueryFunction("queryFunctionOnRR");
 +
 +            rcollector = FunctionService
 +                .onRegion(
 +                    CacheFactory.getAnyInstance().getRegion(repRegionName))
 +                .withArgs(queriesForRR[i]).execute(function);
 +
 +            //Should not come here, an exception is expected from above function call.
 +            fail("Function call did not fail for query with function context");
 +          } catch (FunctionException ex) {
 +            if (!(ex.getCause() instanceof IllegalArgumentException)) {
 +              fail("Should have received an IllegalArgumentException");
 +            }
 +          }
 +        }//For loop ends here.
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Test on PR on one server only using filter.
 +   */
 +  public void testQueriesWithFilterKeysOnPRLocal() {
 +    
 +    client.invoke(new CacheSerializableRunnable("Test query on client and server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Set filter =  new HashSet();
 +        filter.add(0);
 +
 +        for (int i=0; i< queries.length; i++) {
 +          Object[][] r = new Object[1][2];
 +
 +          TestServerQueryFunction func = new TestServerQueryFunction("LDS Server function-1");
 +          function = new TestQueryFunction("queryFunction-1");
 +          QueryUsingFunctionContextDUnitTest test = new QueryUsingFunctionContextDUnitTest("test");
 +          ArrayList queryResults2 = test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, queries[i]);  
 +          if (queryResults2 == null)
 +            fail(queries[i] +"result is null from client function");
 +          
 +          ArrayList queryResults1 = test.runLDSQueryOnClientUsingFunc(func, filter, queries[i]);
 +          if (queryResults1 == null)
 +            fail(queries[i] +"result is null from LDS function");
 +          
 +          r[0][0] = queryResults1;
 +          r[0][1] = queryResults2;
 +          StructSetOrResultsSet ssORrs = new  StructSetOrResultsSet();
 +          ssORrs.CompareQueryResultsAsListWithoutAndWithIndexes(r, 1,false, new String[]{queries[i]});
 +        }   
 +      }
 +    });
 +    
 +  }
 +
 +  public void testInvalidQueries() {
 +    
 +    IgnoredException.addIgnoredException("Syntax error");
 +    client.invoke(new CacheSerializableRunnable("Test query on client and server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Set filter =  new HashSet();
 +        filter.add(0);
 +        String query = "select * from / " + repRegionName + " where ID>=0";
 +        TestServerQueryFunction func = new TestServerQueryFunction("LDS Server function-1");
 +        function = new TestQueryFunction("queryFunction-1");
 +        QueryUsingFunctionContextDUnitTest test = new QueryUsingFunctionContextDUnitTest("test");
 +        try {
 +          test.runQueryOnClientUsingFunc(function, repRegionName, filter, query);  
 +          fail("Query execution should have failed.");
 +        } catch (FunctionException ex) {
 +          assertTrue("The exception message should mention QueryInvalidException. ", ex.getLocalizedMessage().contains("QueryInvalidException"));
 +        }
 +        
 +        query = "select * from / " + PartitionedRegionName1 + " where ID>=0";
 +        func = new TestServerQueryFunction("LDS Server function-1");
 +        function = new TestQueryFunction("queryFunction-1");
 +        test = new QueryUsingFunctionContextDUnitTest("test");
 +        try {
 +          test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, query);  
 +          fail("Query execution should have failed.");
 +        } catch (FunctionException ex) {
 +          assertTrue("The exception message should mention QueryInvalidException. ", ex.getLocalizedMessage().contains("QueryInvalidException"));
 +        }
 +      }
 +    });
 +    
 +  }
 +  
 +  /**
 +   *
 +   */
 +  public void testQueriesWithFilterKeysOnPRLocalAndRemote() {
 +    
 +    client.invoke(new CacheSerializableRunnable("Test query on client and server") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Set filter = getFilter(0, 1);
 +
 +        TestServerQueryFunction func = new TestServerQueryFunction("LDS Server function-1");
 +        function = new TestQueryFunction("queryFunction-2");
 +
 +        for (int i=0; i< queries.length; i++) {
 +          Object[][] r = new Object[1][2];
 +
 +          QueryUsingFunctionContextDUnitTest test = new QueryUsingFunctionContextDUnitTest("test");
 +          ArrayList queryResults2 = test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, queries[i]);
 +          if (queryResults2 == null)
 +            fail(queries[i] +"result is null from client function");
 +          ArrayList queryResults1 = test.runLDSQueryOnClientUsingFunc(func, filter, queries[i]);
 +          if (queryResults1 == null)
 +            fail(queries[i] +"result is null from LDS function");
 +          
 +
 +          r[0][0] = queryResults1;
 +          r[0][1] = queryResults2;
 +          StructSetOrResultsSet ssORrs = new  StructSetOrResultsSet();
 +          ssORrs.CompareQueryResultsAsListWithoutAndWithIndexes(r, 1,false, new String[]{queries[i]});
 +        }    
 +      }
 +    });
 +  }
 +
 +  /**
 +  *
 +  */
 + public void testQueriesWithFilterKeysOnPRLocalAndRemoteWithBucketDestroy() {
 +   
 +   // Set Query Observer in cache on server1
 +   server1.invoke(new CacheSerializableRunnable("Set QueryObserver in cache on server1") {
 +     @Override
 +     public void run2() throws CacheException {
 +
 +       class MyQueryObserver extends IndexTrackingQueryObserver {
 +
 +         @Override
 +         public void startQuery(Query query) {
 +           //Destroy only for first query.
 +           if (query.getQueryString().contains("ID>=0")){
 +             Region pr = CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1);
 +             Region KeyRegion = null;
 +             for (int i=3; i<7; i++) {
 +               KeyRegion = ((PartitionedRegion)pr).getBucketRegion(i/*key*/);
 +               if (KeyRegion != null)
 +               KeyRegion.destroyRegion();
 +             }
 +           }
 +         }
 +       };
 +
 +       QueryObserverHolder.setInstance(new MyQueryObserver());
 +     }
 +   });
 +   
 +   client.invoke(new CacheSerializableRunnable("Test query on client and server") {
 +     
 +     @Override
 +     public void run2() throws CacheException {
 +       Set filter = getFilter(0, 2);
 +       
 +       TestServerQueryFunction func = new TestServerQueryFunction("LDS Server function-2");
 +       function = new TestQueryFunction("queryFunction");
 +
 +       for (int i=0; i< queries.length; i++) {
 +         
 +         QueryUsingFunctionContextDUnitTest test = new QueryUsingFunctionContextDUnitTest("test");
 +         ArrayList queryResults2 = test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, queries[i]);  
 +         
 +         // The Partition Region has 20 buckets with 100 values and key i goes in bucket j=(i%20)
 +         // So each bucket has 5 keys so for 3 buckets 3*5.
 +         if (i==0 && queryResults2.size() != 3*5) {
 +           fail("Result size should have been 15 but was"+queryResults2.size());
 +         }
 +       }    
 +     }
 +   });
 +   // Reset Query Observer in cache on server1
 +   server1.invoke(new CacheSerializableRunnable("Reset Query Observer on server1") {
 +     @Override
 +     public void run2() throws CacheException {
 +       QueryObserverHolder.reset();
 +     }
 +   });
 +
 + }
 +
 +  /**
 +   *
 +   */
 +  public void testQueriesWithFilterKeysOnPRWithBucketDestroy() {
 +    IgnoredException.addIgnoredException("QueryInvocationTargetException");
 +    Object[][] r = new Object[queries.length][2];
 +    Set filter =  new HashSet();
 +
 +    // Close cache on server1
 +    server1.invoke(new CacheSerializableRunnable("Set QueryObserver in cache on server1") {
 +      @Override
 +      public void run2() throws CacheException {
 +
 +        class MyQueryObserver extends IndexTrackingQueryObserver {
 +
 +          @Override
 +          public void startQuery(Query query) {
 +            Region pr = CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1);
 +            Region KeyRegion = null;
 +            for (int i=0; i<7; i++) {
 +              KeyRegion = ((PartitionedRegion)pr).getBucketRegion(i/*key*/);
 +              if (KeyRegion != null)
 +              KeyRegion.destroyRegion();
 +            }
 +          }
 +        };
 +
 +        QueryObserverHolder.setInstance(new MyQueryObserver());
 +      }
 +    });
 +
 +    client.invoke(new CacheSerializableRunnable("Run function on PR") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Set filter =  new HashSet();
 +        ResultCollector rcollector = null;
 +        filter.addAll(getFilter(0, 19));
 +
 +        for (int i = 0; i < queries.length; i++) {
 +
 +          try {
 +            function = new TestQueryFunction("queryFunctionBucketDestroy");
 +
 +            rcollector = FunctionService
 +                .onRegion(
 +                    CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1))
 +                .withArgs(queries[i])
 +                .withFilter(filter)
 +                .execute(function);
 +
 +            //Should not come here, an exception is expected from above function call.
 +            fail("Function call did not fail for query with function context");
 +          } catch (FunctionException ex) {
 +            //ex.printStackTrace();
 +            if (!(ex.getCause() instanceof QueryInvocationTargetException)) {
 +              fail("Should have received an QueryInvocationTargetException but recieved"+ex.getMessage());
 +            }
 +          }
 +        }//For loop ends here.
 +      }
 +    });
 +
 + // Close cache on server1
 +    server1.invoke(new CacheSerializableRunnable("Reset Query Observer on server1") {
 +      @Override
 +      public void run2() throws CacheException {
 +        QueryObserverHolder.reset();
 +      }
 +    });
 +
 +  }
 +
 +  /**
 +  *
 +  */
 + public void testQueriesWithFilterKeysOnPRWithRebalancing() {
 +   IgnoredException.addIgnoredException("QueryInvocationTargetException");
 +   IgnoredException.addIgnoredException("java.net.SocketException");
 +   IgnoredException.addIgnoredException("ServerConnectivityException");
 +   IgnoredException.addIgnoredException("FunctionException");
 +   IgnoredException.addIgnoredException("IOException");
 +
 +   // Close cache on server1
 +   server1.invoke(new CacheSerializableRunnable("Set QueryObserver in cache on server1") {
 +     @Override
 +     public void run2() throws CacheException {
 +
 +       class MyQueryObserver extends IndexTrackingQueryObserver {
 +
 +         @Override
 +         public void startQuery(Query query) {
 +           Region pr = CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1);
 +           Region KeyRegion = null;
 +           for (int i=6; i<9; i++) {
 +             KeyRegion = ((PartitionedRegion)pr).getBucketRegion(i/*key*/);
 +             if (KeyRegion != null)
 +             KeyRegion.destroyRegion();
 +           }
 +         }
 +       };
 +
 +       QueryObserverHolder.setInstance(new MyQueryObserver());
 +     }
 +   });
 +
 +   client.invoke(new CacheSerializableRunnable("Run function on PR") {
 +     @Override
 +     public void run2() throws CacheException {
 +       Set filter =  new HashSet();
 +       ResultCollector rcollector = null;
 +       filter.addAll(getFilter(6, 9));
 +
 +       for (int i = 0; i < queries.length; i++) {
 +
 +         try {
 +           function = new TestQueryFunction("queryFunction");
 +
 +           rcollector = FunctionService
 +               .onRegion(
 +                   CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1))
 +               .withArgs(queries[i])
 +               .withFilter(filter)
 +               .execute(function);
 +
 +           //Should not come here, an exception is expected from above function call.
 +           fail("Function call did not fail for query with function context");
 +         } catch (FunctionException ex) {
 +           if (!((ex.getCause() instanceof QueryInvocationTargetException) || (ex.getCause() instanceof ServerConnectivityException))) {
 +             if (ex.getCause() instanceof FunctionException) {
 +               FunctionException fe = (FunctionException)ex.getCause();
 +               if (!fe.getMessage().startsWith("IOException")) {
 +                 fail("Should have received an QueryInvocationTargetException but recieved"+ex.getMessage());
 +               }
 +             }
 +             else {
 +               fail("Should have received an QueryInvocationTargetException but recieved"+ex.getMessage());
 +             }
 +           }
 +         }
 +       }//For loop ends here.
 +     }
 +   });
 +
 +// Close cache on server1
 +   server1.invoke(new CacheSerializableRunnable("Reset Query Observer on server1") {
 +     @Override
 +     public void run2() throws CacheException {
 +       QueryObserverHolder.reset();
 +     }
 +   });
 +
 + }
 +
 + 
 + public void testNonColocatedRegionQueries() {
 +   IgnoredException.addIgnoredException("UnsupportedOperationException");
 +   client.invoke(new CacheSerializableRunnable("Test query on non-colocated regions on server") {
 +     @Override
 +     public void run2() throws CacheException {
 +       Set filter =  new HashSet();
 +       filter.add(0);
 +
 +       for (int i=0; i< nonColocatedQueries.length; i++) {
 +         function = new TestQueryFunction("queryFunction-1");
 +         QueryUsingFunctionContextDUnitTest test = new QueryUsingFunctionContextDUnitTest("test");
 +         try {
 +          ArrayList queryResults2 = test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, nonColocatedQueries[i]);
 +          fail("Function call did not fail for query with function context");
 +         } catch (FunctionException e) {
 +          if (!(e.getCause() instanceof UnsupportedOperationException)) {
 +            Assert.fail("Should have received an UnsupportedOperationException but received", e);
 +          }
 +         }  
 +        }   
 +     }
 +   });
 +   
 + }
 + 
 + public void testJoinQueryPRWithMultipleIndexes(){
 +   
 +   server1.invoke(new CacheSerializableRunnable("Test query with indexes") {
 +     
 +     @Override
 +     public void run2() throws CacheException {
 +       Set filter = getFilter(0, 1);
 +       function = new TestQueryFunction("queryFunction-2");
 +       Object[][] r = new Object[2][2];
 +       QueryUsingFunctionContextDUnitTest test = new QueryUsingFunctionContextDUnitTest("test");
 +       int j = 0;
 +       for (int i=3; i< 5; i++) {
 +         ArrayList queryResults2 = test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, queries[i]);
 +         if (queryResults2 == null)
 +           fail(queries[i] +"result is null from client function");
 +         r[j++][1] = queryResults2;
 +       }
 +       createIndex();
 +       j = 0;
 +       for (int i=3; i< 5; i++) {
 +         ArrayList queryResults1 = test.runQueryOnClientUsingFunc(function, PartitionedRegionName1, filter, queries[i]);
 +         if (queryResults1 == null)
 +           fail(queries[i] +"result is null from client function");
 +         r[j++][0] = queryResults1;
 +       }
 +       
 +       StructSetOrResultsSet ssORrs = new  StructSetOrResultsSet();
 +       ssORrs.CompareQueryResultsAsListWithoutAndWithIndexes(r, 2,false, queries);
 +
 +     }
 +   });
 + }
 + 
 +
 +  //Helper classes and function
 +  public class TestQueryFunction extends FunctionAdapter {
 +
 +    @Override
 +    public boolean hasResult() {
 +      return true;
 +    }
 +
 +    @Override
 +    public boolean isHA() {
 +      return false;
 +    }
 +
 +    private final String id;
 +
 +
 +    public TestQueryFunction(String id) {
 +      super();
 +      this.id = id;
 +    }
 +
 +    @Override
 +    public void execute(FunctionContext context) {
 +      Cache cache = CacheFactory.getAnyInstance();
 +      QueryService queryService = cache.getQueryService();
 +      ArrayList allQueryResults = new ArrayList();
 +      String qstr = (String) context.getArguments();
 +      try {
 +        Query query = queryService.newQuery(qstr);
 +        context.getResultSender().lastResult((ArrayList) ((SelectResults) query
 +                .execute((RegionFunctionContext) context)).asList());
 +      } catch (Exception e) {
 +        throw new FunctionException(e);
 +      }
 +    }
 +
 +    @Override
 +    public String getId() {
 +      return this.id;
 +    }
 +  }
 +  
 +  public class TestServerQueryFunction extends FunctionAdapter {
 +
 +    @Override
 +    public boolean hasResult() {
 +      return true;
 +    }
 +
 +    @Override
 +    public boolean isHA() {
 +      return false;
 +    }
 +
 +    private final String id;
 +
 +
 +    public TestServerQueryFunction(String id) {
 +      super();
 +      this.id = id;
 +    }
 +
 +    @Override
 +    public void execute(FunctionContext context) {
 +      Cache cache = CacheFactory.getAnyInstance();
 +      QueryService queryService = cache.getQueryService();
 +      ArrayList allQueryResults = new ArrayList();
 +      Object[] args = (Object[])context.getArguments();
 +      Set buckets = getBucketsForFilter((Set)args[1]);
 +      Region localDataSet = new LocalDataSet((PartitionedRegion)CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1), buckets);
 +
 +      try {
 +        Query query = queryService.newQuery((String)args[0]);
 +        context.getResultSender().lastResult((ArrayList) ((SelectResults) ((LocalDataSet) localDataSet).executeQuery(
 +            (DefaultQuery) query, null, buckets)).asList());
 +      } catch (Exception e) {
 +        throw new FunctionException(e);
 +      }
 +    }
 +
 +    @Override
 +    public String getId() {
 +      return this.id;
 +    }
 +    
 +    private Set getBucketsForFilter(Set filter) {
 +      Set bucketids = new HashSet();
 +      for (Object key: filter) {
 +        int intKey = ((Integer)key).intValue();
 +        bucketids.add(intKey%numOfBuckets);
 +      }
 +      return bucketids;
 +    }
 +  }
 +
 +  public void fillValuesInRegions() {
 +    //Create common Portflios and NewPortfolios
 +    final Portfolio[] portfolio = PRQHelp.createPortfoliosAndPositions(cntDest);
 +
 +    //Fill local region
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(localRegionName,
 +        portfolio, cnt, cntDest));
 +
 +    //Fill replicated region
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(repRegionName,
 +        portfolio, cnt, cntDest));
 +
 +    //Fill Partition Region
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(PartitionedRegionName1,
 +        portfolio, cnt, cntDest));
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(PartitionedRegionName2,
 +        portfolio, cnt, cntDest));
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(PartitionedRegionName3,
 +        portfolio, cnt, cntDest));
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(PartitionedRegionName4,
 +        portfolio, cnt, cntDest));
 +    server1.invoke(getCacheSerializableRunnableForPRPuts(PartitionedRegionName5,
 +        portfolio, cnt, cntDest));
 +  }
 +
 +  private void registerFunctionOnServers() {
 +    function = new TestQueryFunction("queryFunction");
 +    server1.invoke(PRClientServerTestBase.class,
 +        "registerFunction", new Object []{function});
 +
 +    server2.invoke(PRClientServerTestBase.class,
 +        "registerFunction", new Object []{function});
 +
 +    server3.invoke(PRClientServerTestBase.class,
 +        "registerFunction", new Object []{function});
 +  }
 +
 +  private void createServersWithRegions() {
 +    //Create caches
 +    Properties props = new Properties();
-     server1.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
-     server2.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
-     server3.invoke(PRClientServerTestBase.class, "createCacheInVm",
-         new Object[] { props });
++    server1.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
++    server2.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
++    server3.invoke(() -> PRClientServerTestBase.createCacheInVm( props ));
 +
 +    //Create Cache Servers
-     Integer port1 = (Integer)server1.invoke(PRClientServerTestBase.class,
-     "createCacheServer");
-     Integer port2 = (Integer)server2.invoke(PRClientServerTestBase.class,
-         "createCacheServer");
-     Integer port3 = (Integer)server3.invoke(PRClientServerTestBase.class,
-         "createCacheServer");
++    Integer port1 = (Integer)server1.invoke(() -> PRClientServerTestBase.createCacheServer());
++    Integer port2 = (Integer)server2.invoke(() -> PRClientServerTestBase.createCacheServer());
++    Integer port3 = (Integer)server3.invoke(() -> PRClientServerTestBase.createCacheServer());
 +    serverPort1 = port1;
 +    serverPort2 = port2;
 +    serverPort3 = port3;
 +
 +    //Create client cache without regions
-     client.invoke(QueryUsingFunctionContextDUnitTest.class, "createCacheClientWithoutRegion",
-         new Object[] { NetworkUtils.getServerHostName(server1.getHost()), port1, port2,
-             port3 });
++    client.invoke(() -> QueryUsingFunctionContextDUnitTest.createCacheClientWithoutRegion( NetworkUtils.getServerHostName(server1.getHost()), port1, port2,
++            port3 ));
 +
 +    //Create proxy regions on client.
-     client.invoke(QueryUsingFunctionContextDUnitTest.class, "createProxyRegions");
++    client.invoke(() -> QueryUsingFunctionContextDUnitTest.createProxyRegions());
 +
 +    //Create local Region on servers
-     server1.invoke(QueryUsingFunctionContextDUnitTest.class, "createLocalRegion");
++    server1.invoke(() -> QueryUsingFunctionContextDUnitTest.createLocalRegion());
 +
 +    //Create ReplicatedRegion on servers
-     server1.invoke(QueryUsingFunctionContextDUnitTest.class, "createReplicatedRegion");
-     server2.invoke(QueryUsingFunctionContextDUnitTest.class, "createReplicatedRegion");
-     server3.invoke(QueryUsingFunctionContextDUnitTest.class, "createReplicatedRegion");
++    server1.invoke(() -> QueryUsingFunctionContextDUnitTest.createReplicatedRegion());
++    server2.invoke(() -> QueryUsingFunctionContextDUnitTest.createReplicatedRegion());
++    server3.invoke(() -> QueryUsingFunctionContextDUnitTest.createReplicatedRegion());
 +
 +    //Create two colocated PartitionedRegions On Servers.
-     server1.invoke(QueryUsingFunctionContextDUnitTest.class, "createColocatedPR");
-     server2.invoke(QueryUsingFunctionContextDUnitTest.class, "createColocatedPR");
-     server3.invoke(QueryUsingFunctionContextDUnitTest.class, "createColocatedPR");
++    server1.invoke(() -> QueryUsingFunctionContextDUnitTest.createColocatedPR());
++    server2.invoke(() -> QueryUsingFunctionContextDUnitTest.createColocatedPR());
++    server3.invoke(() -> QueryUsingFunctionContextDUnitTest.createColocatedPR());
 +
 +  }
 +
 +  public static void createProxyRegions() {
 +    new QueryUsingFunctionContextDUnitTest("temp").createProxyRegs();
 +  }
 +
 +  private void createProxyRegs() {
 +    ClientCache cache = (ClientCache)CacheFactory.getAnyInstance();
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(repRegionName);
 +
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(localRegionName);
 +
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
 +      .create(PartitionedRegionName1);
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
 +      .create(PartitionedRegionName2);
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
 +    .create(PartitionedRegionName3);
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
 +    .create(PartitionedRegionName4);
 +    cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
 +    .create(PartitionedRegionName5);
 +  }
 +
 +  public static void createLocalRegion() {
 +    new QueryUsingFunctionContextDUnitTest("temp").createLocalReg();
 +  }
 +  public void createLocalReg() {
 +    cache = CacheFactory.getAnyInstance();
 +    cache.createRegionFactory(RegionShortcut.LOCAL).create(localRegionName);
 +  }
 +
 +  public static void createReplicatedRegion() {
 +    new QueryUsingFunctionContextDUnitTest("temp").createRR();
 +  }
 +  public void createRR() {
 +    cache = CacheFactory.getAnyInstance();
 +    cache.createRegionFactory(RegionShortcut.REPLICATE).create(repRegionName);
 +  }
 +
 +  public static void createColocatedPR() {
 +    new QueryUsingFunctionContextDUnitTest("temp").createColoPR();
 +  }
 +  public void createColoPR() {
 +    PartitionResolver testKeyBasedResolver = new QueryAPITestPartitionResolver();
 +    cache = CacheFactory.getAnyInstance();
 +    cache
 +        .createRegionFactory(RegionShortcut.PARTITION)
 +        .setPartitionAttributes(
 +            new PartitionAttributesFactory()
 +                .setTotalNumBuckets(numOfBuckets)
 +                .setPartitionResolver(testKeyBasedResolver)
 +                .create())
 +        .create(PartitionedRegionName1);
 +
 +    cache
 +        .createRegionFactory(RegionShortcut.PARTITION)
 +        .setPartitionAttributes(
 +            new PartitionAttributesFactory()
 +                .setTotalNumBuckets(numOfBuckets)
 +                .setPartitionResolver(testKeyBasedResolver)
 +                .setColocatedWith(PartitionedRegionName1)
 +                .create())
 +        .create(PartitionedRegionName2);
 +    
 +    cache
 +    .createRegionFactory(RegionShortcut.PARTITION)
 +    .setPartitionAttributes(
 +        new PartitionAttributesFactory()
 +            .setTotalNumBuckets(numOfBuckets)
 +            .setPartitionResolver(testKeyBasedResolver)
 +            .setColocatedWith(PartitionedRegionName2)
 +            .create())
 +    .create(PartitionedRegionName3);
 +    
 +    cache
 +    .createRegionFactory(RegionShortcut.PARTITION)
 +    .setPartitionAttributes(
 +        new PartitionAttributesFactory()
 +            .setTotalNumBuckets(numOfBuckets)
 +            .setPartitionResolver(testKeyBasedResolver)
 +             .create())
 +    .create(PartitionedRegionName4); // not collocated
 +    
 +    cache
 +    .createRegionFactory(RegionShortcut.PARTITION)
 +    .setPartitionAttributes(
 +        new PartitionAttributesFactory()
 +            .setTotalNumBuckets(numOfBuckets)
 +            .setPartitionResolver(testKeyBasedResolver)
 +            .setColocatedWith(PartitionedRegionName4)
 +             .create())
 +    .create(PartitionedRegionName5); // collocated with 4 
 +  }
 +
 +  public static void createCacheClientWithoutRegion(String host, Integer port1, Integer port2, Integer port3) {
 +    new QueryUsingFunctionContextDUnitTest("temp").createCacheClientWithoutReg(host, port1, port2, port3);
 +  }
 +  private void createCacheClientWithoutReg(String host, Integer port1, Integer port2, Integer port3) {
 +    this.disconnectFromDS();
 +    ClientCache cache = new ClientCacheFactory()
 +      .addPoolServer(host, port1)
 +      .addPoolServer(host, port2)
 +      .addPoolServer(host, port3)
 +      .create();
 +  }
 +
 +  /**
 +   * Run query on server using LocalDataSet.executeQuery() to compare results
 +   * received from client function execution.
 +   */
 +  public static ArrayList runQueryOnServerLocalDataSet(String query, Set filter) {
 +    return new QueryUsingFunctionContextDUnitTest("temp").runQueryOnServerLDS(query, filter);
 +  }
 +
 +  protected ArrayList runQueryOnServerLDS(String queryStr, Set filter) {
 +
 +    Set buckets = getBucketsForFilter(filter);
 +    Region localDataSet = new LocalDataSet((PartitionedRegion)CacheFactory.getAnyInstance().getRegion(PartitionedRegionName1), buckets);
 +
 +    QueryService qservice = CacheFactory.getAnyInstance().getQueryService();
 +
 +    Query query = qservice.newQuery(queryStr);
 +    SelectResults results;
 +    try {
 +      results = (SelectResults) ((LocalDataSet) localDataSet).executeQuery(
 +          (DefaultQuery) query, null, buckets);
 +
 +      return (ArrayList)results.asList();
 +    } catch (Exception e) {
 +      e.printStackTrace();
 +    }
 +    return null;
 +  }
 +
 +  /**
 +   * Run query on server to compare the results received from client function execution.
 +   */
 +  public static ArrayList runQueryOnServerRegion(String query) {
 +    return new QueryUsingFunctionContextDUnitTest("temp").runQueryOnServerReg(query);
 +  }
 +  protected ArrayList runQueryOnServerReg(String queryStr) {
 +
 +    QueryService qservice = CacheFactory.getAnyInstance().getQueryService();
 +
 +    Query query = qservice.newQuery(queryStr);
 +    SelectResults results = null;
 +    try {
 +      results = (SelectResults) query.execute();
 +    } catch (Exception e) {
 +      e.printStackTrace();
 +    }
 +    return results!= null ? (ArrayList)results.asList():null;
 +  }
 +
 +  /**
 +   * Run query using a function executed by client on a region on server with filter.
 +   * @param function
 +   * @param regionName
 +   * @param filter
 +   * @return ArrayList of results
 +   */
 +  public static ArrayList runQueryOnClientUsingFunction(Function function, String regionName, Set filter, String query) {
 +    return new QueryUsingFunctionContextDUnitTest("temp").runQueryOnClientUsingFunc(function, regionName, filter, query);
 +  }
 +
 +  private ArrayList runQueryOnClientUsingFunc(Function func, String regionName, Set filter, String query) {
 +    ResultCollector rcollector = null;
 +
 +    // Filter can not be set as null if withFilter() is called.
 +    if (filter != null) {
 +      rcollector = FunctionService.onRegion(CacheFactory.getAnyInstance().getRegion(regionName))
 +        .withArgs(query)
 +        .withFilter(filter)
 +        .execute(func);
 +    } else {
 +      rcollector = FunctionService.onRegion(CacheFactory.getAnyInstance().getRegion(regionName))
 +      .withArgs(query)
 +      .execute(func);
 +    }
 +    Object result = rcollector.getResult();
 +    assertTrue(result instanceof ArrayList);
 +
 +    //Results from multiple nodes.
 +    ArrayList resultList = (ArrayList)result;
 +    resultList.trimToSize();
 +    List queryResults = null;
 +
 +    if (resultList.size()!=0 && resultList.get(0) instanceof ArrayList) {
 +      queryResults = new ArrayList();
 +      for (Object obj: resultList) {
 +        if (obj != null) {
 +          queryResults.addAll((ArrayList)obj);
 +        }
 +      }
 +    }
 +
 +    return (ArrayList) queryResults;
 +  }
 +
 +  /**
 +   * Runs a {@link LocalDataSet} query on a single server. 
 +   * @param func
 +   * @param filter
 +   * @param query
 +   * @return results in a List
 +   */
 +  private ArrayList runLDSQueryOnClientUsingFunc(Function func, Set filter, String query) {
 +    ResultCollector rcollector = null;
 +
 +    // Filter can not be set as null if withFilter() is called.
 +    rcollector = FunctionService
 +        .onServer(ClientCacheFactory.getAnyInstance())
 +        .withArgs(new Object[]{query, filter}).execute(func);
 +    Object result = rcollector.getResult();
 +    assertTrue(result instanceof ArrayList);
 +
 +    //Results from multiple nodes.
 +    ArrayList resultList = (ArrayList)result;
 +    resultList.trimToSize();
 +    List queryResults = new ArrayList();
 +    
 +    if (resultList.size()!=0 && resultList.get(0) instanceof ArrayList) {
 +      for (Object obj: resultList) {
 +        if (obj != null) {
 +          queryResults.addAll((ArrayList)obj);
 +        }
 +      }
 +    }
 +
 +    return (ArrayList) queryResults;
 +  }
 +
 +  private Set getFilter(int start, int end) {
 +    Set filter = new HashSet();
 +    for (int j=start; j<=end; j++) {
 +      filter.add(j);
 +    }
 +    return filter;
 +  }
 +
 +
 +  private Set getBucketsForFilter(Set filter) {
 +    Set bucketids = new HashSet();
 +    for (Object key: filter) {
 +      int intKey = ((Integer)key).intValue();
 +      bucketids.add(intKey%numOfBuckets);
 +    }
 +    return bucketids;
 +  }
 +
 +  /**
 +   * This function puts portfolio objects into the created Region (PR or Local) *
 +   *
 +   * @param regionName
 +   * @param portfolio
 +   * @param to
 +   * @param from
 +   * @return cacheSerializable object
 +   */
 +  public CacheSerializableRunnable getCacheSerializableRunnableForPRPuts(
 +      final String regionName, final Object[] portfolio, final int from,
 +      final int to)
 +  {
 +    SerializableRunnable puts = new CacheSerializableRunnable("Region Puts") {
 +      @Override
 +      public void run2() throws CacheException
 +      {
 +        Cache cache = CacheFactory.getAnyInstance();
 +        Region region = cache.getRegion(regionName);
 +        for (int j = from; j < to; j++)
 +          region.put(new Integer(j), portfolio[j]);
 +        LogWriterUtils.getLogWriter()
 +            .info(
 +                "PRQueryDUnitHelper#getCacheSerializableRunnableForPRPuts: Inserted Portfolio data on Region "
 +                    + regionName);
 +      }
 +    };
 +    return (CacheSerializableRunnable)puts;
 +  }
 +  
 + 
 +  public void createIndex() {
 +    QueryService qs = CacheFactory.getAnyInstance().getQueryService();
 +    try {
 +      qs.createIndex("ID1", "ID", "/"+ PartitionedRegionName1);
 +      qs.createIndex("ID2", "ID", "/"+ PartitionedRegionName2);
 +      qs.createIndex("ID3", "ID", "/"+ PartitionedRegionName3);
 +    } catch (Exception e) {
 +        fail("Index creation failed " + e);
 +    }
 +  }
 +
 +}


[069/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
index 0000000,fd0eb4f..b1e3af0
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
@@@ -1,0 -1,314 +1,314 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ import static org.mockito.Mockito.mock;
+ import static org.hamcrest.CoreMatchers.*;
+ 
+ import java.nio.ByteBuffer;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.cache.VMCachedDeserializable;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ /**
+  * @author khowe
+  */
+ @Category(UnitTest.class)
+ public class OffHeapHelperJUnitTest extends AbstractStoredObjectTestBase {
+ 
+   private MemoryChunkWithRefCount storedObject                 = null;
+   private Object                  deserializedRegionEntryValue = null;
+   private byte[]                  serializedRegionEntryValue   = null;
+   private MemoryAllocator         ma;
+ 
+   @Before
+   public void setUp() {
+     OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
+     OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
+     LogWriter lw = mock(LogWriter.class);
+ 
+     ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 3, OffHeapStorage.MIN_SLAB_SIZE * 3,
+         OffHeapStorage.MIN_SLAB_SIZE);
+ 
+   }
+ 
+   /**
+    * Extracted from JUnit setUp() to reduce test overhead for cases where
+    * offheap memory isn't needed.
+    */
+   private void allocateOffHeapSerialized() {
+     Object regionEntryValue = getValue();
+     storedObject = createValueAsSerializedStoredObject(regionEntryValue);
+     deserializedRegionEntryValue = storedObject.getValueAsDeserializedHeapObject();
+     serializedRegionEntryValue = storedObject.getSerializedValue();
+   }
+ 
+   private void allocateOffHeapDeserialized() {
+     Object regionEntryValue = getValue();
+     storedObject = createValueAsUnserializedStoredObject(regionEntryValue);
+     deserializedRegionEntryValue = storedObject.getValueAsDeserializedHeapObject();
+     serializedRegionEntryValue = storedObject.getSerializedValue();
+   }
+ 
+   @After
+   public void tearDown() {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+   }
+ 
+   @Override
+   public Object getValue() {
+     return Long.valueOf(Long.MAX_VALUE);
+   }
+ 
+   @Override
+   public byte[] getValueAsByteArray() {
+     return convertValueToByteArray(getValue());
+   }
+ 
+   private byte[] convertValueToByteArray(Object value) {
+     return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong((Long) value).array();
+   }
+ 
+   @Override
+   public Object convertByteArrayToObject(byte[] valueInByteArray) {
+     return ByteBuffer.wrap(valueInByteArray).getLong();
+   }
+ 
+   @Override
+   public Object convertSerializedByteArrayToObject(byte[] valueInSerializedByteArray) {
+     return EntryEventImpl.deserialize(valueInSerializedByteArray);
+   }
+ 
+   @Override
+   protected MemoryChunkWithRefCount createValueAsUnserializedStoredObject(Object value) {
+     byte[] valueInByteArray;
+     if (value instanceof Long) {
+       valueInByteArray = convertValueToByteArray(value);
+     } else {
+       valueInByteArray = (byte[]) value;
+     }
+ 
+     boolean isSerialized = false;
+     boolean isCompressed = false;
+ 
+     MemoryChunkWithRefCount createdObject = createChunk(valueInByteArray, isSerialized, isCompressed);
+     return createdObject;
+   }
+ 
+   @Override
+   protected MemoryChunkWithRefCount createValueAsSerializedStoredObject(Object value) {
+     byte[] valueInSerializedByteArray = EntryEventImpl.serialize(value);
+ 
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
+     MemoryChunkWithRefCount createdObject = createChunk(valueInSerializedByteArray, isSerialized, isCompressed);
+     return createdObject;
+   }
+ 
 -  private GemFireChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
 -    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
++  private ObjectChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed);
+     return chunk;
+   }
+ 
+   @Test
+   public void getHeapFormOfSerializedStoredObjectReturnsDeserializedObject() {
+     allocateOffHeapSerialized();
+     Object heapObject = OffHeapHelper.getHeapForm(storedObject);
+     assertThat("getHeapForm returns non-null object", heapObject, notNullValue());
+     assertThat("Heap and off heap objects are different objects", heapObject, is(not(storedObject)));
+     assertThat("Deserialzed values of offHeap object and returned object are equal", heapObject,
+         is(equalTo(deserializedRegionEntryValue)));
+   }
+ 
+   @Test
+   public void getHeapFormOfNonOffHeapObjectReturnsOriginal() {
+     Object testObject = getValue();
+     Object heapObject = OffHeapHelper.getHeapForm(testObject);
+     assertNotNull(heapObject);
+     assertSame(testObject, heapObject);
+   }
+ 
+   @Test
+   public void getHeapFormWithNullReturnsNull() {
+     Object testObject = null;
+     Object returnObject = OffHeapHelper.getHeapForm(testObject);
+     assertThat(returnObject, is(equalTo(null)));
+   }
+ 
+   @Test
+   public void copyAndReleaseWithNullReturnsNull() {
+     Object testObject = null;
+     Object returnObject = OffHeapHelper.copyAndReleaseIfNeeded(testObject);
+     assertThat(returnObject, is(equalTo(null)));
+   }
+ 
+   @Test
+   public void copyAndReleaseWithRetainedDeserializedObjectDecreasesRefCnt() {
+     allocateOffHeapDeserialized();
+     assertTrue(storedObject.retain());
+     assertThat("Retained chunk ref count", storedObject.getRefCount(), is(2));
+     OffHeapHelper.copyAndReleaseIfNeeded(storedObject);
+     assertThat("Chunk ref count decreases", storedObject.getRefCount(), is(1));
+   }
+ 
+   @Test
+   public void copyAndReleaseWithNonRetainedObjectDecreasesRefCnt() {
+     allocateOffHeapDeserialized();
+     // assertTrue(storedObject.retain());
+     assertThat("Retained chunk ref count", storedObject.getRefCount(), is(1));
+     OffHeapHelper.copyAndReleaseIfNeeded(storedObject);
+     assertThat("Chunk ref count decreases", storedObject.getRefCount(), is(0));
+   }
+ 
+   @Test
+   public void copyAndReleaseWithDeserializedReturnsValueOfOriginal() {
+     allocateOffHeapDeserialized();
+     assertTrue(storedObject.retain());
+     Object returnObject = OffHeapHelper.copyAndReleaseIfNeeded(storedObject);
+     assertThat(returnObject, is(equalTo(deserializedRegionEntryValue)));
+   }
+ 
+   @Test
+   public void copyAndReleaseWithSerializedReturnsValueOfOriginal() {
+     allocateOffHeapSerialized();
+     assertTrue(storedObject.retain());
+     Object returnObject = ((VMCachedDeserializable) OffHeapHelper.copyAndReleaseIfNeeded(storedObject))
+         .getSerializedValue();
+     assertThat(returnObject, is(equalTo(serializedRegionEntryValue)));
+   }
+ 
+   @Test
+   public void copyAndReleaseNonStoredObjectReturnsOriginal() {
+     Object testObject = getValue();
+     Object returnObject = OffHeapHelper.copyAndReleaseIfNeeded(testObject);
+     assertThat(returnObject, is(testObject));
+   }
+ 
+   @Test
+   public void copyIfNeededWithNullReturnsNull() {
+     Object testObject = null;
+     Object returnObject = OffHeapHelper.copyAndReleaseIfNeeded(testObject);
+     assertThat(returnObject, is(equalTo(null)));
+   }
+ 
+   @Test
+   public void copyIfNeededNonOffHeapReturnsOriginal() {
+     Object testObject = getValue();
+     Object returnObject = OffHeapHelper.copyIfNeeded(testObject);
+     assertThat(returnObject, is(testObject));
+   }
+ 
+   @Test
+   public void copyIfNeededOffHeapSerializedReturnsValueOfOriginal() {
+     allocateOffHeapSerialized();
+     Object returnObject = ((VMCachedDeserializable) OffHeapHelper.copyIfNeeded(storedObject)).getSerializedValue();
+     assertThat(returnObject, is(equalTo(serializedRegionEntryValue)));
+   }
+ 
+   @Test
+   public void copyIfNeededOffHeapDeserializedReturnsOriginal() {
+     allocateOffHeapDeserialized();
+     Object returnObject = OffHeapHelper.copyIfNeeded(storedObject);
+     assertThat(returnObject, is(equalTo(deserializedRegionEntryValue)));
+   }
+ 
+   @Test
+   public void copyIfNeededWithOffHeapDeserializedObjDoesNotRelease() {
+     allocateOffHeapDeserialized();
+     int initialRefCountOfObject = storedObject.getRefCount();
+     OffHeapHelper.copyIfNeeded(storedObject);
+     assertThat("Ref count after copy", storedObject.getRefCount(), is(initialRefCountOfObject));
+   }
+ 
+   @Test
+   public void copyIfNeededWithOffHeapSerializedObjDoesNotRelease() {
+     allocateOffHeapSerialized();
+     int initialRefCountOfObject = storedObject.getRefCount();
+     OffHeapHelper.copyIfNeeded(storedObject);
+     assertThat("Ref count after copy", storedObject.getRefCount(), is(initialRefCountOfObject));
+   }
+ 
+   @Test
+   public void releaseOfOffHeapDecrementsRefCount() {
+     allocateOffHeapSerialized();
+     assertThat("Initial Ref Count", storedObject.getRefCount(), is(1));
+     OffHeapHelper.release(storedObject);
+     assertThat("Ref Count Decremented", storedObject.getRefCount(), is(0));
+   }
+ 
+   @Test
+   public void releaseOfOffHeapReturnsTrue() {
+     allocateOffHeapSerialized();
+     assertThat("Releasing OFfHeap object is true", OffHeapHelper.release(storedObject), is(true));
+   }
+ 
+   @Test
+   public void releaseOfNonOffHeapReturnsFalse() {
+     Object testObject = getValue();
+     assertThat("Releasing OFfHeap object is true", OffHeapHelper.release(testObject), is(false));
+   }
+ 
+   @Test
+   public void releaseWithOutTrackingOfOffHeapDecrementsRefCount() {
+     allocateOffHeapSerialized();
+     assertThat("Initial Ref Count", storedObject.getRefCount(), is(1));
+     OffHeapHelper.releaseWithNoTracking(storedObject);
+     assertThat("Ref Count Decremented", storedObject.getRefCount(), is(0));
+   }
+ 
+   @Test
+   public void releaseWithoutTrackingOfOffHeapReturnsTrue() {
+     allocateOffHeapSerialized();
+     assertThat("Releasing OFfHeap object is true", OffHeapHelper.releaseWithNoTracking(storedObject), is(true));
+   }
+ 
+   @Test
+   public void releaseWithoutTrackingOfNonOffHeapReturnsFalse() {
+     Object testObject = getValue();
+     assertThat("Releasing OFfHeap object is true", OffHeapHelper.releaseWithNoTracking(testObject), is(false));
+   }
+ 
+   @Test
+   public void releaseAndTrackOwnerOfOffHeapDecrementsRefCount() {
+     allocateOffHeapSerialized();
+     assertThat("Initial Ref Count", storedObject.getRefCount(), is(1));
+     OffHeapHelper.releaseAndTrackOwner(storedObject, "owner");
+     assertThat("Ref Count Decremented", storedObject.getRefCount(), is(0));
+   }
+ 
+   @Test
+   public void releaseAndTrackOwnerOfOffHeapReturnsTrue() {
+     allocateOffHeapSerialized();
+     assertThat("Releasing OFfHeap object is true", OffHeapHelper.releaseAndTrackOwner(storedObject, "owner"), is(true));
+   }
+ 
+   @Test
+   public void releaseAndTrackOwnerOfNonOffHeapReturnsFalse() {
+     Object testObject = getValue();
+     assertThat("Releasing OFfHeap object is true", OffHeapHelper.releaseAndTrackOwner(testObject, "owner"), is(false));
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
index 0000000,b515959..8de0406
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
@@@ -1,0 -1,593 +1,593 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertFalse;
+ import static org.junit.Assert.assertNotNull;
+ import static org.junit.Assert.assertTrue;
+ import static org.junit.Assert.fail;
+ 
+ import java.io.Serializable;
+ import java.util.Arrays;
+ import java.util.Properties;
+ 
+ import org.junit.Test;
+ 
+ import com.gemstone.gemfire.OutOfOffHeapMemoryException;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.EntryEvent;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionShortcut;
+ import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
+ import com.gemstone.gemfire.compression.Compressor;
+ import com.gemstone.gemfire.compression.SnappyCompressor;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.pdx.PdxReader;
+ import com.gemstone.gemfire.pdx.PdxSerializable;
+ import com.gemstone.gemfire.pdx.PdxWriter;
+ import com.gemstone.gemfire.test.dunit.WaitCriterion;
+ 
+ /**
+  * Basic test of regions that use off heap storage.
+  * Subclasses exist for the different types of offheap store.
+  * 
+  * @author darrel
+  *
+  */
+ public abstract class OffHeapRegionBase {
+   
+   public abstract void configureOffHeapStorage();
+   public abstract void unconfigureOffHeapStorage();
+   public abstract int perObjectOverhead();
+ 
+   private GemFireCacheImpl createCache() {
+     return createCache(false);
+   }
+   private GemFireCacheImpl createCache(boolean isPersistent) {
+     configureOffHeapStorage();
+     Properties props = new Properties();
+     props.setProperty("locators", "");
+     props.setProperty("mcast-port", "0");
+     props.setProperty("off-heap-memory-size", getOffHeapMemorySize());
+     GemFireCacheImpl result = (GemFireCacheImpl) new CacheFactory(props).setPdxPersistent(isPersistent).create();
+     unconfigureOffHeapStorage();
+     return result;
+   }
+   private void closeCache(GemFireCacheImpl gfc, boolean keepOffHeapAllocated) {
+     gfc.close();
+     if (!keepOffHeapAllocated) {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+     // TODO cleanup default disk store files
+   }
+   
+   protected abstract String getOffHeapMemorySize();
+   
+   @Test
+   public void testSizeAllocation() {
+     // prevent cache from closing in reaction to ooom
+     System.setProperty(OffHeapStorage.STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY, "true");
+     GemFireCacheImpl gfc = createCache();
+     try {
+       MemoryAllocator ma = gfc.getOffHeapStore();
+       assertNotNull(ma);
+       final long offHeapSize = ma.getFreeMemory();
+       assertEquals(0, ma.getUsedMemory());
 -      MemoryChunk mc1 = ma.allocate(64, null);
++      MemoryChunk mc1 = ma.allocate(64);
+       assertEquals(64+perObjectOverhead(), ma.getUsedMemory());
+       assertEquals(offHeapSize-(64+perObjectOverhead()), ma.getFreeMemory());
+       mc1.release();
+       assertEquals(offHeapSize, ma.getFreeMemory());
+       assertEquals(0, ma.getUsedMemory());
+       // do an allocation larger than the slab size
+       // TODO: currently the compact will product slabs bigger than the max slab size
+       // (see the todo comment on compact() in SimpleMemoryAllocator).
+       // So we request 20m here since that it the total size.
+       try {
 -        ma.allocate(1024*1024*20, null);
++        ma.allocate(1024*1024*20);
+         fail("Expected an out of heap exception");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       assertEquals(0, ma.getUsedMemory());
+       assertFalse(gfc.isClosed());
+     } finally {
+       System.clearProperty(OffHeapStorage.STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY);
+       closeCache(gfc, false);
+     }
+   }
+   
+   public void keep_testOutOfOffHeapMemoryErrorClosesCache() {
+     // this test is redundant but may be useful
+     final GemFireCacheImpl gfc = createCache();
+     try {
+       MemoryAllocator ma = gfc.getOffHeapStore();
+       assertNotNull(ma);
+       final long offHeapSize = ma.getFreeMemory();
+       assertEquals(0, ma.getUsedMemory());
 -      MemoryChunk mc1 = ma.allocate(64, null);
++      MemoryChunk mc1 = ma.allocate(64);
+       assertEquals(64+perObjectOverhead(), ma.getUsedMemory());
+       assertEquals(offHeapSize-(64+perObjectOverhead()), ma.getFreeMemory());
+       mc1.release();
+       assertEquals(offHeapSize, ma.getFreeMemory());
+       assertEquals(0, ma.getUsedMemory());
+       // do an allocation larger than the slab size
+       try {
 -        ma.allocate(1024*1024*10, null);
++        ma.allocate(1024*1024*10);
+         fail("Expected an out of heap exception");
+       } catch (OutOfOffHeapMemoryException expected) {
+         // passed
+       }
+       assertEquals(0, ma.getUsedMemory());
+       
+       final WaitCriterion waitForDisconnect = new WaitCriterion() {
+         public boolean done() {
+           return gfc.isClosed();
+         }
+         public String description() {
+           return "Waiting for disconnect to complete";
+         }
+       };
+       com.gemstone.gemfire.test.dunit.Wait.waitForCriterion(waitForDisconnect, 10*1000, 100, true);
+ 
+       assertTrue(gfc.isClosed());
+     } finally {
+       closeCache(gfc, false);
+     }
+   }
+ 
+   @Test
+   public void testByteArrayAllocation() {
+     GemFireCacheImpl gfc = createCache();
+     try {
+       MemoryAllocator ma = gfc.getOffHeapStore();
+       assertNotNull(ma);
+       final long offHeapSize = ma.getFreeMemory();
+       assertEquals(0, ma.getUsedMemory());
+       byte[] data = new byte[] {1,2,3,4,5,6,7,8};
 -      MemoryChunk mc1 = (MemoryChunk)ma.allocateAndInitialize(data, false, false, null);
++      MemoryChunk mc1 = (MemoryChunk)ma.allocateAndInitialize(data, false, false);
+       assertEquals(data.length+perObjectOverhead(), ma.getUsedMemory());
+       assertEquals(offHeapSize-(data.length+perObjectOverhead()), ma.getFreeMemory());
+       byte[] data2 = new byte[data.length];
+       mc1.readBytes(0, data2);
+       assertTrue(Arrays.equals(data, data2));
+       mc1.release();
+       assertEquals(offHeapSize, ma.getFreeMemory());
+       assertEquals(0, ma.getUsedMemory());
+       // try some small byte[] that don't need to be stored off heap.
+       data = new byte[] {1,2,3,4,5,6,7};
 -      StoredObject so1 = ma.allocateAndInitialize(data, false, false, null);
++      StoredObject so1 = ma.allocateAndInitialize(data, false, false);
+       assertEquals(0, ma.getUsedMemory());
+       assertEquals(offHeapSize, ma.getFreeMemory());
+       data2 = new byte[data.length];
+       data2 = (byte[])so1.getDeserializedForReading();
+       assertTrue(Arrays.equals(data, data2));
+     } finally {
+       closeCache(gfc, false);
+     }
+   }
+ 
+   private void doRegionTest(final RegionShortcut rs, final String rName) {
+     doRegionTest(rs, rName, false/*compressed*/);
+   }
+ 
+   @SuppressWarnings({ "rawtypes", "unchecked" })
+   private void doRegionTest(final RegionShortcut rs, final String rName, boolean compressed) {
+     boolean isPersistent = rs == RegionShortcut.LOCAL_PERSISTENT || rs == RegionShortcut.REPLICATE_PERSISTENT || rs == RegionShortcut.PARTITION_PERSISTENT;
+     GemFireCacheImpl gfc = createCache(isPersistent);
+     Region r = null;
+     try {
+       gfc.setCopyOnRead(true);
+       final MemoryAllocator ma = gfc.getOffHeapStore();
+       assertNotNull(ma);
+       assertEquals(0, ma.getUsedMemory());
+       Compressor compressor = null;
+       if (compressed) {
+         compressor = SnappyCompressor.getDefaultInstance();
+       }
+       r = gfc.createRegionFactory(rs).setOffHeap(true).setCompressor(compressor).create(rName);
+       assertEquals(true, r.isEmpty());
+       assertEquals(0, ma.getUsedMemory());
+       Object data = new Integer(123456789);
+       r.put("key1", data);
+       //System.out.println("After put of Integer value off heap used memory=" + ma.getUsedMemory());
+       assertTrue(ma.getUsedMemory() == 0);
+       assertEquals(data, r.get("key1"));
+       r.invalidate("key1");
+       assertEquals(0, ma.getUsedMemory());
+       r.put("key1", data);
+       assertTrue(ma.getUsedMemory() == 0);
+       long usedBeforeUpdate = ma.getUsedMemory();
+       r.put("key1", data);
+       assertEquals(usedBeforeUpdate, ma.getUsedMemory());
+       assertEquals(data, r.get("key1"));
+       r.destroy("key1");
+       assertEquals(0, ma.getUsedMemory());
+       
+       data = new Long(0x007FFFFFL);
+       r.put("key1", data);
+       if (!compressed) {
+         assertTrue(ma.getUsedMemory() == 0);
+       }
+       assertEquals(data, r.get("key1"));
+       data = new Long(0xFF8000000L);
+       r.put("key1", data);
+       if (!compressed) {
+         assertTrue(ma.getUsedMemory() == 0);
+       }
+       assertEquals(data, r.get("key1"));
+       
+       
+       // now lets set data to something that will be stored offheap
+       data = new Long(Long.MAX_VALUE);
+       r.put("key1", data);
+       assertEquals(data, r.get("key1"));
+       //System.out.println("After put of Integer value off heap used memory=" + ma.getUsedMemory());
+       assertTrue(ma.getUsedMemory() > 0);
+       data = new Long(Long.MIN_VALUE);
+       r.put("key1", data);
+       assertEquals(data, r.get("key1"));
+       //System.out.println("After put of Integer value off heap used memory=" + ma.getUsedMemory());
+       assertTrue(ma.getUsedMemory() > 0);
+       r.invalidate("key1");
+       assertEquals(0, ma.getUsedMemory());
+       r.put("key1", data);
+       assertTrue(ma.getUsedMemory() > 0);
+       usedBeforeUpdate = ma.getUsedMemory();
+       r.put("key1", data);
+       assertEquals(usedBeforeUpdate, ma.getUsedMemory());
+       assertEquals(data, r.get("key1"));
+       r.destroy("key1");
+       assertEquals(0, ma.getUsedMemory());
+ 
+       // confirm that byte[] do use off heap
+       {
+         byte[] originalBytes = new byte[1024];
+         Object oldV = r.put("byteArray", originalBytes);
+         long startUsedMemory = ma.getUsedMemory();
+         assertEquals(null, oldV);
+         byte[] readBytes = (byte[]) r.get("byteArray");
+         if (originalBytes == readBytes) {
+           fail("Expected different byte[] identity");
+         }
+         if (!Arrays.equals(readBytes, originalBytes)) {
+           fail("Expected byte array contents to be equal");
+         }
+         assertEquals(startUsedMemory, ma.getUsedMemory());
+         oldV = r.put("byteArray", originalBytes);
+         if (!compressed) {
+           assertEquals(null, oldV); // we default to old value being null for offheap
+         }
+         assertEquals(startUsedMemory, ma.getUsedMemory());
+         
+         readBytes = (byte[])r.putIfAbsent("byteArray", originalBytes);
+         if (originalBytes == readBytes) {
+           fail("Expected different byte[] identity");
+         }
+         if (!Arrays.equals(readBytes, originalBytes)) {
+           fail("Expected byte array contents to be equal");
+         }
+         assertEquals(startUsedMemory, ma.getUsedMemory());
+         if (!r.replace("byteArray", readBytes, originalBytes)) {
+           fail("Expected replace to happen");
+         }
+         assertEquals(startUsedMemory, ma.getUsedMemory());
+         byte[] otherBytes = new byte[1024];
+         otherBytes[1023] = 1;
+         if (r.replace("byteArray", otherBytes, originalBytes)) {
+           fail("Expected replace to not happen");
+         }
+         if (r.replace("byteArray", "bogus string", originalBytes)) {
+           fail("Expected replace to not happen");
+         }
+         if (r.remove("byteArray", "bogus string")) {
+           fail("Expected remove to not happen");
+         }
+         assertEquals(startUsedMemory, ma.getUsedMemory());
+         
+         if (!r.remove("byteArray", originalBytes)) {
+           fail("Expected remove to happen");
+         }
+         assertEquals(0, ma.getUsedMemory());
+         oldV = r.putIfAbsent("byteArray", "string value");
+         assertEquals(null, oldV);
+         assertEquals("string value", r.get("byteArray"));
+         if (r.replace("byteArray", "string valuE", originalBytes)) {
+           fail("Expected replace to not happen");
+         }
+         if (!r.replace("byteArray", "string value", originalBytes)) {
+           fail("Expected replace to happen");
+         }
+         oldV = r.destroy("byteArray"); // we default to old value being null for offheap
+         if (!compressed) {
+           assertEquals(null, oldV);
+         }
+         MyCacheListener listener = new MyCacheListener();
+         r.getAttributesMutator().addCacheListener(listener);
+         try {
+           Object valueToReplace = "string value1";
+           r.put("byteArray", valueToReplace);
+           assertEquals(null, listener.ohOldValue);
+           if (!compressed) {
+             assertEquals("string value1", listener.ohNewValue.getDeserializedForReading());
+             valueToReplace = listener.ohNewValue;
+           }
+           if (!r.replace("byteArray", valueToReplace, "string value2")) {
+             fail("expected replace to happen");
+           }
+           if (!compressed) {
+             assertEquals("string value2", listener.ohNewValue.getDeserializedForReading());
+             assertEquals("string value1", listener.ohOldValue.getDeserializedForReading());
+           }
+           // make sure that a custom equals/hashCode are not used when comparing values.
+           
+         } finally {
+           r.getAttributesMutator().removeCacheListener(listener);
+         }
+       }
+       assertTrue(ma.getUsedMemory() > 0);
+       {
+         Object key = "MyValueWithPartialEquals";
+         MyValueWithPartialEquals v1 = new MyValueWithPartialEquals("s1");
+         MyValueWithPartialEquals v2 = new MyValueWithPartialEquals("s2");
+         MyValueWithPartialEquals v3 = new MyValueWithPartialEquals("s1");
+         r.put(key, v1);
+         try {
+           if (r.replace(key, v2, "should not happen")) {
+             fail("v1 should not be equal to v2 on an offheap region");
+           }
+           if (!r.replace(key, v3, "should happen")) {
+             fail("v1 should be equal to v3 on an offheap region");
+           }
+           r.put(key, v1);
+           if (r.remove(key, v2)) {
+             fail("v1 should not be equal to v2 on an offheap region");
+           }
+           if (!r.remove(key, v3)) {
+             fail("v1 should be equal to v3 on an offheap region");
+           }
+         } finally {
+           r.remove(key);
+         }
+       }
+       {
+         Object key = "MyPdxWithPartialEquals";
+         MyPdxWithPartialEquals v1 = new MyPdxWithPartialEquals("s", "1");
+         MyPdxWithPartialEquals v2 = new MyPdxWithPartialEquals("s", "2");
+         MyPdxWithPartialEquals v3 = new MyPdxWithPartialEquals("t", "1");
+         r.put(key, v1);
+         try {
+           if (r.replace(key, v3, "should not happen")) {
+             fail("v1 should not be equal to v3 on an offheap region");
+           }
+           if (!r.replace(key, v2, "should happen")) {
+             fail("v1 should be equal to v2 on an offheap region");
+           }
+           r.put(key, v1);
+           if (r.remove(key, v3)) {
+             fail("v1 should not be equal to v3 on an offheap region");
+           }
+           if (!r.remove(key, v2)) {
+             fail("v1 should be equal to v2 on an offheap region");
+           }
+         } finally {
+           r.remove(key);
+         }
+       }
+       byte[] value = new byte[1024];
+       /*while (value != null) */ {
+         r.put("byteArray", value);
+       }
+       r.remove("byteArray");
+       assertEquals(0, ma.getUsedMemory());
+ 
+       r.put("key1", data);
+       assertTrue(ma.getUsedMemory() > 0);
+       r.invalidateRegion();
+       assertEquals(0, ma.getUsedMemory());
+ 
+       r.put("key1", data);
+       assertTrue(ma.getUsedMemory() > 0);
+       try {
+         r.clear();
+         assertEquals(0, ma.getUsedMemory());
+       } catch (UnsupportedOperationException ok) {
+       }
+ 
+       r.put("key1", data);
+       assertTrue(ma.getUsedMemory() > 0);
+       if (r.getAttributes().getDataPolicy().withPersistence()) {
+         r.put("key2", Integer.valueOf(1234567890));
+         r.put("key3", new Long(0x007FFFFFL));
+         r.put("key4", new Long(0xFF8000000L));
+         assertEquals(4, r.size());
+         r.close();
+         assertEquals(0, ma.getUsedMemory());
+         // simple test of recovery
+         r = gfc.createRegionFactory(rs).setOffHeap(true).create(rName);
+         assertEquals(4, r.size());
+         assertEquals(data, r.get("key1"));
+         assertEquals(Integer.valueOf(1234567890), r.get("key2"));
+         assertEquals(new Long(0x007FFFFFL), r.get("key3"));
+         assertEquals(new Long(0xFF8000000L), r.get("key4"));
+         closeCache(gfc, true);
+         assertEquals(0, ma.getUsedMemory());
+         gfc = createCache();
+         if (ma != gfc.getOffHeapStore()) {
+           fail("identity of offHeapStore changed when cache was recreated");
+         }
+         r = gfc.createRegionFactory(rs).setOffHeap(true).create(rName);
+         assertTrue(ma.getUsedMemory() > 0);
+         assertEquals(4, r.size());
+         assertEquals(data, r.get("key1"));
+         assertEquals(Integer.valueOf(1234567890), r.get("key2"));
+         assertEquals(new Long(0x007FFFFFL), r.get("key3"));
+         assertEquals(new Long(0xFF8000000L), r.get("key4"));
+       }
+         
+       r.destroyRegion();
+       assertEquals(0, ma.getUsedMemory());
+ 
+     } finally {
+       if (r != null && !r.isDestroyed()) {
+         r.destroyRegion();
+       }
+       closeCache(gfc, false);
+     }
+     
+   }
+   
+   /**
+    * This class has an equals that does not compare all its bytes.
+    */
+   private static class MyValueWithPartialEquals implements Serializable {
+     private static final long serialVersionUID = 1L;
+     private final String value;
+     public MyValueWithPartialEquals(String v) {
+       this.value = v;
+     }
+     @Override public boolean equals(Object other) {
+       if (other instanceof MyValueWithPartialEquals) {
+         MyValueWithPartialEquals o = (MyValueWithPartialEquals) other;
+         // just compare the first char
+         return this.value.charAt(0) == o.value.charAt(0);
+       } else {
+         return false;
+       }
+     }
+   }
+   /**
+    * This class has an equals that does not compare all its bytes.
+    */
+   private static class MyPdxWithPartialEquals implements PdxSerializable {
+     private String base;
+     private String value;
+     public MyPdxWithPartialEquals(String b, String v) {
+       this.base = b;
+       this.value = v;
+     }
+     public MyPdxWithPartialEquals() {
+     }
+     @Override
+     public void toData(PdxWriter writer) {
+       writer.writeString("base", this.base);
+       writer.writeString("value", this.value);
+       writer.markIdentityField("base");
+     }
+     @Override
+     public void fromData(PdxReader reader) {
+       this.base = reader.readString("base");
+       this.value = reader.readString("value");
+     }
+   }
+   
+   @SuppressWarnings("rawtypes")
+   private static class MyCacheListener extends CacheListenerAdapter {
+     @Retained(OffHeapIdentifier.TEST_OFF_HEAP_REGION_BASE_LISTENER)
+     public StoredObject ohOldValue;
+     @Retained(OffHeapIdentifier.TEST_OFF_HEAP_REGION_BASE_LISTENER)
+     public StoredObject ohNewValue;
+     
+     /**
+      * This method retains both ohOldValue and ohNewValue
+      */
+     @Retained(OffHeapIdentifier.TEST_OFF_HEAP_REGION_BASE_LISTENER)
+     private void setEventData(EntryEvent e) {
+       close();
+       EntryEventImpl event = (EntryEventImpl) e;
+       this.ohOldValue = event.getOffHeapOldValue();
+       this.ohNewValue = event.getOffHeapNewValue();
+     }
+     
+     @Override
+     public void afterCreate(EntryEvent e) {
+       setEventData(e);
+     }
+ 
+     @Override
+     public void afterDestroy(EntryEvent e) {
+       setEventData(e);
+     }
+ 
+     @Override
+     public void afterInvalidate(EntryEvent e) {
+       setEventData(e);
+     }
+ 
+     @Override
+     public void afterUpdate(EntryEvent e) {
+       setEventData(e);
+     }
+     
+     @Released(OffHeapIdentifier.TEST_OFF_HEAP_REGION_BASE_LISTENER)
+     @Override
+     public void close() {
 -      if (this.ohOldValue instanceof Chunk) {
 -        ((Chunk)this.ohOldValue).release();
++      if (this.ohOldValue instanceof ObjectChunk) {
++        ((ObjectChunk)this.ohOldValue).release();
+       }
 -      if (this.ohNewValue instanceof Chunk) {
 -        ((Chunk)this.ohNewValue).release();
++      if (this.ohNewValue instanceof ObjectChunk) {
++        ((ObjectChunk)this.ohNewValue).release();
+       }
+     }
+   }
+   
+   @Test
+   public void testPR() {
+     doRegionTest(RegionShortcut.PARTITION, "pr1");
+   }
+   @Test
+   public void testPRCompressed() {
+     doRegionTest(RegionShortcut.PARTITION, "pr2", true);
+   }
+   @Test
+   public void testReplicate() {
+     doRegionTest(RegionShortcut.REPLICATE, "rep1");
+   }
+   @Test
+   public void testReplicateCompressed() {
+     doRegionTest(RegionShortcut.REPLICATE, "rep2", true);
+   }
+   @Test
+   public void testLocal() {
+     doRegionTest(RegionShortcut.LOCAL, "local1");
+   }
+   @Test
+   public void testLocalCompressed() {
+     doRegionTest(RegionShortcut.LOCAL, "local2", true);
+   }
+   @Test
+   public void testLocalPersistent() {
+     doRegionTest(RegionShortcut.LOCAL_PERSISTENT, "localPersist1");
+   }
+   @Test
+   public void testLocalPersistentCompressed() {
+     doRegionTest(RegionShortcut.LOCAL_PERSISTENT, "localPersist2", true);
+   }
+   @Test
+   public void testPRPersistent() {
+     doRegionTest(RegionShortcut.PARTITION_PERSISTENT, "prPersist1");
+   }
+   @Test
+   public void testPRPersistentCompressed() {
+     doRegionTest(RegionShortcut.PARTITION_PERSISTENT, "prPersist2", true);
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
index 0000000,b800977..5d53109
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
@@@ -1,0 -1,870 +1,870 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.assertj.core.api.Assertions.assertThat;
+ import static org.mockito.Mockito.mock;
+ import static org.mockito.Mockito.never;
+ import static org.mockito.Mockito.reset;
+ import static org.mockito.Mockito.times;
+ import static org.mockito.Mockito.verify;
+ import static org.mockito.Mockito.when;
+ 
+ import java.nio.ByteBuffer;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ import org.junit.runner.RunWith;
+ import org.mockito.Mockito;
+ import org.powermock.api.mockito.PowerMockito;
+ import org.powermock.core.classloader.annotations.PowerMockIgnore;
+ import org.powermock.core.classloader.annotations.PrepareForTest;
+ import org.powermock.modules.junit4.PowerMockRunner;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.compression.Compressor;
+ import com.gemstone.gemfire.internal.DSCODE;
+ import com.gemstone.gemfire.internal.cache.CachePerfStats;
+ import com.gemstone.gemfire.internal.cache.DiskEntry;
+ import com.gemstone.gemfire.internal.cache.DiskId;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.cache.OffHeapRegionEntry;
+ import com.gemstone.gemfire.internal.cache.RegionEntryContext;
+ import com.gemstone.gemfire.internal.cache.Token;
+ import com.gemstone.gemfire.internal.cache.VMCachedDeserializable;
+ import com.gemstone.gemfire.internal.cache.VersionedStatsDiskRegionEntryOffHeap;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ @RunWith(PowerMockRunner.class)
+ @PowerMockIgnore("*.UnitTest")
 -@PrepareForTest({ Chunk.class, OffHeapRegionEntryHelper.class })
++@PrepareForTest({ ObjectChunk.class, OffHeapRegionEntryHelper.class })
+ public class OffHeapRegionEntryHelperJUnitTest {
+ 
+   private static final Long VALUE_IS_NOT_ENCODABLE = 0L;
+ 
+   private MemoryAllocator ma;
+ 
+   @Before
+   public void setUp() {
+     OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
+     OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
+     LogWriter lw = mock(LogWriter.class);
+ 
+     ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 1, OffHeapStorage.MIN_SLAB_SIZE * 1, OffHeapStorage.MIN_SLAB_SIZE);
+   }
+ 
+   @After
+   public void tearDown() {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+   }
+ 
 -  private GemFireChunk createChunk(Object value) {
++  private ObjectChunk createChunk(Object value) {
+     byte[] v = EntryEventImpl.serialize(value);
+ 
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
 -    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed);
+ 
+     return chunk;
+   }
+ 
+   @Test
+   public void encodeDataAsAddressShouldReturnZeroIfValueIsGreaterThanSevenBytes() {
+     Long value = Long.MAX_VALUE;
+ 
+     byte[] valueInBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(value).array();
+     boolean isSerialized = false;
+     boolean isCompressed = false;
+ 
+     assertThat(valueInBytes.length).isGreaterThanOrEqualTo(OffHeapRegionEntryHelper.MAX_LENGTH_FOR_DATA_AS_ADDRESS);
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(encodedAddress).isEqualTo(VALUE_IS_NOT_ENCODABLE);
+   }
+ 
+   @Test
+   public void encodeDataAsAddressShouldEncodeLongIfItsSerializedAndIfItsNotTooBig() {
+     Long value = 0L;
+     long expectedEncodedAddress = 123L;
+ 
+     byte[] valueInBytes = EntryEventImpl.serialize(value);
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(encodedAddress).isEqualTo(expectedEncodedAddress);
+     assertSerializedAndCompressedBits(encodedAddress, isSerialized, isCompressed);
+   }
+ 
+   @Test
+   public void encodeDataAsAddressShouldReturnZeroIfValueIsLongAndItIsSerializedAndBig() {
+     Long value = Long.MAX_VALUE;
+ 
+     byte[] valueInBytes = EntryEventImpl.serialize(value);
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(encodedAddress).isEqualTo(VALUE_IS_NOT_ENCODABLE);
+   }
+ 
+   @Test
+   public void encodeDataAsAddressShouldReturnZeroIfValueIsLargerThanEightBytesAndNotLong() {
+     byte[] someValue = new byte[8];
+     someValue[0] = DSCODE.CLASS;
+ 
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(someValue, isSerialized, isCompressed);
+ 
+     assertThat(encodedAddress).isEqualTo(VALUE_IS_NOT_ENCODABLE);
+   }
+ 
+   @Test
+   public void encodeDataAsAddressShouldReturnValidAddressIfValueIsLesserThanSevenBytes() {
+     long expectedAddress = 549755813697L;
+ 
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] valueInBytes = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(value).array();
+     boolean isSerialized = false;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(encodedAddress).isEqualTo(expectedAddress);
+     assertSerializedAndCompressedBits(encodedAddress, isSerialized, isCompressed);
+   }
+ 
+   @Test
+   public void encodeDataAsAssressShouldSetSerialziedBitIfSerizliaed() {
+     long expectedAddress = 63221918596947L;
+ 
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] valueInBytes = EntryEventImpl.serialize(value);
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(expectedAddress).isEqualTo(encodedAddress);
+     assertSerializedAndCompressedBits(encodedAddress, isSerialized, isCompressed);
+   }
+ 
+   @Test
+   public void encodeDataAsAssressShouldSetSerialziedBitIfCompressed() {
+     long expectedAddress = 549755813701L;
+ 
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] valueInBytes = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(value).array();
+     boolean isSerialized = false;
+     boolean isCompressed = true;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(encodedAddress).isEqualTo(expectedAddress);
+     assertSerializedAndCompressedBits(encodedAddress, isSerialized, isCompressed);
+   }
+ 
+   @Test
+   public void encodeDataAsAssressShouldSetBothSerialziedAndCompressedBitsIfSerializedAndCompressed() {
+     long expectedAddress = 63221918596951L;
+ 
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] valueInBytes = EntryEventImpl.serialize(value);
+     boolean isSerialized = true;
+     boolean isCompressed = true;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(valueInBytes, isSerialized, isCompressed);
+ 
+     assertThat(expectedAddress).isEqualTo(encodedAddress);
+     assertSerializedAndCompressedBits(encodedAddress, isSerialized, isCompressed);
+   }
+ 
+   private void assertSerializedAndCompressedBits(long encodedAddress, boolean shouldSerializedBitBeSet, boolean shouldCompressedBitBeSet) {
+     boolean isSerializedBitSet = (encodedAddress & OffHeapRegionEntryHelper.SERIALIZED_BIT) == OffHeapRegionEntryHelper.SERIALIZED_BIT ? true : false;
+     boolean isCompressedBitSet = (encodedAddress & OffHeapRegionEntryHelper.COMPRESSED_BIT) == OffHeapRegionEntryHelper.COMPRESSED_BIT ? true : false;
+ 
+     assertThat(isSerializedBitSet).isEqualTo(shouldSerializedBitBeSet);
+     assertThat(isCompressedBitSet).isEqualTo(shouldCompressedBitBeSet);
+   }
+ 
+   @Test
+   public void decodeAddressToBytesShouldReturnActualBytes() {
+     long encodedAddress = 549755813697L;
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] actual = OffHeapRegionEntryHelper.decodeAddressToBytes(encodedAddress, false, false);
+     byte[] expectedValue = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(value).array();
+ 
+     assertThat(actual).isEqualTo(expectedValue);
+   }
+ 
+   @Test
+   public void decodeDataAsAddressShouldDecodeLongIfItsSerializedAndIfItsNotTooBig() {
+     Long value = 0L;
+     long encodedAddress = 123L;
+ 
+     byte[] actual = OffHeapRegionEntryHelper.decodeAddressToBytes(encodedAddress, false, false);
+     byte[] expectedValue = EntryEventImpl.serialize(value);
+ 
+     assertThat(actual).isEqualTo(expectedValue);
+   }
+ 
+   @Test(expected = UnsupportedOperationException.class)
+   public void decodeDataAsAddressShouldThrowExceptionIfDataIsCompressedAndItsNotOkToBeCompressed() {
+     long encodedAddress = 549755813703L;
+     OffHeapRegionEntryHelper.decodeAddressToBytes(encodedAddress, true, false);
+   }
+ 
+   @Test
+   public void encodedAddressShouldBeDecodableEvenIfValueIsSerialized() {
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] serializedValue = EntryEventImpl.serialize(value);
+     boolean isSerialized = true;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(serializedValue, isSerialized, isCompressed);
+ 
+     Integer actualValue = (Integer) OffHeapRegionEntryHelper.decodeAddressToObject(encodedAddress);
+ 
+     assertThat(actualValue).isEqualTo(value);
+   }
+ 
+   @Test
+   public void encodedAddressShouldBeDecodableEvenIfValueIsUnserialized() {
+     Integer value = Integer.MAX_VALUE;
+ 
+     byte[] unSerializedValue = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(value).array();
+     boolean isSerialized = false;
+     boolean isCompressed = false;
+ 
+     long encodedAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(unSerializedValue, isSerialized, isCompressed);
+ 
+     byte[] actualValue = (byte[]) OffHeapRegionEntryHelper.decodeAddressToObject(encodedAddress);
+ 
+     assertThat(actualValue).isEqualTo(unSerializedValue);
+   }
+ 
+   @Test
+   public void isSerializedShouldReturnTrueIfSerialized() {
+     assertThat(OffHeapRegionEntryHelper.isSerialized(1000010L)).isTrue();
+   }
+ 
+   @Test
+   public void isSerializedShouldReturnFalseIfNotSerialized() {
+     assertThat(OffHeapRegionEntryHelper.isSerialized(1000000L)).isFalse();
+   }
+ 
+   @Test
+   public void isCompressedShouldReturnTrueIfCompressed() {
+     assertThat(OffHeapRegionEntryHelper.isCompressed(1000100L)).isTrue();
+   }
+ 
+   @Test
+   public void isCompressedShouldReturnFalseIfNotCompressed() {
+     assertThat(OffHeapRegionEntryHelper.isCompressed(1000000L)).isFalse();
+   }
+ 
+   @Test
+   public void isOffHeapShouldReturnTrueIfAddressIsOnOffHeap() {
 -    Chunk value = createChunk(Long.MAX_VALUE);
++    ObjectChunk value = createChunk(Long.MAX_VALUE);
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(value.getMemoryAddress())).isTrue();
+   }
+ 
+   @Test
+   public void isOffHeapShouldReturnFalseIfAddressIsAnEncodedAddress() {
+     byte[] data = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt((Integer) Integer.MAX_VALUE).array();
+     long address = OffHeapRegionEntryHelper.encodeDataAsAddress(data, false, false);
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(address)).isFalse();
+   }
+ 
+   @Test
+   public void isOffHeapShouldReturnFalseForAnyTokenAddress() {
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.NULL_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.INVALID_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.LOCAL_INVALID_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.DESTROYED_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.REMOVED_PHASE1_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.END_OF_STREAM_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.NOT_AVAILABLE_ADDRESS)).isFalse();
+     assertThat(OffHeapRegionEntryHelper.isOffHeap(OffHeapRegionEntryHelper.TOMBSTONE_ADDRESS)).isFalse();
+   }
+ 
+   @Test
+   public void setValueShouldChangeTheRegionEntryAddressToNewAddress() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
+     // some old address
+     long oldAddress = 1L;
+ 
+     // testing when the newValue is a chunk
 -    Chunk newValue = createChunk(Long.MAX_VALUE);
++    ObjectChunk newValue = createChunk(Long.MAX_VALUE);
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, newValue.getMemoryAddress())).thenReturn(Boolean.TRUE);
+ 
+     // invoke the method under test
+     OffHeapRegionEntryHelper.setValue(re, newValue);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, newValue.getMemoryAddress());
+     // resetting the spy in-order to re-use
+     reset(re);
+ 
+     // testing when the newValue is DataAsAddress
+     DataAsAddress newAddress1 = new DataAsAddress(2L);
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, newAddress1.getEncodedAddress())).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, newAddress1);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, newAddress1.getEncodedAddress());
+     reset(re);
+ 
+     // Testing when newValue is Token Objects
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.NULL_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, null);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.NULL_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.INVALID_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.INVALID);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.INVALID_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.LOCAL_INVALID_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.LOCAL_INVALID);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.LOCAL_INVALID_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.DESTROYED_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.DESTROYED);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.DESTROYED_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.REMOVED_PHASE1_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.REMOVED_PHASE1);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.REMOVED_PHASE1_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.REMOVED_PHASE2);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.END_OF_STREAM_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.END_OF_STREAM);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.END_OF_STREAM_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.NOT_AVAILABLE_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.NOT_AVAILABLE);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.NOT_AVAILABLE_ADDRESS);
+     reset(re);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, OffHeapRegionEntryHelper.TOMBSTONE_ADDRESS)).thenReturn(Boolean.TRUE);
+     OffHeapRegionEntryHelper.setValue(re, Token.TOMBSTONE);
+ 
+     // verify oldAddress is replaced with newAddress
+     verify(re, times(1)).setAddress(oldAddress, OffHeapRegionEntryHelper.TOMBSTONE_ADDRESS);
+     reset(re);
+   }
+ 
+   @Test
+   public void setValueShouldChangeTheRegionEntryAddressToNewAddressAndReleaseOldValueIfItsOnOffHeap() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
 -    Chunk oldValue = createChunk(Long.MAX_VALUE);
 -    Chunk newValue = createChunk(Long.MAX_VALUE - 1);
++    ObjectChunk oldValue = createChunk(Long.MAX_VALUE);
++    ObjectChunk newValue = createChunk(Long.MAX_VALUE - 1);
+ 
+     // mock Chunk static methods - in-order to verify that release is called
 -    PowerMockito.spy(Chunk.class);
 -    PowerMockito.doNothing().when(Chunk.class);
 -    Chunk.release(oldValue.getMemoryAddress(), true);
++    PowerMockito.spy(ObjectChunk.class);
++    PowerMockito.doNothing().when(ObjectChunk.class);
++    ObjectChunk.release(oldValue.getMemoryAddress());
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldValue.getMemoryAddress());
+     when(re.setAddress(oldValue.getMemoryAddress(), newValue.getMemoryAddress())).thenReturn(Boolean.TRUE);
+ 
+     // invoke the method under test
+     OffHeapRegionEntryHelper.setValue(re, newValue);
+ 
+     // verify oldAddress is changed to newAddress
+     verify(re, times(1)).setAddress(oldValue.getMemoryAddress(), newValue.getMemoryAddress());
+ 
+     // verify oldAddress is released
+     PowerMockito.verifyStatic();
 -    Chunk.release(oldValue.getMemoryAddress(), true);
++    ObjectChunk.release(oldValue.getMemoryAddress());
+   }
+ 
+   @Test
+   public void setValueShouldChangeTheRegionEntryAddressToNewAddressAndDoesNothingIfOldAddressIsAnEncodedAddress() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
+     byte[] oldData = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt((Integer) Integer.MAX_VALUE).array();
+     long oldAddress = OffHeapRegionEntryHelper.encodeDataAsAddress(oldData, false, false);
+ 
+     byte[] newData = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt((Integer) Integer.MAX_VALUE - 1).array();
+     DataAsAddress newAddress = new DataAsAddress(OffHeapRegionEntryHelper.encodeDataAsAddress(newData, false, false));
+ 
+     // mock Chunk static methods - in-order to verify that release is never called
 -    PowerMockito.spy(Chunk.class);
 -    PowerMockito.doNothing().when(Chunk.class);
 -    Chunk.release(oldAddress, true);
++    PowerMockito.spy(ObjectChunk.class);
++    PowerMockito.doNothing().when(ObjectChunk.class);
++    ObjectChunk.release(oldAddress);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, newAddress.getEncodedAddress())).thenReturn(Boolean.TRUE);
+ 
+     // invoke the method under test
+     OffHeapRegionEntryHelper.setValue(re, newAddress);
+ 
+     // verify oldAddress is changed to newAddress
+     verify(re, times(1)).setAddress(oldAddress, newAddress.getEncodedAddress());
+ 
+     // verify that release is never called as the old address is not on offheap
+     PowerMockito.verifyStatic(never());
 -    Chunk.release(oldAddress, true);
++    ObjectChunk.release(oldAddress);
+   }
+ 
+   @Test
+   public void setValueShouldChangeTheRegionEntryAddressToNewAddressAndDoesNothingIfOldAddressIsATokenAddress() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
+     long oldAddress = OffHeapRegionEntryHelper.REMOVED_PHASE1_ADDRESS;
+ 
+     Token newValue = Token.REMOVED_PHASE2;
+     long newAddress = OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS;
+ 
+     // mock Chunk static methods - in-order to verify that release is never called
 -    PowerMockito.spy(Chunk.class);
 -    PowerMockito.doNothing().when(Chunk.class);
 -    Chunk.release(oldAddress, true);
++    PowerMockito.spy(ObjectChunk.class);
++    PowerMockito.doNothing().when(ObjectChunk.class);
++    ObjectChunk.release(oldAddress);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(oldAddress);
+     when(re.setAddress(oldAddress, newAddress)).thenReturn(Boolean.TRUE);
+ 
+     // invoke the method under test
+     OffHeapRegionEntryHelper.setValue(re, newValue);
+ 
+     // verify oldAddress is changed to newAddress
+     verify(re, times(1)).setAddress(oldAddress, newAddress);
+ 
+     // verify that release is never called as the old address is not on offheap
+     PowerMockito.verifyStatic(never());
 -    Chunk.release(oldAddress, true);
++    ObjectChunk.release(oldAddress);
+   }
+ 
+   @Test(expected = IllegalStateException.class)
+   public void setValueShouldThrowIllegalExceptionIfNewValueCannotBeConvertedToAddress() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(1L);
+ 
+     // invoke the method under test with some object other than Chunk/DataAsAddress/Token
+     OffHeapRegionEntryHelper.setValue(re, new Object());
+   }
+ 
+   @Test
+   public void getValueAsTokenShouldReturnNotATokenIfValueIsOnOffHeap() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
 -    Chunk chunk = createChunk(Long.MAX_VALUE);
++    ObjectChunk chunk = createChunk(Long.MAX_VALUE);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(chunk.getMemoryAddress());
+     Token token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.NOT_A_TOKEN);
+   }
+ 
+   @Test
+   public void getValueAsTokenShouldReturnNotATokenIfValueIsEncoded() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
+     byte[] data = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(Integer.MAX_VALUE).array();
+     long address = OffHeapRegionEntryHelper.encodeDataAsAddress(data, false, false);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(address);
+     Token token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.NOT_A_TOKEN);
+   }
+ 
+   @Test
+   public void getValueAsTokenShouldReturnAValidToken() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.NULL_ADDRESS);
+     Token token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isNull();
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.INVALID_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.INVALID);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.LOCAL_INVALID_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.LOCAL_INVALID);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.DESTROYED_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.DESTROYED);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.REMOVED_PHASE1_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.REMOVED_PHASE1);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.REMOVED_PHASE2);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.END_OF_STREAM_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.END_OF_STREAM);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.NOT_AVAILABLE_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.NOT_AVAILABLE);
+ 
+     // mock region entry methods required for test
+     when(re.getAddress()).thenReturn(OffHeapRegionEntryHelper.TOMBSTONE_ADDRESS);
+     token = OffHeapRegionEntryHelper.getValueAsToken(re);
+ 
+     assertThat(token).isEqualTo(Token.TOMBSTONE);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnValueFromChunk() {
 -    Chunk expected = createChunk(Long.MAX_VALUE);
++    ObjectChunk expected = createChunk(Long.MAX_VALUE);
+     Object actual = OffHeapRegionEntryHelper.addressToObject(expected.getMemoryAddress(), false, null);
+ 
 -    assertThat(actual).isInstanceOf(Chunk.class);
++    assertThat(actual).isInstanceOf(ObjectChunk.class);
+     assertThat(actual).isEqualTo(expected);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnCachedDeserializableFromChunkIfAskedToDecompress() {
+     byte[] data = EntryEventImpl.serialize(Long.MAX_VALUE);
+     boolean isSerialized = true;
+     boolean isCompressed = true;
+ 
 -    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed, GemFireChunk.TYPE);
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed);
+ 
+     // create the mock context
+     RegionEntryContext regionContext = mock(RegionEntryContext.class);
+     CachePerfStats cacheStats = mock(CachePerfStats.class);
+     Compressor compressor = mock(Compressor.class);
+ 
+     long startTime = 10000L;
+ 
+     // mock required things
+     when(regionContext.getCompressor()).thenReturn(compressor);
+     when(compressor.decompress(data)).thenReturn(data);
+     when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
+     when(cacheStats.startDecompression()).thenReturn(startTime);
+ 
+     Object actual = OffHeapRegionEntryHelper.addressToObject(chunk.getMemoryAddress(), true, regionContext);
+ 
+     assertThat(actual).isInstanceOf(VMCachedDeserializable.class);
+ 
+     Long actualValue = (Long) ((VMCachedDeserializable) actual).getDeserializedForReading();
+     assertThat(actualValue).isEqualTo(Long.MAX_VALUE);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnDecompressedValueFromChunkIfAskedToDecompress() {
+     byte[] data = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(Long.MAX_VALUE).array();
+     boolean isSerialized = false;
+     boolean isCompressed = true;
+ 
 -    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed, GemFireChunk.TYPE);
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed);
+ 
+     // create the mock context
+     RegionEntryContext regionContext = mock(RegionEntryContext.class);
+     CachePerfStats cacheStats = mock(CachePerfStats.class);
+     Compressor compressor = mock(Compressor.class);
+ 
+     long startTime = 10000L;
+ 
+     // mock required things
+     when(regionContext.getCompressor()).thenReturn(compressor);
+     when(compressor.decompress(data)).thenReturn(data);
+     when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
+     when(cacheStats.startDecompression()).thenReturn(startTime);
+ 
+     Object actual = OffHeapRegionEntryHelper.addressToObject(chunk.getMemoryAddress(), true, regionContext);
+ 
+     assertThat(actual).isInstanceOf(byte[].class);
+     assertThat(actual).isEqualTo(data);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnValueFromDataAsAddress() {
+     byte[] data = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(Integer.MAX_VALUE).array();
+     long address = OffHeapRegionEntryHelper.encodeDataAsAddress(data, false, false);
+ 
+     DataAsAddress expected = new DataAsAddress(address);
+     Object actual = OffHeapRegionEntryHelper.addressToObject(address, false, null);
+ 
+     assertThat(actual).isInstanceOf(DataAsAddress.class);
+     assertThat(actual).isEqualTo(expected);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnCachedDeserializableFromSerializedDataAsAddressIfAskedToDecompress() {
+     byte[] data = EntryEventImpl.serialize(Integer.MAX_VALUE);
+     boolean isSerialized = true;
+     boolean isCompressed = true;
+ 
+     long address = OffHeapRegionEntryHelper.encodeDataAsAddress(data, isSerialized, isCompressed);
+ 
+     // create the mock context
+     RegionEntryContext regionContext = mock(RegionEntryContext.class);
+     CachePerfStats cacheStats = mock(CachePerfStats.class);
+     Compressor compressor = mock(Compressor.class);
+ 
+     long startTime = 10000L;
+ 
+     // mock required things
+     when(regionContext.getCompressor()).thenReturn(compressor);
+     when(compressor.decompress(data)).thenReturn(data);
+     when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
+     when(cacheStats.startDecompression()).thenReturn(startTime);
+ 
+     Object actual = OffHeapRegionEntryHelper.addressToObject(address, true, regionContext);
+ 
+     assertThat(actual).isInstanceOf(VMCachedDeserializable.class);
+ 
+     Integer actualValue = (Integer) ((VMCachedDeserializable) actual).getDeserializedForReading();
+     assertThat(actualValue).isEqualTo(Integer.MAX_VALUE);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnDecompressedValueFromDataAsAddressIfAskedToDecompress() {
+     byte[] data = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(Integer.MAX_VALUE).array();
+     boolean isSerialized = false;
+     boolean isCompressed = true;
+ 
+     long address = OffHeapRegionEntryHelper.encodeDataAsAddress(data, isSerialized, isCompressed);
+ 
+     // create the mock context
+     RegionEntryContext regionContext = mock(RegionEntryContext.class);
+     CachePerfStats cacheStats = mock(CachePerfStats.class);
+     Compressor compressor = mock(Compressor.class);
+ 
+     long startTime = 10000L;
+ 
+     // mock required things
+     when(regionContext.getCompressor()).thenReturn(compressor);
+     when(compressor.decompress(data)).thenReturn(data);
+     when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
+     when(cacheStats.startDecompression()).thenReturn(startTime);
+ 
+     Object actual = OffHeapRegionEntryHelper.addressToObject(address, true, regionContext);
+ 
+     assertThat(actual).isInstanceOf(byte[].class);
+     assertThat(actual).isEqualTo(data);
+   }
+ 
+   @Test
+   public void addressToObjectShouldReturnToken() {
+     Token token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.NULL_ADDRESS, false, null);
+     assertThat(token).isNull();
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.INVALID_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.INVALID);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.LOCAL_INVALID_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.LOCAL_INVALID);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.DESTROYED_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.DESTROYED);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.REMOVED_PHASE1_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.REMOVED_PHASE1);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.REMOVED_PHASE2);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.END_OF_STREAM_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.END_OF_STREAM);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.NOT_AVAILABLE_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.NOT_AVAILABLE);
+ 
+     token = (Token) OffHeapRegionEntryHelper.addressToObject(OffHeapRegionEntryHelper.TOMBSTONE_ADDRESS, false, null);
+     assertThat(token).isEqualTo(Token.TOMBSTONE);
+   }
+ 
+   @Test
+   public void getSerializedLengthFromDataAsAddressShouldReturnValidLength() {
+     byte[] data = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(Integer.MAX_VALUE).array();
+     boolean isSerialized = false;
+     boolean isCompressed = true;
+ 
+     long address = OffHeapRegionEntryHelper.encodeDataAsAddress(data, isSerialized, isCompressed);
+     DataAsAddress daa = new DataAsAddress(address);
+ 
+     int actualLength = OffHeapRegionEntryHelper.getSerializedLengthFromDataAsAddress(daa);
+ 
+     assertThat(actualLength).isEqualTo(data.length);
+   }
+ 
+   @Test
+   public void getSerializedLengthFromDataAsAddressShouldReturnZeroForNonEncodedAddress() {
+     DataAsAddress nonEncodedAddress = new DataAsAddress(100000L);
+     int actualLength = OffHeapRegionEntryHelper.getSerializedLengthFromDataAsAddress(nonEncodedAddress);
+     assertThat(actualLength).isZero();
+   }
+ 
+   @Test
+   public void releaseEntryShouldSetValueToRemovePhase2() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
+     when(re.getAddress()).thenReturn(1L);
+     when(re.setAddress(1L, OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS)).thenReturn(Boolean.TRUE);
+ 
+     // mock required methods
+     PowerMockito.spy(OffHeapRegionEntryHelper.class);
+     PowerMockito.doNothing().when(OffHeapRegionEntryHelper.class);
+     OffHeapRegionEntryHelper.setValue(re, Token.REMOVED_PHASE2);
+ 
+     OffHeapRegionEntryHelper.releaseEntry(re);
+ 
+     PowerMockito.verifyStatic();
+     OffHeapRegionEntryHelper.setValue(re, Token.REMOVED_PHASE2);
+   }
+ 
+   @Test
+   public void releaseEntryShouldSetValueToRemovePhase2AndSetsAsyncToFalseForDiskEntry() {
+     // mock region entry
+     OffHeapRegionEntry re = mock(VersionedStatsDiskRegionEntryOffHeap.class);
+     when(re.getAddress()).thenReturn(1L);
+     when(re.setAddress(1L, OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS)).thenReturn(Boolean.TRUE);
+ 
+     DiskId spy = Mockito.spy(DiskId.class);
+     when(((DiskEntry) re).getDiskId()).thenReturn(spy);
+     when(spy.isPendingAsync()).thenReturn(Boolean.TRUE);
+ 
+     // mock required methods
+     PowerMockito.spy(OffHeapRegionEntryHelper.class);
+     PowerMockito.doNothing().when(OffHeapRegionEntryHelper.class);
+     OffHeapRegionEntryHelper.setValue(re, Token.REMOVED_PHASE2);
+ 
+     OffHeapRegionEntryHelper.releaseEntry(re);
+ 
+     verify(spy, times(1)).setPendingAsync(Boolean.FALSE);
+ 
+     PowerMockito.verifyStatic();
+     OffHeapRegionEntryHelper.setValue(re, Token.REMOVED_PHASE2);
+   }
+   
+   @Test
+   public void doWithOffHeapClearShouldSetTheThreadLocalToTrue() {
+     // verify that threadlocal is not set
+     assertThat(OffHeapRegionEntryHelper.doesClearNeedToCheckForOffHeap()).isFalse();
+ 
+     OffHeapRegionEntryHelper.doWithOffHeapClear(new Runnable() {
+       @Override
+       public void run() {
+         // verify that threadlocal is set when offheap is cleared
+         assertThat(OffHeapRegionEntryHelper.doesClearNeedToCheckForOffHeap()).isTrue();
+       }
+     });
+ 
+     // verify that threadlocal is reset after offheap is cleared
+     assertThat(OffHeapRegionEntryHelper.doesClearNeedToCheckForOffHeap()).isFalse();
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
index 0000000,f0f0461..d5db4e4
mode 000000,100755..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
@@@ -1,0 -1,285 +1,285 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertNotNull;
+ import static org.junit.Assert.assertTrue;
+ import static org.junit.Assert.fail;
+ import static org.mockito.Mockito.*;
+ 
+ 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 com.gemstone.gemfire.OutOfOffHeapMemoryException;
+ import com.gemstone.gemfire.StatisticsFactory;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.DistributionStats;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.InternalLocator;
+ import com.gemstone.gemfire.internal.LocalStatisticsFactory;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class OffHeapStorageJUnitTest {
+   @Rule
+   public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+ 
+   private final static long MEGABYTE = 1024 * 1024;
+   private final static long GIGABYTE = 1024 * 1024 * 1024;
+ 
+   @Before
+   public void setUp() throws Exception {
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+   }
+ 
+   @Test
+   public void testParseOffHeapMemorySizeNegative() {
+     assertEquals(0, OffHeapStorage.parseOffHeapMemorySize("-1"));
+   }
+   @Test
+   public void testParseOffHeapMemorySizeNull() {
+     assertEquals(0, OffHeapStorage.parseOffHeapMemorySize(null));
+   }
+   @Test
+   public void testParseOffHeapMemorySizeEmpty() {
+     assertEquals(0, OffHeapStorage.parseOffHeapMemorySize(""));
+   }
+   @Test
+   public void testParseOffHeapMemorySizeBytes() {
+     assertEquals(MEGABYTE, OffHeapStorage.parseOffHeapMemorySize("1"));
+     assertEquals(Integer.MAX_VALUE * MEGABYTE, OffHeapStorage.parseOffHeapMemorySize("" + Integer.MAX_VALUE));
+   }
+   @Test
+   public void testParseOffHeapMemorySizeKiloBytes() {
+     try {
+       OffHeapStorage.parseOffHeapMemorySize("1k");
+       fail("Did not receive expected IllegalArgumentException");
+     } catch (IllegalArgumentException expected) {
+       // Expected
+     }
+   }
+   @Test
+   public void testParseOffHeapMemorySizeMegaBytes() {
+     assertEquals(MEGABYTE, OffHeapStorage.parseOffHeapMemorySize("1m"));
+     assertEquals(Integer.MAX_VALUE * MEGABYTE, OffHeapStorage.parseOffHeapMemorySize("" + Integer.MAX_VALUE + "m"));
+   }
+   @Test
+   public void testParseOffHeapMemorySizeGigaBytes() {
+     assertEquals(GIGABYTE, OffHeapStorage.parseOffHeapMemorySize("1g"));
+     assertEquals(Integer.MAX_VALUE * GIGABYTE, OffHeapStorage.parseOffHeapMemorySize("" + Integer.MAX_VALUE + "g"));
+   }
+   @Test
+   public void testCalcMaxSlabSize() {
+     assertEquals(100, OffHeapStorage.calcMaxSlabSize(100L));
+     assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcMaxSlabSize(Long.MAX_VALUE));
+     try {
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "99");
+       assertEquals(99*1024*1024, OffHeapStorage.calcMaxSlabSize(100L*1024*1024));
+       assertEquals(88, OffHeapStorage.calcMaxSlabSize(88));
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "88m");
+       assertEquals(88*1024*1024, OffHeapStorage.calcMaxSlabSize(100L*1024*1024));
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "77M");
+       assertEquals(77*1024*1024, OffHeapStorage.calcMaxSlabSize(100L*1024*1024));
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "1g");
+       assertEquals(1*1024*1024*1024, OffHeapStorage.calcMaxSlabSize(2L*1024*1024*1024));
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "1G");
+       assertEquals(1L*1024*1024*1024, OffHeapStorage.calcMaxSlabSize(2L*1024*1024*1024+1));
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "foobarG");
+       try {
+         OffHeapStorage.calcMaxSlabSize(100);
+         fail("expected IllegalArgumentException");
+       } catch (IllegalArgumentException expected) {
+       }
+       System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "");
+       assertEquals(100, OffHeapStorage.calcMaxSlabSize(100L));
+       assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcMaxSlabSize(Long.MAX_VALUE));
+     } finally {
+       System.clearProperty("gemfire.OFF_HEAP_SLAB_SIZE");
+     }
+   }
+   @Test
+   public void createOffHeapStorageReturnsNullIfForceLocator() {
+     System.setProperty(InternalLocator.FORCE_LOCATOR_DM_TYPE, "true");
+     assertEquals(null, OffHeapStorage.createOffHeapStorage(null, null, 1, null));
+   }
+   @Test
+   public void createOffHeapStorageReturnsNullIfMemorySizeIsZero() {
+     assertEquals(null, OffHeapStorage.createOffHeapStorage(null, null, 0, null));
+   }
+   @Test
+   public void exceptionIfSlabCountTooSmall() {
+     StatisticsFactory statsFactory = mock(StatisticsFactory.class);
+     try {
+       OffHeapStorage.createOffHeapStorage(null, statsFactory, OffHeapStorage.MIN_SLAB_SIZE-1, null);
+     } catch (IllegalArgumentException expected) {
+       expected.getMessage().equals("The amount of off heap memory must be at least " + OffHeapStorage.MIN_SLAB_SIZE + " but it was set to " + (OffHeapStorage.MIN_SLAB_SIZE-1));
+     }
+   }
+   @Test
+   public void exceptionIfDistributedSystemNull() {
+     StatisticsFactory statsFactory = mock(StatisticsFactory.class);
+     try {
+       OffHeapStorage.createOffHeapStorage(null, statsFactory, OffHeapStorage.MIN_SLAB_SIZE, (DistributedSystem)null);
+     } catch (IllegalArgumentException expected) {
+       expected.getMessage().equals("InternalDistributedSystem is null");
+     }
+   }
+   
+   @Test
+   public void createOffHeapStorageWorks() {
+     StatisticsFactory localStatsFactory = new LocalStatisticsFactory(null);
+     InternalDistributedSystem ids = mock(InternalDistributedSystem.class);
+     MemoryAllocator ma = OffHeapStorage.createOffHeapStorage(null, localStatsFactory, OffHeapStorage.MIN_SLAB_SIZE, ids);
+     System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
+     ma.close();
+   }
+ 
+   @Test
+   public void testCreateOffHeapStorage() {
+     StatisticsFactory localStatsFactory = new LocalStatisticsFactory(null);
+     OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
+     MemoryAllocator ma = OffHeapStorage.basicCreateOffHeapStorage(null, localStatsFactory, 1024*1024, ooohml);
+     try {
+       OffHeapMemoryStats stats = ma.getStats();
+       assertNotNull(stats.getStats());
+       assertEquals(1024*1024, stats.getFreeMemory());
+       assertEquals(1024*1024, stats.getMaxMemory());
+       assertEquals(0, stats.getUsedMemory());
+       assertEquals(0, stats.getCompactions());
+       assertEquals(0, stats.getCompactionTime());
+       assertEquals(0, stats.getFragmentation());
+       assertEquals(1, stats.getFragments());
+       assertEquals(1024*1024, stats.getLargestFragment());
+       assertEquals(0, stats.getObjects());
+       assertEquals(0, stats.getReads());
+ 
+       stats.incFreeMemory(100);
+       assertEquals(1024*1024+100, stats.getFreeMemory());
+       stats.incFreeMemory(-100);
+       assertEquals(1024*1024, stats.getFreeMemory());
+ 
+       stats.incMaxMemory(100);
+       assertEquals(1024*1024+100, stats.getMaxMemory());
+       stats.incMaxMemory(-100);
+       assertEquals(1024*1024, stats.getMaxMemory());
+ 
+       stats.incUsedMemory(100);
+       assertEquals(100, stats.getUsedMemory());
+       stats.incUsedMemory(-100);
+       assertEquals(0, stats.getUsedMemory());
+ 
+       stats.incObjects(100);
+       assertEquals(100, stats.getObjects());
+       stats.incObjects(-100);
+       assertEquals(0, stats.getObjects());
+ 
+       stats.incReads();
+       assertEquals(1, stats.getReads());
+ 
+       stats.setFragmentation(100);
+       assertEquals(100, stats.getFragmentation());
+       stats.setFragmentation(0);
+       assertEquals(0, stats.getFragmentation());
+ 
+       stats.setFragments(2);
+       assertEquals(2, stats.getFragments());
+       stats.setFragments(1);
+       assertEquals(1, stats.getFragments());
+ 
+       stats.setLargestFragment(100);
+       assertEquals(100, stats.getLargestFragment());
+       stats.setLargestFragment(1024*1024);
+       assertEquals(1024*1024, stats.getLargestFragment());
+ 
+       boolean originalEnableClockStats = DistributionStats.enableClockStats;
+       DistributionStats.enableClockStats = true;
+       try {
+         long start = stats.startCompaction();
+         while (stats.startCompaction() == start) {
+           Thread.yield();
+         }
+         stats.endCompaction(start);
+         assertEquals(1, stats.getCompactions());
+         assertTrue(stats.getCompactionTime() > 0);
+       } finally {
+         DistributionStats.enableClockStats = originalEnableClockStats;
+       }
+ 
+       stats.incObjects(100);
+       stats.incUsedMemory(100);
+       stats.setFragmentation(100);
+       OffHeapStorage ohs = (OffHeapStorage) stats;
+       ohs.initialize(new NullOffHeapMemoryStats());
+       assertEquals(0, stats.getFreeMemory());
+       assertEquals(0, stats.getMaxMemory());
+       assertEquals(0, stats.getUsedMemory());
+       assertEquals(0, stats.getCompactions());
+       assertEquals(0, stats.getCompactionTime());
+       assertEquals(0, stats.getFragmentation());
+       assertEquals(0, stats.getFragments());
+       assertEquals(0, stats.getLargestFragment());
+       assertEquals(0, stats.getObjects());
+       assertEquals(0, stats.getReads());
+ 
+       OutOfOffHeapMemoryException ex = null;
+       try {
 -        ma.allocate(1024*1024+1, null);
++        ma.allocate(1024*1024+1);
+         fail("expected OutOfOffHeapMemoryException");
+       } catch (OutOfOffHeapMemoryException expected) {
+         ex = expected;
+       }
+       verify(ooohml).outOfOffHeapMemory(ex);
+       try {
 -        ma.allocate(1024*1024+1, null);
++        ma.allocate(1024*1024+1);
+         fail("expected OutOfOffHeapMemoryException");
+       } catch (OutOfOffHeapMemoryException expected) {
+         ex = expected;
+       }
+       verify(ooohml).outOfOffHeapMemory(ex);
+ 
+     } finally {
+       System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
+       try {
+         ma.close();
+       } finally {
+         System.clearProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY);
+       }
+     }
+   }
+   @Test
+   public void testCalcSlabCount() {
+     final long MSS = OffHeapStorage.MIN_SLAB_SIZE;
+     assertEquals(100, OffHeapStorage.calcSlabCount(MSS*4, MSS*4*100));
+     assertEquals(100, OffHeapStorage.calcSlabCount(MSS*4, (MSS*4*100) + (MSS-1)));
+     assertEquals(101, OffHeapStorage.calcSlabCount(MSS*4, (MSS*4*100) + MSS));
+     assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcSlabCount(MSS, MSS * Integer.MAX_VALUE));
+     assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcSlabCount(MSS, (MSS * Integer.MAX_VALUE) + MSS-1));
+     try {
+       OffHeapStorage.calcSlabCount(MSS, (((long)MSS) * Integer.MAX_VALUE) + MSS);
+       fail("Expected IllegalArgumentException");
+     } catch (IllegalArgumentException expected) {
+     }
+   }
+ }



[076/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
index 0000000,10e4148..a716f14
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
@@@ -1,0 -1,821 +1,920 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.List;
+ import java.util.NavigableSet;
+ import java.util.concurrent.ConcurrentSkipListSet;
+ import java.util.concurrent.CopyOnWriteArrayList;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.concurrent.atomic.AtomicLong;
+ import java.util.concurrent.atomic.AtomicReferenceArray;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.OutOfOffHeapMemoryException;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 -import com.gemstone.gemfire.internal.offheap.MemoryBlock.State;
+ 
+ /**
+  * Manages the free lists for a SimpleMemoryAllocatorImpl
+  */
+ public class FreeListManager {
 -  final private AtomicReferenceArray<SyncChunkStack> tinyFreeLists = new AtomicReferenceArray<SyncChunkStack>(SimpleMemoryAllocatorImpl.TINY_FREE_LIST_COUNT);
++  /** The MemoryChunks that this allocator is managing by allocating smaller chunks of them.
++   * The contents of this array never change.
++   */
++  private final AddressableMemoryChunk[] slabs;
++  private final long totalSlabSize;
++  
++  final private AtomicReferenceArray<SyncChunkStack> tinyFreeLists = new AtomicReferenceArray<SyncChunkStack>(TINY_FREE_LIST_COUNT);
+   // hugeChunkSet is sorted by chunk size in ascending order. It will only contain chunks larger than MAX_TINY.
 -  private final ConcurrentSkipListSet<Chunk> hugeChunkSet = new ConcurrentSkipListSet<Chunk>();
++  private final ConcurrentSkipListSet<ObjectChunk> hugeChunkSet = new ConcurrentSkipListSet<ObjectChunk>();
+   private final AtomicLong allocatedSize = new AtomicLong(0L);
+ 
+   private int getNearestTinyMultiple(int size) {
 -    return (size-1)/SimpleMemoryAllocatorImpl.TINY_MULTIPLE;
++    return (size-1)/TINY_MULTIPLE;
+   }
 -  List<Chunk> getLiveChunks() {
 -    ArrayList<Chunk> result = new ArrayList<Chunk>();
 -    UnsafeMemoryChunk[] slabs = this.ma.getSlabs();
++  List<ObjectChunk> getLiveChunks() {
++    ArrayList<ObjectChunk> result = new ArrayList<ObjectChunk>();
+     for (int i=0; i < slabs.length; i++) {
+       getLiveChunks(slabs[i], result);
+     }
+     return result;
+   }
 -  private void getLiveChunks(UnsafeMemoryChunk slab, List<Chunk> result) {
++  private void getLiveChunks(AddressableMemoryChunk slab, List<ObjectChunk> result) {
+     long addr = slab.getMemoryAddress();
 -    while (addr <= (slab.getMemoryAddress() + slab.getSize() - Chunk.MIN_CHUNK_SIZE)) {
++    while (addr <= (slab.getMemoryAddress() + slab.getSize() - ObjectChunk.MIN_CHUNK_SIZE)) {
+       Fragment f = isAddrInFragmentFreeSpace(addr);
+       if (f != null) {
+         addr = f.getMemoryAddress() + f.getSize();
+       } else {
 -        int curChunkSize = Chunk.getSize(addr);
 -        int refCount = Chunk.getRefCount(addr);
++        int curChunkSize = ObjectChunk.getSize(addr);
++        int refCount = ObjectChunk.getRefCount(addr);
+         if (refCount > 0) {
 -          result.add(this.ma.chunkFactory.newChunk(addr));
++          result.add(new ObjectChunk(addr));
+         }
+         addr += curChunkSize;
+       }
+     }
+   }
+   /**
+    * If addr is in the free space of a fragment then return that fragment; otherwise return null.
+    */
+   private Fragment isAddrInFragmentFreeSpace(long addr) {
+     for (Fragment f: this.fragmentList) {
+       if (addr >= (f.getMemoryAddress() + f.getFreeIndex()) && addr < (f.getMemoryAddress() + f.getSize())) {
+         return f;
+       }
+     }
+     return null;
+   }
+   public long getUsedMemory() {
+     return this.allocatedSize.get();
+   }
+   public long getFreeMemory() {
 -    return this.ma.getTotalMemory() - getUsedMemory();
++    return getTotalMemory() - getUsedMemory();
+   }
+   long getFreeFragmentMemory() {
+     long result = 0;
+     for (Fragment f: this.fragmentList) {
+       int freeSpace = f.freeSpace();
 -      if (freeSpace >= Chunk.MIN_CHUNK_SIZE) {
++      if (freeSpace >= ObjectChunk.MIN_CHUNK_SIZE) {
+         result += freeSpace;
+       }
+     }
+     return result;
+   }
+   long getFreeTinyMemory() {
+     long tinyFree = 0;
+     for (int i=0; i < this.tinyFreeLists.length(); i++) {
+       SyncChunkStack cl = this.tinyFreeLists.get(i);
+       if (cl != null) {
+         tinyFree += cl.computeTotalSize();
+       }
+     }
+     return tinyFree;
+   }
+   long getFreeHugeMemory() {
+     long hugeFree = 0;
 -    for (Chunk c: this.hugeChunkSet) {
++    for (ObjectChunk c: this.hugeChunkSet) {
+       hugeFree += c.getSize();
+     }
+     return hugeFree;
+   }
+ 
+   /**
+    * The id of the last fragment we allocated from.
+    */
+   private final AtomicInteger lastFragmentAllocation = new AtomicInteger(0);
+   private final CopyOnWriteArrayList<Fragment> fragmentList;
+   private final SimpleMemoryAllocatorImpl ma;
+ 
 -  public FreeListManager(SimpleMemoryAllocatorImpl ma) {
++  public FreeListManager(SimpleMemoryAllocatorImpl ma, final AddressableMemoryChunk[] slabs) {
+     this.ma = ma;
 -    UnsafeMemoryChunk[] slabs = ma.getSlabs();
++    this.slabs = slabs;
++    long total = 0;
+     Fragment[] tmp = new Fragment[slabs.length];
+     for (int i=0; i < slabs.length; i++) {
 -      tmp[i] = new Fragment(slabs[i].getMemoryAddress(), slabs[i].getSize());
++      tmp[i] = createFragment(slabs[i].getMemoryAddress(), slabs[i].getSize());
++      total += slabs[i].getSize();
+     }
+     this.fragmentList = new CopyOnWriteArrayList<Fragment>(tmp);
++    this.totalSlabSize = total;
+ 
 -    if(ma.validateMemoryWithFill) {
 -      fillFragments();
 -    }
++    fillFragments();
+   }
+ 
+   /**
 -   * Fills all fragments with a fill used for data integrity validation.
++   * Create and return a Fragment.
++   * This method exists so that tests can override it.
++   */
++  protected Fragment createFragment(long addr, int size) {
++    return new Fragment(addr, size);
++  }
++  
++  /**
++   * Fills all fragments with a fill used for data integrity validation 
++   * if fill validation is enabled.
+    */
+   private void fillFragments() {
++    if (!this.validateMemoryWithFill) {
++      return;
++    }
+     for(Fragment fragment : this.fragmentList) {
+       fragment.fill();
+     }
+   }
+ 
+   /**
+    * Allocate a chunk of memory of at least the given size.
+    * The basic algorithm is:
+    * 1. Look for a previously allocated and freed chunk close to the size requested.
+    * 2. See if the original chunk is big enough to split. If so do so.
+    * 3. Look for a previously allocated and freed chunk of any size larger than the one requested.
+    *    If we find one split it.
+    * <p>
+    * It might be better not to include step 3 since we expect and freed chunk to be reallocated in the future.
+    * Maybe it would be better for 3 to look for adjacent free blocks that can be merged together.
+    * For now we will just try 1 and 2 and then report out of mem.
+    * @param size minimum bytes the returned chunk must have.
 -   * @param chunkType TODO
+    * @return the allocated chunk
+    * @throws IllegalStateException if a chunk can not be allocated.
+    */
+   @SuppressWarnings("synthetic-access")
 -  public Chunk allocate(int size, ChunkType chunkType) {
 -    Chunk result = null;
 -    {
 -      assert size > 0;
 -      if (chunkType == null) {
 -        chunkType = GemFireChunk.TYPE;
 -      }
 -      result = basicAllocate(size, true, chunkType);
 -      result.setDataSize(size);
 -    }
 -    this.ma.stats.incObjects(1);
 -    int resultSize = result.getSize();
 -    this.allocatedSize.addAndGet(resultSize);
 -    this.ma.stats.incUsedMemory(resultSize);
 -    this.ma.stats.incFreeMemory(-resultSize);
++  public ObjectChunk allocate(int size) {
++    assert size > 0;
++    
++    ObjectChunk result = basicAllocate(size, true);
++
++    result.setDataSize(size);
++    this.allocatedSize.addAndGet(result.getSize());
+     result.initializeUseCount();
 -    this.ma.notifyListeners();
+ 
+     return result;
+   }
+ 
 -  private Chunk basicAllocate(int size, boolean useSlabs, ChunkType chunkType) {
++  private ObjectChunk basicAllocate(int size, boolean useSlabs) {
+     if (useSlabs) {
+       // Every object stored off heap has a header so we need
+       // to adjust the size so that the header gets allocated.
+       // If useSlabs is false then the incoming size has already
+       // been adjusted.
 -      size += Chunk.OFF_HEAP_HEADER_SIZE;
++      size += ObjectChunk.OFF_HEAP_HEADER_SIZE;
+     }
 -    if (size <= SimpleMemoryAllocatorImpl.MAX_TINY) {
 -      return allocateTiny(size, useSlabs, chunkType);
++    if (size <= MAX_TINY) {
++      return allocateTiny(size, useSlabs);
+     } else {
 -      return allocateHuge(size, useSlabs, chunkType);
++      return allocateHuge(size, useSlabs);
+     }
+   }
+ 
 -  private Chunk allocateFromFragments(int chunkSize, ChunkType chunkType) {
++  private ObjectChunk allocateFromFragments(int chunkSize) {
+     do {
+       final int lastAllocationId = this.lastFragmentAllocation.get();
+       for (int i=lastAllocationId; i < this.fragmentList.size(); i++) {
 -        Chunk result = allocateFromFragment(i, chunkSize, chunkType);
++        ObjectChunk result = allocateFromFragment(i, chunkSize);
+         if (result != null) {
+           return result;
+         }
+       }
+       for (int i=0; i < lastAllocationId; i++) {
 -        Chunk result = allocateFromFragment(i, chunkSize, chunkType);
++        ObjectChunk result = allocateFromFragment(i, chunkSize);
+         if (result != null) {
+           return result;
+         }
+       }
+     } while (compact(chunkSize));
+     // We tried all the fragments and didn't find any free memory.
+     logOffHeapState(chunkSize);
+     final OutOfOffHeapMemoryException failure = new OutOfOffHeapMemoryException("Out of off-heap memory. Could not allocate size of " + chunkSize);
+     try {
+       throw failure;
+     } finally {
 -      this.ma.ooohml.outOfOffHeapMemory(failure);
++      this.ma.getOutOfOffHeapMemoryListener().outOfOffHeapMemory(failure);
+     }
+   }
+ 
+   private void logOffHeapState(int chunkSize) {
+     if (InternalDistributedSystem.getAnyInstance() != null) {
+       LogWriter lw = InternalDistributedSystem.getAnyInstance().getLogWriter();
 -      lw.info("OutOfOffHeapMemory allocating size of " + chunkSize + ". allocated=" + this.allocatedSize.get() + " compactions=" + this.compactCount.get() + " objects=" + this.ma.stats.getObjects() + " free=" + this.ma.stats.getFreeMemory() + " fragments=" + this.ma.stats.getFragments() + " largestFragment=" + this.ma.stats.getLargestFragment() + " fragmentation=" + this.ma.stats.getFragmentation());
 -      logFragmentState(lw);
 -      logTinyState(lw);
 -      logHugeState(lw);
++      logOffHeapState(lw, chunkSize);
+     }
+   }
+ 
++  void logOffHeapState(LogWriter lw, int chunkSize) {
++    OffHeapMemoryStats stats = this.ma.getStats();
++    lw.info("OutOfOffHeapMemory allocating size of " + chunkSize + ". allocated=" + this.allocatedSize.get() + " compactions=" + this.compactCount.get() + " objects=" + stats.getObjects() + " free=" + stats.getFreeMemory() + " fragments=" + stats.getFragments() + " largestFragment=" + stats.getLargestFragment() + " fragmentation=" + stats.getFragmentation());
++    logFragmentState(lw);
++    logTinyState(lw);
++    logHugeState(lw);
++  }
++
+   private void logHugeState(LogWriter lw) {
 -    for (Chunk c: this.hugeChunkSet) {
++    for (ObjectChunk c: this.hugeChunkSet) {
+       lw.info("Free huge of size " + c.getSize());
+     }
+   }
+   private void logTinyState(LogWriter lw) {
+     for (int i=0; i < this.tinyFreeLists.length(); i++) {
+       SyncChunkStack cl = this.tinyFreeLists.get(i);
+       if (cl != null) {
+         cl.logSizes(lw, "Free tiny of size ");
+       }
+     }
+   }
+   private void logFragmentState(LogWriter lw) {
+     for (Fragment f: this.fragmentList) {
+       int freeSpace = f.freeSpace();
+       if (freeSpace > 0) {
+         lw.info("Fragment at " + f.getMemoryAddress() + " of size " + f.getSize() + " has " + freeSpace + " bytes free.");
+       }
+     }
+   }
+ 
 -  private final AtomicInteger compactCount = new AtomicInteger();
++  protected final AtomicInteger compactCount = new AtomicInteger();
++  /*
++   * Set this to "true" to perform data integrity checks on allocated and reused Chunks.  This may clobber 
++   * performance so turn on only when necessary.
++   */
++  final boolean validateMemoryWithFill = Boolean.getBoolean("gemfire.validateOffHeapWithFill");
++  /**
++   * Every allocated chunk smaller than TINY_MULTIPLE*TINY_FREE_LIST_COUNT will allocate a chunk of memory that is a multiple of this value.
++   * Sizes are always rounded up to the next multiple of this constant
++   * so internal fragmentation will be limited to TINY_MULTIPLE-1 bytes per allocation
++   * and on average will be TINY_MULTIPLE/2 given a random distribution of size requests.
++   * This does not account for the additional internal fragmentation caused by the off-heap header
++   * which currently is always 8 bytes.
++   */
++  public final static int TINY_MULTIPLE = Integer.getInteger("gemfire.OFF_HEAP_ALIGNMENT", 8);
++  static {
++    verifyOffHeapAlignment(TINY_MULTIPLE);
++  }
++  /**
++   * Number of free lists to keep for tiny allocations.
++   */
++  public final static int TINY_FREE_LIST_COUNT = Integer.getInteger("gemfire.OFF_HEAP_FREE_LIST_COUNT", 16384);
++  static {
++    verifyOffHeapFreeListCount(TINY_FREE_LIST_COUNT);
++  }
++  /**
++   * How many unused bytes are allowed in a huge memory allocation.
++   */
++  public final static int HUGE_MULTIPLE = 256;
++  static {
++    verifyHugeMultiple(HUGE_MULTIPLE);
++  }
++  public final static int MAX_TINY = TINY_MULTIPLE*TINY_FREE_LIST_COUNT;
+   /**
+    * Compacts memory and returns true if enough memory to allocate chunkSize
+    * is freed. Otherwise returns false;
+    * TODO OFFHEAP: what should be done about contiguous chunks that end up being bigger than 2G?
+    * Currently if we are given slabs bigger than 2G or that just happen to be contiguous and add
+    * up to 2G then the compactor may unify them together into a single Chunk and our 32-bit chunkSize
+    * field will overflow. This code needs to detect this and just create a chunk of 2G and then start
+    * a new one.
+    * Or to prevent it from happening we could just check the incoming slabs and throw away a few bytes
+    * to keep them from being contiguous.
+    */
 -  private boolean compact(int chunkSize) {
++  boolean compact(int chunkSize) {
+     final long startCompactionTime = this.ma.getStats().startCompaction();
+     final int countPreSync = this.compactCount.get();
++    afterCompactCountFetched();
+     try {
+       synchronized (this) {
+         if (this.compactCount.get() != countPreSync) {
+           // someone else did a compaction while we waited on the sync.
+           // So just return true causing the caller to retry the allocation.
+           return true;
+         }
+         ArrayList<SyncChunkStack> freeChunks = new ArrayList<SyncChunkStack>();
+         collectFreeChunks(freeChunks);
+         final int SORT_ARRAY_BLOCK_SIZE = 128;
+         long[] sorted = new long[SORT_ARRAY_BLOCK_SIZE];
+         int sortedSize = 0;
+         boolean result = false;
+         int largestFragment = 0;
+         for (SyncChunkStack l: freeChunks) {
+           long addr = l.poll();
+           while (addr != 0) {
+             int idx = Arrays.binarySearch(sorted, 0, sortedSize, addr);
 -            //System.out.println("DEBUG addr=" + addr + " size=" + Chunk.getSize(addr) + " idx="+idx + " sortedSize=" + sortedSize);
 -            if (idx >= 0) {
 -              throw new IllegalStateException("duplicate memory address found during compaction!");
 -            }
+             idx = -idx;
+             idx--;
+             if (idx == sortedSize) {
+               // addr is > everything in the array
+               if (sortedSize == 0) {
+                 // nothing was in the array
+                 sorted[0] = addr;
+                 sortedSize++;
+               } else {
+                 // see if we can conflate into sorted[idx]
+                 long lowAddr = sorted[idx-1];
 -                int lowSize = Chunk.getSize(lowAddr);
++                int lowSize = ObjectChunk.getSize(lowAddr);
+                 if (lowAddr + lowSize == addr) {
+                   // append the addr chunk to lowAddr
 -                  Chunk.setSize(lowAddr, lowSize + Chunk.getSize(addr));
++                  ObjectChunk.setSize(lowAddr, lowSize + ObjectChunk.getSize(addr));
+                 } else {
+                   if (sortedSize >= sorted.length) {
+                     long[] newSorted = new long[sorted.length+SORT_ARRAY_BLOCK_SIZE];
+                     System.arraycopy(sorted, 0, newSorted, 0, sorted.length);
+                     sorted = newSorted;
+                   }
+                   sortedSize++;
+                   sorted[idx] = addr;
+                 }
+               }
+             } else {
 -              int addrSize = Chunk.getSize(addr);
++              int addrSize = ObjectChunk.getSize(addr);
+               long highAddr = sorted[idx];
+               if (addr + addrSize == highAddr) {
+                 // append highAddr chunk to addr
 -                Chunk.setSize(addr, addrSize + Chunk.getSize(highAddr));
++                ObjectChunk.setSize(addr, addrSize + ObjectChunk.getSize(highAddr));
+                 sorted[idx] = addr;
+               } else {
+                 boolean insert = idx==0;
+                 if (!insert) {
+                   long lowAddr = sorted[idx-1];
+                   //                  if (lowAddr == 0L) {
+                   //                    long[] tmp = Arrays.copyOf(sorted, sortedSize);
+                   //                    throw new IllegalStateException("addr was zero at idx=" + (idx-1) + " sorted="+ Arrays.toString(tmp));
+                   //                  }
 -                  int lowSize = Chunk.getSize(lowAddr);
++                  int lowSize = ObjectChunk.getSize(lowAddr);
+                   if (lowAddr + lowSize == addr) {
+                     // append the addr chunk to lowAddr
 -                    Chunk.setSize(lowAddr, lowSize + addrSize);
++                    ObjectChunk.setSize(lowAddr, lowSize + addrSize);
+                   } else {
+                     insert = true;
+                   }
+                 }
+                 if (insert) {
+                   if (sortedSize >= sorted.length) {
+                     long[] newSorted = new long[sorted.length+SORT_ARRAY_BLOCK_SIZE];
+                     System.arraycopy(sorted, 0, newSorted, 0, idx);
+                     newSorted[idx] = addr;
+                     System.arraycopy(sorted, idx, newSorted, idx+1, sortedSize-idx);
+                     sorted = newSorted;
+                   } else {
+                     System.arraycopy(sorted, idx, sorted, idx+1, sortedSize-idx);
+                     sorted[idx] = addr;
+                   }
+                   sortedSize++;
+                 }
+               }
+             }
+             addr = l.poll();
+           }
+         }
+         for (int i=sortedSize-1; i > 0; i--) {
+           long addr = sorted[i];
+           long lowAddr = sorted[i-1];
 -          int lowSize = Chunk.getSize(lowAddr);
++          int lowSize = ObjectChunk.getSize(lowAddr);
+           if (lowAddr + lowSize == addr) {
+             // append addr chunk to lowAddr
 -            Chunk.setSize(lowAddr, lowSize + Chunk.getSize(addr));
++            ObjectChunk.setSize(lowAddr, lowSize + ObjectChunk.getSize(addr));
+             sorted[i] = 0L;
+           }
+         }
+         this.lastFragmentAllocation.set(0);
+         ArrayList<Fragment> tmp = new ArrayList<Fragment>();
+         for (int i=sortedSize-1; i >= 0; i--) {
+           long addr = sorted[i];
+           if (addr == 0L) continue;
 -          int addrSize = Chunk.getSize(addr);
 -          Fragment f = new Fragment(addr, addrSize);
++          int addrSize = ObjectChunk.getSize(addr);
++          Fragment f = createFragment(addr, addrSize);
+           if (addrSize >= chunkSize) {
+             result = true;
+           }
+           if (addrSize > largestFragment) {
+             largestFragment = addrSize;
+             // TODO it might be better to sort them biggest first
+             tmp.add(0, f);
+           } else {
+             tmp.add(f);
+           }
+         }
+         this.fragmentList.addAll(tmp);
+ 
 -        // Reinitialize fragments with fill pattern data
 -        if(this.ma.validateMemoryWithFill) {
 -          fillFragments();
 -        }
++        fillFragments();
+ 
+         // Signal any waiters that a compaction happened.
+         this.compactCount.incrementAndGet();
+ 
+         this.ma.getStats().setLargestFragment(largestFragment);
+         this.ma.getStats().setFragments(tmp.size());        
 -        updateFragmentation();
++        updateFragmentation(largestFragment);
+ 
+         return result;
+       } // sync
+     } finally {
+       this.ma.getStats().endCompaction(startCompactionTime);
+     }
+   }
+ 
 -  private void updateFragmentation() {      
 -    long freeSize = this.ma.getStats().getFreeMemory();
++  /**
++   * Unit tests override this method to get better test coverage
++   */
++  protected void afterCompactCountFetched() {
++  }
++  
++  static void verifyOffHeapAlignment(int tinyMultiple) {
++    if (tinyMultiple <= 0 || (tinyMultiple & 3) != 0) {
++      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8.");
++    }
++    if (tinyMultiple > 256) {
++      // this restriction exists because of the dataSize field in the object header.
++      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be <= 256 and a multiple of 8.");
++    }
++  }
++  static void verifyOffHeapFreeListCount(int tinyFreeListCount) {
++    if (tinyFreeListCount <= 0) {
++      throw new IllegalStateException("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
++    }
++  }
++  static void verifyHugeMultiple(int hugeMultiple) {
++    if (hugeMultiple > 256 || hugeMultiple < 0) {
++      // this restriction exists because of the dataSize field in the object header.
++      throw new IllegalStateException("HUGE_MULTIPLE must be >= 0 and <= 256 but it was " + hugeMultiple);
++    }
++  }
++  
++  private void updateFragmentation(long largestFragment) {      
++    long freeSize = getFreeMemory();
+ 
+     // Calculate free space fragmentation only if there is free space available.
+     if(freeSize > 0) {
 -      long largestFragment = this.ma.getStats().getLargestFragment();
+       long numerator = freeSize - largestFragment;
+ 
+       double percentage = (double) numerator / (double) freeSize;
+       percentage *= 100d;
+ 
+       int wholePercentage = (int) Math.rint(percentage);
+       this.ma.getStats().setFragmentation(wholePercentage);
+     } else {
+       // No free space? Then we have no free space fragmentation.
+       this.ma.getStats().setFragmentation(0);
+     }
+   }
+ 
+   private void collectFreeChunks(List<SyncChunkStack> l) {
+     collectFreeFragmentChunks(l);
+     collectFreeHugeChunks(l);
+     collectFreeTinyChunks(l);
+   }
++  List<Fragment> getFragmentList() {
++    return this.fragmentList;
++  }
+   private void collectFreeFragmentChunks(List<SyncChunkStack> l) {
+     if (this.fragmentList.size() == 0) return;
+     SyncChunkStack result = new SyncChunkStack();
+     for (Fragment f: this.fragmentList) {
+       int offset;
+       int diff;
+       do {
+         offset = f.getFreeIndex();
+         diff = f.getSize() - offset;
 -      } while (diff >= Chunk.MIN_CHUNK_SIZE && !f.allocate(offset, offset+diff));
 -      if (diff < Chunk.MIN_CHUNK_SIZE) {
 -        if (diff > 0) {
 -          SimpleMemoryAllocatorImpl.logger.debug("Lost memory of size {}", diff);
 -        }
 -        // fragment is too small to turn into a chunk
 -        // TODO we need to make sure this never happens
 -        // by keeping sizes rounded. I think I did this
 -        // by introducing MIN_CHUNK_SIZE and by rounding
 -        // the size of huge allocations.
++      } while (diff >= ObjectChunk.MIN_CHUNK_SIZE && !f.allocate(offset, offset+diff));
++      if (diff < ObjectChunk.MIN_CHUNK_SIZE) {
++        // If diff > 0 then that memory will be lost during compaction.
++        // This should never happen since we keep the sizes rounded
++        // based on MIN_CHUNK_SIZE.
++        assert diff == 0;
++        // The current fragment is completely allocated so just skip it.
+         continue;
+       }
+       long chunkAddr = f.getMemoryAddress()+offset;
 -      Chunk.setSize(chunkAddr, diff);
++      ObjectChunk.setSize(chunkAddr, diff);
+       result.offer(chunkAddr);
+     }
+     // All the fragments have been turned in to chunks so now clear them
+     // The compaction will create new fragments.
+     this.fragmentList.clear();
+     if (!result.isEmpty()) {
+       l.add(result);
+     }
+   }
+   private void collectFreeTinyChunks(List<SyncChunkStack> l) {
+     for (int i=0; i < this.tinyFreeLists.length(); i++) {
+       SyncChunkStack cl = this.tinyFreeLists.get(i);
+       if (cl != null) {
+         long head = cl.clear();
+         if (head != 0L) {
+           l.add(new SyncChunkStack(head));
+         }
+       }
+     }
+   }
+   private void collectFreeHugeChunks(List<SyncChunkStack> l) {
 -    Chunk c = this.hugeChunkSet.pollFirst();
++    ObjectChunk c = this.hugeChunkSet.pollFirst();
+     SyncChunkStack result = null;
+     while (c != null) {
+       if (result == null) {
+         result = new SyncChunkStack();
+         l.add(result);
+       }
+       result.offer(c.getMemoryAddress());
+       c = this.hugeChunkSet.pollFirst();
+     }
+   }
+ 
 -  private Chunk allocateFromFragment(final int fragIdx, final int chunkSize, ChunkType chunkType) {
++  ObjectChunk allocateFromFragment(final int fragIdx, final int chunkSize) {
+     if (fragIdx >= this.fragmentList.size()) return null;
+     final Fragment fragment;
+     try {
+       fragment = this.fragmentList.get(fragIdx);
+     } catch (IndexOutOfBoundsException ignore) {
+       // A concurrent compaction can cause this.
+       return null;
+     }
+     boolean retryFragment;
+     do {
+       retryFragment = false;
+       int oldOffset = fragment.getFreeIndex();
+       int fragmentSize = fragment.getSize();
+       int fragmentFreeSize = fragmentSize - oldOffset;
+       if (fragmentFreeSize >= chunkSize) {
+         // this fragment has room
 -        // Try to allocate up to BATCH_SIZE more chunks from it
 -        int allocSize = chunkSize * SimpleMemoryAllocatorImpl.BATCH_SIZE;
 -        if (allocSize > fragmentFreeSize) {
 -          allocSize = (fragmentFreeSize / chunkSize) * chunkSize;
 -        }
 -        int newOffset = oldOffset + allocSize;
++        int newOffset = oldOffset + chunkSize;
+         int extraSize = fragmentSize - newOffset;
 -        if (extraSize < Chunk.MIN_CHUNK_SIZE) {
++        if (extraSize < ObjectChunk.MIN_CHUNK_SIZE) {
+           // include these last few bytes of the fragment in the allocation.
+           // If we don't then they will be lost forever.
+           // The extraSize bytes only apply to the first chunk we allocate (not the batch ones).
+           newOffset += extraSize;
+         } else {
+           extraSize = 0;
+         }
+         if (fragment.allocate(oldOffset, newOffset)) {
+           // We did the allocate!
+           this.lastFragmentAllocation.set(fragIdx);
 -          Chunk result = this.ma.chunkFactory.newChunk(fragment.getMemoryAddress()+oldOffset, chunkSize+extraSize, chunkType);
 -          allocSize -= chunkSize+extraSize;
 -          oldOffset += extraSize;
 -          while (allocSize > 0) {
 -            oldOffset += chunkSize;
 -            // we add the batch ones immediately to the freelist
 -            result.readyForFree();
 -            free(result.getMemoryAddress(), false);
 -            result = this.ma.chunkFactory.newChunk(fragment.getMemoryAddress()+oldOffset, chunkSize, chunkType);
 -            allocSize -= chunkSize;
 -          }
 -
 -          if(this.ma.validateMemoryWithFill) {
 -            result.validateFill();
 -          }
 -
++          ObjectChunk result = new ObjectChunk(fragment.getMemoryAddress()+oldOffset, chunkSize+extraSize);
++          checkDataIntegrity(result);
+           return result;
+         } else {
 -          // TODO OFFHEAP: if batch allocations are disabled should we not call basicAllocate here?
 -          // Since we know another thread did a concurrent alloc
 -          // that possibly did a batch check the free list again.
 -          Chunk result = basicAllocate(chunkSize, false, chunkType);
++          ObjectChunk result = basicAllocate(chunkSize, false);
+           if (result != null) {
+             return result;
+           }
+           retryFragment = true;
+         }
+       }
+     } while (retryFragment);
+     return null; // did not find enough free space in this fragment
+   }
+ 
+   private int round(int multiple, int value) {
+     return (int) ((((long)value + (multiple-1)) / multiple) * multiple);
+   }
 -  private Chunk allocateTiny(int size, boolean useFragments, ChunkType chunkType) {
 -    return basicAllocate(getNearestTinyMultiple(size), SimpleMemoryAllocatorImpl.TINY_MULTIPLE, 0, this.tinyFreeLists, useFragments, chunkType);
++  private ObjectChunk allocateTiny(int size, boolean useFragments) {
++    return basicAllocate(getNearestTinyMultiple(size), TINY_MULTIPLE, 0, this.tinyFreeLists, useFragments);
+   }
 -  private Chunk basicAllocate(int idx, int multiple, int offset, AtomicReferenceArray<SyncChunkStack> freeLists, boolean useFragments, ChunkType chunkType) {
++  private ObjectChunk basicAllocate(int idx, int multiple, int offset, AtomicReferenceArray<SyncChunkStack> freeLists, boolean useFragments) {
+     SyncChunkStack clq = freeLists.get(idx);
+     if (clq != null) {
+       long memAddr = clq.poll();
+       if (memAddr != 0) {
 -        Chunk result = this.ma.chunkFactory.newChunk(memAddr, chunkType);
 -
 -        // Data integrity check.
 -        if(this.ma.validateMemoryWithFill) {          
 -          result.validateFill();
 -        }
 -
 -        result.readyForAllocation(chunkType);
++        ObjectChunk result = new ObjectChunk(memAddr);
++        checkDataIntegrity(result);
++        result.readyForAllocation();
+         return result;
+       }
+     }
+     if (useFragments) {
 -      return allocateFromFragments(((idx+1)*multiple)+offset, chunkType);
++      return allocateFromFragments(((idx+1)*multiple)+offset);
+     } else {
+       return null;
+     }
+   }
 -  private Chunk allocateHuge(int size, boolean useFragments, ChunkType chunkType) {
++  private ObjectChunk allocateHuge(int size, boolean useFragments) {
+     // sizeHolder is a fake Chunk used to search our sorted hugeChunkSet.
 -    Chunk sizeHolder = new FakeChunk(size);
 -    NavigableSet<Chunk> ts = this.hugeChunkSet.tailSet(sizeHolder);
 -    Chunk result = ts.pollFirst();
++    ObjectChunk sizeHolder = new FakeChunk(size);
++    NavigableSet<ObjectChunk> ts = this.hugeChunkSet.tailSet(sizeHolder);
++    ObjectChunk result = ts.pollFirst();
+     if (result != null) {
 -      if (result.getSize() - (SimpleMemoryAllocatorImpl.HUGE_MULTIPLE - Chunk.OFF_HEAP_HEADER_SIZE) < size) {
++      if (result.getSize() - (HUGE_MULTIPLE - ObjectChunk.OFF_HEAP_HEADER_SIZE) < size) {
+         // close enough to the requested size; just return it.
 -
 -        // Data integrity check.
 -        if(this.ma.validateMemoryWithFill) {          
 -          result.validateFill();
 -        }
 -        if (chunkType.getSrcType() != Chunk.getSrcType(result.getMemoryAddress())) {
 -          // The java wrapper class that was cached in the huge chunk list is the wrong type.
 -          // So allocate a new one and garbage collect the old one.
 -          result = this.ma.chunkFactory.newChunk(result.getMemoryAddress(), chunkType);
 -        }
 -        result.readyForAllocation(chunkType);
++        checkDataIntegrity(result);
++        result.readyForAllocation();
+         return result;
+       } else {
+         this.hugeChunkSet.add(result);
+       }
+     }
+     if (useFragments) {
+       // We round it up to the next multiple of TINY_MULTIPLE to make
+       // sure we always have chunks allocated on an 8 byte boundary.
 -      return allocateFromFragments(round(SimpleMemoryAllocatorImpl.TINY_MULTIPLE, size), chunkType);
++      return allocateFromFragments(round(TINY_MULTIPLE, size));
+     } else {
+       return null;
+     }
+   }
+   
++  private void checkDataIntegrity(ObjectChunk data) {
++    if (this.validateMemoryWithFill) {
++      data.validateFill();
++    }
++  }
+   /**
+    * Used by the FreeListManager to easily search its
+    * ConcurrentSkipListSet. This is not a real chunk
+    * but only used for searching.
+    */
 -  private static class FakeChunk extends Chunk {
++  private static class FakeChunk extends ObjectChunk {
+     private final int size;
+     public FakeChunk(int size) {
+       super();
+       this.size = size;
+     }
+     @Override
+     public int getSize() {
+       return this.size;
+     }
+   }
+ 
+   @SuppressWarnings("synthetic-access")
+   public void free(long addr) {
++    if (this.validateMemoryWithFill) {
++      ObjectChunk.fill(addr);
++    }
++    
+     free(addr, true);
+   }
+ 
+   private void free(long addr, boolean updateStats) {
 -    int cSize = Chunk.getSize(addr);
++    int cSize = ObjectChunk.getSize(addr);
+     if (updateStats) {
 -      this.ma.stats.incObjects(-1);
++      OffHeapMemoryStats stats = this.ma.getStats();
++      stats.incObjects(-1);
+       this.allocatedSize.addAndGet(-cSize);
 -      this.ma.stats.incUsedMemory(-cSize);
 -      this.ma.stats.incFreeMemory(cSize);
++      stats.incUsedMemory(-cSize);
++      stats.incFreeMemory(cSize);
+       this.ma.notifyListeners();
+     }
 -    if (cSize <= SimpleMemoryAllocatorImpl.MAX_TINY) {
++    if (cSize <= MAX_TINY) {
+       freeTiny(addr, cSize);
+     } else {
+       freeHuge(addr, cSize);
+     }
+   }
+   private void freeTiny(long addr, int cSize) {
+     basicFree(addr, getNearestTinyMultiple(cSize), this.tinyFreeLists);
+   }
+   private void basicFree(long addr, int idx, AtomicReferenceArray<SyncChunkStack> freeLists) {
+     SyncChunkStack clq = freeLists.get(idx);
+     if (clq != null) {
+       clq.offer(addr);
+     } else {
 -      clq = new SyncChunkStack();
++      clq = createFreeListForEmptySlot(freeLists, idx);
+       clq.offer(addr);
+       if (!freeLists.compareAndSet(idx, null, clq)) {
+         clq = freeLists.get(idx);
+         clq.offer(addr);
+       }
+     }
 -
+   }
++  /**
++   * Tests override this method to simulate concurrent modification
++   */
++  protected SyncChunkStack createFreeListForEmptySlot(AtomicReferenceArray<SyncChunkStack> freeLists, int idx) {
++    return new SyncChunkStack();
++  }
++  
+   private void freeHuge(long addr, int cSize) {
 -    this.hugeChunkSet.add(this.ma.chunkFactory.newChunk(addr)); // TODO make this a collection of longs
++    this.hugeChunkSet.add(new ObjectChunk(addr)); // TODO make this a collection of longs
+   }
+ 
+   List<MemoryBlock> getOrderedBlocks() {
+     final List<MemoryBlock> value = new ArrayList<MemoryBlock>();
+     addBlocksFromFragments(this.fragmentList, value); // unused fragments
+     addBlocksFromChunks(getLiveChunks(), value); // used chunks
+     addBlocksFromChunks(this.hugeChunkSet, value);    // huge free chunks
+     addMemoryBlocks(getTinyFreeBlocks(), value);           // tiny free chunks
+     Collections.sort(value, 
+         new Comparator<MemoryBlock>() {
+           @Override
+           public int compare(MemoryBlock o1, MemoryBlock o2) {
+             return Long.valueOf(o1.getMemoryAddress()).compareTo(o2.getMemoryAddress());
+           }
+     });
+     return value;
+   }
+   private void addBlocksFromFragments(Collection<Fragment> src, List<MemoryBlock> dest) {
+     for (MemoryBlock block : src) {
+       dest.add(new MemoryBlockNode(this.ma, block));
+     }
+   }
+   
 -  private void addBlocksFromChunks(Collection<Chunk> src, List<MemoryBlock> dest) {
 -    for (Chunk chunk : src) {
++  private void addBlocksFromChunks(Collection<ObjectChunk> src, List<MemoryBlock> dest) {
++    for (ObjectChunk chunk : src) {
+       dest.add(new MemoryBlockNode(this.ma, chunk));
+     }
+   }
+   
+   private void addMemoryBlocks(Collection<MemoryBlock> src, List<MemoryBlock> dest) {
+     for (MemoryBlock block : src) {
+       dest.add(new MemoryBlockNode(this.ma, block));
+     }
+   }
+   
+   private List<MemoryBlock> getTinyFreeBlocks() {
+     final List<MemoryBlock> value = new ArrayList<MemoryBlock>();
+     final SimpleMemoryAllocatorImpl sma = this.ma;
+     for (int i = 0; i < this.tinyFreeLists.length(); i++) {
+       if (this.tinyFreeLists.get(i) == null) continue;
+       long addr = this.tinyFreeLists.get(i).getTopAddress();
+       while (addr != 0L) {
+         value.add(new MemoryBlockNode(sma, new TinyMemoryBlock(addr, i)));
 -        addr = Chunk.getNext(addr);
++        addr = ObjectChunk.getNext(addr);
+       }
+     }
+     return value;
+   }
+   List<MemoryBlock> getAllocatedBlocks() {
+     final List<MemoryBlock> value = new ArrayList<MemoryBlock>();
+     addBlocksFromChunks(getLiveChunks(), value); // used chunks
+     Collections.sort(value, 
+         new Comparator<MemoryBlock>() {
+           @Override
+           public int compare(MemoryBlock o1, MemoryBlock o2) {
+             return Long.valueOf(o1.getMemoryAddress()).compareTo(o2.getMemoryAddress());
+           }
+     });
+     return value;
+   }
+   /**
+    * Used to represent an address from a tiny free list as a MemoryBlock
+    */
+   private static final class TinyMemoryBlock implements MemoryBlock {
+     private final long address;
+     private final int freeListId;
+ 
+     private TinyMemoryBlock(long address, int freeListId) {
+       this.address = address;
+       this.freeListId = freeListId;
+     }
+ 
+     @Override
+     public State getState() {
+       return State.DEALLOCATED;
+     }
+ 
+     @Override
+     public long getMemoryAddress() {
+       return address;
+     }
+ 
+     @Override
+     public int getBlockSize() {
 -      return Chunk.getSize(address);
++      return ObjectChunk.getSize(address);
+     }
+ 
+     @Override
+     public MemoryBlock getNextBlock() {
+       throw new UnsupportedOperationException();
+     }
+ 
+     @Override
+     public int getSlabId() {
+       throw new UnsupportedOperationException();
+     }
+ 
+     @Override
+     public int getFreeListId() {
+       return freeListId;
+     }
+ 
+     @Override
+     public int getRefCount() {
+       return 0;
+     }
+ 
+     @Override
+     public String getDataType() {
+       return "N/A";
+     }
+ 
+     @Override
+     public boolean isSerialized() {
+       return false;
+     }
+ 
+     @Override
+     public boolean isCompressed() {
+       return false;
+     }
+ 
+     @Override
+     public Object getDataValue() {
+       return null;
+     }
+ 
+     @Override
 -    public ChunkType getChunkType() {
 -      return null;
 -    }
 -    
 -    @Override
+     public boolean equals(Object o) {
+       if (o instanceof TinyMemoryBlock) {
+         return getMemoryAddress() == ((TinyMemoryBlock) o).getMemoryAddress();
+       }
+       return false;
+     }
+     
+     @Override
+     public int hashCode() {
+       long value = this.getMemoryAddress();
+       return (int)(value ^ (value >>> 32));
+     }
+   }
++
++  long getTotalMemory() {
++    return this.totalSlabSize;
++  }
++  
++  void freeSlabs() {
++    for (int i=0; i < slabs.length; i++) {
++      slabs[i].release();
++    }
++  }
++  /**
++   * newSlabs will be non-null in unit tests.
++   * If the unit test gave us a different array
++   * of slabs then something is wrong because we
++   * are trying to reuse the old already allocated
++   * array which means that the new one will never
++   * be used. Note that this code does not bother
++   * comparing the contents of the arrays.
++   */
++  boolean okToReuse(AddressableMemoryChunk[] newSlabs) {
++    return newSlabs == null || newSlabs == this.slabs;
++  }
++  
++  int getLargestSlabSize() {
++    return this.slabs[0].getSize();
++  }
++  int findSlab(long addr) {
++    for (int i=0; i < this.slabs.length; i++) {
++      AddressableMemoryChunk slab = this.slabs[i];
++      long slabAddr = slab.getMemoryAddress();
++      if (addr >= slabAddr) {
++        if (addr < slabAddr + slab.getSize()) {
++          return i;
++        }
++      }
++    }
++    throw new IllegalStateException("could not find a slab for addr " + addr);
++  }
++  void getSlabDescriptions(StringBuilder sb) {
++    for (int i=0; i < slabs.length; i++) {
++      long startAddr = slabs[i].getMemoryAddress();
++      long endAddr = startAddr + slabs[i].getSize();
++      sb.append("[").append(Long.toString(startAddr, 16)).append("..").append(Long.toString(endAddr, 16)).append("] ");
++    }
++  }
++  boolean validateAddressAndSizeWithinSlab(long addr, int size) {
++    for (int i=0; i < slabs.length; i++) {
++      if (slabs[i].getMemoryAddress() <= addr && addr < (slabs[i].getMemoryAddress() + slabs[i].getSize())) {
++        // validate addr + size is within the same slab
++        if (size != -1) { // skip this check if size is -1
++          if (!(slabs[i].getMemoryAddress() <= (addr+size-1) && (addr+size-1) < (slabs[i].getMemoryAddress() + slabs[i].getSize()))) {
++            throw new IllegalStateException(" address 0x" + Long.toString(addr+size-1, 16) + " does not address the original slab memory");
++          }
++        }
++        return true;
++      }
++    }
++    return false;
++  }
++  
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
index 0000000,0a014de..0c063ac
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
@@@ -1,0 -1,64 +1,62 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ /**
+  * Basic contract for a heap that manages off heap memory. Any MemoryChunks allocated from a heap
+  * are returned to that heap when freed.
+  * 
+  * @author darrel
+  * @since 9.0
+  */
+ public interface MemoryAllocator {
+   /**
+    * @param size the size in bytes of the chunk of memory to allocate
 -   * @param chunkType TODO
+    * @return the allocated chunk of memory.
+    * @throws IllegalStateException if the heap does not have enough memory to grant the request
+    */
 -  public MemoryChunk allocate(int size, ChunkType chunkType);
++  public MemoryChunk allocate(int size);
+   
+   /**
+    * Allocates off heap memory for the given data and returns a MemoryChunk
+    * that is backed by this allocated memory and that contains the data.
+    * @param data the bytes of the data to put in the allocated CachedDeserializable
+    * @param isSerialized true if data contains a serialized object; false if it is an actual byte array.
+    * @param isCompressed true if data is compressed; false if it is uncompressed.
 -   * @param chunkType TODO
+    * @throws IllegalStateException if the heap does not have enough memory to grant the request
+    */
 -  public StoredObject allocateAndInitialize(byte[] data, boolean isSerialized, boolean isCompressed, ChunkType chunkType);
++  public StoredObject allocateAndInitialize(byte[] data, boolean isSerialized, boolean isCompressed);
+   
+   public long getFreeMemory();
+   
+   public long getUsedMemory();
+ 
+   public long getTotalMemory();
+ 
+   public OffHeapMemoryStats getStats();
+ 
+   /**
+    * This allocator will no longer be used so free up any system memory that belongs to it.
+    */
+   public void close();
+ 
+   public MemoryInspector getMemoryInspector();
+   
+   public void addMemoryUsageListener(MemoryUsageListener listener);
+   
+   public void removeMemoryUsageListener(MemoryUsageListener listener);
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
index 0000000,3ad9283..d8cb80a
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
@@@ -1,0 -1,71 +1,70 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ 
+ /**
+  * Basic size and usage information about an off-heap memory block under
+  * inspection. For test validation only.
+  * 
+  * @author Kirk Lund
+  * @since 9.0
+  */
+ public interface MemoryBlock {
+ 
+   public enum State {
+     /** Unused fragment (not used and not in a free list) */
+     UNUSED, 
+     /** Allocated chunk currently in use */
+     ALLOCATED, 
+     /** Deallocated chunk currently in a free list */
+     DEALLOCATED 
+   }
+   
+   public State getState();
+   
+   /**
+    * Returns the unsafe memory address of the first byte of this block.
+    */
+   public long getMemoryAddress();
+   
+   /**
+    * Returns the size of this memory block in bytes.
+    */
+   public int getBlockSize();
+   
+   /**
+    * Returns the next memory block immediately after this one.
+    */
+   public MemoryBlock getNextBlock();
+   
+   /**
+    * Returns the identifier of which slab contains this block.
+    */
+   public int getSlabId();
+   
+   /**
+    * Returns the identifier of which free list contains this block.
+    */
+   public int getFreeListId();
+   
+   public int getRefCount();
+   public String getDataType();
 -  public ChunkType getChunkType();
+   public boolean isSerialized();
+   public boolean isCompressed();
+   public Object getDataValue();
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
index 0000000,5c6182a..b41d429
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
@@@ -1,0 -1,170 +1,162 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import java.io.IOException;
+ import java.util.Arrays;
+ 
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ 
+ /**
+  * Basic implementation of MemoryBlock for test validation only.
+  */
+ public class MemoryBlockNode implements MemoryBlock {
+   private final SimpleMemoryAllocatorImpl ma;
+   private final MemoryBlock block;
+   MemoryBlockNode(SimpleMemoryAllocatorImpl ma, MemoryBlock block) {
+     this.ma = ma;
+     this.block = block;
+   }
+   @Override
+   public State getState() {
+     return this.block.getState();
+   }
+   @Override
+   public long getMemoryAddress() {
+     return this.block.getMemoryAddress();
+   }
+   @Override
+   public int getBlockSize() {
+     return this.block.getBlockSize();
+   }
+   @Override
+   public MemoryBlock getNextBlock() {
+     return this.ma.getMemoryInspector().getBlockAfter(this);
+   }
+   public int getSlabId() {
+     return this.ma.findSlab(getMemoryAddress());
+   }
+   @Override
+   public int getFreeListId() {
+     return this.block.getFreeListId();
+   }
+   public int getRefCount() {
+     return this.block.getRefCount(); // delegate to fix GEODE-489
+   }
+   public String getDataType() {
+     if (this.block.getDataType() != null) {
+       return this.block.getDataType();
+     }
+     if (!isSerialized()) {
+       // byte array
+       if (isCompressed()) {
 -        return "compressed byte[" + ((Chunk)this.block).getDataSize() + "]";
++        return "compressed byte[" + ((ObjectChunk)this.block).getDataSize() + "]";
+       } else {
 -        return "byte[" + ((Chunk)this.block).getDataSize() + "]";
++        return "byte[" + ((ObjectChunk)this.block).getDataSize() + "]";
+       }
+     } else if (isCompressed()) {
 -      return "compressed object of size " + ((Chunk)this.block).getDataSize();
++      return "compressed object of size " + ((ObjectChunk)this.block).getDataSize();
+     }
+     //Object obj = EntryEventImpl.deserialize(((Chunk)this.block).getRawBytes());
 -    byte[] bytes = ((Chunk)this.block).getRawBytes();
++    byte[] bytes = ((ObjectChunk)this.block).getRawBytes();
+     return DataType.getDataType(bytes);
+   }
+   public boolean isSerialized() {
+     return this.block.isSerialized();
+   }
+   public boolean isCompressed() {
+     return this.block.isCompressed();
+   }
+   @Override
+   public Object getDataValue() {
+     String dataType = getDataType();
+     if (dataType == null || dataType.equals("N/A")) {
+       return null;
+     } else if (isCompressed()) {
 -      return ((Chunk)this.block).getCompressedBytes();
++      return ((ObjectChunk)this.block).getCompressedBytes();
+     } else if (!isSerialized()) {
+       // byte array
+       //return "byte[" + ((Chunk)this.block).getDataSize() + "]";
 -      return ((Chunk)this.block).getRawBytes();
++      return ((ObjectChunk)this.block).getRawBytes();
+     } else {
+       try {
 -        byte[] bytes = ((Chunk)this.block).getRawBytes();
++        byte[] bytes = ((ObjectChunk)this.block).getRawBytes();
+         return DataSerializer.readObject(DataType.getDataInput(bytes));
+       } catch (IOException e) {
+         e.printStackTrace();
+         return "IOException:" + e.getMessage();
+       } catch (ClassNotFoundException e) {
+         e.printStackTrace();
+         return "ClassNotFoundException:" + e.getMessage();
+       } catch (CacheClosedException e) {
+         e.printStackTrace();
+         return "CacheClosedException:" + e.getMessage();
+       }
+     }
+   }
+   @Override
+   public String toString() {
+     final StringBuilder sb = new StringBuilder(MemoryBlock.class.getSimpleName());
+     sb.append("{");
+     sb.append("MemoryAddress=").append(getMemoryAddress());
+     sb.append(", State=").append(getState());
+     sb.append(", BlockSize=").append(getBlockSize());
+     sb.append(", SlabId=").append(getSlabId());
+     sb.append(", FreeListId=");
+     if (getState() == State.UNUSED || getState() == State.ALLOCATED) {
+       sb.append("NONE");
+     } else if (getFreeListId() == -1) {
+       sb.append("HUGE");
+     } else {
+       sb.append(getFreeListId());
+     }
+     sb.append(", RefCount=").append(getRefCount());
 -    ChunkType ct = this.getChunkType();
 -    if (ct != null) {
 -      sb.append(", " + ct);
 -    }
+     sb.append(", isSerialized=").append(isSerialized());
+     sb.append(", isCompressed=").append(isCompressed());
+     sb.append(", DataType=").append(getDataType());
+     {
+       sb.append(", DataValue=");
+       Object dataValue = getDataValue();
+       if (dataValue instanceof byte[]) {
+         byte[] ba = (byte[]) dataValue;
+         if (ba.length < 1024) {
+           sb.append(Arrays.toString(ba));
+         } else {
+           sb.append("<byte array of length " + ba.length + ">");
+         }
+       } else {
+         sb.append(dataValue);
+       }
+     }
+     sb.append("}");
+     return sb.toString();
+   }
 -  @Override
 -  public ChunkType getChunkType() {
 -    return this.block.getChunkType();
 -  }
+   
+   @Override
+   public boolean equals(Object o) {
+     if (o instanceof MemoryBlockNode) {
+       o = ((MemoryBlockNode)o).block;
+     }
+     return this.block.equals(o);
+   }
+   
+   @Override
+   public int hashCode() {
+     return this.block.hashCode();
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
index 0000000,0000000..29e6956
new file mode 100644
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
@@@ -1,0 -1,0 +1,737 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.offheap;
++
++import java.io.DataOutput;
++import java.io.IOException;
++import java.lang.reflect.Constructor;
++import java.lang.reflect.InvocationTargetException;
++import java.lang.reflect.Method;
++import java.nio.ByteBuffer;
++
++import com.gemstone.gemfire.cache.Region;
++import com.gemstone.gemfire.internal.DSCODE;
++import com.gemstone.gemfire.internal.HeapDataOutputStream;
++import com.gemstone.gemfire.internal.InternalDataSerializer;
++import com.gemstone.gemfire.internal.cache.EntryEventImpl;
++import com.gemstone.gemfire.internal.cache.RegionEntry;
++import com.gemstone.gemfire.internal.cache.RegionEntryContext;
++import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
++
++/**
++   * A chunk that stores a Java object.
++   * Currently the object stored in this chunk
++   * is always an entry value of a Region.
++   * Note: this class has a natural ordering that is inconsistent with equals.
++   * Instances of this class should have a short lifetime. We do not store references
++   * to it in the cache. Instead the memoryAddress is stored in a primitive field in
++   * the cache and if used it will then, if needed, create an instance of this class.
++   */
++  public class ObjectChunk extends OffHeapCachedDeserializable implements Comparable<ObjectChunk>, MemoryBlock {
++    /**
++     * The unsafe memory address of the first byte of this chunk
++     */
++    private final long memoryAddress;
++    
++    /**
++     * The useCount, chunkSize, dataSizeDelta, isSerialized, and isCompressed
++     * are all stored in off heap memory in a HEADER. This saves heap memory
++     * by using off heap.
++     */
++    public final static int OFF_HEAP_HEADER_SIZE = 4 + 4;
++    /**
++     * We need to smallest chunk to at least have enough room for a hdr
++     * and for an off heap ref (which is a long).
++     */
++    public final static int MIN_CHUNK_SIZE = OFF_HEAP_HEADER_SIZE + 8;
++    /**
++     * int field.
++     * The number of bytes in this chunk.
++     */
++    private final static int CHUNK_SIZE_OFFSET = 0;
++    /**
++     * Volatile int field
++     * The upper two bits are used for the isSerialized
++     * and isCompressed flags.
++     * The next three bits are unused.
++     * The lower 3 bits of the most significant byte contains a magic number to help us detect
++     * if we are changing the ref count of an object that has been released.
++     * The next byte contains the dataSizeDelta.
++     * The number of bytes of logical data in this chunk.
++     * Since the number of bytes of logical data is always <= chunkSize
++     * and since chunkSize never changes, we have dataSize be
++     * a delta whose max value would be HUGE_MULTIPLE-1.
++     * The lower two bytes contains the use count.
++     */
++    final static int REF_COUNT_OFFSET = 4;
++    /**
++     * The upper two bits are used for the isSerialized
++     * and isCompressed flags.
++     */
++    final static int IS_SERIALIZED_BIT =    0x80000000;
++    final static int IS_COMPRESSED_BIT =    0x40000000;
++    // UNUSED 0x38000000
++    final static int MAGIC_MASK = 0x07000000;
++    final static int MAGIC_NUMBER = 0x05000000;
++    final static int DATA_SIZE_DELTA_MASK = 0x00ff0000;
++    final static int DATA_SIZE_SHIFT = 16;
++    final static int REF_COUNT_MASK =       0x0000ffff;
++    final static int MAX_REF_COUNT = 0xFFFF;
++    final static long FILL_PATTERN = 0x3c3c3c3c3c3c3c3cL;
++    final static byte FILL_BYTE = 0x3c;
++    
++    protected ObjectChunk(long memoryAddress, int chunkSize) {
++      SimpleMemoryAllocatorImpl.validateAddressAndSize(memoryAddress, chunkSize);
++      this.memoryAddress = memoryAddress;
++      setSize(chunkSize);
++      UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, MAGIC_NUMBER);
++    }
++    public void readyForFree() {
++      UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0);
++    }
++    public void readyForAllocation() {
++      if (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0, MAGIC_NUMBER)) {
++        throw new IllegalStateException("Expected 0 but found " + Integer.toHexString(UnsafeMemoryChunk.readAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET)));
++      }
++    }
++    /**
++     * Should only be used by FakeChunk subclass
++     */
++    protected ObjectChunk() {
++      this.memoryAddress = 0L;
++    }
++    
++    /**
++     * Used to create a Chunk given an existing, already allocated,
++     * memoryAddress. The off heap header has already been initialized.
++     */
++    protected ObjectChunk(long memoryAddress) {
++      SimpleMemoryAllocatorImpl.validateAddress(memoryAddress);
++      this.memoryAddress = memoryAddress;
++    }
++    
++    protected ObjectChunk(ObjectChunk chunk) {
++      this.memoryAddress = chunk.memoryAddress;
++    }
++    
++    /**
++     * Throw an exception if this chunk is not allocated
++     */
++    public void checkIsAllocated() {
++      int originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
++      if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
++        throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
++      }
++    }
++    
++    public void incSize(int inc) {
++      setSize(getSize()+inc);
++    }
++    
++    protected void beforeReturningToAllocator() {
++      
++    }
++
++    @Override
++    public int getSize() {
++      return getSize(this.memoryAddress);
++    }
++
++    public void setSize(int size) {
++      setSize(this.memoryAddress, size);
++    }
++
++    public long getMemoryAddress() {
++      return this.memoryAddress;
++    }
++    
++    public int getDataSize() {
++      /*int dataSizeDelta = UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET);
++      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
++      dataSizeDelta >>= DATA_SIZE_SHIFT;
++      return getSize() - dataSizeDelta;*/
++      return getDataSize(this.memoryAddress);
++    }
++    
++    protected static int getDataSize(long memoryAdress) {
++      int dataSizeDelta = UnsafeMemoryChunk.readAbsoluteInt(memoryAdress+REF_COUNT_OFFSET);
++      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
++      dataSizeDelta >>= DATA_SIZE_SHIFT;
++      return getSize(memoryAdress) - dataSizeDelta;
++    }
++    
++    protected long getBaseDataAddress() {
++      return this.memoryAddress+OFF_HEAP_HEADER_SIZE;
++    }
++    protected int getBaseDataOffset() {
++      return 0;
++    }
++    
++    /**
++     * Creates and returns a direct ByteBuffer that contains the contents of this Chunk.
++     * Note that the returned ByteBuffer has a reference to this chunk's
++     * off-heap address so it can only be used while this Chunk is retained.
++     * @return the created direct byte buffer or null if it could not be created.
++     */
++    @Unretained
++    public ByteBuffer createDirectByteBuffer() {
++      return basicCreateDirectByteBuffer(getBaseDataAddress(), getDataSize());
++    }
++    @Override
++    public void sendTo(DataOutput out) throws IOException {
++      if (!this.isCompressed() && out instanceof HeapDataOutputStream) {
++        ByteBuffer bb = createDirectByteBuffer();
++        if (bb != null) {
++          HeapDataOutputStream hdos = (HeapDataOutputStream) out;
++          if (this.isSerialized()) {
++            hdos.write(bb);
++          } else {
++            hdos.writeByte(DSCODE.BYTE_ARRAY);
++            InternalDataSerializer.writeArrayLength(bb.remaining(), hdos);
++            hdos.write(bb);
++          }
++          return;
++        }
++      }
++      super.sendTo(out);
++    }
++    
++    @Override
++    public void sendAsByteArray(DataOutput out) throws IOException {
++      if (!isCompressed() && out instanceof HeapDataOutputStream) {
++        ByteBuffer bb = createDirectByteBuffer();
++        if (bb != null) {
++          HeapDataOutputStream hdos = (HeapDataOutputStream) out;
++          InternalDataSerializer.writeArrayLength(bb.remaining(), hdos);
++          hdos.write(bb);
++          return;
++        }
++      }
++      super.sendAsByteArray(out);
++    }
++       
++    private static volatile Class dbbClass = null;
++    private static volatile Constructor dbbCtor = null;
++    private static volatile boolean dbbCreateFailed = false;
++    
++    /**
++     * @return the created direct byte buffer or null if it could not be created.
++     */
++    private static ByteBuffer basicCreateDirectByteBuffer(long baseDataAddress, int dataSize) {
++      if (dbbCreateFailed) {
++        return null;
++      }
++      Constructor ctor = dbbCtor;
++      if (ctor == null) {
++        Class c = dbbClass;
++        if (c == null) {
++          try {
++            c = Class.forName("java.nio.DirectByteBuffer");
++          } catch (ClassNotFoundException e) {
++            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
++            dbbCreateFailed = true;
++            dbbAddressFailed = true;
++            return null;
++          }
++          dbbClass = c;
++        }
++        try {
++          ctor = c.getDeclaredConstructor(long.class, int.class);
++        } catch (NoSuchMethodException | SecurityException e) {
++          //throw new IllegalStateException("Could not get constructor DirectByteBuffer(long, int)", e);
++          dbbClass = null;
++          dbbCreateFailed = true;
++          return null;
++        }
++        ctor.setAccessible(true);
++        dbbCtor = ctor;
++      }
++      try {
++        return (ByteBuffer)ctor.newInstance(baseDataAddress, dataSize);
++      } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
++        //throw new IllegalStateException("Could not create an instance using DirectByteBuffer(long, int)", e);
++        dbbClass = null;
++        dbbCtor = null;
++        dbbCreateFailed = true;
++        return null;
++      }
++    }
++    private static volatile Method dbbAddressMethod = null;
++    private static volatile boolean dbbAddressFailed = false;
++    
++    /**
++     * Returns the address of the Unsafe memory for the first byte of a direct ByteBuffer.
++     * If the buffer is not direct or the address can not be obtained return 0.
++     */
++    public static long getDirectByteBufferAddress(ByteBuffer bb) {
++      if (!bb.isDirect()) {
++        return 0L;
++      }
++      if (dbbAddressFailed) {
++        return 0L;
++      }
++      Method m = dbbAddressMethod;
++      if (m == null) {
++        Class c = dbbClass;
++        if (c == null) {
++          try {
++            c = Class.forName("java.nio.DirectByteBuffer");
++          } catch (ClassNotFoundException e) {
++            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
++            dbbCreateFailed = true;
++            dbbAddressFailed = true;
++            return 0L;
++          }
++          dbbClass = c;
++        }
++        try {
++          m = c.getDeclaredMethod("address");
++        } catch (NoSuchMethodException | SecurityException e) {
++          //throw new IllegalStateException("Could not get method DirectByteBuffer.address()", e);
++          dbbClass = null;
++          dbbAddressFailed = true;
++          return 0L;
++        }
++        m.setAccessible(true);
++        dbbAddressMethod = m;
++      }
++      try {
++        return (Long)m.invoke(bb);
++      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
++        //throw new IllegalStateException("Could not create an invoke DirectByteBuffer.address()", e);
++        dbbClass = null;
++        dbbAddressMethod = null;
++        dbbAddressFailed = true;
++        return 0L;
++      }
++    }
++    /**
++     * Returns an address that can be used with unsafe apis to access this chunks memory.
++     * @param offset the offset from this chunk's first byte of the byte the returned address should point to. Must be >= 0.
++     * @param size the number of bytes that will be read using the returned address. Assertion will use this to verify that all the memory accessed belongs to this chunk. Must be > 0.
++     * @return a memory address that can be used with unsafe apis
++     */
++    public long getUnsafeAddress(int offset, int size) {
++      assert offset >= 0 && offset + size <= getDataSize(): "Offset=" + offset + ",size=" + size + ",dataSize=" + getDataSize() + ", chunkSize=" + getSize() + ", but offset + size must be <= " + getDataSize();
++      assert size > 0;
++      long result = getBaseDataAddress() + offset;
++      // validateAddressAndSizeWithinSlab(result, size);
++      return result;
++    }
++    
++    @Override
++    public byte readByte(int offset) {
++      assert offset < getDataSize();
++      return UnsafeMemoryChunk.readAbsoluteByte(getBaseDataAddress() + offset);
++    }
++
++    @Override
++    public void writeByte(int offset, byte value) {
++      assert offset < getDataSize();
++      UnsafeMemoryChunk.writeAbsoluteByte(getBaseDataAddress() + offset, value);
++    }
++
++    @Override
++    public void readBytes(int offset, byte[] bytes) {
++      readBytes(offset, bytes, 0, bytes.length);
++    }
++
++    @Override
++    public void writeBytes(int offset, byte[] bytes) {
++      writeBytes(offset, bytes, 0, bytes.length);
++    }
++
++    public long getAddressForReading(int offset, int size) {
++      //delegate to getUnsafeAddress - as both the methods does return the memory address from given offset
++      return getUnsafeAddress(offset, size);
++    }
++    
++    @Override
++    public void readBytes(int offset, byte[] bytes, int bytesOffset, int size) {
++      assert offset+size <= getDataSize();
++      UnsafeMemoryChunk.readAbsoluteBytes(getBaseDataAddress() + offset, bytes, bytesOffset, size);
++    }
++
++    @Override
++    public void writeBytes(int offset, byte[] bytes, int bytesOffset, int size) {
++      assert offset+size <= getDataSize();
++      UnsafeMemoryChunk.writeAbsoluteBytes(getBaseDataAddress() + offset, bytes, bytesOffset, size);
++    }
++    
++    @Override
++    public void release() {
++      release(this.memoryAddress);
++     }
++
++    @Override
++    public int compareTo(ObjectChunk o) {
++      int result = Integer.signum(getSize() - o.getSize());
++      if (result == 0) {
++        // For the same sized chunks we really don't care about their order
++        // but we need compareTo to only return 0 if the two chunks are identical
++        result = Long.signum(getMemoryAddress() - o.getMemoryAddress());
++      }
++      return result;
++    }
++    
++    @Override
++    public boolean equals(Object o) {
++      if (o instanceof ObjectChunk) {
++        return getMemoryAddress() == ((ObjectChunk) o).getMemoryAddress();
++      }
++      return false;
++    }
++    
++    @Override
++    public int hashCode() {
++      long value = this.getMemoryAddress();
++      return (int)(value ^ (value >>> 32));
++    }
++
++    // OffHeapCachedDeserializable methods 
++    
++    @Override
++    public void setSerializedValue(byte[] value) {
++      writeBytes(0, value);
++    }
++    
++    public byte[] getDecompressedBytes(RegionEntryContext context) {
++      byte[] result = getCompressedBytes();
++      long time = context.getCachePerfStats().startDecompression();
++      result = context.getCompressor().decompress(result);
++      context.getCachePerfStats().endDecompression(time);      
++      return result;
++    }
++    
++    /**
++     * Returns the raw possibly compressed bytes of this chunk
++     */
++    public byte[] getCompressedBytes() {
++      byte[] result = new byte[getDataSize()];
++      readBytes(0, result);
++      //debugLog("reading", true);
++      SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
++      return result;
++    }
++    protected byte[] getRawBytes() {
++      byte[] result = getCompressedBytes();
++      // TODO OFFHEAP: change the following to assert !isCompressed();
++      if (isCompressed()) {
++        throw new UnsupportedOperationException();
++      }
++      return result;
++    }
++
++    @Override
++    public byte[] getSerializedValue() {
++      byte [] result = getRawBytes();
++      if (!isSerialized()) {
++        // The object is a byte[]. So we need to make it look like a serialized byte[] in our result
++        result = EntryEventImpl.serialize(result);
++      }
++      return result;
++    }
++    
++    @Override
++    public Object getDeserializedValue(Region r, RegionEntry re) {
++      if (isSerialized()) {
++        // TODO OFFHEAP: debug deserializeChunk
++        return EntryEventImpl.deserialize(getRawBytes());
++        //assert !isCompressed();
++        //return EntryEventImpl.deserializeChunk(this);
++      } else {
++        return getRawBytes();
++      }
++    }
++    
++    /**
++     * We want this to include memory overhead so use getSize() instead of getDataSize().
++     */
++    @Override
++    public int getSizeInBytes() {
++      // Calling getSize includes the off heap header size.
++      // We do not add anything to this since the size of the reference belongs to the region entry size
++      // not the size of this object.
++      return getSize();
++    }
++
++    @Override
++    public int getValueSizeInBytes() {
++      return getDataSize();
++    }
++
++    @Override
++    public void copyBytes(int src, int dst, int size) {
++      throw new UnsupportedOperationException("Implement if used");
++//      assert src+size <= getDataSize();
++//      assert dst+size < getDataSize();
++//      getSlabs()[this.getSlabIdx()].copyBytes(getBaseDataAddress()+src, getBaseDataAddress()+dst, size);
++    }
++
++    @Override
++    public boolean isSerialized() {
++      return (UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET) & IS_SERIALIZED_BIT) != 0;
++    }
++
++    @Override
++    public boolean isCompressed() {
++      return (UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET) & IS_COMPRESSED_BIT) != 0;
++    }
++
++    @Override
++    public boolean retain() {
++      return retain(this.memoryAddress);
++    }
++
++    @Override
++    public int getRefCount() {
++      return getRefCount(this.memoryAddress);
++    }
++
++    public static int getSize(long memAddr) {
++      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
++      return UnsafeMemoryChunk.readAbsoluteInt(memAddr+CHUNK_SIZE_OFFSET);
++    }
++    public static void setSize(long memAddr, int size) {
++      SimpleMemoryAllocatorImpl.validateAddressAndSize(memAddr, size);
++      UnsafeMemoryChunk.writeAbsoluteInt(memAddr+CHUNK_SIZE_OFFSET, size);
++    }
++    public static long getNext(long memAddr) {
++      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
++      return UnsafeMemoryChunk.readAbsoluteLong(memAddr+OFF_HEAP_HEADER_SIZE);
++    }
++    public static void setNext(long memAddr, long next) {
++      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
++      UnsafeMemoryChunk.writeAbsoluteLong(memAddr+OFF_HEAP_HEADER_SIZE, next);
++    }
++    
++    /**
++     * Fills the chunk with a repeated byte fill pattern.
++     * @param baseAddress the starting address for a {@link ObjectChunk}.
++     */
++    public static void fill(long baseAddress) {
++      long startAddress = baseAddress + MIN_CHUNK_SIZE;
++      int size = getSize(baseAddress) - MIN_CHUNK_SIZE;
++      
++      UnsafeMemoryChunk.fill(startAddress, size, FILL_BYTE);
++    }
++    
++    /**
++     * Validates that the fill pattern for this chunk has not been disturbed.  This method
++     * assumes the TINY_MULTIPLE is 8 bytes.
++     * @throws IllegalStateException when the pattern has been violated.
++     */
++    public void validateFill() {
++      assert FreeListManager.TINY_MULTIPLE == 8;
++      
++      long startAddress = getMemoryAddress() + MIN_CHUNK_SIZE;
++      int size = getSize() - MIN_CHUNK_SIZE;
++      
++      for(int i = 0;i < size;i += FreeListManager.TINY_MULTIPLE) {
++        if(UnsafeMemoryChunk.readAbsoluteLong(startAddress + i) != FILL_PATTERN) {
++          throw new IllegalStateException("Fill pattern violated for chunk " + getMemoryAddress() + " with size " + getSize());
++        }        
++      }
++    }
++
++    public void setSerialized(boolean isSerialized) {
++      if (isSerialized) {
++        int bits;
++        int originalBits;
++        do {
++          originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
++          if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
++            throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
++          }
++          bits = originalBits | IS_SERIALIZED_BIT;
++        } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
++      }
++    }
++    public void setCompressed(boolean isCompressed) {
++      if (isCompressed) {
++        int bits;
++        int originalBits;
++        do {
++          originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
++          if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
++            throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
++          }
++          bits = originalBits | IS_COMPRESSED_BIT;
++        } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
++      }
++    }
++    public void setDataSize(int dataSize) { // KIRK
++      assert dataSize <= getSize();
++      int delta = getSize() - dataSize;
++      assert delta <= (DATA_SIZE_DELTA_MASK >> DATA_SIZE_SHIFT);
++      delta <<= DATA_SIZE_SHIFT;
++      int bits;
++      int originalBits;
++      do {
++        originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
++        if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
++          throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
++        }
++        bits = originalBits;
++        bits &= ~DATA_SIZE_DELTA_MASK; // clear the old dataSizeDelta bits
++        bits |= delta; // set the dataSizeDelta bits to the new delta value
++      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
++    }
++    
++    public void initializeUseCount() {
++      int rawBits;
++      do {
++        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
++        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
++          throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(rawBits));
++        }
++        int uc = rawBits & REF_COUNT_MASK;
++        if (uc != 0) {
++          throw new IllegalStateException("Expected use count to be zero but it was: " + uc + " rawBits=0x" + Integer.toHexString(rawBits));
++        }
++      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, rawBits, rawBits+1));
++    }
++
++    public static int getRefCount(long memAddr) {
++      return UnsafeMemoryChunk.readAbsoluteInt(memAddr+REF_COUNT_OFFSET) & REF_COUNT_MASK;
++    }
++
++    public static boolean retain(long memAddr) {
++      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
++      int uc;
++      int rawBits;
++      int retryCount = 0;
++      do {
++        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET);
++        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
++          // same as uc == 0
++          // TODO MAGIC_NUMBER rethink its use and interaction with compactor fragments
++          return false;
++        }
++        uc = rawBits & REF_COUNT_MASK;
++        if (uc == MAX_REF_COUNT) {
++          throw new IllegalStateException("Maximum use count exceeded. rawBits=" + Integer.toHexString(rawBits));
++        } else if (uc == 0) {
++          return false;
++        }
++        retryCount++;
++        if (retryCount > 1000) {
++          throw new IllegalStateException("tried to write " + (rawBits+1) + " to @" + Long.toHexString(memAddr) + " 1,000 times.");
++        }
++      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET, rawBits, rawBits+1));
++      //debugLog("use inced ref count " + (uc+1) + " @" + Long.toHexString(memAddr), true);
++      if (ReferenceCountHelper.trackReferenceCounts()) {
++        ReferenceCountHelper.refCountChanged(memAddr, false, uc+1);
++      }
++
++      return true;
++    }
++    public static void release(final long memAddr) {
++      release(memAddr, null);
++    }
++    static void release(final long memAddr, FreeListManager freeListManager) {
++      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
++      int newCount;
++      int rawBits;
++      boolean returnToAllocator;
++      do {
++        returnToAllocator = false;
++        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET);
++        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
++          String msg = "It looks like off heap memory @" + Long.toHexString(memAddr) + " was already freed. rawBits=" + Integer.toHexString(rawBits) + " history=" + ReferenceCountHelper.getFreeRefCountInfo(memAddr);
++          //debugLog(msg, true);
++          throw new IllegalStateException(msg);
++        }
++        int curCount = rawBits&REF_COUNT_MASK;
++        if ((curCount) == 0) {
++          //debugLog("too many frees @" + Long.toHexString(memAddr), true);
++          throw new IllegalStateException("Memory has already been freed." + " history=" + ReferenceCountHelper.getFreeRefCountInfo(memAddr) /*+ System.identityHashCode(this)*/);
++        }
++        if (curCount == 1) {
++          newCount = 0; // clear the use count, bits, and the delta size since it will be freed.
++          returnToAllocator = true;
++        } else {
++          newCount = rawBits-1;
++        }
++      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET, rawBits, newCount));
++      //debugLog("free deced ref count " + (newCount&USE_COUNT_MASK) + " @" + Long.toHexString(memAddr), true);
++      if (returnToAllocator ) {
++       if (ReferenceCountHelper.trackReferenceCounts()) {
++          if (ReferenceCountHelper.trackFreedReferenceCounts()) {
++            ReferenceCountHelper.refCountChanged(memAddr, true, newCount&REF_COUNT_MASK);
++          }
++          ReferenceCountHelper.freeRefCountInfo(memAddr);
++        }
++        if (freeListManager == null) {
++          freeListManager = SimpleMemoryAllocatorImpl.getAllocator().getFreeListManager();
++        }
++        freeListManager.free(memAddr);
++      } else {
++        if (ReferenceCountHelper.trackReferenceCounts()) {
++          ReferenceCountHelper.refCountChanged(memAddr, true, newCount&REF_COUNT_MASK);
++        }
++      }
++    }
++    
++    @Override
++    public String toString() {
++      return toStringForOffHeapByteSource();
++      // This old impl is not safe because it calls getDeserializedForReading and we have code that call toString that does not inc the refcount.
++      // Also if this Chunk is compressed we don't know how to decompress it.
++      //return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + getMemoryAddress() + " storedObject=" + getDeserializedForReading() + ">";
++    }
++    
++    protected String toStringForOffHeapByteSource() {
++      return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + Long.toHexString(getMemoryAddress()) + ">";
++    }
++    
++    @Override
++    public State getState() {
++      if (getRefCount() > 0) {
++        return State.ALLOCATED;
++      } else {
++        return State.DEALLOCATED;
++      }
++    }
++    @Override
++    public MemoryBlock getNextBlock() {
++      throw new UnsupportedOperationException();
++    }
++    @Override
++    public int getBlockSize() {
++      return getSize();
++    }
++    @Override
++    public int getSlabId() {
++      throw new UnsupportedOperationException();
++    }
++    @Override
++    public int getFreeListId() {
++      return -1;
++    }
++    @Override
++    public String getDataType() {
++      return null;
++    }
++    @Override
++    public Object getDataValue() {
++      return null;
++    }
++    public ObjectChunk slice(int position, int limit) {
++      return new ObjectChunkSlice(this, position, limit);
++    }
++  }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.java
index 0000000,0000000..3d6bf57
new file mode 100644
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSlice.java
@@@ -1,0 -1,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 com.gemstone.gemfire.internal.offheap;
++
++/**
++ * Represents a slice of an ObjectChunk.
++ * A slice is a subsequence of the bytes stored in an ObjectChunk.
++ */
++public class ObjectChunkSlice extends ObjectChunk {
++  private final int offset;
++  private final int capacity;
++  public ObjectChunkSlice(ObjectChunk objectChunk, int position, int limit) {
++    super(objectChunk);
++    this.offset = objectChunk.getBaseDataOffset() + position;
++    this.capacity = limit - position;
++  }
++  @Override
++  public int getDataSize() {
++    return this.capacity;
++  }
++  
++  @Override
++  protected long getBaseDataAddress() {
++    return super.getBaseDataAddress() + this.offset;
++  }
++  @Override
++  protected int getBaseDataOffset() {
++    return this.offset;
++  }
++}



[089/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
index 0000000,51bfb53..24b0697
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
@@@ -1,0 -1,4811 +1,4811 @@@
+ /*
+  * 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 com.gemstone.gemfire.distributed.internal;
+ 
+ import java.io.Externalizable;
+ import java.io.IOException;
+ import java.io.NotSerializableException;
+ import java.io.ObjectInput;
+ import java.io.ObjectOutput;
+ import java.io.Serializable;
+ import java.net.InetAddress;
+ import java.net.UnknownHostException;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Date;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.NoSuchElementException;
+ import java.util.Set;
+ import java.util.concurrent.BlockingQueue;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.Executor;
+ import java.util.concurrent.ExecutorService;
+ import java.util.concurrent.LinkedBlockingQueue;
+ import java.util.concurrent.Semaphore;
+ import java.util.concurrent.SynchronousQueue;
+ import java.util.concurrent.ThreadFactory;
+ import java.util.concurrent.ThreadPoolExecutor;
+ import java.util.concurrent.TimeUnit;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelCriterion;
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.ForcedDisconnectException;
+ import com.gemstone.gemfire.IncompatibleSystemException;
+ import com.gemstone.gemfire.InternalGemFireError;
+ import com.gemstone.gemfire.InternalGemFireException;
+ import com.gemstone.gemfire.InvalidDeltaException;
+ import com.gemstone.gemfire.SystemConnectException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.ToDataException;
+ import com.gemstone.gemfire.admin.GemFireHealthConfig;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
+ import com.gemstone.gemfire.distributed.Locator;
+ import com.gemstone.gemfire.distributed.Role;
+ import com.gemstone.gemfire.distributed.internal.locks.ElderState;
+ import com.gemstone.gemfire.distributed.internal.membership.DistributedMembershipListener;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.distributed.internal.membership.MemberFactory;
+ import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
+ import com.gemstone.gemfire.distributed.internal.membership.NetView;
+ import com.gemstone.gemfire.i18n.StringId;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.NanoTimer;
+ import com.gemstone.gemfire.internal.OSProcess;
+ import com.gemstone.gemfire.internal.SetUtils;
+ import com.gemstone.gemfire.internal.SocketCreator;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.admin.remote.AdminConsoleDisconnectMessage;
+ import com.gemstone.gemfire.internal.admin.remote.RemoteGfManagerAgent;
+ import com.gemstone.gemfire.internal.admin.remote.RemoteTransportConfig;
+ import com.gemstone.gemfire.internal.cache.InitialImageOperation;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
+ import com.gemstone.gemfire.internal.logging.log4j.AlertAppender;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+ import com.gemstone.gemfire.internal.sequencelog.MembershipLogger;
+ import com.gemstone.gemfire.internal.tcp.Connection;
+ import com.gemstone.gemfire.internal.tcp.ConnectionTable;
+ import com.gemstone.gemfire.internal.tcp.ReenteredConnectException;
+ import com.gemstone.gemfire.internal.util.concurrent.StoppableReentrantLock;
+ 
+ /**
+  * The <code>DistributionManager</code> uses a {@link
+  * MembershipManager} to distribute {@link DistributionMessage messages}
+  * queued in {@link MQueue}s.
+  *
+  * <P>
+  *
+  * Code that wishes to send a {@link DistributionMessage} must get
+  * the <code>DistributionManager</code> and invoke {@link
+  * #putOutgoing}.
+  *
+  * <P>
+  *
+  * <code>DistributionManager</code> is not intended to be
+  * serialized.  It is <code>Externalizable</code> only to prevent it
+  * from being copy shared.  See {@link #writeExternal}.
+  *
+  * <P>
+  *
+  * Prior to GemFire 4.0, <code>DistributionManager</code> was an
+  * abstract class with two concrete subclasses,
+  * <code>LocalDistributionManager</code> and
+  * <code>ConsoleDistributionManager</code>.  We decided that
+  * <code>ConsoleDistributionManager</code> (which was used for the GUI
+  * console and admin APIs) did not offer enough interesting
+  * functionality to warrant a separate class.  More importantly, it
+  * prevented the Cache and admin APIs from being used in the same VM.
+  * So, we refactored the code of those two subclasses into
+  * <code>DistributionManager</code>.
+  *
+  * @author David Whitlock
+  * @since 2.0
+  *
+  * @see DistributionMessage#process
+  * @see IgnoredByManager
+  */
+ public class DistributionManager
+   implements Externalizable, DM {
+ 
+   private static final Logger logger = LogService.getLogger();
+   
+   private static final boolean SYNC_EVENTS =
+     Boolean.getBoolean("DistributionManager.syncEvents");
+ 
+   /**
+    * WARNING: setting this to true may break dunit tests.
+    * <p>see com.gemstone.gemfire.cache30.ClearMultiVmCallBkDUnitTest
+    */
+   public static final boolean INLINE_PROCESS = 
+     !Boolean.getBoolean("DistributionManager.enqueueOrderedMessages");
+ 
+   /** Flag indicating whether to use single Serial-Executor thread or 
+    * Multiple Serial-executor thread, 
+    */
+   public static final boolean MULTI_SERIAL_EXECUTORS = 
+     !Boolean.getBoolean("DistributionManager.singleSerialExecutor");
+ 
+   /** The name of the distribution manager (identifies it in GemFire) */
+   public static final String NAME = "GemFire";
+   
+   /** The number of milliseconds to wait for distribution-related
+    * things to happen */
+   public static final long TIMEOUT =
+     Long.getLong("DistributionManager.TIMEOUT", -1).longValue();
+ 
+   public static final int PUSHER_THREADS =
+     Integer.getInteger("DistributionManager.PUSHER_THREADS", 50).intValue();
+ 
+   public static final int PUSHER_QUEUE_SIZE =
+     Integer.getInteger("DistributionManager.PUSHER_QUEUE_SIZE", 4096).intValue();
+ 
+   
+   public static final int MAX_WAITING_THREADS = 
+     Integer.getInteger("DistributionManager.MAX_WAITING_THREADS", Integer.MAX_VALUE).intValue();
+   
+   public static final int MAX_PR_META_DATA_CLEANUP_THREADS = 
+       Integer.getInteger("DistributionManager.MAX_PR_META_DATA_CLEANUP_THREADS", 1).intValue();
+ 
+   public static final int MAX_THREADS = Integer.getInteger("DistributionManager.MAX_THREADS", 100).intValue();
+   public static final int MAX_PR_THREADS = Integer.getInteger("DistributionManager.MAX_PR_THREADS", Math.max(Runtime.getRuntime().availableProcessors()*4, 16)).intValue();
+   public static final int MAX_FE_THREADS = Integer.getInteger("DistributionManager.MAX_FE_THREADS", Math.max(Runtime.getRuntime().availableProcessors()*4, 16)).intValue();
+   //    Integer.getInteger("DistributionManager.MAX_THREADS", max(Runtime.getRuntime().availableProcessors()*2, 2)).intValue();
+ 
+   public static final int INCOMING_QUEUE_LIMIT =
+     Integer.getInteger("DistributionManager.INCOMING_QUEUE_LIMIT", 80000).intValue();
+   public static final int INCOMING_QUEUE_THROTTLE =
+     Integer.getInteger("DistributionManager.INCOMING_QUEUE_THROTTLE", (int)(INCOMING_QUEUE_LIMIT * 0.75)).intValue();
+ 
+   /** Throttling based on the Queue byte size */
+   public static final double THROTTLE_PERCENT =
+     (double) (Integer.getInteger("DistributionManager.SERIAL_QUEUE_THROTTLE_PERCENT", 75).intValue())/100;
+   public static final int SERIAL_QUEUE_BYTE_LIMIT =
+     Integer.getInteger("DistributionManager.SERIAL_QUEUE_BYTE_LIMIT", (40 * (1024 * 1024))).intValue();
+   public static final int SERIAL_QUEUE_THROTTLE =
+     Integer.getInteger("DistributionManager.SERIAL_QUEUE_THROTTLE", (int)(SERIAL_QUEUE_BYTE_LIMIT * THROTTLE_PERCENT)).intValue();
+   public static final int TOTAL_SERIAL_QUEUE_BYTE_LIMIT =
+     Integer.getInteger("DistributionManager.TOTAL_SERIAL_QUEUE_BYTE_LIMIT", (80 * (1024 * 1024))).intValue();
+   public static final int TOTAL_SERIAL_QUEUE_THROTTLE =
+     Integer.getInteger("DistributionManager.TOTAL_SERIAL_QUEUE_THROTTLE", (int)(SERIAL_QUEUE_BYTE_LIMIT * THROTTLE_PERCENT)).intValue();
+   
+   /** Throttling based on the Queue item size */
+   public static final int SERIAL_QUEUE_SIZE_LIMIT =
+     Integer.getInteger("DistributionManager.SERIAL_QUEUE_SIZE_LIMIT", 20000).intValue();
+   public static final int SERIAL_QUEUE_SIZE_THROTTLE =
+     Integer.getInteger("DistributionManager.SERIAL_QUEUE_SIZE_THROTTLE", (int)(SERIAL_QUEUE_SIZE_LIMIT * THROTTLE_PERCENT)).intValue();
+ 
+   /** Max number of serial Queue executors, in case of multi-serial-queue executor */
+   public static final int MAX_SERIAL_QUEUE_THREAD =
+     Integer.getInteger("DistributionManager.MAX_SERIAL_QUEUE_THREAD", 20).intValue();
+ 
+   /**
+    * Whether or not to include link local addresses in the list of addresses we use
+    * to determine if two members are no the same host.
+    * 
+    * Added for normura issue 7033 - they have duplicate link local addresses on different boxes
+    */
+   public static volatile boolean INCLUDE_LINK_LOCAL_ADDRESSES = 
+     Boolean.getBoolean("gemfire.IncludeLinkLocalAddresses");
+   
+   /** The DM type for regular distribution managers */
+   public static final int NORMAL_DM_TYPE = 10;
+ 
+   /** The DM type for locator distribution managers 
+    * @since 7.0
+    */
+   public static final int LOCATOR_DM_TYPE = 11;
+ 
+   /** The DM type for Console (admin-only) distribution managers */
+   public static final int ADMIN_ONLY_DM_TYPE = 12;
+ 
+   public static final int LONER_DM_TYPE = 13;
+ 
+   /**
+    * an NIO priority type
+    * @see com.gemstone.gemfire.distributed.internal.PooledDistributionMessage
+    * @see #SERIAL_EXECUTOR
+    * @see #HIGH_PRIORITY_EXECUTOR
+    * @see #WAITING_POOL_EXECUTOR
+    */
+   public static final int STANDARD_EXECUTOR = 73;
+ 
+   /**
+    * an NIO priority type
+    * 
+    * @see com.gemstone.gemfire.distributed.internal.SerialDistributionMessage
+    * @see #STANDARD_EXECUTOR
+    */
+   public static final int SERIAL_EXECUTOR = 74;
+ 
+   /**
+    * an NIO priority type
+ 
+    * @see com.gemstone.gemfire.distributed.internal.HighPriorityDistributionMessage
+    * @see #STANDARD_EXECUTOR
+    */
+   public static final int HIGH_PRIORITY_EXECUTOR = 75;
+   
+   // 76 not in use
+ 
+   /**
+    * an NIO priority type
+    * 
+    * @see com.gemstone.gemfire.internal.cache.InitialImageOperation
+    * @see #STANDARD_EXECUTOR
+    */
+   public static final int WAITING_POOL_EXECUTOR = 77;
+ 
+   /**
+    * an NIO priority type
+    * 
+    * @see com.gemstone.gemfire.internal.cache.InitialImageOperation
+    * @see #STANDARD_EXECUTOR
+    */
+   public static final int PARTITIONED_REGION_EXECUTOR = 78;
+ 
+   
+   /**
+    * Executor for view related messages
+    * 
+    * @see com.gemstone.gemfire.distributed.internal.membership.gms.messages.ViewAckMessage
+    * @see #STANDARD_EXECUTOR
+    */
+   public static final int VIEW_EXECUTOR = 79;
+ 
+ 
+   public static final int REGION_FUNCTION_EXECUTION_EXECUTOR = 80;
+ 
+   /** The number of open  distribution managers in this VM */
+   private static int openDMs = 0;
+ 
+ //  /** The stack trace of the last time a console DM was opened */
+ //  private static Exception openStackTrace;
+ 
+   /** Is this VM dedicated to administration (like a GUI console or a
+    * JMX agent)?  If so, then it creates {@link #ADMIN_ONLY_DM_TYPE}
+    * type distribution managers.
+    *
+    * @since 4.0 
+    */
+   public static volatile boolean isDedicatedAdminVM = false;
+   
+   /**
+    * Is this admin agent used for a command line console.
+    * This flag controls whether connect will throw 
+    * an exception or just wait for a DS if one is not
+    * available. If true, we will throw an exception.
+    * 
+    */
+   public static volatile boolean isCommandLineAdminVM = false;
+   
+   
+   
+   /////////////////////  Instance Fields  //////////////////////
+ 
+   /** The id of this distribution manager */
+   final protected InternalDistributedMember myid;
+ 
+   /** The distribution manager type of this dm; set in its constructor. */
+   private final int dmType;
+ 
+   /** The <code>MembershipListener</code>s that are registered on this
+    * manager. */
+   private final ConcurrentMap membershipListeners;
+ 
+   /** A lock to hold while adding and removing membership listeners */
+   protected final Object membershipListenersLock =
+     new MembershipListenersLock();
+   /** The <code>MembershipListener</code>s that are registered on this
+    * manager for ALL members.
+    * @since 5.7
+    */
+   protected volatile Set allMembershipListeners = Collections.EMPTY_SET;
+   /**
+    * A lock to hold while adding and removing all membership listeners.
+    * @since 5.7
+    */
+   protected final Object allMembershipListenersLock =
+     new MembershipListenersLock();
+   /** A queue of MemberEvent instances */
+   protected final BlockingQueue membershipEventQueue =
+     new LinkedBlockingQueue();
+   /** Used to invoke registered membership listeners in the background. */
+   private Thread memberEventThread;
+ 
+ 
+   /** A brief description of this DistributionManager */
+   protected final String description;
+ 
+   /** Statistics about distribution */
+   protected /*final*/ DistributionStats stats;
+ 
+   /** Did an exception occur in one of the DM threads? */
+   protected boolean exceptionInThreads;
+ 
+   static ThreadLocal isStartupThread = new ThreadLocal();
+     
+   protected volatile boolean shutdownMsgSent = false;
+ 
+   /** Set to true when this manager is being shutdown */
+   protected volatile boolean closeInProgress = false;
+   
+   private volatile boolean receivedStartupResponse = false;
+   
+   private volatile String rejectionMessage = null;
+ 
+   protected MembershipManager membershipManager;
+   
+   /** The channel through which distributed communication occurs. */
+   protected DistributionChannel channel;
+ 
+   /**
+    * The (non-admin-only) members of the distributed system.  This is a
+    * map of memberid->memberid for fast access to canonical ID references.
+    * All accesses to this 
+    * field must be synchronized on {@link #membersLock}.
+    */
+   private Map<InternalDistributedMember,InternalDistributedMember> members = Collections.emptyMap();
+   /** 
+    * All (admin and non-admin) members of the distributed system. All accesses 
+    * to this field must be synchronized on {@link #membersLock}.
+    */
+   private Set membersAndAdmin = Collections.emptySet();
+   /** 
+    * Map of all locator members of the distributed system. The value is a
+    * collection of locator strings that are hosted in that member. All accesses 
+    * to this field must be synchronized on {@link #membersLock}.
+    */
+   private Map<InternalDistributedMember, Collection<String>> hostedLocatorsAll = Collections.emptyMap();
+   
+   /** 
+    * Map of all locator members of the distributed system which have the shared configuration. The value is a
+    * collection of locator strings that are hosted in that member. All accesses 
+    * to this field must be synchronized on {@link #membersLock}.
+    */
+   private Map<InternalDistributedMember, Collection<String>> hostedLocatorsWithSharedConfiguration = Collections.emptyMap();
+ 
+   /**
+    * Since 6.6.2 and hereafter we will save the versions here. But pre-6.6.2's
+    * StartupResponseMessage does not contain version. We will assign a default
+    * version for them.
+    */
+   public static final String DEFAULT_VERSION_PRE_6_6_2 = "6.6.0.0";
+   /** 
+    * The lock held while accessing the field references to the following:<br>
+    * 1) {@link #members}<br>
+    * 2) {@link #membersAndAdmin}<br>
+    * 3) {@link #hostedLocatorsAll}<br>
+    * 4) {@link #hostedLocatorsWithSharedConfiguration}<br>
+    */
+   private final Object membersLock = new MembersLock();
+ 
+   /**
+    * The lock held while writing {@link #adminConsoles}.
+    */
+   private final Object adminConsolesLock = new Object();
+   /** 
+    * The ids of all known admin consoles
+    * Uses Copy on Write. Writers must sync on adminConsolesLock.
+    * Readers don't need to sync.
+    */
+   private volatile Set<InternalDistributedMember> adminConsoles = Collections.emptySet();
+ 
+   /** The pusher thread */
+   //private Thread pusher;
+ 
+   /** The group of distribution manager threads */
+   protected LoggingThreadGroup threadGroup;
+   
+   /** Message processing thread pool */
+   private ThreadPoolExecutor threadPool;
+ 
+   /** High Priority processing thread pool, used for initializing messages
+    *  such as UpdateAttributes and CreateRegion messages
+    */
+   private ThreadPoolExecutor highPriorityPool;
+   
+   /** Waiting Pool, used for messages that may have to wait on something.
+    *  Use this separate pool with an unbounded queue so that waiting
+    *  runnables don't get in the way of other processing threads.
+    *  Used for threads that will most likely have to wait for a region to be
+    *  finished initializing before it can proceed
+    */
+   private ThreadPoolExecutor waitingPool;
+   
+   private ThreadPoolExecutor prMetaDataCleanupThreadPool;
+   
+   /**
+    * Thread used to decouple {@link com.gemstone.gemfire.internal.cache.partitioned.PartitionMessage}s from 
+    * {@link com.gemstone.gemfire.internal.cache.DistributedCacheOperation}s </b>
+    * @see #SERIAL_EXECUTOR
+    */
+   private ThreadPoolExecutor partitionedRegionThread;
+   private ThreadPoolExecutor partitionedRegionPool;
+   private ThreadPoolExecutor functionExecutionThread;
+   private ThreadPoolExecutor functionExecutionPool;
+ 
+   /** Message processing executor for serial, ordered, messages. */
+   private ThreadPoolExecutor serialThread;
+   
+   /** Message processing executor for view messages
+    * @see com.gemstone.gemfire.distributed.internal.membership.gms.messages.ViewAckMessage 
+    */
+   private ThreadPoolExecutor viewThread;
+   
+   /** If using a throttling queue for the serialThread, we cache the queue here
+       so we can see if delivery would block */
+   private ThrottlingMemLinkedQueueWithDMStats serialQueue;
+ 
+   /** a map keyed on InternalDistributedMember, to direct channels to other systems */
+   //protected final Map channelMap = CFactory.createCM();
+ 
+   protected volatile boolean readyForMessages = false;
+ 
+   /**
+    * Set to true once this DM is ready to send messages.
+    * Note that it is always ready to send the startup message.
+    */
+   private volatile boolean readyToSendMsgs = false;
+   private final Object readyToSendMsgsLock = new Object();
+ 
+   /** Is this distribution manager closed? */
+   protected volatile boolean closed = false;
+ 
+   /** The distributed system to which this distribution manager is
+    * connected. */
+   private InternalDistributedSystem system;
+ 
+   /** The remote transport configuration for this dm */
+   private RemoteTransportConfig transport;
+ 
+   /** The administration agent associated with this distribution
+    * manager. */
+   private volatile RemoteGfManagerAgent agent;
+ 
+   private SerialQueuedExecutorPool serialQueuedExecutorPool;
+   
+   private final Semaphore parallelGIIs = new Semaphore(InitialImageOperation.MAX_PARALLEL_GIIS);
+ 
+   /**
+    * Map of InetAddress to HashSets of InetAddress, to define equivalences
+    * between network interface cards and hosts.
+    */
+   private final HashMap<InetAddress, Set<InetAddress>> equivalentHosts = new HashMap<InetAddress, Set<InetAddress>>();
+ 
+   private int distributedSystemId = DistributionConfig.DEFAULT_DISTRIBUTED_SYSTEM_ID;
+   
+   
+   private final Map<InternalDistributedMember, String> redundancyZones = Collections.synchronizedMap(new HashMap<InternalDistributedMember, String>());
+   
+   private boolean enforceUniqueZone = false;
+ 
+   private volatile boolean isSharedConfigEnabledForDS = false;
+ 
+   @Override
+   public boolean isSharedConfigurationServiceEnabledForDS() {
+     return isSharedConfigEnabledForDS;
+   }
+ 
+   /**
+    * Identifier for function execution threads and any of their children
+    */
+   public static final InheritableThreadLocal<Boolean> isFunctionExecutionThread = new InheritableThreadLocal<Boolean>() {
+     @Override
+     protected Boolean initialValue() {
+       return Boolean.FALSE;
+     }
+   };
+   //////////////////////  Static Methods  //////////////////////
+ 
+   /**
+    * Given two DistributionManager ids, check to see if they are
+    * from the same host address.
+    * @param id1 a DistributionManager id
+    * @param id2 a DistributionManager id
+    * @return true if id1 and id2 are from the same host, false otherwise
+    */
+   public static boolean isSameHost(InternalDistributedMember id1, InternalDistributedMember id2) {
+     return (id1.getInetAddress().equals(id2.getInetAddress()));
+   }
+ 
+   // @todo davidw Modify JGroups so that we do not have to send out a
+   // {@link StartupMessage}
+   /**
+    * Creates a new distribution manager and discovers the other members of the
+    * distributed system. Note that it does not check to see whether or not this
+    * VM already has a distribution manager.
+    * 
+    * @param system
+    *                The distributed system to which this distribution manager
+    *                will send messages.
+    */
+   public static DistributionManager create(InternalDistributedSystem system)
+   {
+ 
+     DistributionManager dm = null;
+     
+     try {
+ 
+       int vmKind;
+       
+       if (Boolean.getBoolean(InternalLocator.FORCE_LOCATOR_DM_TYPE)) {
+         // if this DM is starting for a locator, set it to be a locator DM
+         vmKind = LOCATOR_DM_TYPE;
+ 
+       } else if (isDedicatedAdminVM) {
+         vmKind = ADMIN_ONLY_DM_TYPE;
+ 
+       } else {
+         vmKind = NORMAL_DM_TYPE;
+       }
+     
+       RemoteTransportConfig transport = new RemoteTransportConfig(system.getConfig(), vmKind);
+       transport.setIsReconnectingDS(system.isReconnectingDS());
+       transport.setOldDSMembershipInfo(system.oldDSMembershipInfo());
+       
+       long start = System.currentTimeMillis();
+ 
+       dm = new DistributionManager(system, transport);
+       dm.assertDistributionManagerType();
+ 
+       {
+         InternalDistributedMember id = dm.getDistributionManagerId();
+         if (!"".equals(id.getName())) {
+           for (InternalDistributedMember m: (List<InternalDistributedMember>)dm.getViewMembers()) {
+             if (m.equals(id)) {
+               // I'm counting on the members returned by getViewMembers being ordered such that
+               // members that joined before us will precede us AND members that join after us
+               // will succeed us.
+               // SO once we find ourself break out of this loop.
+               break;
+             }
+             if (id.getName().equals(m.getName())) {
+               if (dm.getMembershipManager().verifyMember(m, "member is using the name of " + id)) {
+                 throw new IncompatibleSystemException("Member " + id + " could not join this distributed system because the existing member " + m + " used the same name. Set the \"name\" gemfire property to a unique value.");
+               }
+             }
+           }
+         }
+         dm.addNewMember(id); // add ourselves
+         dm.selectElder(); // ShutdownException could be thrown here
+       }
+ 
+       // Send out a StartupMessage to the other members.
+       StartupOperation op = new StartupOperation(dm, transport);
+ 
+       try {
+         if (!dm.sendStartupMessage(op, true)) {
+           // We'll we didn't hear back from anyone else.  We assume that
+           // we're the first one.
+           if (dm.getOtherDistributionManagerIds().size() == 0) {
+             logger.info(LocalizedMessage.create(LocalizedStrings.DistributionManager_DIDNT_HEAR_BACK_FROM_ANY_OTHER_SYSTEM_I_AM_THE_FIRST_ONE));
+           } else if (transport.isMcastEnabled()) {
+             // perform a multicast ping test
+             if (!dm.testMulticast()) {
+               logger.warn(LocalizedMessage.create(
+                   LocalizedStrings.DistributionManager_RECEIVED_NO_STARTUP_RESPONSES_BUT_OTHER_MEMBERS_EXIST_MULTICAST_IS_NOT_RESPONSIVE));
+             }
+           }
+         }
+       } catch (InterruptedException ex) {
+         Thread.currentThread().interrupt();
+         // This is ALWAYS bad; don't consult a CancelCriterion.
+         throw new InternalGemFireException(LocalizedStrings.DistributionManager_INTERRUPTED_WHILE_WAITING_FOR_FIRST_STARTUPRESPONSEMESSAGE.toLocalizedString(), ex);
+       } catch (IncompatibleSystemException ex) {
+         logger.fatal(ex.getMessage(), ex);
+         throw ex;
+       } finally {
+         dm.readyToSendMsgs();
+       }
+ 
+       if (logger.isInfoEnabled()) {
+         long delta = System.currentTimeMillis() - start;
+         Object[] logArgs = new Object[] {
+             dm.getDistributionManagerId(),
+             transport,
+             Integer.valueOf(dm.getOtherDistributionManagerIds().size()),
+             dm.getOtherDistributionManagerIds(), 
+             (logger.isInfoEnabled(LogMarker.DM) ? " (VERBOSE, took " + delta + " ms)" : ""),
+             ((dm.getDMType() == ADMIN_ONLY_DM_TYPE) ? " (admin only)" : (dm.getDMType() == LOCATOR_DM_TYPE) ? " (locator)" : "")
+         };
+         logger.info(LogMarker.DM, LocalizedMessage.create(
+             LocalizedStrings.DistributionManager_DISTRIBUTIONMANAGER_0_STARTED_ON_1_THERE_WERE_2_OTHER_DMS_3_4_5, logArgs));
+ 
+         MembershipLogger.logStartup(dm.getDistributionManagerId());
+       }
+       return dm;
+     }
+     catch (RuntimeException r) {
+       if (dm != null) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("cleaning up incompletely started DistributionManager due to exception", r); 
+         }
+         dm.uncleanShutdown(true);
+       }
+       throw r;
+     }
+   }
+ 
+   void runUntilShutdown(Runnable r) {
+     try {
+       r.run();
+     }
+     catch (CancelException e) {
+       if (logger.isTraceEnabled()) {
+         logger.trace("Caught shutdown exception", e); 
+       }
+     }
+     catch (VirtualMachineError err) {
+       SystemFailure.initiateFailure(err);
+       // If this ever returns, rethrow the error.  We're poisoned
+       // now, so don't let this thread continue.
+       throw err;
+     }
+     catch (Throwable t) {
+       // Whenever you catch Error or Throwable, you must also
+       // catch VirtualMachineError (see above).  However, there is
+       // _still_ a possibility that you are dealing with a cascading
+       // error condition, so you also need to check to see if the JVM
+       // is still usable:
+       SystemFailure.checkFailure();
+       if (isCloseInProgress()) {
+         logger.debug("Caught unusual exception during shutdown: {}", t.getMessage(), t);
+       }
+       else {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.DistributionManager_TASK_FAILED_WITH_EXCEPTION), t);
+       }
+     }  }
+   
+   volatile Throwable rootCause = null;
+   
+   private static class Stopper extends CancelCriterion {
+     private DistributionManager dm;
+     
+     // validateDM is commented out because expiry threads hit it with 
+     // an ugly failure... use only for debugging lingering DM bugs
+ //    private String validateDM() {
+ //      GemFireCache cache = GemFireCache.getInstance();
+ //      if (cache == null) {
+ //        return null; // Distributed system with no cache
+ //      }
+ //      Object obj = cache.getDistributedSystem();
+ //      if (obj == null) {
+ //        return null; // Cache is very dead
+ //      }
+ //      InternalDistributedSystem ids = (InternalDistributedSystem)obj;
+ //      DM current = ids.getDistributionManager();
+ //      if (current != dm) {
+ //        String response = LocalizedStrings.DistributionManager_CURRENT_CACHE_DISTRIBUTIONMANAGER_0_IS_NOT_THE_SAME_AS_1
+ //        .toLocalizedString(new Object[] { current, dm});
+ //        return response; 
+ //      }
+ //      return null;
+ //    }
+     
+     Stopper(DistributionManager dm) {
+       this.dm = dm;  
+     }
+     @Override
+     public String cancelInProgress() {
+       checkFailure();
+ 
+       // remove call to validateDM() to fix bug 38356
+       
+       if (dm.shutdownMsgSent) {
+         return LocalizedStrings.DistributionManager__0_MESSAGE_DISTRIBUTION_HAS_TERMINATED.toLocalizedString(dm.toString());
+       }
+       if (dm.rootCause != null) {
+         return dm.toString() + ": " + dm.rootCause.getMessage();
+       }
+       
+       // Nope.
+       return null;
+     }
+ 
+     @Override
+     public RuntimeException generateCancelledException(Throwable e) {
+       String reason = cancelInProgress();
+       if (reason == null) {
+         return null;
+       }
+       Throwable rc = dm.rootCause; // volatile read
+       if (rc == null) {
+         // No root cause, specify the one given and be done with it.
+         return new DistributedSystemDisconnectedException(reason, e);
+       }
+       
+       if (e == null) {
+         // Caller did not specify  any root cause, so just use our own.
+         return new DistributedSystemDisconnectedException(reason, rc);
+       }
+ 
+       // Attempt to stick rootCause at tail end of the exception chain.
+       Throwable nt = e;
+       while (nt.getCause() != null) {
+         nt = nt.getCause();
+       }
+       if (nt == rc) {
+         // Root cause already in place; we're done
+         return new DistributedSystemDisconnectedException(reason, e);
+       }
+       
+       try {
+         nt.initCause(rc);
+         return new DistributedSystemDisconnectedException(reason, e);
+       }
+       catch (IllegalStateException e2) {
+         // Bug 39496 (Jrockit related)  Give up.  The following
+         // error is not entirely sane but gives the correct general picture.
+         return new DistributedSystemDisconnectedException(reason, rc);
+       }
+     }
+   }
+   private final Stopper stopper = new Stopper(this);
+   
+   public CancelCriterion getCancelCriterion() {
+     return stopper;
+   }
+   
+   ///////////////////////  Constructors  ///////////////////////
+   
+   /**
+    * no-arg constructor for Externalizable
+    * TODO: does this class really need to implement Externalizable?  I
+    * think it only implements that interface for the old copy-sharing
+    * shared-memory stuff that's no longer in GemFire
+    */
+   public DistributionManager() {
+     this.elderLock = null;
+     this.membershipListeners = null;
+     this.myid = null;
+     this.description = null;
+     this.dmType = 0;
+     throw new IllegalAccessError("this constructor should never be invoked");
+   }
+ 
+   /**
+    * Creates a new <code>DistributionManager</code> by initializing
+    * itself, creating the membership manager and executors
+    *
+    * @param transport
+    *        The configuration for the communications transport
+    *
+    */
+   private DistributionManager(RemoteTransportConfig transport,
+                               InternalDistributedSystem system) {
+ 
+     this.dmType = transport.getVmKind();
+     this.system = system;
+     this.elderLock = new StoppableReentrantLock(stopper);
+     this.transport = transport;
+ 
+     this.membershipListeners = new ConcurrentHashMap();
+     this.distributedSystemId = system.getConfig().getDistributedSystemId();
+     {
+       long statId = OSProcess.getId();
+       /* deadcoded since we don't know the channel id yet.
+         if (statId == 0 || statId == -1) {
+         statId = getChannelId();
+         }
+       */
+       this.stats = new DistributionStats(system, statId);
+       DistributionStats.enableClockStats = system.getConfig().getEnableTimeStatistics();
+     }
+ 
+     this.exceptionInThreads = false;
+     
+     // Start the processing threads
+     final LoggingThreadGroup group =
+       LoggingThreadGroup.createThreadGroup("DistributionManager Threads", logger);
+     this.threadGroup = group;
+     
+     boolean finishedConstructor = false;
+     try {
+ 
+     if (MULTI_SERIAL_EXECUTORS) {
+       if (logger.isInfoEnabled(LogMarker.DM)) {
+         logger.info(LogMarker.DM,
+             "Serial Queue info :" + 
+             " THROTTLE_PERCENT: " + THROTTLE_PERCENT +
+             " SERIAL_QUEUE_BYTE_LIMIT :" + SERIAL_QUEUE_BYTE_LIMIT +   
+             " SERIAL_QUEUE_THROTTLE :" + SERIAL_QUEUE_THROTTLE + 
+             " TOTAL_SERIAL_QUEUE_BYTE_LIMIT :" + TOTAL_SERIAL_QUEUE_BYTE_LIMIT +  
+             " TOTAL_SERIAL_QUEUE_THROTTLE :" + TOTAL_SERIAL_QUEUE_THROTTLE + 
+             " SERIAL_QUEUE_SIZE_LIMIT :" + SERIAL_QUEUE_SIZE_LIMIT +
+             " SERIAL_QUEUE_SIZE_THROTTLE :" + SERIAL_QUEUE_SIZE_THROTTLE
+         ); 
+       }
+       //  when TCP/IP is disabled we can't throttle the serial queue or we run the risk of 
+       // distributed deadlock when we block the UDP reader thread
+       boolean throttlingDisabled = system.getConfig().getDisableTcp();
+       this.serialQueuedExecutorPool = new SerialQueuedExecutorPool(this.threadGroup, this.stats, throttlingDisabled);
+     }
+       
+     {
+       BlockingQueue poolQueue;
+       if (SERIAL_QUEUE_BYTE_LIMIT == 0) {
+         poolQueue = new OverflowQueueWithDMStats(this.stats.getSerialQueueHelper());
+       } else {
+         this.serialQueue = new ThrottlingMemLinkedQueueWithDMStats(TOTAL_SERIAL_QUEUE_BYTE_LIMIT, 
+             TOTAL_SERIAL_QUEUE_THROTTLE, SERIAL_QUEUE_SIZE_LIMIT, SERIAL_QUEUE_SIZE_THROTTLE, 
+             this.stats.getSerialQueueHelper());
+         poolQueue = this.serialQueue;
+      } 
+       ThreadFactory tf = new ThreadFactory() {
+         public Thread newThread(final Runnable command) {
+           DistributionManager.this.stats.incSerialThreadStarts();
+           final Runnable r = new Runnable() {
+             public void run() {
+               DistributionManager.this.stats.incNumSerialThreads(1);
+               try {
+               ConnectionTable.threadWantsSharedResources();
+               Connection.makeReaderThread();
+               runUntilShutdown(command);
+               // command.run();
+               } finally {
+                 ConnectionTable.releaseThreadsSockets();
+                 DistributionManager.this.stats.incNumSerialThreads(-1);
+               }
+             }
+           };
+           Thread thread = new Thread(group, r, LocalizedStrings.DistributionManager_SERIAL_MESSAGE_PROCESSOR.toLocalizedString());
+           thread.setDaemon(true);
+           return thread;
+         }
+       };
+       SerialQueuedExecutorWithDMStats executor = new SerialQueuedExecutorWithDMStats(poolQueue, 
+           this.stats.getSerialProcessorHelper(), tf);
+       this.serialThread = executor;
+     }
+     {
+       BlockingQueue q = new LinkedBlockingQueue();
+       ThreadFactory tf = new ThreadFactory() {
+           public Thread newThread(final Runnable command) {
+             DistributionManager.this.stats.incViewThreadStarts();
+             final Runnable r = new Runnable() {
+                 public void run() {
+                   DistributionManager.this.stats.incNumViewThreads(1);
+                   try {
+                     ConnectionTable.threadWantsSharedResources();
+                     Connection.makeReaderThread();
+                     runUntilShutdown(command);
+                   } finally {
+                     ConnectionTable.releaseThreadsSockets();
+                     DistributionManager.this.stats.incNumViewThreads(-1);
+                   }
+                 }
+               };
+             Thread thread = new Thread(group, r, LocalizedStrings.DistributionManager_VIEW_MESSAGE_PROCESSOR.toLocalizedString());
+             thread.setDaemon(true);
+             return thread;
+           }
+         };
+       this.viewThread = new SerialQueuedExecutorWithDMStats(q, 
+           this.stats.getViewProcessorHelper(), tf);
+     }
+ 
+     {
+       BlockingQueue poolQueue;
+       if (INCOMING_QUEUE_LIMIT == 0) {
+         poolQueue = new OverflowQueueWithDMStats(this.stats.getOverflowQueueHelper());
+       } else {
+         poolQueue = new OverflowQueueWithDMStats(INCOMING_QUEUE_LIMIT, this.stats.getOverflowQueueHelper());
+       }
+       ThreadFactory tf = new ThreadFactory() {
+           private int next = 0;
+ 
+           public Thread newThread(final Runnable command) {
+             DistributionManager.this.stats.incProcessingThreadStarts();
+             final Runnable r = new Runnable() {
+                 public void run() {
+                   DistributionManager.this.stats.incNumProcessingThreads(1);
+                   try {
+                   ConnectionTable.threadWantsSharedResources();
+                   Connection.makeReaderThread();
+                   runUntilShutdown(command);
+                   } finally {
+                     ConnectionTable.releaseThreadsSockets();
+                     DistributionManager.this.stats.incNumProcessingThreads(-1);
+                   }
+                 }
+               };
+             Thread thread = new Thread(group, r, 
+                LocalizedStrings.DistributionManager_POOLED_MESSAGE_PROCESSOR.toLocalizedString() + (next++));
+             thread.setDaemon(true);
+             return thread;
+           }
+         };
+       ThreadPoolExecutor pool =
+         new PooledExecutorWithDMStats(poolQueue, MAX_THREADS, this.stats.getNormalPoolHelper(), tf);
+       this.threadPool = pool;
+     }
+ 
+ 
+     {
+       BlockingQueue poolQueue;
+       if (INCOMING_QUEUE_LIMIT == 0) {
+         poolQueue = new OverflowQueueWithDMStats(this.stats.getHighPriorityQueueHelper());
+       } else {
+         poolQueue = new OverflowQueueWithDMStats(INCOMING_QUEUE_LIMIT, this.stats.getHighPriorityQueueHelper());
+       }
+       ThreadFactory tf = new ThreadFactory() {
+           private int next = 0;
+ 
+           public Thread newThread(final Runnable command) {
+             DistributionManager.this.stats.incHighPriorityThreadStarts();
+             final Runnable r = new Runnable() {
+                 public void run() {
+                   DistributionManager.this.stats.incHighPriorityThreads(1);
+                   try {
+                     ConnectionTable.threadWantsSharedResources();
+                     Connection.makeReaderThread();
+                     runUntilShutdown(command);
+                   } finally {
+                     ConnectionTable.releaseThreadsSockets();
+                     DistributionManager.this.stats.incHighPriorityThreads(-1);
+                   }
+                 }
+               };
+             Thread thread = new Thread(group, r, 
+                 LocalizedStrings.DistributionManager_POOLED_HIGH_PRIORITY_MESSAGE_PROCESSOR.toLocalizedString() + (next++));
+             thread.setDaemon(true);
+             return thread;
+           }
+         };
+       this.highPriorityPool = new PooledExecutorWithDMStats(poolQueue, MAX_THREADS, this.stats.getHighPriorityPoolHelper(), tf);
+     }
+ 
+ 
+     {
+       ThreadFactory tf = new ThreadFactory() {
+           private int next = 0;
+ 
+           public Thread newThread(final Runnable command) {
+             DistributionManager.this.stats.incWaitingThreadStarts();
+             final Runnable r = new Runnable() {
+                 public void run() {
+                   DistributionManager.this.stats.incWaitingThreads(1);
+                   try {
+                   ConnectionTable.threadWantsSharedResources();
+                   Connection.makeReaderThread();
+                   runUntilShutdown(command);
+                   } finally {
+                    ConnectionTable.releaseThreadsSockets();
+                    DistributionManager.this.stats.incWaitingThreads(-1);
+                   }
+                 }
+               };
+             Thread thread = new Thread(group, r, 
+                                        LocalizedStrings.DistributionManager_POOLED_WAITING_MESSAGE_PROCESSOR.toLocalizedString() + (next++));
+             thread.setDaemon(true);
+             return thread;
+           }
+         };
+       BlockingQueue poolQueue;
+       if (MAX_WAITING_THREADS == Integer.MAX_VALUE) {
+         // no need for a queue since we have infinite threads
+         poolQueue = new SynchronousQueue();
+       } else {
+         poolQueue = new OverflowQueueWithDMStats(this.stats.getWaitingQueueHelper());
+       }
+       this.waitingPool = new PooledExecutorWithDMStats(poolQueue,
+                                                        MAX_WAITING_THREADS,
+                                                        this.stats.getWaitingPoolHelper(),
+                                                        tf);
+     }
+     
+     {
+       ThreadFactory tf = new ThreadFactory() {
+           private int next = 0;
+ 
+           public Thread newThread(final Runnable command) {
+             DistributionManager.this.stats.incWaitingThreadStarts();//will it be ok?
+             final Runnable r = new Runnable() {
+                 public void run() {
+                   DistributionManager.this.stats.incWaitingThreads(1);//will it be ok
+                   try {
+                   ConnectionTable.threadWantsSharedResources();
+                   Connection.makeReaderThread();
+                   runUntilShutdown(command);
+                   } finally {
+                    ConnectionTable.releaseThreadsSockets();
+                    DistributionManager.this.stats.incWaitingThreads(-1);
+                   }
+                 }
+               };
+             Thread thread = new Thread(group, r, 
+                                        LocalizedStrings.DistributionManager_PR_META_DATA_CLEANUP_MESSAGE_PROCESSOR.toLocalizedString() + (next++));
+             thread.setDaemon(true);
+             return thread;
+           }
+         };
+       BlockingQueue poolQueue;
+       poolQueue = new OverflowQueueWithDMStats(this.stats.getWaitingQueueHelper());
+       this.prMetaDataCleanupThreadPool = new PooledExecutorWithDMStats(poolQueue,
+                                                         MAX_PR_META_DATA_CLEANUP_THREADS,
+                                                        this.stats.getWaitingPoolHelper(),
+                                                        tf);
+     }
+ 
+     {
+       BlockingQueue poolQueue;
+       if (INCOMING_QUEUE_LIMIT == 0) {
+         poolQueue = new OverflowQueueWithDMStats(this.stats.getPartitionedRegionQueueHelper());
+       } else {
+         poolQueue = new OverflowQueueWithDMStats(INCOMING_QUEUE_LIMIT, this.stats.getPartitionedRegionQueueHelper());
+       }
+       ThreadFactory tf = new ThreadFactory() {
+         private int next = 0;
+ 
+         public Thread newThread(final Runnable command) {
+           DistributionManager.this.stats.incPartitionedRegionThreadStarts();
+           final Runnable r = new Runnable() {
+               public void run() {
+                 stats.incPartitionedRegionThreads(1);
+                 try {
+                   ConnectionTable.threadWantsSharedResources();
+                   Connection.makeReaderThread();
+                   runUntilShutdown(command);
+                 } finally {
+                   ConnectionTable.releaseThreadsSockets();
+                   stats.incPartitionedRegionThreads(-1);
+                 }
+               }
+             };
+           Thread thread = new Thread(group, r, 
+                                      "PartitionedRegion Message Processor" + (next++));
+           thread.setDaemon(true);
+           return thread;
+         }
+       };
+       if (MAX_PR_THREADS > 1) {
+         this.partitionedRegionPool = new PooledExecutorWithDMStats(poolQueue, 
+             MAX_PR_THREADS, this.stats.getPartitionedRegionPoolHelper(), tf);
+       } else {
+         SerialQueuedExecutorWithDMStats executor = new SerialQueuedExecutorWithDMStats(poolQueue, 
+             this.stats.getPartitionedRegionPoolHelper(), tf);
+         this.partitionedRegionThread = executor;
+       }
+       
+     }
+ 
+     {
+       BlockingQueue poolQueue;
+       if (INCOMING_QUEUE_LIMIT == 0) {
+         poolQueue = new OverflowQueueWithDMStats(this.stats.getFunctionExecutionQueueHelper());
+       } else {
+         poolQueue = new OverflowQueueWithDMStats(INCOMING_QUEUE_LIMIT, this.stats.getFunctionExecutionQueueHelper());
+       }
+       ThreadFactory tf = new ThreadFactory() {
+         private int next = 0;
+ 
+         public Thread newThread(final Runnable command) {
+           DistributionManager.this.stats.incFunctionExecutionThreadStarts();
+           final Runnable r = new Runnable() {
+               public void run() {
+                 stats.incFunctionExecutionThreads(1);
+                 isFunctionExecutionThread.set(Boolean.TRUE);
+                 try {
+                   ConnectionTable.threadWantsSharedResources();
+                   Connection.makeReaderThread();
+                   runUntilShutdown(command);
+                 } finally {
+                   ConnectionTable.releaseThreadsSockets();
+                   stats.incFunctionExecutionThreads(-1);
+                 }
+               }
+             };
+           Thread thread = new Thread(group, r, 
+                                      "Function Execution Processor" + (next++));
+           thread.setDaemon(true);
+           return thread;
+         }
+       };
+       
+       if(MAX_FE_THREADS > 1){
+         this.functionExecutionPool = new FunctionExecutionPooledExecutor(poolQueue, 
+             MAX_FE_THREADS, this.stats.getFunctionExecutionPoolHelper(), tf,true /*for fn exec*/);
+       } else {
+         SerialQueuedExecutorWithDMStats executor = new SerialQueuedExecutorWithDMStats(poolQueue, 
+             this.stats.getFunctionExecutionPoolHelper(), tf);
+         this.functionExecutionThread = executor;
+       }
+     
+     }
+     
+     if (!SYNC_EVENTS) {
+       this.memberEventThread = new Thread(group, new MemberEventInvoker(), 
+           "DM-MemberEventInvoker");
+       this.memberEventThread.setDaemon(true);
+     }
+ 
+     StringBuffer sb = new StringBuffer(" (took ");
+ 
+    long start = System.currentTimeMillis();
+     
+     // Create direct channel first
+ //    DirectChannel dc = new DirectChannel(new MyListener(this), system.getConfig(), logger, null);
+ //    setDirectChannelPort(dc.getPort()); // store in a thread local
+ 
+     // connect to JGroups
+     start = System.currentTimeMillis();
+     
+     MyListener l = new MyListener(this);
+     membershipManager = MemberFactory.newMembershipManager(l, system.getConfig(), transport, stats);
+ 
+     sb.append(System.currentTimeMillis() - start);
+ 
+     this.myid = membershipManager.getLocalMember();
+ 
+ //    dc.patchUpAddress(this.myid);
+ //    id.setDirectChannelPort(dc.getPort());
+ 
+     // create the distribution channel
+     this.channel = new DistributionChannel(membershipManager);
+ 
+     membershipManager.postConnect();
+     
+     //Assert.assertTrue(this.getChannelMap().size() >= 1);
+     //       System.out.println("Channel Map:");
+     //       for (Iterator iter = this.getChannelMap().entrySet().iterator();
+     //            iter.hasNext(); ) {
+     //         Map.Entry entry = (Map.Entry) iter.next();
+     //         Object key = entry.getKey();
+     //         System.out.println("  " + key + " a " +
+     //                            key.getClass().getName() + " -> " +
+     //                            entry.getValue());
+     //       }
+ 
+     sb.append(" ms)");
+ 
+     logger.info(LocalizedMessage.create(LocalizedStrings.DistributionManager_STARTING_DISTRIBUTIONMANAGER_0_1,
+         new Object[] { this.myid, (logger.isInfoEnabled(LogMarker.DM) ? sb.toString() : "")}));
+ 
+     this.description = NAME + " on " + this.myid + " started at "
+       + (new Date(System.currentTimeMillis())).toString();
+ 
+     finishedConstructor = true;
+     } finally {
+       if (!finishedConstructor) {
+         askThreadsToStop(); // fix for bug 42039
+       }
+     }
+   }
+ 
+   /**
+    * Creates a new distribution manager
+    *
+    * @param system
+    *        The distributed system to which this distribution manager
+    *        will send messages.
+    */
+   private DistributionManager(
+     InternalDistributedSystem system,
+     RemoteTransportConfig transport)
+   {
+     this(transport, system);
+ 
+     boolean finishedConstructor = false;
+     try {
+ 
+     isStartupThread.set(Boolean.TRUE);
+     
+     startThreads();
+     
+     // Since we need a StartupResponseMessage to make sure licenses
+     // are compatible the following has been deadcoded.
+ //     // For the time being, invoke processStartupResponse()
+ //     String rejectionMessage = null;
+ //     if (GemFireVersion.getGemFireVersion().
+ //         equals(state.getGemFireVersion())) {
+ //       rejectionMessage = "Rejected new system node " +
+ //         this.getDistributionManagerId() + " with version \"" +
+ //         GemFireVersion.getGemFireVersion() +
+ //         "\" because the distributed system's version is \"" +
+ //         state.getGemFireVersion() + "\".";
+ //     }
+ //     this.processStartupResponse(state.getCacheTime(),
+ //                         rejectionMessage);
+ 
+     // Allow events to start being processed.
+     membershipManager.startEventProcessing();
+     for (;;) {
+       this.getCancelCriterion().checkCancelInProgress(null);
+       boolean interrupted = Thread.interrupted();
+       try {
+         membershipManager.waitForEventProcessing();
+         break;
+       }
+       catch (InterruptedException e) {
+         interrupted = true;
+       }
+       finally {
+         if (interrupted) {
+           Thread.currentThread().interrupt();
+         }
+       }
+     }
+     
+     synchronized (DistributionManager.class) {
+       openDMs++;
+     }
+     finishedConstructor = true;
+     } finally {
+       if (!finishedConstructor) {
+         askThreadsToStop(); // fix for bug 42039
+       }
+     }
+   }
+ 
+   ////////////////////  Instance Methods  /////////////////////
+ 
+   /**
+    * Returns true if the two members are on the same equivalent host based 
+    * on overlapping IP addresses collected for all NICs during exchange of
+    * startup messages.
+    * 
+    * @param member1 First member
+    * @param member2 Second member
+    */
+   public boolean areOnEquivalentHost(InternalDistributedMember member1,
+                                      InternalDistributedMember member2) {
+     Set<InetAddress> equivalents1 = getEquivalents(member1.getInetAddress());
+     return equivalents1.contains(member2.getInetAddress());
+   }
+   
+   /**
+    * Set the host equivalencies for a given host.  This overrides any
+    * previous information in the tables.
+    * @param equivs list of InetAddress's that all point at same host
+    */
+   public void setEquivalentHosts(Set<InetAddress> equivs) {
+     Iterator<InetAddress> it = equivs.iterator();
+     synchronized (equivalentHosts) {
+      while (it.hasNext()) {
+        equivalentHosts.put(it.next(), Collections.unmodifiableSet(equivs));
+      }
+     }
+   }
+   
+   public HashMap<InetAddress, Set<InetAddress>> getEquivalentHostsSnapshot() {
+     synchronized (this.equivalentHosts) {
+       return new HashMap<InetAddress, Set<InetAddress>>(this.equivalentHosts);
+     }
+   }
+   
+   /**
+    * Return all of the InetAddress's that are equivalent to the given one (same
+    * host)
+    * @param in host to match up
+    * @return all the addresses thus equivalent
+    */
+   public Set<InetAddress> getEquivalents(InetAddress in) {
+     Set<InetAddress> result;
+     synchronized (equivalentHosts) {
+       result = equivalentHosts.get(in);
+     }
+     //DS 11/25/08 - It appears that when using VPN, the distributed member
+     //id is the vpn address, but that doesn't show up in the equivalents.
+     if(result == null) {
+       result = Collections.singleton(in);
+     }
+     return result;
+   }
+   
+   public void setRedundancyZone(InternalDistributedMember member, String redundancyZone) {
+     if(redundancyZone != null && !redundancyZone.equals("")) {
+       this.redundancyZones.put(member, redundancyZone);
+     }
+     if (member != getDistributionManagerId()) {
+       String relationship = areInSameZone(getDistributionManagerId(), member) ? ""
+           : "not ";
+       Object[] logArgs = new Object[] { member, relationship };
+       logger.info(LocalizedMessage.create(LocalizedStrings.DistributionManager_DISTRIBUTIONMANAGER_MEMBER_0_IS_1_EQUIVALENT, logArgs));
+     }
+   }
+ 
+   /**
+    * Set the flag indicating that we should enforce unique zones.
+    * If we are already enforcing unique zones, keep it that way.
+    */
+   public void setEnforceUniqueZone(boolean enforceUniqueZone) {
+     this.enforceUniqueZone |= enforceUniqueZone;
+   }
+   
+   public boolean enforceUniqueZone() {
+     return enforceUniqueZone;
+   }
+   
+   public String getRedundancyZone(InternalDistributedMember member) {
+     return redundancyZones.get(member);
+   }
+   
+   /**
+    * Asserts that distributionManagerType is LOCAL, GEMFIRE, or
+    * ADMIN_ONLY.  Also asserts that the distributionManagerId
+    * (jgroups DistributedMember) has a VmKind that matches.
+    */
+   private void assertDistributionManagerType() {
+     // Assert that dmType is one of the three DM types...
+     int theDmType = getDMType();
+     switch (theDmType) {
+     case NORMAL_DM_TYPE:
+     case LONER_DM_TYPE:
+     case ADMIN_ONLY_DM_TYPE:
+     case LOCATOR_DM_TYPE:
+       break;
+     default:
+       Assert.assertTrue(false, "unknown distribution manager type");
+     }
+     
+     // Assert InternalDistributedMember VmKind matches this DistributionManagerType...
+     final InternalDistributedMember theId = getDistributionManagerId();
+     final int vmKind = theId.getVmKind();
+     if (theDmType != vmKind) {
+       Assert.assertTrue(false, 
+           "InternalDistributedMember has a vmKind of " + vmKind + 
+           " instead of " + theDmType);
+     }
+   }
+ 
+   public int getDMType() {
+     return this.dmType;
+   }
+   
+   public List<InternalDistributedMember> getViewMembers() {
+     NetView result = null;
+     DistributionChannel ch = this.channel;
+     if (ch != null) {
+       MembershipManager mgr = ch.getMembershipManager();
+       if (mgr != null) {
+         result = mgr.getView();
+         }
+     }
+     if (result == null) {
+       result = new NetView();
+     }
+     return result.getMembers();
+   }
+   /* implementation of DM.getOldestMember */
+   public DistributedMember getOldestMember(Collection c) throws NoSuchElementException {
+     List<InternalDistributedMember> view = getViewMembers();
+     for (int i=0; i<view.size(); i++) {
+       Object viewMbr = view.get(i);
+       Iterator it = c.iterator();
+       while (it.hasNext()) {
+         Object nextMbr = it.next();
+         if (viewMbr.equals(nextMbr)) {
+           return (DistributedMember)nextMbr;
+         }
+       }
+     }
+     throw new NoSuchElementException(LocalizedStrings.DistributionManager_NONE_OF_THE_GIVEN_MANAGERS_IS_IN_THE_CURRENT_MEMBERSHIP_VIEW.toLocalizedString());
+   }
+   
+   private boolean testMulticast() {
+     return this.membershipManager.testMulticast();
+   }
+ 
+   /**
+    * Print a membership view (list of {@link InternalDistributedMember}s)
+    * 
+    * @param v the list
+    * @return String
+    */
+   static public String printView(NetView v) {
+     if (v == null)
+       return "null";
+     
+     return v.toString();
+   }
+ 
+   /**
+    * Need to do this outside the constructor so that the child
+    * constructor can finish.
+    */
+   protected void startThreads() {
+     this.system.setDM(this); // fix for bug 33362
+     if (this.memberEventThread != null)
+       this.memberEventThread.start();
+     try {
+       
+       // And the distinguished guests today are...
+       NetView v = membershipManager.getView();
+       logger.info(LocalizedMessage.create(LocalizedStrings.DistributionManager_INITIAL_MEMBERSHIPMANAGER_VIEW___0, printView(v)));
+       
+       // Add them all to our view
+       Iterator<InternalDistributedMember> it = v.getMembers().iterator();
+       while (it.hasNext()) {
+         addNewMember(it.next());
+       }
+       
+       // Figure out who the elder is...
+       selectElder(); // ShutdownException could be thrown here
+     } catch (Exception ex) {
+       throw new InternalGemFireException(LocalizedStrings.DistributionManager_COULD_NOT_PROCESS_INITIAL_VIEW.toLocalizedString(), ex);
+     }
+     try {
+       getWaitingThreadPool().execute(new Runnable() {
+           public void run() {
+             // call in background since it might need to send a reply
+             // and we are not ready to send messages until startup is finished
+             isStartupThread.set(Boolean.TRUE);
+             readyForMessages();
+           }
+         });
+     }
+     catch (VirtualMachineError err) {
+       SystemFailure.initiateFailure(err);
+       // If this ever returns, rethrow the error.  We're poisoned
+       // now, so don't let this thread continue.
+       throw err;
+     }
+     catch (Throwable t) {
+       // Whenever you catch Error or Throwable, you must also
+       // catch VirtualMachineError (see above).  However, there is
+       // _still_ a possibility that you are dealing with a cascading
+       // error condition, so you also need to check to see if the JVM
+       // is still usable:
+       SystemFailure.checkFailure();
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributionManager_UNCAUGHT_EXCEPTION_CALLING_READYFORMESSAGES), t);
+     }
+   }
+ 
+   protected void readyForMessages() {
+     synchronized (this) {
+       this.readyForMessages = true;
+       this.notifyAll();
+     }
+     membershipManager.startEventProcessing();
+   }
+   
+   protected void waitUntilReadyForMessages() {
+     if (readyForMessages)
+       return;
+ //    membershipManager.waitForEventProcessing();
+     synchronized (this) {
+       for (;;) {
+         if (readyForMessages)
+           break;
+         stopper.checkCancelInProgress(null);
+         boolean interrupted = Thread.interrupted();
+         try {
+           this.wait();
+         }
+         catch (InterruptedException e) {
+           interrupted = true;
+           stopper.checkCancelInProgress(e);
+         }
+         finally {
+           if (interrupted) {
+             Thread.currentThread().interrupt();
+           }
+         }
+       } // for
+     } // synchronized
+   }
+ 
+   /**
+    * Call when the DM is ready to send messages.
+    */
+   private void readyToSendMsgs() {
+     synchronized (this.readyToSendMsgsLock) {
+       this.readyToSendMsgs = true;
+       this.readyToSendMsgsLock.notifyAll();
+     }
+   }
+   /**
+    * Return when DM is ready to send out messages.
+    * @param msg the messsage that is currently being sent
+    */
+   protected void waitUntilReadyToSendMsgs(DistributionMessage msg) {
+     if (this.readyToSendMsgs) {
+       return;
+     }
+     // another process may have been started in the same view, so we need
+     // to be responsive to startup messages and be able to send responses
+     if (msg instanceof StartupMessage || msg instanceof StartupResponseMessage
+         || msg instanceof AdminMessageType) {
+       return;
+     }
+     if (isStartupThread.get() != null) {
+       // let the startup thread send messages
+       // the only case I know of that does this is if we happen to log a
+       // message during startup and an alert listener has registered.
+       return;
+     }
+ //    membershipManager.waitForEventProcessing();
+     synchronized (this.readyToSendMsgsLock) {
+       for (;;) {
+         if (this.readyToSendMsgs)
+           break;
+         stopper.checkCancelInProgress(null);
+         boolean interrupted = Thread.interrupted();
+         try {
+           this.readyToSendMsgsLock.wait();
+         }
+         catch (InterruptedException e) {
+           interrupted = true;
+           stopper.checkCancelInProgress(e);
+         }
+         finally {
+           if (interrupted) {
+             Thread.currentThread().interrupt();
+           }
+         }
+       } // for
+     } // synchronized
+   }
+   
+   // DM method
+   @Override
+   public void forceUDPMessagingForCurrentThread() {
+     membershipManager.forceUDPMessagingForCurrentThread();
+   }
+   
+   // DM method
+   @Override
+   public void releaseUDPMessagingForCurrentThread() {
+     membershipManager.releaseUDPMessagingForCurrentThread();
+   }
+ 
+   /**
+    * Did an exception occur in one of the threads launched by this
+    * distribution manager?
+    */
+   public boolean exceptionInThreads() {
+     return this.exceptionInThreads || this.threadGroup.getUncaughtExceptionsCount() > 0;
+   }
+ 
+   /**
+    * Clears the boolean that determines whether or not an exception
+    * occurred in one of the worker threads.  This method should be
+    * used for testing purposes only!
+    */
+   void clearExceptionInThreads() {
+     this.exceptionInThreads = false;
+     this.threadGroup.clearUncaughtExceptionsCount();
+   }
+ 
+   /**
+    * Returns the current "cache time" in milliseconds since the epoch.
+    * The "cache time" takes into account skew among the local clocks
+    * on the various machines involved in the cache.
+    */
+   public long cacheTimeMillis() {
+     return this.system.getClock().cacheTimeMillis();
+   }
+ 
+ 
+ 
+   /**
+    * Returns the id of this distribution manager.
+    */
+   public InternalDistributedMember getDistributionManagerId() {
+     return this.myid;
+   }
+ 
+   /**
+    * Returns an unmodifiable set containing the identities of all of
+    * the known (non-admin-only) distribution managers.
+    */
+   public Set getDistributionManagerIds() {
+     // access to members synchronized under membersLock in order to 
+     // ensure serialization
+     synchronized (this.membersLock) {
+       return this.members.keySet();
+     }
+   }
+   
+   /**
+    * Adds the entry in {@link #hostedLocatorsAll} for a member with one or more
+    * hosted locators. The value is a collection of host[port] strings. If a 
+    * bind-address was used for a locator then the form is bind-addr[port].
+    *
+    * @since 6.6.3
+    */
+   public void addHostedLocators(InternalDistributedMember member, Collection<String> locators, boolean isSharedConfigurationEnabled) {
+     synchronized (this.membersLock) {
+       if (locators == null || locators.isEmpty()) {
+         throw new IllegalArgumentException("Cannot use empty collection of locators");
+       }
+       if (this.hostedLocatorsAll.isEmpty()) {
+         this.hostedLocatorsAll = new HashMap<InternalDistributedMember, Collection<String>>();
+       }
+       
+       if (!this.isSharedConfigEnabledForDS) {
+         this.isSharedConfigEnabledForDS = isSharedConfigurationEnabled;
+       }
+       
+       Map<InternalDistributedMember, Collection<String>> tmp = 
+           new HashMap<InternalDistributedMember, Collection<String>>(this.hostedLocatorsAll);
+       tmp.remove(member);
+       tmp.put(member, locators);
+       tmp = Collections.unmodifiableMap(tmp);
+       this.hostedLocatorsAll = tmp;
+       
+       if (isSharedConfigurationEnabled) {
+         if (locators == null || locators.isEmpty()) {
+           throw new IllegalArgumentException("Cannot use empty collection of locators");
+         }
+         if (this.hostedLocatorsWithSharedConfiguration.isEmpty()) {
+           this.hostedLocatorsWithSharedConfiguration = new HashMap<InternalDistributedMember, Collection<String>>();
+         }
+         tmp = new HashMap<InternalDistributedMember, Collection<String>>(this.hostedLocatorsWithSharedConfiguration);
+         tmp.remove(member);
+         tmp.put(member, locators);
+         tmp = Collections.unmodifiableMap(tmp);
+         this.hostedLocatorsWithSharedConfiguration = tmp;
+       }
+ 
+     }
+   }
+   
+   
+   private void removeHostedLocators(InternalDistributedMember member) {
+     synchronized (this.membersLock) {
+       if (this.hostedLocatorsAll.containsKey(member)) {
+         Map<InternalDistributedMember, Collection<String>> tmp = 
+             new HashMap<InternalDistributedMember, Collection<String>>(this.hostedLocatorsAll);
+         tmp.remove(member);
+         if (tmp.isEmpty()) {
+           tmp = Collections.emptyMap();
+         } else {
+           tmp = Collections.unmodifiableMap(tmp);
+         }
+         this.hostedLocatorsAll = tmp;
+       }
+       if (this.hostedLocatorsWithSharedConfiguration.containsKey(member)) {
+         Map<InternalDistributedMember, Collection<String>> tmp = 
+             new HashMap<InternalDistributedMember, Collection<String>>(this.hostedLocatorsWithSharedConfiguration);
+         tmp.remove(member);
+         if (tmp.isEmpty()) {
+           tmp = Collections.emptyMap();
+         } else {
+           tmp = Collections.unmodifiableMap(tmp);
+         }
+         this.hostedLocatorsWithSharedConfiguration = tmp;
+       }
+     }
+   }
+   
+   
+   
+   /**
+    * Gets the value in {@link #hostedLocatorsAll} for a member with one or more
+    * hosted locators. The value is a collection of host[port] strings. If a 
+    * bind-address was used for a locator then the form is bind-addr[port].
+    * 
+    * @since 6.6.3
+    */
+   public Collection<String> getHostedLocators(InternalDistributedMember member) {
+     synchronized (this.membersLock) {
+       return this.hostedLocatorsAll.get(member);
+     }
+   }
+   
+   /**
+    * Returns a copy of the map of all members hosting locators. The key is the 
+    * member, and the value is a collection of host[port] strings. If a 
+    * bind-address was used for a locator then the form is bind-addr[port].
+    * 
+    * @since 6.6.3
+    */
+   public Map<InternalDistributedMember, Collection<String>> getAllHostedLocators() {
+     synchronized (this.membersLock) {
+       return this.hostedLocatorsAll;
+     }
+   }
+   /**
+    * Returns a copy of the map of all members hosting locators with shared configuration. The key is the 
+    * member, and the value is a collection of host[port] strings. If a 
+    * bind-address was used for a locator then the form is bind-addr[port].
+    * 
+    * @since 8.0
+    */
+   @Override
+   public Map<InternalDistributedMember, Collection<String>> getAllHostedLocatorsWithSharedConfiguration() {
+     synchronized (this.membersLock) {
+       return this.hostedLocatorsWithSharedConfiguration;
+     }
+   }
+   /**
+    * Returns an unmodifiable set containing the identities of all of
+    * the known (including admin) distribution managers.
+    */
+   public Set getDistributionManagerIdsIncludingAdmin() {
+     // access to members synchronized under membersLock in order to 
+     // ensure serialization
+     synchronized (this.membersLock) {
+       return this.membersAndAdmin;
+     }
+   }
+   
+ 
+   /**
+    * Returns the low-level distribution channel for this distribution
+    * manager. (brought over from ConsoleDistributionManager)
+    *
+    * @since 4.0
+    */
+   public DistributionChannel getDistributionChannel() {
+     return this.channel;
+   }
+ 
+ 
+   /**
+    * Returns a private-memory list containing the identities of all
+    * the other known distribution managers not including me.
+    */
+   public Set getOtherDistributionManagerIds() {
+     // We return a modified copy of the list, so
+     // collect the old list and copy under the lock.
+     Set result = new HashSet(getDistributionManagerIds());
+ 
+     InternalDistributedMember me = getDistributionManagerId();
+     result.remove(me);
+ 
+     // It's okay for my own id to not be in the list of all ids yet.
+     return result;
+   }
+   @Override
+   public Set getOtherNormalDistributionManagerIds() {
+     // We return a modified copy of the list, so
+     // collect the old list and copy under the lock.
+     Set result = new HashSet(getNormalDistributionManagerIds());
+ 
+     InternalDistributedMember me = getDistributionManagerId();
+     result.remove(me);
+ 
+     // It's okay for my own id to not be in the list of all ids yet.
+     return result;
+   }
+ 
+   public InternalDistributedMember getCanonicalId(DistributedMember id) {
+     // the members set is copy-on-write, so it is safe to iterate over it
+     InternalDistributedMember result = this.members.get(id);
+     if (result == null) {
+       return (InternalDistributedMember)id;
+     }
+     return result;
+   }
+ 
+   /**
+    * Add a membership listener and return other DistribtionManagerIds
+    * as an atomic operation
+    */
+   public Set addMembershipListenerAndGetDistributionManagerIds(MembershipListener l) {
+     // switched sync order to fix bug 30360
+     synchronized (this.membersLock) {
+       // Don't let the members come and go while we are adding this
+       // listener.  This ensures that the listener (probably a
+       // ReplyProcessor) gets a consistent view of the members.
+       addMembershipListener(l);
+       // Note it is ok to return the members set
+       // because we will never modify the returned set.
+       return members.keySet();
+     }
+   }
+ 
+   public void addNewMember(InternalDistributedMember member) {
+     // This is the place to cleanup the zombieMembers
+     int vmType = member.getVmKind();
+     switch (vmType) {
+       case ADMIN_ONLY_DM_TYPE:
+         handleConsoleStartup(member);
+         break;
+       case LOCATOR_DM_TYPE:
+       case NORMAL_DM_TYPE:
+         handleManagerStartup(member);
+         break;        
+       default:
+         throw new InternalGemFireError(LocalizedStrings.DistributionManager_UNKNOWN_MEMBER_TYPE_0.toLocalizedString(Integer.valueOf(vmType)));
+     }
+   }
+ 
+    /**
+    * Returns the identity of this <code>DistributionManager</code>
+    */
+   public InternalDistributedMember getId() {
+     return this.myid;
+   }
+ 
+   /**
+    * Returns the id of the underlying distribution channel used for
+    * communication.
+    *
+    * @since 3.0
+    */
+   public long getChannelId() {
+     return this.channel.getId();
+   }
+ 
+   /**
+    * Adds a message to the outgoing queue.  Note that
+    * <code>message</code> should not be modified after it has been
+    * added to the queue.  After <code>message</code> is distributed,
+    * it will be recycled.
+    *
+    * @return list of recipients who did not receive the message
+    * @throws NotSerializableException if the content is not serializable
+    */
+   public Set putOutgoingUserData(final DistributionMessage message) 
+       throws NotSerializableException {
+     return sendMessage(message); 
+   }
+ 
+   /**
+    * Send outgoing data; message is guaranteed to be serialized.
+    * @return list of recipients who did not receive the message
+    * @throws InternalGemFireException if message is not serializable
+    */
+   public Set putOutgoing(final DistributionMessage msg) {
+     try {
+       DistributionMessageObserver observer = DistributionMessageObserver.getInstance();
+       if(observer != null) {
+         observer.beforeSendMessage(this, msg);
+       }
+       return sendMessage(msg);
+     }
+     catch (NotSerializableException e) {
+       throw new InternalGemFireException(e);
+     }
+     catch (ToDataException e) {
+       // exception from user code
+       throw e;
+     }
+   }
+ 
+   @Override
+   public String toString() {
+     return this.description;
+   }
+ 
+   /**
+    * @see #closeInProgress
+    */
+   private final Object shutdownMutex = new Object();
+   
+   /**
+    * Informs other members that this dm is shutting down.
+    * Stops the pusher, puller, and processor threads and closes the
+    * connection to the transport layer.
+    */
+   protected void shutdown() {
+     // Make sure only one thread initiates shutdown...
+     synchronized (shutdownMutex) {
+       if (closeInProgress) {
+         return;
+       }
+       this.closeInProgress = true;
+     } // synchronized
+ 
+     // [bruce] log shutdown at info level and with ID to balance the
+     // "Starting" message.  recycleConn.conf is hard to debug w/o this
+     final String exceptionStatus = (this.exceptionInThreads() ? LocalizedStrings.DistributionManager_AT_LEAST_ONE_EXCEPTION_OCCURRED.toLocalizedString() : "");
+     logger.info(LocalizedMessage.create(
+         LocalizedStrings.DistributionManager_SHUTTING_DOWN_DISTRIBUTIONMANAGER_0_1,
+         new Object[] {this.myid, exceptionStatus}));
+ 
+     final long start = System.currentTimeMillis();
+     try {
+       if (this.rootCause instanceof ForcedDisconnectException) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("inhibiting sending of shutdown message to other members due to forced-disconnect");
+         }
+       } else {
+         // Don't block indefinitely trying to send the shutdown message, in
+         // case other VMs in the system are ill-behaved. (bug 34710)
+         final Runnable r = new Runnable() {
+           public void run() {
+             try {
+               ConnectionTable.threadWantsSharedResources();
+               sendShutdownMessage();
+             }
+             catch (final CancelException e) {
+               // We were terminated.
+               logger.debug("Cancelled during shutdown message", e);
+             }
+           }
+         };
+         final Thread t = new Thread(threadGroup,
+             r, LocalizedStrings.DistributionManager_SHUTDOWN_MESSAGE_THREAD_FOR_0.toLocalizedString(this.myid));
+         t.start();
+         boolean interrupted = Thread.interrupted();
+         try {
+           t.join(MAX_STOP_TIME);
+         }
+         catch (final InterruptedException e) {
+           interrupted = true;
+           t.interrupt();
+           logger.warn(LocalizedMessage.create(
+               LocalizedStrings.DistributionManager_INTERRUPTED_SENDING_SHUTDOWN_MESSAGE_TO_PEERS), e);
+         }
+         finally {
+           if (interrupted) {
+             Thread.currentThread().interrupt();
+           }
+         }
+ 
+         if (t.isAlive()) {
+           t.interrupt();
+           logger.warn(LocalizedMessage.create(LocalizedStrings.DistributionManager_FAILED_SENDING_SHUTDOWN_MESSAGE_TO_PEERS_TIMEOUT));
+         }
+       }
+       
+     }
+     finally {
+       this.shutdownMsgSent = true; // in case sendShutdownMessage failed....
+       try {
+         this.uncleanShutdown(false);
+       }
+       finally {
+         final Long delta = Long.valueOf(System.currentTimeMillis() - start);
+         logger.info(LocalizedMessage.create(
+           LocalizedStrings.DistributionManager_DISTRIBUTIONMANAGER_STOPPED_IN_0_MS, delta));
+       }
+     }
+   }
+   
+   private void askThreadsToStop() {
+     // Stop executors after they have finished
+     ExecutorService es;
+     es = this.serialThread;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.viewThread;
+     if (es != null) {
+       // Hmmm...OK, I'll let any view events currently in the queue be
+       // processed.  Not sure it's very important whether they get
+       // handled...
+       es.shutdown();
+     }
+     if (this.serialQueuedExecutorPool != null) {
+       this.serialQueuedExecutorPool.shutdown();
+     }
+     es = this.functionExecutionThread;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.functionExecutionPool;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.partitionedRegionThread;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.partitionedRegionPool;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.highPriorityPool;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.waitingPool;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.prMetaDataCleanupThreadPool;
+     if (es != null) {
+       es.shutdown();
+     }
+     es = this.threadPool;
+     if (es != null) {
+       es.shutdown();
+     }
+     
+     Thread th = this.memberEventThread;
+     if (th != null)
+       th.interrupt();
+   }
+   
+   private void waitForThreadsToStop(long timeInMillis) throws InterruptedException {
+     long start = System.currentTimeMillis();
+     long remaining = timeInMillis;
+     
+     ExecutorService[] allExecutors = new ExecutorService[] {
+         this.serialThread, 
+         this.viewThread, 
+         this.functionExecutionThread, 
+         this.functionExecutionPool,
+         this.partitionedRegionThread, 
+         this.partitionedRegionPool,
+         this.highPriorityPool,
+         this.waitingPool,
+         this.prMetaDataCleanupThreadPool,
+         this.threadPool};
+     for(ExecutorService es : allExecutors) { 
+       if (es != null) {
+         es.awaitTermination(remaining, TimeUnit.MILLISECONDS);
+       }
+       remaining = timeInMillis - (System.currentTimeMillis() - start);
+       if(remaining <= 0) {
+         return;
+       }
+     }
+     
+     
+     this.serialQueuedExecutorPool.awaitTermination(remaining, TimeUnit.MILLISECONDS);
+     remaining = timeInMillis - (System.currentTimeMillis() - start);
+     if(remaining <= 0) {
+       return;
+     }
+     Thread th = this.memberEventThread;
+     if (th != null) {
+       th.interrupt(); // bug #43452 - this thread sometimes eats interrupts, so we interrupt it again here
+       th.join(remaining);
+     }
+     
+   }
+   
+   /**
+    * maximum time, in milliseconds, to wait for all threads to exit
+    */
+   static private final int MAX_STOP_TIME = 20000;
+   
+   /**
+    * Time to sleep, in milliseconds, while polling to see if threads have 
+    * finished
+    */
+   static private final int STOP_PAUSE_TIME = 1000;
+   
+   /**
+    * Maximum number of interrupt attempts to stop a thread
+    */
+   static private final int MAX_STOP_ATTEMPTS = 10;
+   
+   /**
+    * Cheap tool to kill a referenced thread
+    * 
+    * @param t the thread to kill
+    */
+   private void clobberThread(Thread t) {
+     if (t == null)
+       return;
+     if (t.isAlive()) {
+       logger.warn(LocalizedMessage.create(LocalizedStrings.DistributionManager_FORCING_THREAD_STOP_ON__0_, t));
+       
+       // Start by being nice.
+       t.interrupt();
+       
+ // we could be more violent here...
+ //      t.stop();
+       try {
+         for (int i = 0; i < MAX_STOP_ATTEMPTS && t.isAlive(); i++) {
+           t.join(STOP_PAUSE_TIME);
+           t.interrupt();
+         }
+       }
+       catch (InterruptedException ex) {
+         logger.debug("Interrupted while attempting to terminate threads.");
+         Thread.currentThread().interrupt();
+         // just keep going
+       }
+       
+       if (t.isAlive()) {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.DistributionManager_CLOBBERTHREAD_THREAD_REFUSED_TO_DIE__0, t));
+       }
+     }
+   }
+   
+   /**
+    * Cheap tool to examine an executor to see if it is still working
+    * @param tpe
+    * @return true if executor is still active
+    */
+   private boolean executorAlive(ThreadPoolExecutor tpe, String name)
+   {
+     if (tpe == null) {
+       return false;
+     } else {
+       int ac = tpe.getActiveCount();
+ //      boolean result = tpe.getActiveCount() > 0;
+       if (ac > 0) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("Still waiting for {} threads in '{}' pool to exit", ac, name);
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }
+   }
+   
+   /**
+    * Wait for the ancillary queues to exit.  Kills them if they are
+    * still around.
+    *
+    */
+   private void forceThreadsToStop() {
+     long endTime = System.currentTimeMillis() + MAX_STOP_TIME;
+     String culprits = "";
+     for (;;) {
+       boolean stillAlive = false;
+       culprits = "";
+       if (executorAlive(this.serialThread, "serial thread")) {
+         stillAlive = true;
+         culprits = culprits + " serial thread;";
+       }
+       if (executorAlive(this.viewThread, "view thread")) {
+         stillAlive = true;
+         culprits = culprits + " view thread;";
+       }
+       if (executorAlive(this.partitionedRegionThread, "partitioned region thread")) {
+         stillAlive = true;
+         culprits = culprits + " partitioned region thread;";
+       }
+       if (executorAlive(this.partitionedRegionPool, "partitioned region pool")) {
+         stillAlive = true;
+         culprits = culprits + " partitioned region pool;";
+       }
+       if (executorAlive(this.highPriorityPool, "high priority pool")) {
+         stillAlive = true;
+         culprits = culprits + " high priority pool;";
+       }
+       if (executorAlive(this.waitingPool, "waiting pool")) {
+         stillAlive = true;
+         culprits = culprits + " waiting pool;";
+       }
+       if (executorAlive(this.prMetaDataCleanupThreadPool, "prMetaDataCleanupThreadPool")) {
+         stillAlive = true;
+         culprits = culprits + " special waiting pool;";
+       }
+       if (executorAlive(this.threadPool, "thread pool")) {
+         stillAlive = true;
+         culprits = culprits + " thread pool;";
+       }
+       
+       if (!stillAlive)
+         return;
+       
+       long now = System.currentTimeMillis();
+       if (now >= endTime)
+         break;
+       
+       try {
+         Thread.sleep(STOP_PAUSE_TIME);
+       }
+       catch (InterruptedException e) {
+         Thread.currentThread().interrupt();
+         // Desperation, the shutdown thread is being killed.  Don't
+         // consult a CancelCriterion.
+         logger.warn(LocalizedMessage.create(
+             LocalizedStrings.DistributionManager_INTERRUPTED_DURING_SHUTDOWN), e); 
+         break;
+       }
+     } // for
+     
+     logger.warn(LocalizedMessage.create(
+         LocalizedStrings.DistributionManager_DAEMON_THREADS_ARE_SLOW_TO_STOP_CULPRITS_INCLUDE_0, culprits));
+     
+     // Kill with no mercy
+     if (this.serialThread != null) {
+       this.serialThread.shutdownNow();
+     }
+     if (this.viewThread != null) {
+       this.viewThread.shutdownNow();
+     }    
+     if (this.functionExecutionThread != null) {
+       this.functionExecutionThread.shutdownNow();
+     }
+     if (this.functionExecutionPool != null) {
+       this.functionExecutionPool.shutdownNow();
+     }
+     if (this.partitionedRegionThread != null) {
+       this.partitionedRegionThread.shutdownNow();
+     }
+     if (this.partitionedRegionPool != null) {
+       this.partitionedRegionPool.shutdownNow();
+     }
+     if (this.highPriorityPool != null) {
+       this.highPriorityPool.shutdownNow();
+     }
+     if (this.waitingPool != null) {
+       this.waitingPool.shutdownNow();
+     }
+     if (this.prMetaDataCleanupThreadPool != null) {
+       this.prMetaDataCleanupThreadPool.shutdownNow();
+     }
+     if (this.threadPool != null) {
+       this.threadPool.shutdownNow();
+     }
+     
+     Thread th = this.memberEventThread;
+     if (th != null) {
+       clobberThread(th);
+     }
+   }
+   
+   private volatile boolean shutdownInProgress = false;
+ 
+   /** guard for membershipViewIdAcknowledged */
+   private final Object membershipViewIdGuard = new Object();
+   
+   /** the latest view ID that has been processed by all membership listeners */
+   private long membershipViewIdAcknowledged;
+   
+   public boolean shutdownInProgress() {
+     return this.shutdownInProgress;
+   }
+   
+   /**
+    * Stops the pusher, puller and processor threads and closes the
+    * connection to the transport layer.  This should only be used from
+    * shutdown() or from the dm initialization code
+    */
+   private void uncleanShutdown(boolean duringStartup)
+   {
+     try {
+       this.closeInProgress = true; // set here also to fix bug 36736
+       removeAllHealthMonitors();
+       shutdownInProgress = true;
+       if (this.channel != null) {
+         this.channel.setShutDown();
+       }
+       
+       askThreadsToStop();
+ 
+       // wait a moment before asking threads to terminate
+       try { waitForThreadsToStop(1000); } 
+       catch (InterruptedException ie) {
+         // No need to reset interrupt bit, we're really trying to quit...
+       }
+       forceThreadsToStop();
+       
+ //      // bug36329: desperation measure, send a second interrupt?
+ //      try { Thread.sleep(1000); } 
+ //      catch (InterruptedException ie) {
+ //        // No need to reset interrupt bit, we're really trying to quit...
+ //      }
+ //      forceThreadsToStop();
+     } // try
+     finally {
+       // ABSOLUTELY ESSENTIAL that we close the distribution channel!
+       try {
+         // For safety, but channel close in a finally AFTER this...
+         if (this.stats != null) {
+           this.stats.close();
+           try { Thread.sleep(100); } 
+           catch (InterruptedException ie) {
+             // No need to reset interrupt bit, we're really trying to quit...
+           }
+         }
+       }
+       finally {
+         if (this.channel != null) {
+           logger.info(LocalizedMessage.create(LocalizedStrings.DistributionManager_NOW_CLOSING_DISTRIBUTION_FOR__0, this.myid));
+           this.channel.disconnect(duringStartup);
+ //          this.channel = null;  DO NOT NULL OUT INSTANCE VARIABLES AT SHUTDOWN - bug #42087
+         }
+       }
+     }
+   }
+ 
+   /**
+    * Returns the distributed system to which this distribution manager
+    * is connected.
+    */
+   public InternalDistributedSystem getSystem() {
+     return this.system;
+   }
+   
+   /**
+    * Returns the transport configuration for this distribution manager
+    * @since 5.0
+    */
+   public RemoteTransportConfig getTransport() {
+     return this.transport;
+   }
+ 
+ 
+   /**
+    * Adds a <code>MembershipListener</code> to this distribution
+    * manager.
+    */
+   public void addMembershipListener(MembershipListener l) {
+     this.membershipListeners.putIfAbsent(l, Boolean.TRUE);
+   }
+ 
+   /**
+    * Removes a <code>MembershipListener</code> from this distribution
+    * manager.
+    *
+    * @throws IllegalArgumentException
+    *         <code>l</code> was not registered on this distribution
+    *         manager
+    */
+   public void removeMembershipListener(MembershipListener l) {
+     this.membershipListeners.remove(l);
+   }
+ 
+   /**
+    * Adds a <code>MembershipListener</code> to this distribution
+    * manager.
+    * @since 5.7
+    */
+   public void addAllMembershipListener(MembershipListener l) {
+     synchroniz

<TRUNCATED>


[029/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
index adaf400,0000000..69ae6d8
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
@@@ -1,3110 -1,0 +1,3112 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.DataInputStream;
 +import java.io.IOException;
 +import java.net.Socket;
 +import java.net.SocketException;
 +import java.nio.ByteBuffer;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.Date;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.ConcurrentLinkedQueue;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +import java.util.concurrent.atomic.AtomicInteger;
 +import java.util.concurrent.atomic.AtomicReference;
 +import java.util.concurrent.locks.Lock;
 +import java.util.concurrent.locks.ReadWriteLock;
 +import java.util.concurrent.locks.ReentrantReadWriteLock;
 +import java.util.regex.Pattern;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.StatisticsFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.ClientSession;
 +import com.gemstone.gemfire.cache.DynamicRegionFactory;
 +import com.gemstone.gemfire.cache.InterestRegistrationEvent;
 +import com.gemstone.gemfire.cache.InterestResultPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.RegionExistsException;
 +import com.gemstone.gemfire.cache.client.internal.RegisterInterestTracker;
 +import com.gemstone.gemfire.cache.operations.DestroyOperationContext;
 +import com.gemstone.gemfire.cache.operations.InvalidateOperationContext;
 +import com.gemstone.gemfire.cache.operations.OperationContext;
 +import com.gemstone.gemfire.cache.operations.PutOperationContext;
 +import com.gemstone.gemfire.cache.operations.RegionClearOperationContext;
 +import com.gemstone.gemfire.cache.operations.RegionCreateOperationContext;
 +import com.gemstone.gemfire.cache.operations.RegionDestroyOperationContext;
 +import com.gemstone.gemfire.cache.query.CqException;
 +import com.gemstone.gemfire.cache.query.CqQuery;
 +import com.gemstone.gemfire.cache.query.internal.cq.CqService;
 +import com.gemstone.gemfire.cache.query.internal.cq.InternalCqQuery;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.SystemTimer;
 +import com.gemstone.gemfire.internal.SystemTimer.SystemTimerTask;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.ClientServerObserver;
 +import com.gemstone.gemfire.internal.cache.ClientServerObserverHolder;
 +import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisee;
 +import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.InitialImageAdvice;
 +import com.gemstone.gemfire.internal.cache.Conflatable;
 +import com.gemstone.gemfire.internal.cache.DistributedRegion;
 +import com.gemstone.gemfire.internal.cache.EnumListenerEvent;
 +import com.gemstone.gemfire.internal.cache.EventID;
 +import com.gemstone.gemfire.internal.cache.FilterProfile;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.InterestRegistrationEventImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.StateFlushOperation;
 +import com.gemstone.gemfire.internal.cache.ha.HAContainerWrapper;
 +import com.gemstone.gemfire.internal.cache.ha.HARegionQueue;
 +import com.gemstone.gemfire.internal.cache.ha.HARegionQueueAttributes;
 +import com.gemstone.gemfire.internal.cache.ha.HARegionQueueStats;
 +import com.gemstone.gemfire.internal.cache.tier.InterestType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientUpdateMessageImpl.CqNameToOp;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.command.Get70;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +import com.gemstone.gemfire.internal.security.AuthorizeRequestPP;
 +import com.gemstone.gemfire.security.AccessControl;
 +import com.gemstone.gemfire.i18n.StringId;
 +
 +/**
 + * Class <code>CacheClientProxy</code> represents the server side of the
 + * {@link CacheClientUpdater}. It queues messages to be sent from the server to
 + * the client. It then reads those messages from the queue and sends them to the
 + * client.
 + *
 + * @author Barry Oglesby
 + *
 + * @since 4.2
 + */
 +@SuppressWarnings("synthetic-access")
 +public class CacheClientProxy implements ClientSession {
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  /**
 +   * The socket between the server and the client
 +   */
 +  protected Socket _socket;
 +  
 +  private final AtomicBoolean _socketClosed = new AtomicBoolean();
 +
 +  /**
 +   * A communication buffer used by each message we send to the client
 +   */
 +  protected ByteBuffer _commBuffer;
 +
 +  /**
 +   * The remote host's IP address string (cached for convenience)
 +   */
 +  protected String _remoteHostAddress;
 +
 +  /**
 +   * Concurrency: protected by synchronization of {@link #isMarkedForRemovalLock}
 +   */
 +  protected boolean isMarkedForRemoval = false;
 +  
 +  /**
 +   * @see #isMarkedForRemoval
 +   */
 +  protected final Object isMarkedForRemovalLock = new Object();
 +  
 +  /**
 +   * The proxy id of the client represented by this proxy
 +   */
 +  protected ClientProxyMembershipID proxyID;
 +
 +  /**
 +   * The GemFire cache
 +   */
 +  protected final GemFireCacheImpl _cache;
 +
 +  /**
 +   * The list of keys that the client represented by this proxy is interested in
 +   * (stored by region)
 +   */
 +  protected final ClientInterestList[] cils = new ClientInterestList[2];
 +  
 +  /**
 +   * A thread that dispatches messages to the client
 +   */
 +  protected volatile MessageDispatcher _messageDispatcher;
 +
 +  /**
 +   * The statistics for this proxy
 +   */
 +  protected final CacheClientProxyStats _statistics;
 +
 +  protected final AtomicReference _durableExpirationTask = new AtomicReference();
 +
 +  protected SystemTimer durableTimer;
 +
 +  /**
 +   * Whether this dispatcher is paused
 +   */
 +  protected volatile boolean _isPaused = true;
 +
 +  /**
 +   * True if we are connected to a client.
 +   */
 +  private volatile boolean connected = false;
 +//  /**
 +//   * A string representing interest in all keys
 +//   */
 +//  protected static final String ALL_KEYS = "ALL_KEYS";
 +//
 +  /**
 +   * True if a marker message is still in the ha queue.
 +   */
 +  private boolean markerEnqueued = false;
 +
 +  /**
 +   * The number of times to peek on shutdown before giving up and shutting down
 +   */
 +  protected static final int MAXIMUM_SHUTDOWN_PEEKS = Integer.getInteger("gemfire.MAXIMUM_SHUTDOWN_PEEKS",50).intValue();
 +
 +  /**
 +   * The number of milliseconds to wait for an offering to the message queue
 +   */
 +  protected static final int MESSAGE_OFFER_TIME = 0;
 +
 +  /**
 +   * The default maximum message queue size
 +   */
 +//   protected static final int MESSAGE_QUEUE_SIZE_DEFAULT = 230000;
 +
 +  /** The message queue size */
 +  protected final int _maximumMessageCount;
 +
 +  /**
 +   * The time (in seconds ) after which a message in the client queue will
 +   * expire.
 +   */
 +  protected final int _messageTimeToLive;
 +
 +  /**
 +   * The <code>CacheClientNotifier</code> registering this proxy.
 +   */
 +  protected final CacheClientNotifier _cacheClientNotifier;
 +
 +  /**
 +   * Defaults to true; meaning do some logging of dropped client notification
 +   * messages. Set the system property to true to cause dropped messages to NOT
 +   * be logged.
 +   */
 +  protected static final boolean LOG_DROPPED_MSGS = !Boolean
 +      .getBoolean("gemfire.disableNotificationWarnings");
 +
 +  /**
 +   * for testing purposes, delays the start of the dispatcher thread
 +   */
 +  public static boolean isSlowStartForTesting = false;
 +
 +  /**
 +   * Default value for slow starting time of dispatcher
 +   */
 +  private static final long DEFAULT_SLOW_STARTING_TIME = 5000;
 +
 +  /**
 +   * Key in the system property from which the slow starting time value will be
 +   * retrieved
 +   */
 +  private static final String KEY_SLOW_START_TIME_FOR_TESTING = "slowStartTimeForTesting";
 +
 +  private boolean isPrimary;
 +  
 +  /** @since 5.7 */
 +  protected byte clientConflation = HandShake.CONFLATION_DEFAULT;
 +  
 +  /**
 +   * Flag to indicate whether to keep a durable client's queue alive
 +   */
 +  boolean keepalive = false;
 +
 +  private AccessControl postAuthzCallback;
 +
 +  /**
 +   * For multiuser environment..
 +   */
 +  private ClientUserAuths clientUserAuths;
 +  
 +  private final Object clientUserAuthsLock = new Object();
 +  
 +  /**
 +   * The version of the client
 +   */
 +  private Version clientVersion;  
 +
 +  /**
 +   * A map of region name as key and integer as its value. Basically, it stores
 +   * the names of the regions with <code>DataPolicy</code> as EMPTY. If an 
 +   * event's region name is present in this map, it's full value (and not 
 +   * delta) is sent to the client represented by this proxy.
 +   *
 +   * @since 6.1
 +   */
 +  private volatile Map regionsWithEmptyDataPolicy = new HashMap();
 +
 +  /**
 +   * A debug flag used for testing Backward compatibility
 +   */
 +  public static boolean AFTER_MESSAGE_CREATION_FLAG = false;
 +  
 +  /**
 +   * Notify the region when a client interest registration occurs. This tells
 +   * the region to update access time when an update is to be pushed to a
 +   * client. It is enabled only for <code>PartitionedRegion</code>s
 +   * currently.
 +   */
 +  protected static final boolean NOTIFY_REGION_ON_INTEREST = Boolean
 +      .getBoolean("gemfire.updateAccessTimeOnClientInterest");   
 +  
 +  /**
 +   * The AcceptorImpl identifier to which the proxy is connected.
 +   */
 +  private final long _acceptorId;
 +  
 +  /** acceptor's setting for notifyBySubscription */
 +  private final boolean notifyBySubscription;
 +  
 +  /** To queue the events arriving during message dispatcher initialization */ 
 +  private volatile ConcurrentLinkedQueue<Conflatable> queuedEvents = new ConcurrentLinkedQueue<Conflatable>();
 +  
 +  private final Object queuedEventsSync = new Object();
 +  
 +  private volatile boolean messageDispatcherInit = false;
 +
 +  /**
 +   * A counter that keeps track of how many task iterations that have occurred
 +   * since the last ping or message. The
 +   * {@linkplain CacheClientNotifier#scheduleClientPingTask ping task}
 +   * increments it. Normal messages sent to the client reset it. If the counter
 +   * reaches 3, a ping is sent.
 +   */
 +  private final AtomicInteger pingCounter = new AtomicInteger();
 +  
 +  
 +  /** Date on which this instances was created */
 +  private Date creationDate;
 +
 +  /** true when the durable client associated with this proxy is being 
 +   * restarted and prevents cqs from being closed and drained**/
 +  private boolean drainLocked = false;
 +  private final Object drainLock = new Object();
 +
 +  /** number of cq drains that are currently in progress **/
 +  private int numDrainsInProgress = 0;
 +  private final Object drainsInProgressLock = new Object();
 +  
 +  /**
 +   * Constructor.
 +   *
 +   * @param ccn
 +   *          The <code>CacheClientNotifier</code> registering this proxy
 +   * @param socket
 +   *          The socket between the server and the client
 +   * @param proxyID
 +   *          representing the Connection Proxy of the clien
 +   * @param isPrimary
 +   *          The boolean stating whether this prozxy is primary
 +   * @throws CacheException {
 +   */
 +  protected CacheClientProxy(CacheClientNotifier ccn, Socket socket,
 +      ClientProxyMembershipID proxyID, boolean isPrimary, byte clientConflation, 
 +      Version clientVersion, long acceptorId, boolean notifyBySubscription)
 +      throws CacheException {
 +    initializeTransientFields(socket, proxyID, isPrimary, clientConflation, clientVersion);
 +    this._cacheClientNotifier = ccn;
 +    this._cache = (GemFireCacheImpl)ccn.getCache();
 +    this._maximumMessageCount = ccn.getMaximumMessageCount();    
 +    this._messageTimeToLive = ccn.getMessageTimeToLive();
 +    this._acceptorId = acceptorId;
 +    this.notifyBySubscription = notifyBySubscription;
 +    StatisticsFactory factory = this._cache.getDistributedSystem();
 +    this._statistics = new CacheClientProxyStats(factory, 
 +        "id_"+this.proxyID.getDistributedMember().getId()+ "_at_"+ this._remoteHostAddress + ":" + this._socket.getPort());
 +
 +    // Create the interest list
 +    this.cils[RegisterInterestTracker.interestListIndex] =
 +      new ClientInterestList(this, this.proxyID);
 +    // Create the durable interest list
 +    this.cils[RegisterInterestTracker.durableInterestListIndex] =
 +      new ClientInterestList(this, this.getDurableId());
 +    this.postAuthzCallback = null;
 +    this._cacheClientNotifier.getAcceptorStats().incCurrentQueueConnections();
 +    this.creationDate = new Date();
 +    initializeClientAuths();
 +  }
 +  
 +  private void initializeClientAuths()
 +  {
 +    if(AcceptorImpl.isPostAuthzCallbackPresent())
 +      this.clientUserAuths = ServerConnection.getClientUserAuths(this.proxyID);
 +  }
 +
 +  private void reinitializeClientAuths()
 +  {
 +    if (this.clientUserAuths != null && AcceptorImpl.isPostAuthzCallbackPresent()) {
 +      synchronized (this.clientUserAuthsLock) {
 +        ClientUserAuths newClientAuth = ServerConnection.getClientUserAuths(this.proxyID);
 +        newClientAuth.fillPreviousCQAuth(this.clientUserAuths);
 +        this.clientUserAuths = newClientAuth;
 +      }        
 +    }
 +  }
 +  
 +  public void setPostAuthzCallback(AccessControl authzCallback) {
 +    //TODO:hitesh synchronization
 +    synchronized (this.clientUserAuthsLock) {
 +      if (this.postAuthzCallback != null)
 +        this.postAuthzCallback.close();
 +      this.postAuthzCallback = authzCallback;
 +    }
 +  }
 +  
 +  public void setCQVsUserAuth(String cqName, long uniqueId, boolean isDurable)
 +  {
 +    if(postAuthzCallback == null) //only for multiuser
 +    {
 +      if(this.clientUserAuths != null)
 +        this.clientUserAuths.setUserAuthAttributesForCq(cqName, uniqueId, isDurable);
 +    }
 +  }
 +
 +  private void initializeTransientFields(Socket socket,
 +      ClientProxyMembershipID pid, boolean ip,  byte cc, Version vers) {
 +    this._socket = socket;
 +    this.proxyID = pid;
 +    this.connected = true;
 +    {
 +      int bufSize = 1024;
 +      try {
 +        bufSize = _socket.getSendBufferSize();
 +        if (bufSize < 1024) {
 +          bufSize = 1024;
 +        }
 +      } catch (SocketException ignore) {
 +      }
 +      this._commBuffer = ServerConnection.allocateCommBuffer(bufSize, socket);
 +    }
 +    this._remoteHostAddress = socket.getInetAddress().getHostAddress();
 +    this.isPrimary = ip;
 +    this.clientConflation = cc;
 +    this.clientVersion = vers;
 +  }
 +
 +  public boolean isMarkerEnqueued() {
 +    return markerEnqueued;
 +  }
 +
 +  public void setMarkerEnqueued(boolean bool) {
 +    markerEnqueued = bool;
 +  }
 +
 +  public long getAcceptorId(){
 +    return this._acceptorId;
 +  }
 +
 +  /**
 +   * @return the notifyBySubscription
 +   */
 +  public boolean isNotifyBySubscription() {
 +    return this.notifyBySubscription;
 +  }
 +
 +  
 +  /**
 +   * Returns the DistributedMember represented by this proxy
 +   */
 +  public ClientProxyMembershipID getProxyID()
 +  {
 +    return this.proxyID;
 +  }
 +  
 +  // the following code was commented out simply because it was not used
 +//   /**
 +//    * Determines if the proxy represents the client host (and only the host, not
 +//    * necessarily the exact VM running on the host)
 +//    *
 +//    * @return Whether the proxy represents the client host
 +//    */
 +//   protected boolean representsClientHost(String clientHost)
 +//   {
 +//     // [bruce] TODO BUGBUGBUG: this should compare InetAddresses, not Strings
 +//     return this._remoteHostAddress.equals(clientHost);
 +//   }
 +
 +//   protected boolean representsClientVM(DistributedMember remoteMember)
 +//   {
 +//     // logger.warn("Is input port " + clientPort + " contained in " +
 +//     // logger.warn("Does input host " + clientHost + " equal " +
 +//     // this._remoteHostAddress+ ": " + representsClientHost(clientHost));
 +//     // logger.warn("representsClientVM: " +
 +//     // (representsClientHost(clientHost) && containsPort(clientPort)));
 +//     return (proxyID.getDistributedMember().equals(remoteMember));
 +//   }
 +
 +//   /**
 +//    * Determines if the CacheClientUpdater proxied by this instance is listening
 +//    * on the input clientHost and clientPort
 +//    *
 +//    * @param clientHost
 +//    *          The host name of the client to compare
 +//    * @param clientPort
 +//    *          The port number of the client to compare
 +//    *
 +//    * @return Whether the CacheClientUpdater proxied by this instance is
 +//    *         listening on the input clientHost and clientPort
 +//    */
 +//   protected boolean representsCacheClientUpdater(String clientHost,
 +//       int clientPort)
 +//   {
 +//     return (clientPort == this._socket.getPort() && representsClientHost(clientHost));
 +//   }
 +
 +  protected boolean isMember(ClientProxyMembershipID memberId)
 +  {
 +    return this.proxyID.equals(memberId);
 +  }
 +
 +  protected boolean isSameDSMember(ClientProxyMembershipID memberId)
 +  {
 +    return this.proxyID.isSameDSMember(memberId);
 +  }
 +
 +  /**
 +   * Set the queue keepalive option
 +   *
 +   * @param option whether to keep the durable client's queue alive
 +   */
 +  protected void setKeepAlive(boolean option) {
 +    this.keepalive = option;
 +  }
 +
 +  /**
 +   * Returns the socket between the server and the client
 +   *
 +   * @return the socket between the server and the client
 +   */
 +  protected Socket getSocket()
 +  {
 +    return this._socket;
 +  }
 +  
 +  public String getSocketHost()
 +  {
 +    return this._socket.getInetAddress().getHostAddress();
 +  }
 +  
 +  protected ByteBuffer getCommBuffer() {
 +    return this._commBuffer;
 +  }
 +
 +  /**
 +   * Returns the remote host's IP address string
 +   *
 +   * @return the remote host's IP address string
 +   */
 +  protected String getRemoteHostAddress()
 +  {
 +    return this._remoteHostAddress;
 +  }
 +
 +  /**
 +   * Returns the remote host's port
 +   *
 +   * @return the remote host's port
 +   */
 +  public int getRemotePort()
 +  {
 +    return this._socket.getPort();
 +  }
 +
 +  /**
 +   * Returns whether the proxy is connected to a remote client
 +   *
 +   * @return whether the proxy is connected to a remote client
 +   */
 +  public boolean isConnected() {
 +    return this.connected;
 +  }
 +
 +  /**
 +   * Mark the receiver as needing removal
 +   * @return true if it was already marked for removal
 +   */
 +  protected boolean startRemoval() {
 +    boolean result;
 +    synchronized (this.isMarkedForRemovalLock) {
 +      result = this.isMarkedForRemoval;
 +      this.isMarkedForRemoval = true;
 +    }
 +    return result;
 +  }
 +  
 +  /**
 +   * Wait until the receiver's removal has completed before
 +   * returning.
 +   * @return true if the proxy was initially marked for removal
 +   */
 +  protected boolean waitRemoval() {
 +    boolean result;
 +    synchronized (this.isMarkedForRemovalLock) {
 +      result = this.isMarkedForRemoval;
 +      boolean interrupted = false;
 +      try {
 +        while (this.isMarkedForRemoval) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Waiting for CacheClientProxy removal: {}", this);
 +          }
 +          try {
 +            this.isMarkedForRemovalLock.wait();
 +          }
 +          catch (InterruptedException e) {
 +            interrupted = true;
 +            this._cache.getCancelCriterion().checkCancelInProgress(e);
 +          }
 +        } // while
 +      }
 +      finally {
 +        if (interrupted) {
 +          Thread.currentThread().interrupt();
 +        }
 +      }
 +    } // synchronized
 +    return result;
 +  }
 +  
 +  /**
 +   * Indicate that removal has completed on this instance
 +   */
 +  protected void notifyRemoval() {
 +    synchronized (this.isMarkedForRemovalLock) {
 +      this.isMarkedForRemoval = false;
 +      this.isMarkedForRemovalLock.notifyAll();
 +    }
 +  }
 +  
 +  /**
 +   * Returns the GemFire cache
 +   *
 +   * @return the GemFire cache
 +   */
 +  public GemFireCacheImpl getCache()
 +  {
 +    return this._cache;
 +  }
 +
 +  public Set<String> getInterestRegisteredRegions() {
 +    HashSet<String> regions = new HashSet<String>();
 +    for(int i=0; i < this.cils.length; i++){
 +      if (!this.cils[i].regions.isEmpty()) {
 +        regions.addAll(this.cils[i].regions);
 +      }
 +    }
 +    return regions;
 +  }
 +  
 +  /**
 +   * Returns the proxy's statistics
 +   *
 +   * @return the proxy's statistics
 +   */
 +  public CacheClientProxyStats getStatistics()
 +  {
 +    return this._statistics;
 +  }
 +
 +  /**
 +   * Returns this proxy's <code>CacheClientNotifier</code>.
 +   * @return this proxy's <code>CacheClientNotifier</code>
 +   */
 +  protected CacheClientNotifier getCacheClientNotifier() {
 +    return this._cacheClientNotifier;
 +  }
 +
 +  /**
 +   * Returns the size of the queue for heuristic purposes.  This
 +   * size may be changing concurrently if puts/gets are occurring
 +   * at the same time.
 +   */
 +  public int getQueueSize() {
 +    return this._messageDispatcher == null ? 0
 +        : this._messageDispatcher.getQueueSize();
 +  }
 +  
 +  /** 
 +   * returns the queue size calculated through stats
 +   */
 +  public int getQueueSizeStat() {
 +    return this._messageDispatcher == null ? 0
 +        : this._messageDispatcher.getQueueSizeStat();  
 +  }
 +  
 +      
 +  public boolean drainInProgress() {
 +    synchronized(drainsInProgressLock) {
 +      return numDrainsInProgress > 0;
 +    }
 +  }
 +  
 +  //Called from CacheClientNotifier when attempting to restart paused proxy
 +  //locking the drain lock requires that no drains are in progress 
 +  //when the lock was acquired.
 +  public boolean lockDrain() {
 +    synchronized(drainsInProgressLock) {
 +      if (!drainInProgress()) {
 +        synchronized(drainLock) {
 +          if (testHook != null) {
 +            testHook.doTestHook("PRE_ACQUIRE_DRAIN_LOCK_UNDER_SYNC");
 +          }
 +          //prevent multiple lockings of drain lock
 +          if (!drainLocked) {
 +            drainLocked = true;
 +            return true;
 +          }
 +        }
 +      }
 +    }
 +    return false;
 +  }
 +  
 +  //Called from CacheClientNotifier when completed restart of proxy
 +  public void unlockDrain() {
 +    if (testHook != null) {
 +      testHook.doTestHook("PRE_RELEASE_DRAIN_LOCK");
 +    }
 +    synchronized(drainLock) {
 +      drainLocked = false;
 +    }
 +  }
 +  
 +  //Only close the client cq if it is paused and no one is attempting to restart the proxy
 +  public boolean closeClientCq(String clientCQName) throws CqException {
 +    if (testHook != null) {
 +      testHook.doTestHook("PRE_DRAIN_IN_PROGRESS");
 +    }
 +    synchronized(drainsInProgressLock) {
 +      numDrainsInProgress ++;
 +    }
 +    if (testHook != null) {
 +      testHook.doTestHook("DRAIN_IN_PROGRESS_BEFORE_DRAIN_LOCK_CHECK");
 +    }
 +    try {
 +      //If the drain lock was acquired, the other thread did so before we could bump up
 +      //the numDrainsInProgress.  That means we need to stop.
 +      if (drainLocked) {
 +        // someone is trying to restart a paused proxy
 +        String msg = LocalizedStrings.CacheClientProxy_COULD_NOT_DRAIN_CQ_DUE_TO_RESTARTING_DURABLE_CLIENT.toLocalizedString(clientCQName, proxyID.getDurableId());
 +        logger.info(msg);
 +        throw new CqException(msg);
 +      }
 +      //isConnected is to protect against the case where a durable client has reconnected
 +      //but has not yet sent a ready for events message
 +      //we can probably remove the isPaused check
 +      if (isPaused() && !isConnected()) {
 +        CqService cqService = getCache().getCqService();
 +        if (cqService != null) {
 +          InternalCqQuery  cqToClose = cqService.getCq(cqService.constructServerCqName(
 +              clientCQName, this.proxyID));
 +          // close and drain
 +          if (cqToClose != null) {
 +            cqService.closeCq(clientCQName, this.proxyID);
 +            this._messageDispatcher.drainClientCqEvents(this.proxyID, cqToClose);
 +          }
 +          else {
 +            String msg = LocalizedStrings.CqService_CQ_NOT_FOUND_FAILED_TO_CLOSE_THE_SPECIFIED_CQ_0.toLocalizedString(clientCQName);
 +            logger.info(msg);
 +            throw new CqException(msg);
 +          }
 +        }
 +      } else {
 +        String msg = LocalizedStrings.CacheClientProxy_COULD_NOT_DRAIN_CQ_DUE_TO_ACTIVE_DURABLE_CLIENT.toLocalizedString(clientCQName, proxyID.getDurableId());
 +        logger.info(msg);
 +        throw new CqException(msg);
 +      }
 +    } finally {
 +      synchronized (drainsInProgressLock) {
 +        numDrainsInProgress--;
 +      }
 +      if (testHook != null) {
 +        testHook.doTestHook("DRAIN_COMPLETE");
 +      }
 +
 +    }
 +    return true;
 +  }
 +  
 +  
 +  /**
 +   * Returns whether the proxy is alive. It is alive if its message dispatcher
 +   * is processing messages.
 +   *
 +   * @return whether the proxy is alive
 +   */
 +  protected boolean isAlive()
 +  {
 +    if (this._messageDispatcher == null) {
 +      return false;
 +    }
 +    return !this._messageDispatcher.isStopped();
 +  }
 +
 +  /**
 +   * Returns whether the proxy is paused. It is paused if its message dispatcher
 +   * is paused. This only applies to durable clients.
 +   *
 +   * @return whether the proxy is paused
 +   *
 +   * @since 5.5
 +   */
 +  protected boolean isPaused() {
 +    return this._isPaused;
 +  }
 +
 +  protected void setPaused(boolean isPaused) {
 +    this._isPaused = isPaused;
 +  }
 +
 +  /**
 +   * Closes the proxy. This method checks the message queue for any unprocessed
 +   * messages and processes them for MAXIMUM_SHUTDOWN_PEEKS.
 +   *
 +   * @see CacheClientProxy#MAXIMUM_SHUTDOWN_PEEKS
 +   */
 +  protected void close()
 +  {
 +    close(true, false);
 +  }
 +
 +  /**
 +   * Set to true once this proxy starts being closed.
 +   * Remains true for the rest of its existence.
 +   */
 +  private final AtomicBoolean closing = new AtomicBoolean(false);
 +
 +  /**
 +   * Close the <code>CacheClientProxy</code>.
 +   *
 +   * @param checkQueue
 +   *          Whether to message check the queue and process any contained
 +   *          messages (up to MAXIMUM_SHUTDOWN_PEEKS).
 +   * @param stoppedNormally
 +   *          Whether client stopped normally
 +   *
 +   * @return whether to keep this <code>CacheClientProxy</code>
 +   * @see CacheClientProxy#MAXIMUM_SHUTDOWN_PEEKS
 +   */
 +  protected boolean close(boolean checkQueue, boolean stoppedNormally) {
 +    boolean pauseDurable = false;
 +    // If the client is durable and either (a) it hasn't stopped normally or (b) it
 +    // has stopped normally but it is configured to be kept alive, set pauseDurable
 +    // to true
 +    if (isDurable()
 +        && (!stoppedNormally || (getDurableKeepAlive() && stoppedNormally))) {
 +      pauseDurable = true;
 +    }
 +
 +    boolean keepProxy = false;
 +    if (pauseDurable) {
 +      pauseDispatching();
 +      keepProxy = true;
 +    } else {
 +      terminateDispatching(checkQueue);
 +      closeTransientFields();
 +    }
 +
 +    this.connected = false;
 +
 +    // Close the Authorization callback (if any)
 +    try {
 +      if (!pauseDurable) {
 +        if (this.postAuthzCallback != null) {//for single user
 +          this.postAuthzCallback.close();
 +          this.postAuthzCallback = null;
 +        }else if(this.clientUserAuths != null) {//for multiple users
 +          this.clientUserAuths.cleanup(true);
 +          this.clientUserAuths = null;
 +        }
 +      }
 +    }
 +    catch (Exception ex) {
 +      if (this._cache.getSecurityLoggerI18n().warningEnabled()) {
 +        this._cache.getSecurityLoggerI18n().warning(LocalizedStrings.TWO_ARG_COLON, new Object[] {this, ex});
 +      }
 +    }
 +    // Notify the caller whether to keep this proxy. If the proxy is durable
 +    // and should be paused, then return true; otherwise return false.
 +    return keepProxy;
 +  }
 +
 +  protected void pauseDispatching() {
 +    if (this._messageDispatcher == null){
 +      return;
 +    }
 +
 +    // If this is the primary, pause the dispatcher (which closes its transient
 +    // fields. Otherwise, just close the transient fields.
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Pausing processing", this);
 +    }
 +    //BUGFIX for BUG#38234
 +    if(!testAndSetPaused(true) && this.isPrimary) {
 +      if (this._messageDispatcher != Thread.currentThread()) {
 +        // don't interrupt ourself to fix bug 40611
 +        this._messageDispatcher.interrupt();
 +      }
 +    }
 +
 +    try {
 +      // Close transient fields
 +      closeTransientFields();
 +    } finally {
 +      // make sure this gets called if closeTransientFields throws; see bug 40611
 +      // Start timer
 +      scheduleDurableExpirationTask();
 +    }
 +  }
 +
 +  private boolean testAndSetPaused(boolean newValue) {
 +    
 +    synchronized(this._messageDispatcher._pausedLock) {
 +      if (this._isPaused != newValue) {
 +        this._isPaused = newValue;
 +        this._messageDispatcher._pausedLock.notifyAll();
 +        return !this._isPaused;
 +      }
 +      else {
 +        this._messageDispatcher._pausedLock.notifyAll();
 +        return this._isPaused;
 +      }
 +    }
 +  }
 +  protected void terminateDispatching(boolean checkQueue) {
 +    if (this._messageDispatcher == null){
 +      return;
 +    }
 +    
 +    try {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Terminating processing", this);
 +    }
 +    if (this._messageDispatcher == Thread.currentThread()) {
 +      // I'm not even sure this is possible but if the dispatcher
 +      // calls us then at least call stopDispatching
 +      // the old code did this (I'm not even sure it is safe to do).
 +      // This needs to be done without testing OR setting "closing".
 +      this._messageDispatcher.stopDispatching(checkQueue);
 +      this.cils[RegisterInterestTracker.interestListIndex].clearClientInterestList();
 +      this.cils[RegisterInterestTracker.durableInterestListIndex].clearClientInterestList();
 +      // VJR: bug 37487 fix
 +      destroyRQ();
 +      return;
 +    }
 +
 +    if (!this.closing.compareAndSet(false, true)) {
 +      // must already be closing so just return
 +      // this is part of the fix for 37684
 +      return;
 +    }
 +    // Unregister interest in all interests (if necessary) 
 +    this.cils[RegisterInterestTracker.interestListIndex].clearClientInterestList();
 +    this.cils[RegisterInterestTracker.durableInterestListIndex].clearClientInterestList();
 +
 +    // If the message dispatcher is paused, unpause it. The next bit of
 +    // code will interrupt the waiter.
 +    if (this.testAndSetPaused(false)) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Paused but terminating processing", this);
 +      }
 +      // Cancel the expiration task
 +      cancelDurableExpirationTask(false);
 +    }
 +
 +    boolean alreadyDestroyed = false;
 +    boolean gotInterrupt = Thread.interrupted(); // clears the flag
 +    try {
 +      // Stop the message dispatcher
 +      this._messageDispatcher.stopDispatching(checkQueue);
 +
 +      gotInterrupt |= Thread.interrupted(); // clears the flag
 +
 +      // to fix bug 37684
 +      // 1. check to see if dispatcher is still alive
 +      if (this._messageDispatcher.isAlive()) {
 +        closeSocket();
 +        destroyRQ();
 +        alreadyDestroyed = true;
 +        this._messageDispatcher.interrupt();
 +        if (this._messageDispatcher.isAlive()) {
 +          try {
 +            this._messageDispatcher.join(1000);
 +          } catch (InterruptedException ex) {
 +            gotInterrupt = true;
 +          }
 +          // if it is still alive then warn and move on
 +          if (this._messageDispatcher.isAlive()) {
 +            //com.gemstone.gemfire.internal.OSProcess.printStacks(com.gemstone.gemfire.internal.OSProcess.getId());
 +            logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0_COULD_NOT_STOP_MESSAGE_DISPATCHER_THREAD, this));
 +          }
 +        }
 +      }
 +    }
 +    finally {
 +      if (gotInterrupt) {
 +        Thread.currentThread().interrupt();
 +      }
 +      if (!alreadyDestroyed) {
 +        destroyRQ();
 +      }
 +    }
 +    } finally {
 +      //  Close the statistics
 +      this._statistics.close(); // fix for bug 40105
 +      closeTransientFields(); // make sure this happens
 +    }
 +  }
 +
 +  private void closeSocket() {
 +    if (this._socketClosed.compareAndSet(false, true)) {
 +      // Close the socket
 +      this._cacheClientNotifier.getSocketCloser().asyncClose(this._socket, this._remoteHostAddress, null);
 +      getCacheClientNotifier().getAcceptorStats().decCurrentQueueConnections();
 +    }
 +  }
 +  
 +  private void closeTransientFields() {
 +    closeSocket();
 +
 +    // Null out comm buffer, host address, ports and proxy id. All will be
 +    // replaced when the client reconnects.
 +    releaseCommBuffer();
 +    {
 +      String remoteHostAddress = this._remoteHostAddress;
 +      if (remoteHostAddress != null) {
 +        this._cacheClientNotifier.getSocketCloser().releaseResourcesForAddress(remoteHostAddress);
 +        this._remoteHostAddress = null;
 +      }
 +    }
 +    try {
 +      this.cils[RegisterInterestTracker.interestListIndex].clearClientInterestList();
 +    } catch (CacheClosedException e) {
 +      // ignore if cache is shutting down
 +    }
 +    // Commented to fix bug 40259
 +    //this.clientVersion = null;
 +    closeNonDurableCqs();    
 +  }
 +  
 +  private void releaseCommBuffer() {
 +    ByteBuffer bb = this._commBuffer;
 +    if (bb != null) {
 +      this._commBuffer = null;
 +      ServerConnection.releaseCommBuffer(bb);
 +    }
 +  }
 +
 +  private void closeNonDurableCqs(){
 +    CqService cqService = getCache().getCqService();
 +    if (cqService != null) {
 +      try {
 +        cqService.closeNonDurableClientCqs(getProxyID());
 +      }
 +      catch (CqException ex) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_CQEXCEPTION_WHILE_CLOSING_NON_DURABLE_CQS_0, ex.getLocalizedMessage()));
 +      }
 +    }
 +  }
 +  
 +  private void destroyRQ() {
 +    if (this._messageDispatcher == null) {
 +      return;
 +    }
 +    try {
 +      // Using Destroy Region bcoz this method is modified in HARegion so as
 +      // not to distribute.
 +      // For normal Regions , even the localDestroyRegion actually propagates
 +      HARegionQueue rq = this._messageDispatcher._messageQueue;
 +      rq.destroy();
 +
 +      // if (!rq.getRegion().isDestroyed()) {
 +      // rq.getRegion().destroyRegion();
 +      // }
 +    }
 +    catch (RegionDestroyedException rde) {
 +//      throw rde;
 +    }
 +    catch (CancelException e) {
 +//      throw e;
 +    }
 +    catch (Exception warning) {
 +      logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0_EXCEPTION_IN_CLOSING_THE_UNDERLYING_HAREGION_OF_THE_HAREGIONQUEUE, this), warning);
 +    }
 +  }
 +
 +  public void registerInterestRegex(String regionName, String regex,
 +      boolean isDurable) {
 +    registerInterestRegex(regionName, regex, isDurable, true);
 +  }
 +  
 +  public void registerInterestRegex(String regionName, String regex,
 +      boolean isDurable, boolean receiveValues) {
 +    if (this.isPrimary) {
 +      // Notify all secondaries and client of change in interest
 +      notifySecondariesAndClient(regionName, regex, InterestResultPolicy.NONE,
 +          isDurable, receiveValues, InterestType.REGULAR_EXPRESSION);
 +    } else {
 +      throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
 +    }
 +  }
 +
 +  public void registerInterest(String regionName, Object keyOfInterest,
 +      InterestResultPolicy policy, boolean isDurable) {
 +    registerInterest(regionName, keyOfInterest, policy, isDurable, true);
 +  }
 +  
 +  public void registerInterest(String regionName, Object keyOfInterest,
 +      InterestResultPolicy policy, boolean isDurable,
 +      boolean receiveValues) {
 +    if (keyOfInterest instanceof String && keyOfInterest.equals("ALL_KEYS")) {
 +      registerInterestRegex(regionName, ".*", isDurable, receiveValues);
 +    } else if (keyOfInterest instanceof List) {
 +      if (this.isPrimary) {
 +        notifySecondariesAndClient(regionName, keyOfInterest, policy,
 +            isDurable, receiveValues, InterestType.KEY);
 +      } else {
 +        throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
 +      }
 +    } else {
 +      if (this.isPrimary) {
 +        // Notify all secondaries and client of change in interest
 +        notifySecondariesAndClient(regionName, keyOfInterest, policy,
 +            isDurable, receiveValues, InterestType.KEY);
 +        
 +        // Enqueue the initial value message for the client if necessary
 +        if (policy == InterestResultPolicy.KEYS_VALUES) {
 +          Get70 request = (Get70)Get70.getCommand();
 +          LocalRegion lr = (LocalRegion) this._cache.getRegion(regionName);
 +          Get70.Entry entry = request.getValueAndIsObject(lr, keyOfInterest, null,
 +              null);
 +          boolean isObject = entry.isObject;
 +          byte[] value = null;
 +          if (entry.value instanceof byte[]) {
 +            value = (byte[])entry.value;
 +          } else {
 +            try {
 +              value = CacheServerHelper.serialize(entry.value);
 +            } catch (IOException e) {
 +              logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_THE_FOLLOWING_EXCEPTION_OCCURRED_0, entry.value), e);
 +            }
 +          }
 +          VersionTag tag = entry.versionTag;
 +          ClientUpdateMessage updateMessage = new ClientUpdateMessageImpl(
 +              EnumListenerEvent.AFTER_CREATE, lr, keyOfInterest, value, null,
 +              (isObject ? (byte) 0x01 : (byte) 0x00), null, this.proxyID,
 +              new EventID(this._cache.getDistributedSystem()), tag);
 +          CacheClientNotifier.routeSingleClientMessage(updateMessage, this.proxyID);
 +        }
 +        // Add the client to the region's filters
 +        //addFilterRegisteredClients(regionName, keyOfInterest);
 +      } else {
 +        throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
 +      }
 +    }
 +  }
 +
 +  private void notifySecondariesAndClient(String regionName,
 +      Object keyOfInterest, InterestResultPolicy policy, boolean isDurable,
 +      boolean receiveValues, int interestType) {
 +    // Create a client interest message for the keyOfInterest
 +    ClientInterestMessageImpl message = new ClientInterestMessageImpl(
 +        new EventID(this._cache.getDistributedSystem()), regionName,
 +        keyOfInterest, interestType, policy.getOrdinal(), isDurable,
 +        !receiveValues, ClientInterestMessageImpl.REGISTER);
 +
 +    // Notify all secondary proxies of a change in interest
 +    notifySecondariesOfInterestChange(message);
 +
 +    // Modify interest registration
 +    if (keyOfInterest instanceof List) {
 +      registerClientInterestList(regionName, (List) keyOfInterest, isDurable,
 +          !receiveValues, true);
 +    } else {
 +      registerClientInterest(regionName, keyOfInterest, interestType,
 +          isDurable, !receiveValues, true);
 +    }
 +
 +    // Enqueue the interest registration message for the client.
 +    // If the client is not 7.0.1 or greater and the key of interest is a list,
 +    // then create an individual message for each entry in the list since the
 +    // client doesn't support a ClientInterestMessageImpl containing a list.
 +    if (Version.GFE_701.compareTo(this.clientVersion) > 0
 +        && keyOfInterest instanceof List) {
 +      for (Iterator i = ((List) keyOfInterest).iterator(); i.hasNext();) {
 +        this._messageDispatcher.enqueueMessage(new ClientInterestMessageImpl(
 +            new EventID(this._cache.getDistributedSystem()), regionName,
 +            i.next(), interestType, policy.getOrdinal(), isDurable, !receiveValues,
 +            ClientInterestMessageImpl.REGISTER));
 +     }
 +    } else {
 +      this._messageDispatcher.enqueueMessage(message);
 +    }
 +  }
 +
 +  public void unregisterInterestRegex(String regionName, String regex,
 +      boolean isDurable) {
 +    unregisterInterestRegex(regionName, regex, isDurable, true);
 +  }
 +  
 +  public void unregisterInterestRegex(String regionName, String regex,
 +      boolean isDurable, boolean receiveValues) {
 +    if (this.isPrimary) {
 +      notifySecondariesAndClient(regionName, regex, isDurable, receiveValues,
 +          InterestType.REGULAR_EXPRESSION);
 +    } else {
 +      throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
 +    }
 +  }
 +  
 +  public void unregisterInterest(String regionName, Object keyOfInterest,
 +      boolean isDurable) {
 +    unregisterInterest(regionName, keyOfInterest, isDurable, true);
 +  }
 +  
 +  public void unregisterInterest(String regionName, Object keyOfInterest,
 +      boolean isDurable, boolean receiveValues) {
 +    if (keyOfInterest instanceof String && keyOfInterest.equals("ALL_KEYS")) {
 +      unregisterInterestRegex(regionName, ".*", isDurable, receiveValues);
 +    } else {
 +      if (this.isPrimary) {
 +        notifySecondariesAndClient(regionName, keyOfInterest, isDurable,
 +            receiveValues, InterestType.KEY);
 +      } else {
 +        throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
 +      }
 +    }
 +  }
 +
 +  private void notifySecondariesAndClient(String regionName,
 +      Object keyOfInterest, boolean isDurable, boolean receiveValues,
 +      int interestType) {
 +    // Notify all secondary proxies of a change in interest
 +    ClientInterestMessageImpl message = new ClientInterestMessageImpl(
 +        new EventID(this._cache.getDistributedSystem()), regionName,
 +        keyOfInterest, interestType, (byte) 0, isDurable, !receiveValues,
 +        ClientInterestMessageImpl.UNREGISTER);
 +    notifySecondariesOfInterestChange(message);
 + 
 +    // Modify interest registration
 +    if (keyOfInterest instanceof List) {
 +      unregisterClientInterest(regionName, (List) keyOfInterest, false);
 +    } else {
 +      unregisterClientInterest(regionName, keyOfInterest, interestType,
 +          false);
 +    }
 + 
 +    // Enqueue the interest unregistration message for the client.
 +    // If the client is not 7.0.1 or greater and the key of interest is a list,
 +    // then create an individual message for each entry in the list since the
 +    // client doesn't support a ClientInterestMessageImpl containing a list.
 +    if (Version.GFE_701.compareTo(this.clientVersion) > 0
 +        && keyOfInterest instanceof List) {
 +      for (Iterator i = ((List) keyOfInterest).iterator(); i.hasNext();) {
 +        this._messageDispatcher.enqueueMessage(new ClientInterestMessageImpl(
 +            new EventID(this._cache.getDistributedSystem()), regionName,
 +            i.next(), interestType, (byte) 0, isDurable, !receiveValues,
 +            ClientInterestMessageImpl.UNREGISTER));
 +      }
 +    } else {
 +      this._messageDispatcher.enqueueMessage(message);
 +    }
 +  }
 +  
 +  protected void notifySecondariesOfInterestChange(ClientInterestMessageImpl message) {
 +    if (logger.isDebugEnabled()) {
 +      StringBuffer subBuffer = new StringBuffer();
 +      if (message.isRegister()) {
 +        subBuffer
 +          .append("register ")
 +          .append(message.getIsDurable() ? "" : "non-")
 +          .append("durable interest in ");
 +      } else {
 +        subBuffer.append("unregister interest in ");
 +      }
 +      StringBuffer buffer = new StringBuffer();
 +      buffer
 +        .append(this)
 +        .append(": Notifying secondary proxies to ")
 +        .append(subBuffer.toString())
 +        .append(message.getRegionName())
 +        .append("->")
 +        .append(message.getKeyOfInterest())
 +        .append("->")
 +        .append(InterestType.getString(message.getInterestType()));
 +      logger.debug(buffer.toString());
 +    }
 +    this._cacheClientNotifier.deliverInterestChange(this.proxyID, message);
 +  }
 +
 +  /*
 +  protected void addFilterRegisteredClients(String regionName,
 +      Object keyOfInterest) {
 +    try {
 +      this._cacheClientNotifier.addFilterRegisteredClients(regionName,
 +          this.proxyID);
 +    } catch (RegionDestroyedException e) {
 +      logger.warn(LocalizedStrings.CacheClientProxy_0_INTEREST_REG_FOR_0_FAILED, regionName + "->" + keyOfInterest, e);
 +    }
 +  }
 +  */
 +  
 +  /**
 +   * Registers interest in the input region name and key
 +   *
 +   * @param regionName
 +   *          The fully-qualified name of the region in which to register
 +   *          interest
 +   * @param keyOfInterest
 +   *          The key in which to register interest
 +   */
 +  protected void registerClientInterest(String regionName,
 +      Object keyOfInterest, int interestType, boolean isDurable,
 +      boolean sendUpdatesAsInvalidates, boolean flushState)
 +  {
 +    ClientInterestList cil =
 +      this.cils[RegisterInterestTracker.getInterestLookupIndex(
 +          isDurable, false)];
 +    cil.registerClientInterest(regionName, keyOfInterest, interestType, sendUpdatesAsInvalidates);
 +    if (flushState) {
 +      flushForInterestRegistration(regionName, this._cache.getDistributedSystem().getDistributedMember());
 +    }
 +    HARegionQueue queue = getHARegionQueue();
 +    if (queue != null) { // queue is null during initialization
 +      queue.setHasRegisteredInterest(true);
 +    }
 +  }
 +  
 +  /**
 +   * flush other regions to the given target.  This is usually the member
 +   * that is registering the interest.  During queue creation it is the
 +   * queue's image provider.
 +   */
 +  public void flushForInterestRegistration(String regionName, DistributedMember target) {
 +    Region r = this._cache.getRegion(regionName);
 +    if (r == null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Unable to find region '{}' to flush for interest registration", regionName);
 +      }
 +    } else if (r.getAttributes().getScope().isDistributed()) {
 +      if (logger.isDebugEnabled()){
 +        logger.debug("Flushing region '{}' for interest registration", regionName);
 +      }
 +      CacheDistributionAdvisee cd = (CacheDistributionAdvisee)r;
 +      final StateFlushOperation sfo;
 +      if (r instanceof PartitionedRegion) {
 +        // need to flush all buckets.  SFO should be changed to target buckets
 +        // belonging to a particular PR, but it doesn't have that option right now
 +        sfo = new StateFlushOperation(
 +            this._cache.getDistributedSystem().getDistributionManager());
 +      } else {
 +        sfo = new StateFlushOperation((DistributedRegion)r);
 +      }
 +      try {
 +        // bug 41681 - we need to flush any member that may have a cache operation
 +        // in progress so that the changes are received there before returning
 +        // from this method
 +        InitialImageAdvice advice = cd.getCacheDistributionAdvisor().adviseInitialImage(null);
 +        HashSet recips = new HashSet(advice.getReplicates());
 +        recips.addAll(advice.getUninitialized());
 +        recips.addAll(advice.getEmpties());
 +        recips.addAll(advice.getPreloaded());
 +        recips.addAll(advice.getOthers());
 +        sfo.flush(recips,
 +            target,
 +            DistributionManager.HIGH_PRIORITY_EXECUTOR, true);
 +      } catch (InterruptedException ie) {
 +        Thread.currentThread().interrupt();
 +        return;
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Unregisters interest in the input region name and key
 +   *
 +   * @param regionName
 +   *          The fully-qualified name of the region in which to unregister
 +   *          interest
 +   * @param keyOfInterest
 +   *          The key in which to unregister interest
 +   * @param isClosing
 +   *          Whether the caller is closing
 +   */
 +  protected void unregisterClientInterest(String regionName,
 +      Object keyOfInterest, int interestType, boolean isClosing)
 +  {
 +    // only unregister durable interest if isClosing and !keepalive
 +    if (!isClosing /* explicit unregister */
 +        || !getDurableKeepAlive() /* close and no keepAlive*/) {
 +      this.cils[RegisterInterestTracker.durableInterestListIndex].
 +        unregisterClientInterest(regionName, keyOfInterest, interestType);
 +    }
 +    // always unregister non durable interest
 +    this.cils[RegisterInterestTracker.interestListIndex].
 +      unregisterClientInterest(regionName, keyOfInterest, interestType);
 +  }
 +
 +  /**
 +   * Registers interest in the input region name and list of keys
 +   *
 +   * @param regionName
 +   *          The fully-qualified name of the region in which to register
 +   *          interest
 +   * @param keysOfInterest
 +   *          The list of keys in which to register interest
 +   */
 +  protected void registerClientInterestList(String regionName,
 +      List keysOfInterest, boolean isDurable, boolean sendUpdatesAsInvalidates,
 +      boolean flushState)
 +  {
 +    // we only use two interest lists to map the non-durable and durable
 +    // identifiers to their interest settings
 +    ClientInterestList cil =
 +      this.cils[RegisterInterestTracker.getInterestLookupIndex(
 +          isDurable, false/*sendUpdatesAsInvalidates*/)];
 +    cil.registerClientInterestList(regionName, keysOfInterest, sendUpdatesAsInvalidates);
 +    if (getHARegionQueue() != null) {
 +      if (flushState) {
 +        flushForInterestRegistration(regionName, this._cache.getDistributedSystem().getDistributedMember());
 +      }
 +      getHARegionQueue().setHasRegisteredInterest(true);
 +    }
 +  }
 +
 +  /**
 +   * Unregisters interest in the input region name and list of keys
 +   *
 +   * @param regionName
 +   *          The fully-qualified name of the region in which to unregister
 +   *          interest
 +   * @param keysOfInterest
 +   *          The list of keys in which to unregister interest
 +   * @param isClosing
 +   *          Whether the caller is closing
 +   */
 +  protected void unregisterClientInterest(String regionName,
 +      List keysOfInterest, boolean isClosing)
 +  {
 +    // only unregister durable interest if isClosing and !keepalive
 +    if (!isClosing /* explicit unregister */
 +        || !getDurableKeepAlive() /* close and no keepAlive*/) {
 +      this.cils[RegisterInterestTracker.durableInterestListIndex].
 +        unregisterClientInterestList(regionName, keysOfInterest);
 +    }
 +    // always unregister non durable interest
 +    this.cils[RegisterInterestTracker.interestListIndex].
 +      unregisterClientInterestList(regionName, keysOfInterest);
 +  }
 +
 +
 +  /** sent by the cache client notifier when there is an interest registration change */
 +  protected void processInterestMessage(ClientInterestMessageImpl message) { 
 +    int interestType = message.getInterestType(); 
 +    String regionName = message.getRegionName(); 
 +    Object key = message.getKeyOfInterest(); 
 +    if (message.isRegister()) {
 +      // Register interest in this region->key
 +      if (key instanceof List) {
 +        registerClientInterestList(regionName, (List) key,
 +            message.getIsDurable(), message.getForUpdatesAsInvalidates(), true);
 +      } else {
 +        registerClientInterest(regionName, key, interestType,
 +            message.getIsDurable(), message.getForUpdatesAsInvalidates(), true);
 +      }
 +       
 +      // Add the client to the region's filters 
 +      //addFilterRegisteredClients(regionName, key); 
 + 
 +      if (logger.isDebugEnabled()) { 
 +        StringBuffer buffer = new StringBuffer();
 +        buffer 
 +          .append(this) 
 +          .append(": Interest listener registered ") 
 +          .append(message.getIsDurable() ? "" : "non-") 
 +          .append("durable interest in ") 
 +          .append(message.getRegionName()) 
 +          .append("->") 
 +          .append(message.getKeyOfInterest())
 +          .append("->")
 +          .append(InterestType.getString(message.getInterestType()));
 +        logger.debug(buffer.toString()); 
 +      } 
 +    } else { 
 +      // Unregister interest in this region->key 
 +      if (key instanceof List) {
 +        unregisterClientInterest(regionName, (List) key, false);
 +      } else {
 +        unregisterClientInterest(regionName, key, interestType, false);
 +      }
 +       
 +      if (logger.isDebugEnabled()) { 
 +        StringBuffer buffer = new StringBuffer(); 
 +        buffer 
 +          .append(this) 
 +          .append(": Interest listener unregistered interest in ") 
 +          .append(message.getRegionName()) 
 +          .append("->") 
 +          .append(message.getKeyOfInterest())
 +          .append("->")
 +          .append(InterestType.getString(message.getInterestType()));
 +        logger.debug(buffer.toString()); 
 +      } 
 +    } 
 +  } 
 +
 +  private boolean postDeliverAuthCheckPassed(ClientUpdateMessage clientMessage) {
 +    // Before adding it in the queue for dispatching, check for post
 +    // process authorization
 +    if (AcceptorImpl.isAuthenticationRequired()
 +        && this.postAuthzCallback == null
 +        && AcceptorImpl.isPostAuthzCallbackPresent()) {
 +      // security is on and callback is null: it means multiuser mode.
 +      ClientUpdateMessageImpl cumi = (ClientUpdateMessageImpl)clientMessage;
 +
 +      CqNameToOp clientCq = cumi.getClientCq(this.proxyID);
 +
 +      if (clientCq != null && !clientCq.isEmpty()) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("CCP clientCq size before processing auth {}", clientCq.size());
 +        }
 +        String[] regionNameHolder = new String[1];
 +        OperationContext opctxt = getOperationContext(clientMessage,
 +            regionNameHolder);
 +        if (opctxt == null) {
 +          logger.warn(LocalizedMessage.create(
 +              LocalizedStrings.CacheClientProxy__0_NOT_ADDING_MESSAGE_TO_QUEUE_1_BECAUSE_THE_OPERATION_CONTEXT_OBJECT_COULD_NOT_BE_OBTAINED_FOR_THIS_CLIENT_MESSAGE,
 +              new Object[] {this, clientMessage}));
 +          return false;
 +        }
 +
 +        String[] cqNames = clientCq.getNames();
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("CCP clientCq names array size {}", cqNames.length);
 +        }
 +        for (int i = 0; i < cqNames.length; i++) {
 +          try {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("CCP clientCq name {}", cqNames[i]);
 +            }
 +            boolean isAuthorized = false;
 +
 +            if (this.proxyID.isDurable() && this.getDurableKeepAlive()
 +                && this._isPaused) {
 +              // need to take lock as we may be reinitializing proxy cache
 +              synchronized (this.clientUserAuthsLock) {
 +                AuthorizeRequestPP postAuthCallback = this.clientUserAuths
 +                    .getUserAuthAttributes(cqNames[i]).getPostAuthzRequest();
 +                if (logger.isDebugEnabled() && postAuthCallback == null) {
 +                  logger.debug("CCP clientCq post callback is null");
 +                }
 +                if (postAuthCallback != null && postAuthCallback
 +                    .getPostAuthzCallback().authorizeOperation(
 +                        regionNameHolder[0], opctxt)) {
 +                  isAuthorized = true;
 +                }
 +              }
 +            } else {
 +              UserAuthAttributes userAuthAttributes = this.clientUserAuths
 +                  .getUserAuthAttributes(cqNames[i]);
 +
 +              AuthorizeRequestPP postAuthCallback = userAuthAttributes
 +                  .getPostAuthzRequest();
 +              if (postAuthCallback == null && logger.isDebugEnabled()) {
 +                logger.debug("CCP clientCq post callback is null");
 +              }
 +              if (postAuthCallback != null && postAuthCallback
 +                  .getPostAuthzCallback().authorizeOperation(
 +                      regionNameHolder[0], opctxt)) {
 +                isAuthorized = true;
 +              }
 +            }
 +
 +            if (!isAuthorized) {
 +              logger.warn(LocalizedMessage.create(
 +                  LocalizedStrings.CacheClientProxy__0_NOT_ADDING_CQ_MESSAGE_TO_QUEUE_1_BECAUSE_AUTHORIZATION_FAILED,
 +                  new Object[] {this, clientMessage}));
 +              clientCq.delete(cqNames[i]);
 +            }
 +          } catch (Exception ex) {
 +            // ignore...
 +          }
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("CCP clientCq size after processing auth {}", clientCq.size());
 +          }
 +        }
 +        // again need to check as there may be no CQ available
 +        if (!clientMessage.hasCqs(this.proxyID)) {
 +          this._statistics.incMessagesNotQueuedNotInterested();
 +          if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
 +            logger.debug("{}: Not adding message to queue. It is not interested in this region and key: {}", clientMessage);
 +          }
 +          return false;
 +        }
 +      }
 +    }
 +    else if (this.postAuthzCallback != null) {
 +      String[] regionNameHolder = new String[1];
 +      boolean isAuthorize = false;
 +      OperationContext opctxt = getOperationContext(clientMessage,
 +          regionNameHolder);
 +      if (opctxt == null) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy__0_NOT_ADDING_MESSAGE_TO_QUEUE_1_BECAUSE_THE_OPERATION_CONTEXT_OBJECT_COULD_NOT_BE_OBTAINED_FOR_THIS_CLIENT_MESSAGE, new Object[] {this, clientMessage}));
 +        return false;
 +      }
 +      if (logger.isTraceEnabled()){
 +        logger.trace("{}: Invoking authorizeOperation for message: {}", this, clientMessage);
 +      }
 +
 +      if (this.proxyID.isDurable() && this.getDurableKeepAlive()
 +          && this._isPaused) {
 +        synchronized (this.clientUserAuthsLock) {
 +          isAuthorize = this.postAuthzCallback.authorizeOperation(
 +              regionNameHolder[0], opctxt);
 +        }
 +      } else {
 +        isAuthorize = this.postAuthzCallback.authorizeOperation(
 +            regionNameHolder[0], opctxt);
 +      }
 +      if (!isAuthorize) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy__0_NOT_ADDING_MESSAGE_TO_QUEUE_1_BECAUSE_AUTHORIZATION_FAILED, new Object[] {this, clientMessage}));
 +        return false;
 +      }
 +    }
 +
 +    return true;
 +  }
 +
 +  /**
 +   * Delivers the message to the client representing this client proxy.
 +   * @param conflatable 
 +   */
 +  protected void deliverMessage(Conflatable conflatable)
 +  {
 +    ClientUpdateMessage clientMessage = null;
 +    if(conflatable instanceof HAEventWrapper) {
 +      clientMessage = ((HAEventWrapper)conflatable).getClientUpdateMessage();
 +    } else {
 +      clientMessage = (ClientUpdateMessage)conflatable;
 +    } 
 +
 +    this._statistics.incMessagesReceived();
 +
 +    if (clientMessage.needsNoAuthorizationCheck() || postDeliverAuthCheckPassed(clientMessage)) {
 +      // If dispatcher is getting initialized, add the event to temporary queue.
 +      if (this.messageDispatcherInit) {
 +        synchronized (this.queuedEventsSync) {
 +          if (this.messageDispatcherInit) {  // Check to see value did not changed while getting the synchronize lock.
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Message dispatcher for proxy {} is getting initialized. Adding message to the queuedEvents.", this);
 +            }
 +            this.queuedEvents.add(conflatable);
 +            return;
 +          }
 +        }
 +      }
 +      
 +      if (this._messageDispatcher != null) {
 +        this._messageDispatcher.enqueueMessage(conflatable);
 +      } else {
 +        this._statistics.incMessagesFailedQueued();
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Message is not added to the queue. Message dispatcher for proxy: {} doesn't exist.", this);
 +        }
 +      }
 +    } else {
 +      this._statistics.incMessagesFailedQueued();
 +    }
 +  }
 +
 +  protected void sendMessageDirectly(ClientMessage message) {
 +    // Send the message directly if the connection exists
 +    // (do not go through the queue).
 +    if (logger.isDebugEnabled()){
 +      logger.debug("About to send message directly to {}", this);
 +    }
 +    if (this._messageDispatcher != null && this._socket != null && !this._socket.isClosed()) {
 +      // If the socket is open, send the message to it
 +      this._messageDispatcher.sendMessageDirectly(message);
 +      if (logger.isDebugEnabled()){
 +        logger.debug("Sent message directly to {}", this);
 +      }
 +    } else {
 +      // Otherwise just reset the ping counter
 +      resetPingCounter();
 +      if (logger.isDebugEnabled()){
 +        logger.debug("Skipped sending message directly to {}", this);
 +      }
 +    }
 +  }
 +  
 +  private OperationContext getOperationContext(ClientMessage cmsg,
 +      String[] regionNameHolder) {
 +    ClientUpdateMessageImpl cmsgimpl = (ClientUpdateMessageImpl)cmsg;
 +    OperationContext opctxt = null;
 +    // TODO SW: Special handling for DynamicRegions; this should be reworked
 +    // when DynamicRegion API is deprecated
 +    String regionName = cmsgimpl.getRegionName();
 +    regionNameHolder[0] = regionName;
 +    if (cmsgimpl.isCreate()) {
 +      if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
 +        regionNameHolder[0] = (String)cmsgimpl.getKeyOfInterest();
 +        opctxt = new RegionCreateOperationContext(true);
 +      }
 +      else {
 +        PutOperationContext tmp = new PutOperationContext(cmsgimpl.getKeyOfInterest(), cmsgimpl
 +            .getValue(), cmsgimpl.valueIsObject(), PutOperationContext.CREATE,
 +            true);
 +        tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
 +        opctxt = tmp;
 +      }
 +    }
 +    else if (cmsgimpl.isUpdate()) {
 +      if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
 +        regionNameHolder[0] = (String)cmsgimpl.getKeyOfInterest();
 +        opctxt = new RegionCreateOperationContext(true);
 +      }
 +      else {
 +        PutOperationContext tmp = new PutOperationContext(cmsgimpl.getKeyOfInterest(), cmsgimpl
 +            .getValue(), cmsgimpl.valueIsObject(), PutOperationContext.UPDATE,
 +            true);
 +        tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
 +        opctxt = tmp;
 +      }
 +    }
 +    else if (cmsgimpl.isDestroy()) {
 +      if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
 +        regionNameHolder[0] = (String)cmsgimpl.getKeyOfInterest();
 +        opctxt = new RegionDestroyOperationContext(true);
 +      }
 +      else {
 +        DestroyOperationContext tmp = new DestroyOperationContext(cmsgimpl.getKeyOfInterest(), true);
 +        tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
 +        opctxt = tmp;
 +      }
 +    }
 +    else if (cmsgimpl.isDestroyRegion()) {
 +      opctxt = new RegionDestroyOperationContext(true);
 +    }
 +    else if (cmsgimpl.isInvalidate()) {
 +      InvalidateOperationContext tmp = new InvalidateOperationContext(cmsgimpl.getKeyOfInterest(), true);
 +      tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
 +      opctxt = tmp;
 +    }
 +    else if (cmsgimpl.isClearRegion()) {
 +      RegionClearOperationContext tmp = new RegionClearOperationContext(true);
 +      tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
 +      opctxt = tmp;
 +    }
 +    return opctxt;
 +  }
 +
 +  /**
 +   * Initializes the message dispatcher thread. The
 +   * <code>MessageDispatcher</code> processes the message queue.
 +   *
 +   * @throws CacheException
 +   */
 +  public void initializeMessageDispatcher() throws CacheException
 +  {
 +    this.messageDispatcherInit = true; // Initialization process.
 +    try {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Initializing message dispatcher with capacity of {} entries", this, _maximumMessageCount);
 +      }
 +      String name = "Client Message Dispatcher for "
 +        + getProxyID().getDistributedMember() + (isDurable()? " (" + getDurableId()+")" : "");
 +      this._messageDispatcher = new MessageDispatcher(this, name);
 +      
 +      //Fix for 41375 - drain as many of the queued events
 +      //as we can without synchronization.
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{} draining {} events from init queue into intialized queue", this, this.queuedEvents.size());
 +      }
 +      Conflatable nextEvent;
 +      while((nextEvent = queuedEvents.poll()) != null) {
 +        this._messageDispatcher.enqueueMessage(nextEvent);
 +      }
 +      
 +      //Now finish emptying the queue with synchronization to make
 +      //sure we don't miss any events.
 +      synchronized (this.queuedEventsSync){
 +          while((nextEvent = queuedEvents.poll()) != null) {
 +            this._messageDispatcher.enqueueMessage(nextEvent);
 +          }
 +          
 +          this.messageDispatcherInit = false; // Done initialization.
 +      }
 +    } finally {
 +      if (this.messageDispatcherInit) { // If its not successfully completed.
 +        this._statistics.close();
 +      }
 +    }
 +  }
 +
 +  protected void startOrResumeMessageDispatcher(boolean processedMarker) {
 +    // Only start or resume the dispatcher if it is Primary
 +    if (this.isPrimary) {
 +      // Add the marker to the queue
 +      if (!processedMarker) {
 +        EventID eventId = new EventID(this._cache.getDistributedSystem());
 +        this._messageDispatcher.enqueueMarker(new ClientMarkerMessageImpl(eventId));
 +      }
 +
 +      // Set the message queue to primary.
 +      this._messageDispatcher._messageQueue.setPrimary(true);
 +
 +      // Start or resume the dispatcher
 +      synchronized (this._messageDispatcher._pausedLock) {
 +        if (this.isPaused()) {
 +          // It is paused, resume it
 +          this.setPaused(false);
 +          if (this._messageDispatcher.isStopped()) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}: Starting dispatcher", this);
 +            }
 +            this._messageDispatcher.start();
 +          }
 +          else {
 +            // ARB: Initialize transient fields.
 +            this._messageDispatcher.initializeTransients();
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}: Resuming dispatcher", this);
 +            }
 +            this._messageDispatcher.resumeDispatching();
 +          }
 +        } else if (!this._messageDispatcher.isAlive()) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("{}: Starting dispatcher", this);
 +          }
 +          this._messageDispatcher.start();
 +        }
 +      }
 +    }
 +  }
 +
 +  /*
 +   * Returns whether the client represented by this <code> CacheClientProxy
 +   * </code> has registered interest in anything. @return whether the client
 +   * represented by this <code> CacheClientProxy </code> has registered interest
 +   * in anything
 +   */
 +  protected boolean hasRegisteredInterested()
 +  {
 +    return
 +    this.cils[RegisterInterestTracker.interestListIndex].hasInterest() ||
 +    this.cils[RegisterInterestTracker.durableInterestListIndex].hasInterest();
 +  }
 +
 +  /**
 +   * Returns a string representation of the proxy
 +   */
 +  @Override
 +  public String toString()
 +  {
 +    StringBuffer buffer = new StringBuffer();
 +    buffer.append("CacheClientProxy[")
 +      // .append("client proxy id=")
 +      .append(this.proxyID)
 +      // .append("; client host name=")
 +      // .append(this._socket.getInetAddress().getCanonicalHostName())
 +      // .append("; client host address=")
 +      // .append(this._remoteHostAddress)
 +      .append("; port=").append(this._socket.getPort())
 +      .append("; primary=").append(isPrimary)
 +      .append("; version=").append(clientVersion)
 +      .append("]");
 +    return buffer.toString();
 +  }
 +  
 +  public String getState(){
 +    StringBuffer buffer = new StringBuffer();
 +    buffer.append("CacheClientProxy[")
 +      // .append("client proxy id=")
 +      .append(this.proxyID)
 +      // .append("; client host name=")
 +      // .append(this._socket.getInetAddress().getCanonicalHostName())
 +      // .append("; client host address=")
 +      // .append(this._remoteHostAddress)
 +      .append("; port=").append(this._socket.getPort())
 +      .append("; primary=").append(isPrimary)
 +      .append("; version=").append(clientVersion)
 +      .append("; paused=").append(isPaused())
 +      .append("; alive=").append(isAlive())
 +      .append("; connected=").append(isConnected())
 +      .append("; isMarkedForRemoval=").append(isMarkedForRemoval)
 +      .append("]");
 +    return buffer.toString();
 +  }
 +
 +  public boolean isPrimary()
 +  {
 +    //boolean primary = this._messageDispatcher.isAlive()
 +    //    || this._messageDispatcher._messageQueue.isPrimary();
 +    boolean primary = this.isPrimary;
 +    //System.out.println(this + ": DISPATCHER IS ALIVE: " + this._messageDispatcher.isAlive());
 +    //System.out.println(this + ": DISPATCHER QUEUE IS PRIMARY: " + this._messageDispatcher._messageQueue.isPrimary());
 +    //System.out.println(this + ": IS PRIMARY: " + primary);
 +    return primary;
 +    // return this.isPrimary ;
 +  }
 +
 +  protected boolean basicIsPrimary() {
 +    return this.isPrimary;
 +  }
 +
 +  protected void setPrimary(boolean isPrimary) {
 +    this.isPrimary = isPrimary;
 +  }
 +
 +  // private static int nextId = 0;
 +  // static protected int getNextId() {
 +  // synchronized (CacheClientProxy.class) {
 +  // return ++nextId;
 +  // }
 +  // }
 +  /*
 +   * Return this client's HA region queue
 +   * @returns - HARegionQueue of the client
 +   */
 +   public HARegionQueue getHARegionQueue() {
 +     if (this._messageDispatcher != null){
 +       return _messageDispatcher._messageQueue;
 +     }
 +     return null;
 +   }
 +
 +
 +  /**
 +   * Reinitialize a durable <code>CacheClientProxy</code> with a new client.
 +   * @param socket
 +   *          The socket between the server and the client
 +   * @param ip
 +   *          whether this proxy represents the primary
 +   */
 +  protected void reinitialize(Socket socket, ClientProxyMembershipID proxyId,
 +      Cache cache, boolean ip, byte cc, Version ver) {
 +    // Re-initialize transient fields
 +    initializeTransientFields(socket, proxyId, ip, cc, ver);
 +    getCacheClientNotifier().getAcceptorStats().incCurrentQueueConnections();
 +
 +
 +    // Cancel expiration task
 +    cancelDurableExpirationTask(true);
 +
 +    // Set the message dispatcher's primary flag. This could go from primary
 +    // to secondary
 +    this._messageDispatcher._messageQueue.setPrimary(ip);
 +    this._messageDispatcher._messageQueue.setClientConflation(cc);
 +
 +    reinitializeClientAuths();
 +    this.creationDate = new Date();
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}: Has been reinitialized", this);
 +    }
 +  }
 +
 +  protected boolean isDurable() {
 +    return getProxyID().isDurable();
 +  }
 +
 +  protected String getDurableId() {
 +    return getProxyID().getDurableId();
 +  }
 +
 +  protected int getDurableTimeout() {
 +    return getProxyID().getDurableTimeout();
 +  }
 +
 +  private boolean getDurableKeepAlive() {
 +    return this.keepalive;
 +  }
 +
 +  protected String getHARegionName() {
 +    return getProxyID().getHARegionName();
 +  }
 +
 +  public Region getHARegion() {
 +    return this._messageDispatcher._messageQueue.getRegion();
 +  }
 +  
 +  public Version getVersion() {
 +    return this.clientVersion;
 +  }
 +  
 +  protected void scheduleDurableExpirationTask() {
 +    SystemTimer.SystemTimerTask task = new SystemTimer.SystemTimerTask() {
 +      @Override
 +      public void run2() {
 +        _durableExpirationTask.compareAndSet(this, null);
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0__THE_EXPIRATION_TASK_HAS_FIRED_SO_THIS_PROXY_IS_BEING_TERMINATED, CacheClientProxy.this));
 +        // Remove the proxy from the CacheClientNofier's registry
 +        getCacheClientNotifier().removeClientProxy(CacheClientProxy.this);
 +        getCacheClientNotifier().durableClientTimedOut(CacheClientProxy.this.proxyID);
 +
 +        // Close the proxy
 +        terminateDispatching(false);
 +        _cacheClientNotifier._statistics.incQueueDroppedCount();
 +
 +        /**
 +         * Setting the expiration task to null again and cancelling existing
 +         * one, if any. See #50894.
 +         * <p/>
 +         * The message dispatcher may again set the expiry task in below path:
 +         * <code>
 +         *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.scheduleDurableExpirationTask(CacheClientProxy.java:2020)
 +         *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.pauseDispatching(CacheClientProxy.java:924)
 +         *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy$MessageDispatcher.pauseOrUnregisterProxy(CacheClientProxy.java:2813)
 +         *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy$MessageDispatcher.run(CacheClientProxy.java:2692)
 +         * </code>
 +         * <p/>
 +         * This is because message dispatcher may get an IOException with
 +         * "Proxy closing due to socket being closed locally" during/after
 +         * terminateDispatching(false) above.
 +         */
 +        Object task = _durableExpirationTask.getAndSet(null);
 +        if (task != null) {
 +          ((SystemTimerTask)task).cancel();
 +        }
 +      }
 +
 +    };
 +    if(this._durableExpirationTask.compareAndSet(null, task)) {
 +      _cache.getCCPTimer().schedule(task,
 +          getDurableTimeout()*1000L);
 +    }
 +  }
 +
 +  protected void cancelDurableExpirationTask(boolean logMessage) {
 +    SystemTimer.SystemTimerTask task = (SystemTimerTask) _durableExpirationTask.getAndSet(null);
 +    if (task != null) {
 +      if (logMessage) {
 +        logger.info(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0_CANCELLING_EXPIRATION_TASK_SINCE_THE_CLIENT_HAS_RECONNECTED, this));
 +      }
 +      task.cancel();
 +    }
 +  }
 +
 +  /**
 +   * Class <code>ClientInterestList</code> provides a convenient interface
 +   * for manipulating client interest information.
 +   */
 +  static protected class ClientInterestList
 +   {
 +    
 +    final CacheClientProxy ccp;
 +    
 +    final Object id;
 +
 +     /**
 +     * An object used for synchronizing the interest lists
 +     */
 +    final private Object interestListLock = new Object();
 +    
 +    /**
 +     * Regions that this client is interested in
 +     */
 +    final protected Set<String> regions = new HashSet<String>();
 +
 +    /**
 +     * Constructor.
 +     */
 +    protected ClientInterestList(CacheClientProxy ccp, Object interestID) {
 +      this.ccp = ccp;
 +      this.id = interestID;
 +      // this.id = getNextId();
 +    }
 +
 +    /**
 +     * Registers interest in the input region name and key
 +     */
 +    protected void registerClientInterest(String regionName,
 +        Object keyOfInterest, int interestType, boolean sendUpdatesAsInvalidates)
 +    {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: registerClientInterest region={} key={}", ccp, regionName, keyOfInterest);
 +      }
 +      Set keysRegistered = null;
 +      synchronized(this.interestListLock) {
 +        LocalRegion r = (LocalRegion)this.ccp._cache.getRegion(regionName, true);
 +        if (r == null) {
 +          throw new RegionDestroyedException("Region could not be found for interest registration", regionName);
 +        }
 +        if ( ! (r instanceof CacheDistributionAdvisee) ) {
 +          throw new IllegalArgumentException("region " + regionName + " is not distributed and does not support interest registration");
 +        }
 +        FilterProfile p = r.getFilterProfile();
 +        keysRegistered = p.registerClientInterest(id, keyOfInterest, interestType, sendUpdatesAsInvalidates);
 +        regions.add(regionName);
 +      }
 +      // Perform actions if any keys were registered  
 +      if ((keysRegistered != null) && containsInterestRegistrationListeners()
 +          && !keysRegistered.isEmpty()) {
 +        handleInterestEvent(regionName, keysRegistered, interestType, true);
 +      } 
 +    }
 +    
 +    
 +    protected FilterProfile getProfile(String regionName) {
 +      try {
 +        return this.ccp._cache.getFilterProfile(regionName);
 +      } catch (CacheClosedException e) {
 +        return null;
 +      }
 +    }
 +
 +    /**
 +     * Unregisters interest in the input region name and key
 +     *
 +     * @param regionName
 +     *          The fully-qualified name of the region in which to unregister
 +     *          interest
 +     * @param keyOfInterest
 +     *          The key in which to unregister interest
 +     */
 +    protected void unregisterClientInterest(String regionName,
 +        Object keyOfInterest, int interestType)
 +    {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: unregisterClientInterest region={} key={}", ccp, regionName, keyOfInterest);
 +      }
 +      FilterProfile p = getProfile(regionName);
 +      Set keysUnregistered = null;
 +      synchronized(this.interestListLock) {
 +        if (p != null) {
 +          keysUnregistered = p.unregisterClientInterest(
 +            id, keyOfInterest, interestType);
 +          if (!p.hasInterestFor(id)) {
 +            this.regions.remove(regionName);
 +          }
 +        } else {
 +          this.regions.remove(regionName);
 +        }
 +      }
 +      if (keysUnregistered != null && !keysUnregistered.isEmpty()) { 
 +        handleInterestEvent(regionName, keysUnregistered, interestType, false); 
 +      } 
 +    }
 +
 +    /**
 +     * Registers interest in the input region name and list of keys
 +     *
 +     * @param regionName
 +     *          The fully-qualified name of the region in which to register
 +     *          interest
 +     * @param keysOfInterest
 +     *          The list of keys in which to register interest
 +     */
 +    protected void registerClientInterestList(String regionName,
 +        List keysOfInterest, boolean sendUpdatesAsInvalidates) {
 +      FilterProfile p = getProfile(regionName);
 +      if (p == null) {
 +        throw new RegionDestroyedException("Region not found during client interest registration", regionName);
 +      }
 +      Set keysRegistered = null;
 +      synchronized(this.interestListLock) {
 +        keysRegistered = p.registerClientInterestList(id, keysOfInterest, sendUpdatesAsInvalidates);
 +        regions.add(regionName);
 +      }
 +      // Perform actions if any keys were registered 
 +      if (containsInterestRegistrationListeners() && !keysRegistered.isEmpty()) {
 +        handleInterestEvent(regionName, keysRegistered, InterestType.KEY, true);
 +      } 
 +    }
 +
 +    /**
 +     * Unregisters interest in the input region name and list of keys
 +     *
 +     * @param regionName
 +     *          The fully-qualified name of the region in which to unregister
 +     *          interest
 +     * @param keysOfInterest
 +     *          The list of keys in which to unregister interest
 +     */
 +    protected void unregisterClientInterestList(String regionName,
 +        List keysOfInterest)
 +    {
 +      FilterProfile p = getProfile(regionName);
 +      Set keysUnregistered = null;
 +      synchronized(this.interestListLock) {
 +        if (p != null) {
 +          keysUnregistered = p.unregisterClientInterestList(
 +              id, keysOfInterest);
 +          if (!p.hasInterestFor(id)) {
 +            regions.remove(regionName);
 +          }
 +        } else {
 +          regions.remove(regionName);
 +        }
 +      }
 +     // Perform actions if any keys were unregistered
 +      if (!keysUnregistered.isEmpty()) { 
 +        handleInterestEvent(regionName, keysUnregistered, InterestType.KEY,false); 
 +      } 
 +    }
 +
 +    /*
 +     * Returns whether this interest list has any keys, patterns or filters of
 +     * interest. It answers the question: Are any clients being notified because
 +     * of this interest list? @return whether this interest list has any keys,
 +     * patterns or filters of interest
 +     */
 +    protected boolean hasInterest() {
 +      return regions.size() > 0;
 +    }
 +
 +    protected void clearClientInterestList() {
 +      boolean isClosed = ccp.getCache().isClosed();
 +      
 +      synchronized(this.interestListLock) {
 +        for (String regionName: regions) {
 +          FilterProfile p = getProfile(regionName);
 +          if (p == null) {
 +            continue;
 +          }
 +          if (!isClosed) {
 +            if (p.hasAllKeysInterestFor(id)) {
 +              Set allKeys = new HashSet();
 +              allKeys.add(".*");
 +              allKeys = Collections.unmodifiableSet(allKeys);
 +              handleInterestEvent(regionName, allKeys,
 +                  InterestType.REGULAR_EXPRESSION, false);
 +            }
 +            Set keysOfInterest = p.getKeysOfInterestFor(id);
 +            if (keysOfInterest != null && keysOfInterest.size() > 0) {
 +              handleInterestEvent(regionName, keysOfInterest,
 +                  InterestType.KEY, false);
 +            }
 +            Map<String,Pattern> patternsOfInterest =
 +              p.getPatternsOfInterestFor(id);
 +            if (patternsOfInterest != null && patternsOfInterest.size() > 0) {
 +              handleInterestEvent(regionName, patternsOfInterest.keySet(),
 +                  InterestType.REGULAR_EXPRESSION, false);
 +            }
 +          }
 +          p.clearInterestFor(id);
 +        }
 +        regions.clear();
 +      }
 +    }
 +
 +
 +    private void handleInterestEvent(String regionName, Set keysOfInterest,
 +        int interestType, boolean isRegister) {
 +      // Notify the region about this register interest event if:
 +      // - the application has requested it
 +      // - this is a primary CacheClientProxy (otherwise multiple notifications
 +      // may occur)
 +      // - it is a key interest type (regex is currently not supported)
 +      InterestRegistrationEvent event = null;
 +      if (NOTIFY_REGION_ON_INTEREST && this.ccp.isPrimary()
 +          && interestType == InterestType.KEY) {
 +        event = new InterestRegistrationEventImpl(this.ccp, regionName,
 +            keysOfInterest, interestType, isRegister);
 +        try {
 +          notifyRegionOfInterest(event);
 +        }
 +        catch (Exception e) {
 +          logger.warn(LocalizedStrings.CacheClientProxy_REGION_NOTIFICATION_OF_INTEREST_FAILED, e);
 +        }
 +      }
 +      // Invoke interest registration listeners
 +      if (containsInterestRegistrationListeners()) {
 +        if (event == null) {
 +          event = new InterestRegistrationEventImpl(this.ccp, regionName,
 +              keysOfInterest, interestType, isRegister);
 +        }
 +        notifyInterestRegistrationListeners(event);
 +      }      
 +    }
 +
 +    private void notifyRegionOfInterest(InterestRegistrationEvent event) {
 +      this.ccp.getCacheClientNotifier().handleInterestEvent(event);
 +    }
 +
 +    private void notifyInterestRegistrationListeners(
 +        InterestRegistrationEvent event) {
 +      this.ccp.getCacheClientNotifier().notifyInterestRegistrationListeners(
 +          event);
 +    }
 +
 +    private boolean containsInterestRegistrationListeners() {
 +      return this.ccp.getCacheClientNotifier()
 +          .containsInterestRegistrationListeners();
 +    }
 +  }
 +
 +
 +  /**
 +   * Class <code>MessageDispatcher</code> is a <code>Thread</code> that
 +   * processes messages bound for the client by taking messsages from the
 +   * message queue and sending them to the client over the socket.
 +   */
 +  static class MessageDispatcher extends Thread
 +   {
 +
 +    /**
 +     * The queue of messages to be sent to the client
 +     */
 +    protected final HARegionQueue _messageQueue;
 +
 +//    /**
 +//     * An int used to keep track of the number of messages dropped for logging
 +//     * purposes. If greater than zero then a warning has been logged about
 +//     * messages being dropped.
 +//     */
 +//    private int _numberOfMessagesDropped = 0;
 +
 +    /**
 +     * The proxy for which this dispatcher is processing messages
 +     */
 +    private final CacheClientProxy _proxy;
 +
 +//    /**
 +//     * The conflator faciliates message conflation
 +//     */
 +//     protected BridgeEventConflator _eventConflator;
 +
 +    /**
 +     * Whether the dispatcher is stopped
 +     */
 +    private volatile boolean _isStopped = true;
 +
 +    /**
 +     * @guarded.By _pausedLock
 +     */
 +    //boolean _isPausedDispatcher = false;
 +    
 +    /**
 +     * A lock object used to control pausing this dispatcher
 +     */
 +    protected final Object _pausedLock = new Object();
 +
 +    /**
 +     * An object used to protect when dispatching is being stopped.
 +     */
 +    private final Object _stopDispatchingLock = new Object();
 +
 +    private final ReadWriteLock socketLock = new ReentrantReadWriteLock();
 +
 +    private final Lock socketWriteLock = socketLock.writeLock();
 +//    /**
 +//     * A boolean verifying whether a warning has already been issued if the
 +//     * message queue has reached its capacity.
 +//     */
 +//    private boolean _messageQueueCapacityReachedWarning = false;
 +
 +    /**
 +     * Constructor.
 +     *
 +     * @param proxy
 +     *          The <code>CacheClientProxy</code> for which this dispatcher is
 +     *          processing messages
 +     * @param name thread name for this dispatcher
 +     

<TRUNCATED>


[027/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
index 6d9ca49,0000000..018d05b
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
@@@ -1,436 -1,0 +1,435 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.tier.sockets.command;
 +
 +import java.io.IOException;
 +import java.util.HashSet;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.client.internal.ExecuteFunctionHelper;
- import com.gemstone.gemfire.cache.client.internal.Op;
 +import com.gemstone.gemfire.cache.execute.Function;
 +import com.gemstone.gemfire.cache.execute.FunctionException;
 +import com.gemstone.gemfire.cache.execute.FunctionInvocationTargetException;
 +import com.gemstone.gemfire.cache.execute.FunctionService;
 +import com.gemstone.gemfire.cache.operations.ExecuteFunctionOperationContext;
- import com.gemstone.gemfire.i18n.LogWriterI18n;
++import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.DistributedRegion;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
 +import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionExecutor;
 +import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
 +import com.gemstone.gemfire.internal.cache.execute.MemberMappedArgument;
 +import com.gemstone.gemfire.internal.cache.execute.PartitionedRegionFunctionExecutor;
 +import com.gemstone.gemfire.internal.cache.execute.ServerToClientFunctionResultSender;
 +import com.gemstone.gemfire.internal.cache.execute.ServerToClientFunctionResultSender65;
 +import com.gemstone.gemfire.internal.cache.tier.CachedRegionHelper;
 +import com.gemstone.gemfire.internal.cache.tier.Command;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ChunkedMessage;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.security.AuthorizeRequest;
 +
 +/**
 + * 
 + * @author kbachhav
 + *  @since 6.6
 + */
 +public class ExecuteRegionFunction66 extends BaseCommand {
 +  
 +  private final static ExecuteRegionFunction66 singleton = new ExecuteRegionFunction66();
 +
 +  public static Command getCommand() {
 +    return singleton;
 +  }
 +
 +  private ExecuteRegionFunction66() {
 +  }
 +
 +  @Override
 +  public void cmdExecute(Message msg, ServerConnection servConn, long start)
 +      throws IOException {
 +    String regionName = null;
 +    Object function = null;
 +    Object args = null;
 +    MemberMappedArgument memberMappedArg = null;
 +    final boolean isBucketsAsFilter ;
 +    final byte isReExecute ;
 +    Set<Object> filter = null;
 +    byte hasResult = 0;
 +    int removedNodesSize = 0;
 +    Set<Object> removedNodesSet = null;
 +    int filterSize = 0, partNumber = 0;
 +    CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
 +    byte functionState = 0;
 +    int functionTimeout = GemFireCacheImpl.DEFAULT_CLIENT_FUNCTION_TIMEOUT;
 +    try {
 +      byte[] bytes = msg.getPart(0).getSerializedForm();
 +      functionState = bytes[0];
 +      if (bytes.length >= 5 && servConn.getClientVersion().ordinal() >= Version.GFE_8009.ordinal()) {
 +        functionTimeout = Part.decodeInt(bytes, 1);
 +      }
 +      if (functionState != 1) {
 +        hasResult = (byte)((functionState & 2) - 1);
 +      }
 +      else {
 +        hasResult = functionState;
 +      }
 +      if (hasResult == 1) {
 +        servConn.setAsTrue(REQUIRES_RESPONSE);
 +        servConn.setAsTrue(REQUIRES_CHUNKED_RESPONSE);
 +      }
 +      regionName = msg.getPart(1).getString();
 +      function = msg.getPart(2).getStringOrObject();
 +      args = msg.getPart(3).getObject();
 +      Part part = msg.getPart(4);
 +      if (part != null) {
 +        Object obj = part.getObject();
 +        if (obj instanceof MemberMappedArgument) {
 +          memberMappedArg = (MemberMappedArgument)obj;
 +        }
 +      }
 +      byte[] flags =msg.getPart(5).getSerializedForm();
 +      if(servConn.getClientVersion().ordinal() > Version.GFE_81.ordinal()) {
 +        isBucketsAsFilter = (flags[0] & ExecuteFunctionHelper.BUCKETS_AS_FILTER_MASK) != 0 ; 
 +        isReExecute = (flags[0] & ExecuteFunctionHelper.IS_REXECUTE_MASK) != 0 ? (byte)1 : 0;
 +      }else {
 +        isReExecute = flags[0];
 +        isBucketsAsFilter = false;
 +      }
 +      filterSize = msg.getPart(6).getInt();
 +      if (filterSize != 0) {
 +        filter = new HashSet<Object>();
 +        partNumber = 7;
 +        for (int i = 0; i < filterSize; i++) {
 +          filter.add(msg.getPart(partNumber + i).getStringOrObject());
 +        }
 +      }
 +
 +      partNumber = 7 + filterSize;
 +      removedNodesSize = msg.getPart(partNumber).getInt();
 +
 +      if (removedNodesSize != 0) {
 +        removedNodesSet = new HashSet<Object>();
 +        partNumber = partNumber + 1;
 +
 +        for (int i = 0; i < removedNodesSize; i++) {
 +          removedNodesSet.add(msg.getPart(partNumber + i).getStringOrObject());
 +        }
 +      }
 +
 +    }
 +    catch (ClassNotFoundException exception) {
 +      logger.warn(LocalizedMessage.create(LocalizedStrings.ExecuteRegionFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, function), exception);
 +      if (hasResult == 1) {
 +        writeChunkedException(msg, exception, false, servConn);
 +      }
 +      else {
 +        writeException(msg, exception, false, servConn);
 +      }
 +      servConn.setAsTrue(RESPONDED);
 +      return;
 +    }
 +    if (function == null || regionName == null) {
 +      String message = null;
 +      if (function == null) {
 +        message = LocalizedStrings.ExecuteRegionFunction_THE_INPUT_0_FOR_THE_EXECUTE_FUNCTION_REQUEST_IS_NULL
 +            .toLocalizedString("function");
 +      }
 +      if (regionName == null) {
 +        message = LocalizedStrings.ExecuteRegionFunction_THE_INPUT_0_FOR_THE_EXECUTE_FUNCTION_REQUEST_IS_NULL
 +            .toLocalizedString("region");
 +      }
 +      logger.warn("{}: {}", servConn.getName(), message);
 +      sendError(hasResult, msg, message, servConn);
 +      return;
 +    }
 +    else {
 +      Region region = crHelper.getRegion(regionName);
 +      if (region == null) {
 +        String message = LocalizedStrings.ExecuteRegionFunction_THE_REGION_NAMED_0_WAS_NOT_FOUND_DURING_EXECUTE_FUNCTION_REQUEST
 +            .toLocalizedString(regionName);
 +        logger.warn("{}: {}", servConn.getName(), message);
 +        sendError(hasResult, msg, message, servConn);
 +        return;
 +      }
 +      HandShake handShake = (HandShake)servConn.getHandshake();
 +      int earlierClientReadTimeout = handShake.getClientReadTimeout();
 +      handShake.setClientReadTimeout(functionTimeout);
 +      ServerToClientFunctionResultSender resultSender = null;
 +      Function functionObject = null;
 +      try {
 +        if (function instanceof String) {
 +          functionObject = FunctionService.getFunction((String)function);
 +          if (functionObject == null) {
 +            String message = LocalizedStrings.ExecuteRegionFunction_THE_FUNCTION_0_HAS_NOT_BEEN_REGISTERED
 +                .toLocalizedString(function);
 +            logger.warn("{}: {}", servConn.getName(), message);
 +            sendError(hasResult, msg, message, servConn);
 +            return;
 +          }
 +          else {
 +            byte functionStateOnServerSide = AbstractExecution
 +                .getFunctionState(functionObject.isHA(), functionObject
 +                    .hasResult(), functionObject.optimizeForWrite());
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Function State on server side: {} on client: {}", functionStateOnServerSide, functionState);
 +            }
 +            if (functionStateOnServerSide != functionState) {
 +              String message = LocalizedStrings.FunctionService_FUNCTION_ATTRIBUTE_MISMATCH_CLIENT_SERVER
 +                  .toLocalizedString(function);
 +              logger.warn("{}: {}", servConn.getName(), message);
 +              sendError(hasResult, msg, message, servConn);
 +              return;
 +            }
 +          }
 +        }
 +        else {
 +          functionObject = (Function)function;
 +        }
 +        // check if the caller is authorized to do this operation on server
 +        AuthorizeRequest authzRequest = servConn.getAuthzRequest();
 +        final String functionName = functionObject.getId();
 +        final String regionPath = region.getFullPath();
 +        ExecuteFunctionOperationContext executeContext = null;
 +        if (authzRequest != null) {
 +          executeContext = authzRequest.executeFunctionAuthorize(functionName,
 +              regionPath, filter, args, functionObject.optimizeForWrite());
 +        }
 +
 +        // Construct execution
 +        AbstractExecution execution = (AbstractExecution)FunctionService
 +            .onRegion(region);
 +        ChunkedMessage m = servConn.getFunctionResponseMessage();
 +        m.setTransactionId(msg.getTransactionId());
 +        resultSender = new ServerToClientFunctionResultSender65(m,
 +            MessageType.EXECUTE_REGION_FUNCTION_RESULT, servConn,
 +            functionObject, executeContext);
 +
 +        if (execution instanceof PartitionedRegionFunctionExecutor) {
 +          if((hasResult == 1) && filter!= null &&filter.size() == 1) {
 +            ServerConnection.executeFunctionOnLocalNodeOnly((byte)1);
 +          }
 +          execution = new PartitionedRegionFunctionExecutor(
 +              (PartitionedRegion)region, filter, args, memberMappedArg,
 +              resultSender, removedNodesSet, isBucketsAsFilter);
 +        }
 +        else {
 +          execution = new DistributedRegionFunctionExecutor(
 +              (DistributedRegion)region, filter, args, memberMappedArg,
 +              resultSender);
 +        }
 +        if (isReExecute == 1) {
 +          execution = execution.setIsReExecute();
 +        }
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Executing Function: {} on Server: {} with Execution: {} functionState={} reExecute={} hasResult={}", functionObject.getId(), servConn, execution, functionState, isReExecute, hasResult);
 +        }
 +        if (hasResult == 1) {
 +          if (function instanceof String) {
 +            switch (functionState) {
 +              case AbstractExecution.NO_HA_HASRESULT_NO_OPTIMIZEFORWRITE:
 +                execution.execute((String)function, true, false, false)
 +                    .getResult();
 +                break;
 +              case AbstractExecution.HA_HASRESULT_NO_OPTIMIZEFORWRITE:
 +                execution.execute((String)function, true, true, false)
 +                    .getResult();
 +                break;
 +              case AbstractExecution.HA_HASRESULT_OPTIMIZEFORWRITE:
 +                execution.execute((String)function, true, true, true)
 +                    .getResult();
 +                break;
 +              case AbstractExecution.NO_HA_HASRESULT_OPTIMIZEFORWRITE:
 +                execution.execute((String)function, true, false, true)
 +                    .getResult();
 +                break;
 +            }
 +          }
 +          else {
 +            execution.execute(functionObject).getResult();
 +          }
 +        }
 +        else {
 +          if (function instanceof String) {
 +            switch (functionState) {
 +              case AbstractExecution.NO_HA_NO_HASRESULT_NO_OPTIMIZEFORWRITE:
 +                execution.execute((String)function, false, false, false);
 +                break;
 +              case AbstractExecution.NO_HA_NO_HASRESULT_OPTIMIZEFORWRITE:
 +                execution.execute((String)function, false, false, true);
 +                break;
 +            }
 +          }
 +          else {
 +            execution.execute(functionObject);
 +          }
 +          writeReply(msg, servConn);
 +        }
 +      }
 +      catch (IOException ioe) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.ExecuteRegionFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, function), ioe);
 +        final String message = LocalizedStrings.ExecuteRegionFunction_SERVER_COULD_NOT_SEND_THE_REPLY
 +            .toLocalizedString();
 +        sendException(hasResult, msg, message, servConn, ioe);
 +      }
 +      catch (FunctionException fe) {
 +        String message = fe.getMessage();
- 
-         if (fe.getCause() instanceof FunctionInvocationTargetException) {
-           if (fe.getCause() instanceof InternalFunctionInvocationTargetException) {
++        Object cause = fe.getCause();
++        if (cause instanceof FunctionInvocationTargetException || cause instanceof QueryInvocationTargetException) {
++          if (cause instanceof InternalFunctionInvocationTargetException) {
 +            // Fix for #44709: User should not be aware of
 +            // InternalFunctionInvocationTargetException. No instance of
 +            // InternalFunctionInvocationTargetException is giving useful
 +            // information to user to take any corrective action hence logging
 +            // this at fine level logging
 +            // 1> When bucket is moved
 +            // 2> Incase of HA FucntionInvocationTargetException thrown. Since
 +            // it is HA, fucntion will be reexecuted on right node
 +            // 3> Multiple target nodes found for single hop operation
 +            // 4> in case of HA member departed
 +            if (logger.isDebugEnabled()) {
 +              logger.debug(LocalizedMessage.create(LocalizedStrings.ExecuteFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, new Object[] { function }), fe);
 +            }
 +          }
 +          else if (functionObject.isHA()) {
 +            logger.warn(LocalizedMessage.create(LocalizedStrings.ExecuteRegionFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, function + " :" + message));
 +          }
 +          else {
 +            logger.warn(LocalizedMessage.create(LocalizedStrings.ExecuteRegionFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, function), fe);
 +          }
 +
 +          resultSender.setException(fe);
 +        }
 +        else {
 +          logger.warn(LocalizedMessage.create(LocalizedStrings.ExecuteRegionFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, function), fe);
 +          sendException(hasResult, msg, message, servConn, fe);
 +        }
 +
 +      }
 +      catch (Exception e) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.ExecuteRegionFunction_EXCEPTION_ON_SERVER_WHILE_EXECUTIONG_FUNCTION_0, function), e);
 +        String message = e.getMessage();
 +        sendException(hasResult, msg, message, servConn, e);
 +      }
 +
 +      finally {
 +        handShake.setClientReadTimeout(earlierClientReadTimeout);
 +        ServerConnection.executeFunctionOnLocalNodeOnly((byte)0);
 +      }
 +    }
 +  }
 +
 +  private void sendException(byte hasResult, Message msg, String message,
 +      ServerConnection servConn, Throwable e) throws IOException {
 +    synchronized (msg) {
 +      if (hasResult == 1) {
 +        writeFunctionResponseException(msg, MessageType.EXCEPTION, message,
 +            servConn, e);
 +      }
 +      else {
 +        writeException(msg, e, false, servConn);
 +      }
 +      servConn.setAsTrue(RESPONDED);
 +    }
 +  }
 +
 +  private void sendError(byte hasResult, Message msg, String message,
 +      ServerConnection servConn) throws IOException {
 +    synchronized (msg) {
 +      if (hasResult == 1) {
 +        writeFunctionResponseError(msg,
 +            MessageType.EXECUTE_REGION_FUNCTION_ERROR, message, servConn);
 +      }
 +      else {
 +        writeErrorResponse(msg, MessageType.EXECUTE_REGION_FUNCTION_ERROR,
 +            message, servConn);
 +      }
 +      servConn.setAsTrue(RESPONDED);
 +    }
 +  }
 +
 +  protected static void writeFunctionResponseException(Message origMsg,
 +      int messageType, String message, ServerConnection servConn, Throwable e)
 +      throws IOException {
 +    ChunkedMessage functionResponseMsg = servConn.getFunctionResponseMessage();
 +    ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
 +    int numParts = 0;
 +    if (functionResponseMsg.headerHasBeenSent()) {
 +      if (e instanceof FunctionException
 +          && e.getCause() instanceof InternalFunctionInvocationTargetException) {
 +        functionResponseMsg.setNumberOfParts(3);
 +        functionResponseMsg.addObjPart(e);
 +        functionResponseMsg.addStringPart(BaseCommand.getExceptionTrace(e));
 +        InternalFunctionInvocationTargetException fe = (InternalFunctionInvocationTargetException)e
 +            .getCause();
 +        functionResponseMsg.addObjPart(fe.getFailedNodeSet());
 +        numParts = 3;
 +      }
 +      else {
 +        functionResponseMsg.setNumberOfParts(2);
 +        functionResponseMsg.addObjPart(e);
 +        functionResponseMsg.addStringPart(BaseCommand.getExceptionTrace(e));
 +        numParts = 2;
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk while reply in progress: ", servConn.getName(), e);
 +      }
 +      functionResponseMsg.setServerConnection(servConn);
 +      functionResponseMsg.setLastChunkAndNumParts(true, numParts);
 +      // functionResponseMsg.setLastChunk(true);
 +      functionResponseMsg.sendChunk(servConn);
 +    }
 +    else {
 +      chunkedResponseMsg.setMessageType(messageType);
 +      chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
 +      chunkedResponseMsg.sendHeader();
 +      if (e instanceof FunctionException
 +          && e.getCause() instanceof InternalFunctionInvocationTargetException) {
 +        chunkedResponseMsg.setNumberOfParts(3);
 +        chunkedResponseMsg.addObjPart(e);
 +        chunkedResponseMsg.addStringPart(BaseCommand.getExceptionTrace(e));
 +        InternalFunctionInvocationTargetException fe = (InternalFunctionInvocationTargetException)e
 +            .getCause();
 +        chunkedResponseMsg.addObjPart(fe.getFailedNodeSet());
 +        numParts = 3;
 +      }
 +      else {
 +        chunkedResponseMsg.setNumberOfParts(2);
 +        chunkedResponseMsg.addObjPart(e);
 +        chunkedResponseMsg.addStringPart(BaseCommand.getExceptionTrace(e));
 +        numParts = 2;
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}: Sending exception chunk: ", servConn.getName(), e);
 +      }
 +      chunkedResponseMsg.setServerConnection(servConn);
 +      chunkedResponseMsg.setLastChunkAndNumParts(true, numParts);
 +      chunkedResponseMsg.sendChunk(servConn);
 +    }
 +  }
 +}
 +

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/AsyncEventQueueCreation.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/AsyncEventQueueCreation.java
index 60afc14,0000000..77f9596
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/AsyncEventQueueCreation.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/AsyncEventQueueCreation.java
@@@ -1,222 -1,0 +1,223 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.xmlcache;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
 +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
 +import com.gemstone.gemfire.cache.wan.GatewayEventFilter;
 +import com.gemstone.gemfire.cache.wan.GatewayEventSubstitutionFilter;
 +import com.gemstone.gemfire.cache.wan.GatewaySender.OrderPolicy;
 +import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAttributes;
 +
 +public class AsyncEventQueueCreation implements AsyncEventQueue {
 +
 +  private String id = null;
 +  private List<GatewayEventFilter> gatewayEventFilters = new ArrayList<GatewayEventFilter>();
 +  private GatewayEventSubstitutionFilter gatewayEventSubstitutionFilter = null;
 +  private AsyncEventListener asyncEventListener = null;
 +  private int batchSize = 0;
 +  private int batchTimeInterval = 0;
 +  private boolean isBatchConflationEnabled = false;
 +  private boolean isPersistent = false;
 +  private String diskStoreName = null;
 +  private boolean isDiskSynchronous = false;
 +  private int maxQueueMemory = 0;
 +  private boolean isParallel = false;
 +  private boolean isBucketSorted = false;
 +  private boolean isHDFSQueue = false;
 +  private int dispatcherThreads = 1;
 +  private OrderPolicy orderPolicy = OrderPolicy.KEY;
 +  
 +  public AsyncEventQueueCreation() {
 +  }
 +  
 +  public AsyncEventQueueCreation(String id, GatewaySenderAttributes senderAttrs, AsyncEventListener eventListener) {
 +    this.id = id;
 +    this.batchSize = senderAttrs.batchSize;
 +    this.batchTimeInterval = senderAttrs.batchTimeInterval;
 +    this.isBatchConflationEnabled = senderAttrs.isBatchConflationEnabled;
 +    this.isPersistent = senderAttrs.isPersistenceEnabled;
 +    this.diskStoreName = senderAttrs.diskStoreName;
 +    this.isDiskSynchronous = senderAttrs.isDiskSynchronous;
 +    this.maxQueueMemory = senderAttrs.maximumQueueMemory;
 +    this.isParallel = senderAttrs.isParallel;
 +    this.dispatcherThreads = senderAttrs.dispatcherThreads;
 +    this.orderPolicy = senderAttrs.policy;
 +    this.asyncEventListener = eventListener;
 +    this.isBucketSorted = senderAttrs.isBucketSorted; 
 +    this.isHDFSQueue = senderAttrs.isHDFSQueue;
++    this.gatewayEventSubstitutionFilter = senderAttrs.eventSubstitutionFilter;
 +  }
 +  
 +  @Override
 +  public AsyncEventListener getAsyncEventListener() {
 +    return this.asyncEventListener;
 +  }
 +  
 +  public void setAsyncEventListener(AsyncEventListener eventListener) {
 +    this.asyncEventListener = eventListener;
 +  }
 +  
 +  public void addGatewayEventFilter(
 +      GatewayEventFilter filter) {
 +    this.gatewayEventFilters.add(filter);
 +  }
 +
 +  public List<GatewayEventFilter> getGatewayEventFilters() {
 +    return this.gatewayEventFilters;
 +  }
 +
 +  public GatewayEventSubstitutionFilter getGatewayEventSubstitutionFilter() {
 +    return this.gatewayEventSubstitutionFilter;
 +  }
 +  
 +  public void setGatewayEventSubstitutionFilter(GatewayEventSubstitutionFilter filter) {
 +    this.gatewayEventSubstitutionFilter = filter;
 +  }
 +
 +  @Override
 +  public int getBatchSize() {
 +    return this.batchSize;
 +  }
 +  
 +  public void setBatchSize(int batchSize) {
 +    this.batchSize = batchSize;
 +  }
 +  
 +  @Override
 +  public int getBatchTimeInterval() {
 +    return this.batchTimeInterval;
 +  }
 +  
 +  public void setBatchTimeInterval(int batchTimeInterval) {
 +    this.batchTimeInterval = batchTimeInterval;
 +  }
 +  
 +  @Override
 +  public boolean isBatchConflationEnabled() {
 +    return this.isBatchConflationEnabled;
 +  }
 +  
 +  public void setBatchConflationEnabled(boolean batchConflationEnabled) {
 +    this.isBatchConflationEnabled = batchConflationEnabled;
 +  }
 +
 +  @Override
 +  public String getDiskStoreName() {
 +    return this.diskStoreName;
 +  }
 +  
 +  public void setDiskStoreName(String diskStore) {
 +    this.diskStoreName = diskStore;
 +  }
 +  
 +  @Override
 +  public boolean isDiskSynchronous() {
 +    return this.isDiskSynchronous;
 +  }
 +  
 +  public void setDiskSynchronous(boolean diskSynchronous) {
 +    this.isDiskSynchronous = diskSynchronous;
 +  }
 +
 +  @Override
 +  public String getId() {
 +    return this.id;
 +  }
 +  
 +  public void setId(String id) {
 +    this.id = id;
 +  }
 +  
 +  @Override
 +  public int getMaximumQueueMemory() {
 +    return this.maxQueueMemory;
 +  }
 +  
 +  public void setMaximumQueueMemory(int maxQueueMemory) {
 +    this.maxQueueMemory = maxQueueMemory;
 +  }
 +  
 +  @Override
 +  public boolean isPersistent() {
 +    return this.isPersistent;
 +  }
 +  
 +  public void setPersistent(boolean isPersistent) {
 +    this.isPersistent = isPersistent;
 +  }
 +
 +  public void setParallel(boolean isParallel) {
 +    this.isParallel = isParallel;
 +  }
 +  
 +  @Override
 +  public int getDispatcherThreads() {
 +    return this.dispatcherThreads;
 +  }
 +  
 +  public void setDispatcherThreads(int numThreads) {
 +    this.dispatcherThreads = numThreads;
 +  }
 +  
 +  @Override
 +  public OrderPolicy getOrderPolicy() {
 +    return this.orderPolicy;
 +  }
 +  
 +  public void setOrderPolicy(OrderPolicy policy) {
 +    this.orderPolicy = policy;
 +  }
 +  
 +  @Override
 +  public boolean isPrimary() {
 +    return true;
 +  }
 +  
 +  @Override
 +  public int size() {
 +    return 0;
 +  }
 + 
 +  public void start() {};
 +  public void stop() {};
 +  public void destroy() {};
 +  public void pause() {};
 +  public void resume() {}
 +
 +  public boolean isParallel() {
 +    return this.isParallel;
 +  }
 +
 +  public boolean isBucketSorted() {
 +    return this.isBucketSorted;
 +  }
 +  
 +  public void setBucketSorted(boolean isBucketSorted) {
 +    this.isBucketSorted = isBucketSorted;
 +  }
 +  public boolean isHDFSQueue() {
 +    return this.isHDFSQueue;
 +  }
 +  
 +  public void setIsHDFSQueue(boolean isHDFSQueue) {
 +    this.isHDFSQueue = isHDFSQueue;
 +  }
 +}


[099/100] [abbrv] incubator-geode git commit: GEODE-870: test case fixes.

Posted by ud...@apache.org.
GEODE-870: test case fixes.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/bd6749c1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/bd6749c1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/bd6749c1

Branch: refs/heads/feature/GEODE-870
Commit: bd6749c1092bffe51d4238120fe1671cac61ce8b
Parents: cafcf56
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Wed Feb 17 14:51:19 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 07:29:00 2016 +1100

----------------------------------------------------------------------
 .../membership/gms/membership/GMSJoinLeave.java | 212 ++++++++++++-------
 .../cache30/CacheSerializableRunnable.java      |  16 +-
 .../test/dunit/SerializableRunnable.java        |   2 +-
 3 files changed, 156 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bd6749c1/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index 8ba4952..dcb2721 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -55,104 +55,166 @@ import static com.gemstone.gemfire.internal.DataSerializableFixedID.*;
  * that Geode formerly used for this purpose.
  */
 public class GMSJoinLeave implements JoinLeave, MessageHandler {
-  
+
   public static final String BYPASS_DISCOVERY_PROPERTY = "gemfire.bypass-discovery";
 
-  /** amount of time to wait for responses to FindCoordinatorRequests */
+  /**
+   * amount of time to wait for responses to FindCoordinatorRequests
+   */
   private static final int DISCOVERY_TIMEOUT = Integer.getInteger("gemfire.discovery-timeout", 3000);
 
-  /** amount of time to sleep before trying to join after a failed attempt */
+  /**
+   * amount of time to sleep before trying to join after a failed attempt
+   */
   private static final int JOIN_RETRY_SLEEP = Integer.getInteger("gemfire.join-retry-sleep", 1000);
 
-  /** time to wait for a broadcast message to be transmitted by jgroups */
+  /**
+   * time to wait for a broadcast message to be transmitted by jgroups
+   */
   private static final long BROADCAST_MESSAGE_SLEEP_TIME = Long.getLong("gemfire.broadcast-message-sleep-time", 1000);
 
-  /** if the locators don't know who the coordinator is we send find-coord requests to this many nodes */
+  /**
+   * if the locators don't know who the coordinator is we send find-coord requests to this many nodes
+   */
   private static final int MAX_DISCOVERY_NODES = Integer.getInteger("gemfire.max-discovery-nodes", 30);
 
-  /** interval for broadcasting the current view to members in case they didn't get it the first time */
+  /**
+   * interval for broadcasting the current view to members in case they didn't get it the first time
+   */
   private static final long VIEW_BROADCAST_INTERVAL = Long.getLong("gemfire.view-broadcast-interval", 60000);
 
-  /** membership logger */
+  /**
+   * membership logger
+   */
   private static final Logger logger = Services.getLogger();
 
-  /** the view ID where I entered into membership */
+  /**
+   * the view ID where I entered into membership
+   */
   private int birthViewId;
 
-  /** my address */
+  /**
+   * my address
+   */
   private InternalDistributedMember localAddress;
 
   private Services services;
 
-  /** have I connected to the distributed system? */
+  /**
+   * have I connected to the distributed system?
+   */
   private volatile boolean isJoined;
 
-  /** guarded by viewInstallationLock */
+  /**
+   * guarded by viewInstallationLock
+   */
   private boolean isCoordinator;
 
-  /** a synch object that guards view installation */
+  /**
+   * a synch object that guards view installation
+   */
   private final Object viewInstallationLock = new Object();
-  
-  /** the currently installed view.  Guarded by viewInstallationLock */
+
+  /**
+   * the currently installed view.  Guarded by viewInstallationLock
+   */
   private volatile NetView currentView;
 
-  /** the previous view **/
+  /**
+   * the previous view
+   **/
   private volatile NetView previousView;
 
-  /** members who we have been declared dead in the current view */
+  /**
+   * members who we have been declared dead in the current view
+   */
   private final Set<InternalDistributedMember> removedMembers = new HashSet<>();
 
-  /** members who we've received a leave message from **/
+  /**
+   * members who we've received a leave message from
+   **/
   private final Set<InternalDistributedMember> leftMembers = new HashSet<>();
 
-  /** a new view being installed */
+  /**
+   * a new view being installed
+   */
   private NetView preparedView;
 
-  /** the last view that conflicted with view preparation */
+  /**
+   * the last view that conflicted with view preparation
+   */
   private NetView lastConflictingView;
 
   private List<InetSocketAddress> locators;
 
-  /** a list of join/leave/crashes */
+  /**
+   * a list of join/leave/crashes
+   */
   private final List<DistributionMessage> viewRequests = new LinkedList<DistributionMessage>();
 
-  /** the established request collection jitter.  This can be overridden for testing with delayViewCreationForTest */
+  /**
+   * the established request collection jitter.  This can be overridden for testing with delayViewCreationForTest
+   */
   long requestCollectionInterval = MEMBER_REQUEST_COLLECTION_INTERVAL;
 
-  /** collects the response to a join request */
+  /**
+   * collects the response to a join request
+   */
   private JoinResponseMessage[] joinResponse = new JoinResponseMessage[1];
 
-  /** collects responses to new views */
+  /**
+   * collects responses to new views
+   */
   private ViewReplyProcessor viewProcessor = new ViewReplyProcessor(false);
 
-  /** collects responses to view preparation messages */
+  /**
+   * collects responses to view preparation messages
+   */
   private ViewReplyProcessor prepareProcessor = new ViewReplyProcessor(true);
 
-  /** whether quorum checks can cause a forced-disconnect */
+  /**
+   * whether quorum checks can cause a forced-disconnect
+   */
   private boolean quorumRequired = false;
 
-  /** timeout in receiving view acknowledgement */
+  /**
+   * timeout in receiving view acknowledgement
+   */
   private int viewAckTimeout;
 
-  /** background thread that creates new membership views */
+  /**
+   * background thread that creates new membership views
+   */
   private ViewCreator viewCreator;
 
-  /** am I shutting down? */
+  /**
+   * am I shutting down?
+   */
   private volatile boolean isStopping;
 
-  /** state of collected artifacts during discovery */
+  /**
+   * state of collected artifacts during discovery
+   */
   final SearchState searchState = new SearchState();
 
-  /** a collection used to detect unit testing */
+  /**
+   * a collection used to detect unit testing
+   */
   Set<String> unitTesting = new HashSet<>();
-  
-  /** a test hook to make this member unresponsive */
+
+  /**
+   * a test hook to make this member unresponsive
+   */
   private volatile boolean playingDead;
-  
-  /** the view where quorum was most recently lost */
+
+  /**
+   * the view where quorum was most recently lost
+   */
   NetView quorumLostView;
 
-  /** a flag to mark a coordinator's viewCreator for shutdown */
+  /**
+   * a flag to mark a coordinator's viewCreator for shutdown
+   */
   private boolean markViewCreatorForShutdown = false;
 
   static class SearchState {
@@ -182,13 +244,13 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   /**
    * attempt to join the distributed system
    * loop
-   *   send a join request to a locator & get a response
-   *
+   * send a join request to a locator & get a response
+   * <p>
    * If the response indicates there's no coordinator it
    * will contain a set of members that have recently contacted
    * it.  The "oldest" member is selected as the coordinator
    * based on ID sort order.
-   * 
+   *
    * @return true if successful, false if not
    */
   public boolean join() {
@@ -372,12 +434,12 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         || !currentView.contains(mbr)) {
       return true;
     }
-    synchronized(removedMembers) {
+    synchronized (removedMembers) {
       if (removedMembers.contains(mbr)) {
         return true;
       }
     }
-    synchronized(leftMembers) {
+    synchronized (leftMembers) {
       if (leftMembers.contains(mbr)) {
         return true;
       }
@@ -419,13 +481,13 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       return;
     }
 
-//      Remove JoinResponseMessage to fix GEODE-870
-//        if (!this.localAddress.getNetMember().preferredForCoordinator() &&
-//            incomingRequest.getMemberID().getNetMember().preferredForCoordinator()){
-//          JoinResponseMessage joinResponseMessage = new JoinResponseMessage(incomingRequest.getMemberID(), currentView, true);
-//          services.getMessenger().send(joinResponseMessage);
-//          return;
-//        }
+    //      Remove JoinResponseMessage to fix GEODE-870
+//    if (!this.localAddress.getNetMember().preferredForCoordinator() &&
+//        incomingRequest.getMemberID().getNetMember().preferredForCoordinator()) {
+//      JoinResponseMessage joinResponseMessage = new JoinResponseMessage(incomingRequest.getMemberID(), currentView, true);
+//      services.getMessenger().send(joinResponseMessage);
+//      return;
+//    }
     recordViewRequest(incomingRequest);
   }
 
@@ -449,8 +511,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     InternalDistributedMember mbr = incomingRequest.getMemberID();
 
     if (logger.isDebugEnabled()) {
-      logger.debug("JoinLeave.processLeaveRequest invoked.  isCoordinator="+isCoordinator+ "; isStopping="+isStopping
-          +"; cancelInProgress="+ services.getCancelCriterion().isCancelInProgress());
+      logger.debug("JoinLeave.processLeaveRequest invoked.  isCoordinator=" + isCoordinator + "; isStopping=" + isStopping
+          + "; cancelInProgress=" + services.getCancelCriterion().isCancelInProgress());
     }
 
     if (!v.contains(mbr) && mbr.getVmViewId() < v.getViewId()) {
@@ -472,12 +534,12 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         check.removeAll(removedMembers);
         check.addCrashedMembers(removedMembers);
       }
-      synchronized(leftMembers) {
+      synchronized (leftMembers) {
         leftMembers.add(mbr);
         check.removeAll(leftMembers);
       }
       if (check.getCoordinator().equals(localAddress)) {
-        synchronized(viewInstallationLock) {
+        synchronized (viewInstallationLock) {
           becomeCoordinator(incomingRequest.getMemberID());
         }
       }
@@ -516,8 +578,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
     if (!fromMe) {
       logger.info("Membership received a request to remove " + mbr
-        + " from " + incomingRequest.getSender()
-        + " reason="+incomingRequest.getReason());
+          + " from " + incomingRequest.getSender()
+          + " reason=" + incomingRequest.getReason());
     }
 
     if (mbr.equals(this.localAddress)) {
@@ -754,7 +816,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     if (preparing) {
       logger.debug("waiting for view responses");
 
-      Set<InternalDistributedMember> failedToRespond = rp.waitForResponses();
+      Set<InternalDistributedMember> failedToRespond = viewReplyProcessor.waitForResponses();
 
       logger.info("finished waiting for responses to view preparation");
 
@@ -775,7 +837,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     return true;
   }
 
-  private void processViewMessage(final InstallViewMessage installViewMessage) {
+  private void processViewMessage(final InstallViewMessage m) {
 
     NetView view = m.getView();
 
@@ -789,7 +851,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     if (!this.isJoined) {
       // if we're still waiting for a join response and we're in this view we
       // should install the view so join() can finish its work
-      for (InternalDistributedMember mbr: view.getMembers()) {
+      for (InternalDistributedMember mbr : view.getMembers()) {
         if (localAddress.compareTo(mbr) == 0) {
           viewContainsMyUnjoinedAddress = true;
           break;
@@ -940,7 +1002,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     }
     InternalDistributedMember coord = null;
     boolean coordIsNoob = true;
-    for (; it.hasNext();) {
+    for (; it.hasNext(); ) {
       InternalDistributedMember mbr = it.next();
       if (!state.alreadyTried.contains(mbr)) {
         boolean mbrIsNoob = (mbr.getVmViewId() < 0);
@@ -1603,13 +1665,17 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       }
     }
 
-    /** call with synchronized(this) */
+    /**
+     * call with synchronized(this)
+     */
     private void stopWaitingFor(InternalDistributedMember mbr) {
       notRepliedYet.remove(mbr);
       checkIfDone();
     }
 
-    /** call with synchronized(this) */
+    /**
+     * call with synchronized(this)
+     */
     private void checkIfDone() {
       if (notRepliedYet.isEmpty() || (pendingRemovals != null && pendingRemovals.containsAll(notRepliedYet))) {
         logger.debug("All anticipated view responses received - notifying waiting thread");
@@ -1828,7 +1894,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       sendInitialView();
       long okayToCreateView = System.currentTimeMillis() + requestCollectionInterval;
       try {
-        for (;;) {
+        for (; ; ) {
           synchronized (viewRequests) {
             if (shutdown) {
               return;
@@ -2168,8 +2234,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
      *
      * @param mbrs
      */
-    private void removeHealthyMembers(final Collection<InternalDistributedMember> mbrs) throws InterruptedException {
-      List<Callable<InternalDistributedMember>> checkers = new ArrayList<Callable<InternalDistributedMember>>(mbrs.size());
+    private void removeHealthyMembers(final Set<InternalDistributedMember> suspects) throws InterruptedException {
+      List<Callable<InternalDistributedMember>> checkers = new ArrayList<Callable<InternalDistributedMember>>(suspects.size());
 
       Set<InternalDistributedMember> newRemovals = new HashSet<>();
       Set<InternalDistributedMember> newLeaves = new HashSet<>();
@@ -2197,6 +2263,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
             }
             return mbr;
           }
+
           @Override
           public String toString() {
             return mbr.toString();
@@ -2228,7 +2295,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         // now wait for the tasks to do their work
         long waitTime = giveUpTime - System.currentTimeMillis();
         synchronized (viewRequests) {
-          while ( waitTime > 0 ) {
+          while (waitTime > 0) {
             logger.debug("removeHealthyMembers: mbrs" + suspects.size());
 
             filterMembers(suspects, newRemovals, REMOVE_MEMBER_REQUEST);
@@ -2237,7 +2304,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
             suspects.removeAll(newLeaves);
 
-            if(suspects.isEmpty() || newRemovals.containsAll(suspects)) {
+            if (suspects.isEmpty() || newRemovals.containsAll(suspects)) {
               break;
             }
 
@@ -2252,19 +2319,20 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
     /**
      * This gets pending requests and returns the IDs of any that are in the given collection
-     * @param mbrs collection of IDs to search for
+     *
+     * @param mbrs            collection of IDs to search for
      * @param matchingMembers collection to store matching IDs in
-     * @param requestType leave/remove/join
+     * @param requestType     leave/remove/join
      */
     protected void filterMembers(Collection<InternalDistributedMember> mbrs, Set<InternalDistributedMember> matchingMembers, short requestType) {
       Set<InternalDistributedMember> requests = getPendingRequestIDs(requestType);
 
-      if(!requests.isEmpty()) {
+      if (!requests.isEmpty()) {
         logger.debug("filterMembers: processing " + requests.size() + " requests for type " + requestType);
         Iterator<InternalDistributedMember> itr = requests.iterator();
-        while(itr.hasNext()) {
+        while (itr.hasNext()) {
           InternalDistributedMember memberID = itr.next();
-          if(mbrs.contains(memberID)) {
+          if (mbrs.contains(memberID)) {
             testFlagForRemovalRequest = true;
             matchingMembers.add(memberID);
           }
@@ -2272,8 +2340,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       }
     }
 
-    private <T> List<Future<T>> submitAll ( ExecutorService executor, Collection<? extends Callable<T> > tasks ) {
-      List<Future<T>> result = new ArrayList<Future<T>>( tasks.size() );
+    private <T> List<Future<T>> submitAll(ExecutorService executor, Collection<? extends Callable<T>> tasks) {
+      List<Future<T>> result = new ArrayList<Future<T>>(tasks.size());
 
       for (Callable<T> task : tasks) {
         result.add(executor.submit(task));
@@ -2288,7 +2356,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   }
 
   boolean checkIfAvailable(InternalDistributedMember fmbr) {
- // return the member id if it fails health checks
+    // return the member id if it fails health checks
     logger.info("checking state of member " + fmbr);
     if (services.getHealthMonitor().checkIfAvailable(fmbr, "Member failed to acknowledge a membership view", false)) {
       logger.info("member " + fmbr + " passed availability check");

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bd6749c1/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheSerializableRunnable.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheSerializableRunnable.java b/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheSerializableRunnable.java
index 8b80def..3745928 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheSerializableRunnable.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheSerializableRunnable.java
@@ -48,13 +48,25 @@ public abstract class CacheSerializableRunnable
   }
 
   /**
+   * Creates a new <code>CacheSerializableRunnable</code> with the
+   * given name
+   */
+  public CacheSerializableRunnable(String name,Object[] args) {
+    super(name);
+    this.args = args;
+  }
+
+  /**
    * Invokes the {@link #run2} method and will wrap any {@link
    * CacheException} thrown by <code>run2</code> in a {@link
    * CacheSerializableRunnableException}. 
    */
   public final void run() {
     try {
-      run2();
+      if(args == null){
+      run2();}else{
+        run3();
+      }
 
     } catch (CacheException ex) {
       String s = "While invoking \"" + this + "\"";
@@ -96,6 +108,8 @@ public abstract class CacheSerializableRunnable
    */
   public abstract void run2() throws CacheException;
 
+  public void run3() throws CacheException{}
+
   /////////////////////////  Inner Classes  /////////////////////////
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bd6749c1/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
index 4caf815..2e24cfd 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
@@ -51,7 +51,7 @@ public abstract class SerializableRunnable implements SerializableRunnableIF {
   private static final long serialVersionUID = 7584289978241650456L;
 
   private String name;
-  private Object[] args;
+  protected Object[] args;
 
   public SerializableRunnable() {
     this.name = null;


[063/100] [abbrv] incubator-geode git commit: This closes #99

Posted by ud...@apache.org.
This closes #99


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/31a69e42
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/31a69e42
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/31a69e42

Branch: refs/heads/feature/GEODE-870
Commit: 31a69e42f0f3f2172847d8a75684e7179e42337e
Parents: 1e3f89d 6891f5b
Author: Jinmei Liao <ji...@pivotal.io>
Authored: Mon Feb 22 09:32:52 2016 -0800
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Mon Feb 22 09:32:52 2016 -0800

----------------------------------------------------------------------
 .../gemfire/management/internal/cli/i18n/CliStrings.java     | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------



[064/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
index 0000000,6a3de04..95d46a4
mode 000000,100755..100755
--- a/geode-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
+++ b/geode-cq/src/test/java/com/gemstone/gemfire/internal/cache/ha/CQListGIIDUnitTest.java
@@@ -1,0 -1,827 +1,812 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.ha;
+ 
+ import java.io.File;
+ import java.io.IOException;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Properties;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.cache.AttributesFactory;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheException;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.DataPolicy;
+ import com.gemstone.gemfire.cache.DiskStoreFactory;
+ import com.gemstone.gemfire.cache.ExpirationAttributes;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionAttributes;
+ import com.gemstone.gemfire.cache.Scope;
+ import com.gemstone.gemfire.cache.client.PoolFactory;
+ import com.gemstone.gemfire.cache.client.PoolManager;
+ import com.gemstone.gemfire.cache.query.CqAttributes;
+ import com.gemstone.gemfire.cache.query.CqAttributesFactory;
+ import com.gemstone.gemfire.cache.query.CqListener;
+ import com.gemstone.gemfire.cache.query.CqQuery;
+ import com.gemstone.gemfire.cache.query.QueryService;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.query.cq.dunit.CqQueryTestListener;
+ import com.gemstone.gemfire.cache.query.data.Portfolio;
+ import com.gemstone.gemfire.cache.server.CacheServer;
+ import com.gemstone.gemfire.cache30.CertifiableTestCacheListener;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.internal.AvailablePort;
+ import com.gemstone.gemfire.internal.cache.CacheServerImpl;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerTestUtil;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientUpdateMessageImpl;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ConflationDUnitTest;
+ import com.gemstone.gemfire.internal.cache.InternalRegionArguments;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.test.dunit.Assert;
+ import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+ import com.gemstone.gemfire.test.dunit.Host;
+ import com.gemstone.gemfire.test.dunit.NetworkUtils;
+ import com.gemstone.gemfire.test.dunit.VM;
+ 
+ import junit.framework.Test;
+ import junit.framework.TestSuite;
+ 
+ /**
+  *
+  *
+  * @author ashetkar
+  * @since 5.7
+  *
+  */
+ public class CQListGIIDUnitTest extends DistributedTestCase {
+   private final static int CREATE = 0;
+ 
+   private final static int UPDATE = 1;
+ 
+   private final static int DESTROY = 2;
+ 
+   private final static int INVALIDATE = 3;
+ 
+   private final static int CLOSE = 4;
+ 
+   private final static int REGION_CLEAR = 5;
+ 
+   private final static int REGION_INVALIDATE = 6;
+ 
+   protected static Cache cache = null;
+ 
+   protected static VM serverVM0 = null;
+ 
+   private static VM serverVM1 = null;
+ 
+   protected static VM clientVM1 = null;
+ 
+   protected static VM clientVM2 = null;
+ 
+   private int PORT1;
+ 
+   private int PORT2;
+ 
+   private static final String regionName = "CQListGIIDUnitTest";
+ 
+   private static final Map map = new HashMap();
+ 
+   private static LogWriter logger = null;
+ 
+   public static final String[] regions = new String[] { "regionA", "regionB" };
+ 
+   public static final String KEY = "key-";
+ 
+   public String[] cqs = new String[] {
+   // 0 - Test for ">"
+       "SELECT ALL * FROM /root/" + regions[0] + " p where p.ID > 0",
+ 
+       // 1 - Test for "=" and "and".
+       "SELECT ALL * FROM /root/" + regions[0]
+           + " p where p.ID = 2 and p.status='active'",
+ 
+       // 2 - Test for "<" and "and".
+       "SELECT ALL * FROM /root/" + regions[1]
+           + " p where p.ID < 5 and p.status='active'",
+ 
+       // FOLLOWING CQS ARE NOT TESTED WITH VALUES; THEY ARE USED TO TEST PARSING
+       // LOGIC WITHIN CQ.
+       // 3
+       "SELECT * FROM /root/" + regions[0] + " ;",
+       // 4
+       "SELECT ALL * FROM /root/" + regions[0],
+       // 5
+       "import com.gemstone.gemfire.cache.\"query\".data.Portfolio; "
+           + "SELECT ALL * FROM /root/" + regions[0] + " TYPE Portfolio",
+       // 6
+       "import com.gemstone.gemfire.cache.\"query\".data.Portfolio; "
+           + "SELECT ALL * FROM /root/" + regions[0] + " p TYPE Portfolio",
+       // 7
+       "SELECT ALL * FROM /root/" + regions[1]
+           + " p where p.ID < 5 and p.status='active';",
+       // 8
+       "SELECT ALL * FROM /root/" + regions[0] + "  ;",
+       // 9
+       "SELECT ALL * FROM /root/" + regions[0] + " p where p.description = NULL",
+       // 10
+       "SELECT ALL * FROM /root/" + regions[0]
+           + " p where p.ID > 0 and p.status='active'", };
+ 
+   /**
+    * @param name
+    *          name of the test
+    */
+   public CQListGIIDUnitTest(String name) {
+     super(name);
+   }
+ 
+   /**
+    * Sets up the test.
+    */
+   public void setUp() throws Exception {
+     super.setUp();
+ 
+     final Host host = Host.getHost(0);
+     serverVM0 = host.getVM(0);
+     serverVM1 = host.getVM(1);
+     clientVM1 = host.getVM(2);
+     clientVM2 = host.getVM(3);
+ 
+     PORT1 = ((Integer)serverVM0.invoke(() -> CQListGIIDUnitTest.createServerCache( HARegionQueue.HA_EVICTION_POLICY_MEMORY ))).intValue();
+     PORT2 = ((Integer)serverVM1.invoke(() -> CQListGIIDUnitTest.createServerCache( HARegionQueue.HA_EVICTION_POLICY_ENTRY ))).intValue();
+   }
+ 
+   /**
+    * Tears down the test.
+    */
+   @Override
+   protected final void preTearDown() throws Exception {
+     serverVM0.invoke(() -> ConflationDUnitTest.unsetIsSlowStart());
+     serverVM1.invoke(() -> ConflationDUnitTest.unsetIsSlowStart());
+     closeCache();
+     clientVM1.invoke(() -> CQListGIIDUnitTest.closeCache());
+     clientVM2.invoke(() -> CQListGIIDUnitTest.closeCache());
+     // then close the servers
+     serverVM0.invoke(() -> CQListGIIDUnitTest.closeCache());
+     serverVM1.invoke(() -> CQListGIIDUnitTest.closeCache());
+     disconnectAllFromDS();
+   }
+   
 -  public static Test suite() {
 -    Class[] classes = new Class[] {com.gemstone.gemfire.internal.cache.ha.CQListGIIDUnitTest.class,
 -        com.gemstone.gemfire.cache30.RegionReliabilityDistAckDUnitTest.class,
 -        com.gemstone.gemfire.cache30.RegionReliabilityGlobalDUnitTest.class,
 -        com.gemstone.gemfire.internal.cache.execute.PRClientServerFunctionExecutionNoAckDUnitTest.class,
 -        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionDUnitTest.class,
 -        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionNoSingleHopDUnitTest.class,
 -        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionSelectorNoSingleHopDUnitTest.class,
 -        com.gemstone.gemfire.internal.cache.execute.PRClientServerRegionFunctionExecutionSingleHopDUnitTest.class,
 -        com.gemstone.gemfire.internal.cache.ha.HASlowReceiverDUnitTest.class};
 -    
 -    return new TestSuite(classes);
 -  }
 -
 -
+   private void createCache(Properties props) throws Exception {
+     DistributedSystem ds = getSystem(props);
+     ds.disconnect();
+     ds = getSystem(props);
+     assertNotNull(ds);
+     cache = CacheFactory.create(ds);
+     assertNotNull(cache);
+   }
+ 
+   public static Integer createServerCache() throws Exception {
+     return createServerCache(null);
+   }
+ 
+   public static Integer createServerCache(String ePolicy) throws Exception {
+     return createServerCache(ePolicy, Integer.valueOf(1));
+   }
+ 
+   public static Integer createServerCache(String ePolicy, Integer cap)
+       throws Exception {
+     new CQListGIIDUnitTest("temp").createCache(new Properties());
+     AttributesFactory factory = new AttributesFactory();
+     factory.setScope(Scope.DISTRIBUTED_ACK);
+     factory.setDataPolicy(DataPolicy.REPLICATE);
+     RegionAttributes attrs = factory.create();
+     // cache.createRegion(regionName, attrs);
+     createRegion(regions[0], "root", attrs);
+     createRegion(regions[1], "root", attrs);
+     Thread.sleep(2000);
+     logger = cache.getLogger();
+ 
+     int port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     CacheServer server1 = cache.addCacheServer();
+     server1.setPort(port);
+     server1.setNotifyBySubscription(true);
+     if (ePolicy != null) {
+       File overflowDirectory = new File("bsi_overflow_"+port);
+       overflowDirectory.mkdir();
+       DiskStoreFactory dsf = cache.createDiskStoreFactory();
+       File[] dirs1 = new File[] {overflowDirectory};
+ 
+       server1.getClientSubscriptionConfig().setEvictionPolicy(ePolicy);
+       server1.getClientSubscriptionConfig().setCapacity(cap.intValue());
+       // specify diskstore for this server
+       server1.getClientSubscriptionConfig().setDiskStoreName(dsf.setDiskDirs(dirs1).create("bsi").getName());
+     }
+     server1.start();
+     Thread.sleep(2000);
+     return Integer.valueOf(server1.getPort());
+   }
+ 
+   public static Integer createOneMoreBridgeServer(Boolean notifyBySubscription)
+       throws Exception {
+     int port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     CacheServer server1 = cache.addCacheServer();
+     server1.setPort(port);
+     server1.setNotifyBySubscription(notifyBySubscription.booleanValue());
+     server1.getClientSubscriptionConfig().setEvictionPolicy(
+         HARegionQueue.HA_EVICTION_POLICY_MEMORY);
+     // let this server to use default diskstore
+     server1.start();
+     return Integer.valueOf(server1.getPort());
+   }
+ 
+   public static final Region createRegion(String name, String rootName,
+       RegionAttributes attrs) throws CacheException {
+     Region root = cache.getRegion(rootName);
+     if (root == null) {
+       // don't put listeners on root region
+       RegionAttributes rootAttrs = attrs;
+       AttributesFactory fac = new AttributesFactory(attrs);
+       ExpirationAttributes expiration = ExpirationAttributes.DEFAULT;
+ 
+       // fac.setCacheListener(null);
+       fac.setCacheLoader(null);
+       fac.setCacheWriter(null);
+       fac.setPoolName(null);
+       fac.setPartitionAttributes(null);
+       fac.setRegionTimeToLive(expiration);
+       fac.setEntryTimeToLive(expiration);
+       fac.setRegionIdleTimeout(expiration);
+       fac.setEntryIdleTimeout(expiration);
+       rootAttrs = fac.create();
+       root = cache.createRegion(rootName, rootAttrs);
+     }
+ 
+     return createSubregion(root, name, attrs, null);
+   }
+ 
+   /**
+    * A helper for creating a subregion, potentially using a package protected
+    * method to do so.  
+    * @param root the parent region
+    * @param name the name of the subregion to create
+    * @param attrs the attributes used to create the subregion
+    * @param internalArgs if not null, then use the package protected creation mechanism
+    * @return the subregion whose parent is the provided root
+    * @throws CacheException
+    * @see Region#createSubregion(String, RegionAttributes)
+    * @see LocalRegion#createSubregion(String, RegionAttributes, InternalRegionArguments)
+    */
+   public static Region createSubregion(Region root, String name,
+       RegionAttributes attrs, final InternalRegionArguments internalArgs) throws CacheException
+   {
+     if (internalArgs == null) {
+       return root.createSubregion(name, attrs);
+     } else {
+       try {
+         LocalRegion lr = (LocalRegion) root;
+         return lr.createSubregion(name, attrs, internalArgs);
+       } catch (IOException ioe) {
+         AssertionError assErr = new AssertionError("unexpected exception");
+         assErr.initCause(ioe);
+         throw assErr;
+       } catch (ClassNotFoundException cnfe) {
+         AssertionError assErr = new AssertionError("unexpected exception");
+         assErr.initCause(cnfe);
+         throw assErr;
+       } 
+     }
+   }
+   
+   public static void createClientCache(Integer port1, Integer port2,
+       String rLevel) throws Exception {
+     createClientCache(port1, port2, Integer.valueOf(-1), rLevel, Boolean.FALSE);
+   }
+ 
+   public static void createClientCache(Integer port1, Integer port2,
+       String rLevel, Boolean addListener) throws Exception {
+     createClientCache(port1, port2, Integer.valueOf(-1), rLevel, addListener);
+   }
+ 
+   public static void createClientCache(Integer port1, Integer port2,
+       Integer port3, String rLevel) throws Exception {
+     createClientCache(port1, port2, port3, rLevel, Boolean.FALSE);
+   }
+ 
+   public static void destroyClientPool() {
+     cache.getRegion("root").getSubregion(regions[0]).close();
+     cache.getRegion("root").getSubregion(regions[1]).close();
+     PoolManager.find("clientPool").destroy();
+   }
+   
+   public static void createClientCache(Integer port1, Integer port2,
+       Integer port3, String rLevel, Boolean addListener) throws Exception {
+     CacheServerTestUtil.disableShufflingOfEndpoints();
+     String host = NetworkUtils.getIPLiteral();
+ 
+     Properties props = new Properties();
+     props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+     props.setProperty(DistributionConfig.LOCATORS_NAME, "");
+     new CQListGIIDUnitTest("temp").createCache(props);
+ 
+     PoolFactory pf = PoolManager.createFactory();
+     int endPointCount = 1;
+     pf.addServer(host, port1);
+     if (port2.intValue() != -1) {
+       pf.addServer(host, port2);
+       endPointCount++;
+     }
+     if (port3.intValue() != -1) {
+       pf.addServer(host, port3);
+       endPointCount++;
+     }
+     pf.setRetryAttempts(5);
+     pf.setReadTimeout(2500);
+     pf.setSocketBufferSize(32768);
+     pf.setPingInterval(1000);
+     pf.setMinConnections(endPointCount*2);
+     pf.setSubscriptionRedundancy(Integer.parseInt(rLevel));
+     pf.setSubscriptionEnabled(true).create("clientPool");
+ 
+     try {
+       cache.getQueryService();
+     }
+     catch (Exception cqe) {
+       Assert.fail("Failed to getCQService.", cqe);
+     }
+ 
+     AttributesFactory factory = new AttributesFactory();
+     factory.setScope(Scope.LOCAL);
+     factory.setPoolName("clientPool");
+ 
+     RegionAttributes attrs = factory.create();
+     createRegion(regions[0], "root", attrs);
+     createRegion(regions[1], "root", attrs);
+     logger = cache.getLogger();
+   }
+ 
+   /* Register CQs */
+   public static void createCQ(String cqName, String queryStr) {
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("### Create CQ. ###" + cqName);
+     // Get CQ Service.
+     QueryService cqService = null;
+     try {
+       cqService = cache.getQueryService();
+     }
+     catch (Exception cqe) {
+       Assert.fail("Failed to getCQService.", cqe);
+     }
+     // Create CQ Attributes.
+     CqAttributesFactory cqf = new CqAttributesFactory();
+     CqListener[] cqListeners = { new CqQueryTestListener(com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter()) };
+     ((CqQueryTestListener)cqListeners[0]).cqName = cqName;
+ 
+     cqf.initCqListeners(cqListeners);
+     CqAttributes cqa = cqf.create();
+ 
+     // Create CQ.
+     try {
+       CqQuery cq1 = cqService.newCq(cqName, queryStr, cqa);
+       assertTrue("newCq() state mismatch", cq1.getState().isStopped());
+     }
+     catch (Exception ex) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("CqService is :" + cqService);
+       ex.printStackTrace();
+       AssertionError err = new AssertionError("Failed to create CQ " + cqName
+           + " . ");
+       err.initCause(ex);
+       throw err;
+     }
+   }
+ 
+   public static void executeCQ(String cqName, Boolean initialResults) {
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("### DEBUG EXECUTE CQ START ####");
+     // Get CQ Service.
+     QueryService cqService = null;
+     CqQuery cq1 = null;
+     cqService = cache.getQueryService();
+ 
+     // Get CqQuery object.
+     try {
+       cq1 = cqService.getCq(cqName);
+       if (cq1 == null) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Failed to get CqQuery object for CQ name: " + cqName);
+         Assert.fail("Failed to get CQ " + cqName, new Exception("Failed to get CQ "
+             + cqName));
+       }
+       else {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Obtained CQ, CQ name: " + cq1.getName());
+         assertTrue("newCq() state mismatch", cq1.getState().isStopped());
+       }
+     }
+     catch (Exception ex) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("CqService is :" + cqService);
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().error(ex);
+       AssertionError err = new AssertionError("Failed to execute  CQ " + cqName);
+       err.initCause(ex);
+       throw err;
+     }
+ 
+     if (initialResults.booleanValue()) {
+       SelectResults cqResults = null;
+ 
+       try {
+         cqResults = cq1.executeWithInitialResults();
+       }
+       catch (Exception ex) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("CqService is :" + cqService);
+         ex.printStackTrace();
+         AssertionError err = new AssertionError("Failed to execute  CQ "
+             + cqName);
+         err.initCause(ex);
+         throw err;
+       }
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("initial result size = " + cqResults.size());
+       assertTrue("executeWithInitialResults() state mismatch", cq1.getState()
+           .isRunning());
+       // if (expectedResultsSize >= 0) {
+       // assertEquals("unexpected results size", expectedResultsSize, cqResults
+       // .size());
+       // }
+     }
+     else {
+ 
+       try {
+         cq1.execute();
+       }
+       catch (Exception ex) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("CqService is :" + cqService);
+         ex.printStackTrace();
+         AssertionError err = new AssertionError("Failed to execute  CQ "
+             + cqName);
+         err.initCause(ex);
+         throw err;
+       }
+       assertTrue("execute() state mismatch", cq1.getState().isRunning());
+     }
+   }
+ 
+   public static void registerInterestListCQ(String regionName, int keySize) {
+     // Get CQ Service.
+     Region region = null;
+     try {
+       region = cache.getRegion("root").getSubregion(regionName);
+       region.getAttributesMutator().setCacheListener(
+           new CertifiableTestCacheListener(com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter()));
+     }
+     catch (Exception cqe) {
+       AssertionError err = new AssertionError("Failed to get Region.");
+       err.initCause(cqe);
+       throw err;
+     }
+ 
+     try {
+       List list = new ArrayList();
+       for (int i = 1; i <= keySize; i++) {
+         list.add(KEY + i);
+       }
+       region.registerInterest(list);
+     }
+     catch (Exception ex) {
+       AssertionError err = new AssertionError("Failed to Register InterestList");
+       err.initCause(ex);
+       throw err;
+     }
+   }
+ 
+   public static void waitForCreated(String cqName, String key) {
+     waitForEvent(0, cqName, key);
+   }
+ 
+   public static void waitForEvent(int event, String cqName, String key) {
+     // Get CQ Service.
+     QueryService cqService = null;
+     try {
+       cqService = cache.getQueryService();
+     }
+     catch (Exception cqe) {
+       cqe.printStackTrace();
+       Assert.fail("Failed to getCQService.", cqe);
+     }
+ 
+     CqQuery cQuery = cqService.getCq(cqName);
+     if (cQuery == null) {
+       Assert.fail("Failed to get CqQuery for CQ : " + cqName, new Exception(
+           "Failed to get CqQuery for CQ : " + cqName));
+     }
+ 
+     CqAttributes cqAttr = cQuery.getCqAttributes();
+     CqListener[] cqListener = cqAttr.getCqListeners();
+     CqQueryTestListener listener = (CqQueryTestListener)cqListener[0];
+ 
+     switch (event) {
+       case CREATE:
+         listener.waitForCreated(key);
+         break;
+ 
+       case UPDATE:
+         listener.waitForUpdated(key);
+         break;
+ 
+       case DESTROY:
+         listener.waitForDestroyed(key);
+         break;
+ 
+       case INVALIDATE:
+         listener.waitForInvalidated(key);
+         break;
+ 
+       case CLOSE:
+         listener.waitForClose();
+         break;
+ 
+       case REGION_CLEAR:
+         listener.waitForRegionClear();
+         break;
+ 
+       case REGION_INVALIDATE:
+         listener.waitForRegionInvalidate();
+         break;
+ 
+     }
+   }
+ 
+   public static void registerInterestListAll() {
+     try {
+       Region r = cache.getRegion("/" + regionName);
+       assertNotNull(r);
+       r.registerInterest("ALL_KEYS");
+     }
+     catch (Exception ex) {
+       Assert.fail("failed in registerInterestListAll", ex);
+     }
+   }
+ 
+   public static void registerInterestList() {
+     try {
+       Region r = cache.getRegion("/" + regionName);
+       assertNotNull(r);
+       r.registerInterest("k1");
+       r.registerInterest("k3");
+       r.registerInterest("k5");
+     }
+     catch (Exception ex) {
+       Assert.fail("failed while registering keys", ex);
+     }
+   }
+ 
+   public static void putEntries(String rName, Integer num) {
+     try {
+       Region r = cache.getRegion("root").getSubregion(rName);
+       assertNotNull(r);
+       for (int i = 0; i < num.longValue(); i++) {
+         r.put(KEY + i, new Portfolio(i + 1));
+       }
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+           "### Number of Entries in Region " + rName + ": " + r.keys().size());
+     }
+     catch (Exception ex) {
+       Assert.fail("failed in putEntries()", ex);
+     }
+   }
+ 
+   /**
+    *
+    *
+    * @throws Exception
+    */
+   public void _testSpecificClientCQIsGIIedPart1() throws Exception {
+     Integer size = Integer.valueOf(10);
+     // slow start for dispatcher
+     serverVM0.invoke(() -> ConflationDUnitTest.setIsSlowStart( "30000" ));
+     serverVM1.invoke(() -> ConflationDUnitTest.setIsSlowStart( "30000" ));
+ 
+     // createClientCache(Integer.valueOf(PORT1), Integer.valueOf(PORT2), "1");
+     clientVM1.invoke(() -> CQListGIIDUnitTest.createClientCache( Integer.valueOf(PORT1), Integer.valueOf(PORT2), "1" ));
+     clientVM2.invoke(() -> CQListGIIDUnitTest.createClientCache( Integer.valueOf(PORT1), Integer.valueOf(PORT2), "0" ));
+ 
+     clientVM1.invoke(() -> CQListGIIDUnitTest.createCQ(
+         "testSpecificClientCQIsGIIed_0", cqs[0] ));
+     clientVM1.invoke(() -> CQListGIIDUnitTest.executeCQ(
+         "testSpecificClientCQIsGIIed_0", Boolean.FALSE ));
+     clientVM2.invoke(() -> CQListGIIDUnitTest.createCQ(
+         "testSpecificClientCQIsGIIed_0", cqs[0] ));
+     clientVM2.invoke(() -> CQListGIIDUnitTest.executeCQ(
+         "testSpecificClientCQIsGIIed_0", Boolean.FALSE ));
+ 
+     serverVM1.invoke(() -> CQListGIIDUnitTest.stopServer());
+ 
+     serverVM0.invoke(() -> CQListGIIDUnitTest.putEntries(
+         regions[0], size ));
+ 
+     serverVM1.invoke(() -> CQListGIIDUnitTest.startServer());
+     Thread.sleep(3000); // TODO: Find a better 'n reliable alternative
+ 
+     serverVM0.invoke(() -> CQListGIIDUnitTest.VerifyCUMCQList(
+         size, Integer.valueOf(2) ));
+     serverVM1.invoke(() -> CQListGIIDUnitTest.VerifyCUMCQList(
+         size, Integer.valueOf(1) ));
+     serverVM0.invoke(() -> ConflationDUnitTest.unsetIsSlowStart());
+     serverVM1.invoke(() -> ConflationDUnitTest.unsetIsSlowStart());
+   }
+ 
+   /**
+    * This test asserts that cq list of a client for an event is not lost if that
+    * client's queue has been GII'ed to a server where that event already
+    * existed.
+    *
+    * @throws Exception
+    */
+   public void testClientCQNotLostAtGIIReceiver() throws Exception {
+     Integer size = Integer.valueOf(10);
+     VM serverVM2 = clientVM2;
+ 
+     int port3 = ((Integer)serverVM2.invoke(() -> CQListGIIDUnitTest.createServerCache( HARegionQueue.HA_EVICTION_POLICY_MEMORY ))).intValue();
+ 
+     // slow start for dispatcher
+     serverVM0.invoke(() -> ConflationDUnitTest.setIsSlowStart( "45000" ));
+ 
+     // createClientCache(Integer.valueOf(PORT1), Integer.valueOf(PORT2), "1");
+     createClientCache(Integer.valueOf(PORT1), Integer.valueOf(PORT2),
+         Integer.valueOf(port3), "1");
+     try {
+     clientVM1.invoke(() -> CQListGIIDUnitTest.createClientCache( Integer.valueOf(PORT1), Integer.valueOf(port3),
+             Integer.valueOf(PORT2), "1" ));
+     try {
+     createCQ("testSpecificClientCQIsGIIed_0", cqs[0]);
+     executeCQ("testSpecificClientCQIsGIIed_0", Boolean.FALSE);
+     clientVM1.invoke(() -> CQListGIIDUnitTest.createCQ(
+         "testSpecificClientCQIsGIIed_0", cqs[0] ));
+     clientVM1.invoke(() -> CQListGIIDUnitTest.executeCQ(
+         "testSpecificClientCQIsGIIed_0", Boolean.FALSE ));
+ 
+     serverVM0.invoke(() -> CQListGIIDUnitTest.putEntries(
+         regions[0], size ));
+ 
+     serverVM1.invoke(() -> CQListGIIDUnitTest.VerifyCUMCQList(
+         size, Integer.valueOf(1) ));
+ 
+     serverVM2.invoke(() -> CQListGIIDUnitTest.stopServer());
+     Thread.sleep(3000); // TODO: Find a better 'n reliable alternative
+ 
+     serverVM0.invoke(() -> CQListGIIDUnitTest.VerifyCUMCQList(
+       size, Integer.valueOf(2) ));
+     serverVM1.invoke(() -> CQListGIIDUnitTest.VerifyCUMCQList(
+         size, Integer.valueOf(2) ));
+     } finally {
+       clientVM1.invoke(() -> CQListGIIDUnitTest.destroyClientPool());
+     }
+ 
+     } finally {
+       destroyClientPool();
+     }
+   }
+ 
+   public static void VerifyCUMCQList(Integer numOfKeys, Integer numOfClients) {
+     try {
+       Iterator iter = cache.getCacheServers().iterator();
+       if (iter.hasNext()) {
+         CacheServerImpl server = (CacheServerImpl)iter.next();
+         Map haContainer = server.getAcceptor().getCacheClientNotifier()
+             .getHaContainer();
+         Object[] keys = haContainer.keySet().toArray();
+         logger.fine("### numOfKeys :" + numOfKeys.intValue() + " keys.length : " + keys.length +
+             " haContainer size : " + haContainer.size());
+         assertEquals(numOfKeys.intValue(), keys.length);
+         for (int i = 0; i < numOfKeys.intValue(); i++) {
+           logger.fine("i=: " + i);
+           ClientUpdateMessageImpl cum = (ClientUpdateMessageImpl)haContainer
+               .get(keys[i]);
+           assertNotNull(cum);
+           assertNotNull(cum.getClientCqs());
+           assertEquals("This test may fail if the image provider gets an ack from client before providing image",
+               numOfClients.intValue(), cum.getClientCqs().size());
+         }
+       }
+     }
+     catch (Exception e) {
+       Assert.fail("failed in VerifyCUMCQList()" + e, e);
+     }
+   }
+ 
+   private static void stopOneBridgeServer(Integer port) {
+     try {
+       Iterator iter = cache.getCacheServers().iterator();
+       if (iter.hasNext()) {
+         CacheServer server = (CacheServer)iter.next();
+         if (server.getPort() == port.intValue()) {
+           server.stop();
+         }
+       }
+     }
+     catch (Exception e) {
+       fail("failed in stopOneBridgeServer()" + e);
+     }
+   }
+ 
+   public static void stopServer() {
+     try {
+       Iterator iter = cache.getCacheServers().iterator();
+       if (iter.hasNext()) {
+         CacheServer server = (CacheServer)iter.next();
+         server.stop();
+       }
+     }
+     catch (Exception e) {
+       fail("failed in stopServer()" + e);
+     }
+   }
+ 
+   public static void startServer() {
+     try {
+       Iterator iter = cache.getCacheServers().iterator();
+       if (iter.hasNext()) {
+         CacheServer server = (CacheServer)iter.next();
+         server.start();
+       }
+     }
+     catch (Exception e) {
+       fail("failed in startServer()" + e);
+     }
+   }
+ 
+   public static void waitTillMessagesAreDispatched(Integer port, Long waitLimit) {
+     try {
+       boolean dispatched = false;
+       Map haContainer = null;
+       haContainer = cache.getRegion(Region.SEPARATOR
+           + CacheServerImpl.generateNameForClientMsgsRegion(port.intValue()));
+       if (haContainer == null) {
+         Object[] servers = cache.getCacheServers().toArray();
+         for (int i = 0; i < servers.length; i++) {
+           if (port.intValue() == ((CacheServerImpl)servers[i]).getPort()) {
+             haContainer = ((CacheServerImpl)servers[i]).getAcceptor()
+                 .getCacheClientNotifier().getHaContainer();
+             break;
+           }
+         }
+       }
+       long startTime = System.currentTimeMillis();
+       while (waitLimit.longValue() > (System.currentTimeMillis() - startTime)) {
+         if (haContainer.size() == 0) {
+           dispatched = true;
+           break;
+         }
+         try {
+           Thread.sleep(50);
+         }
+         catch (InterruptedException ie) {
+           fail("interrupted");
+         }
+       }
+       logger.fine("Exiting sleep, time elapsed was: "
+           + (System.currentTimeMillis() - startTime));
+       if (!dispatched) {
+         throw new Exception(
+             "Test tuning issue: The HARegionQueue is not fully drained, so cannot continue the test.");
+       }
+     }
+     catch (Exception e) {
+       fail("failed in waitTillMessagesAreDispatched()" + e);
+     }
+   }
+ 
+   public static void closeCache() {
+     if (cache != null && !cache.isClosed()) {
+       cache.close();
+       cache.getDistributedSystem().disconnect();
+     }
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-pulse/build.gradle
----------------------------------------------------------------------
diff --cc geode-pulse/build.gradle
index 0000000,6137996..ebd851a
mode 000000,100755..100755
--- a/geode-pulse/build.gradle
+++ b/geode-pulse/build.gradle
@@@ -1,0 -1,116 +1,98 @@@
+ /*
+  * 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.
+  */
 -
 -buildscript {
 -  repositories {
 -    maven {
 -      url "https://plugins.gradle.org/m2/"
 -    }
 -  }
 -  dependencies {
 -    classpath "org.ajoberstar:gradle-git:1.3.2"
 -  }
 -}
 -
+ apply plugin: 'war'
+ 
+ sourceSets {
+   main {
+     resources {
+       exclude('**/gemfire*.properties')
+       exclude('**/sqlfire.properties')
+     }
+   }
+ }
+ 
+ dependencies {
 -  compile 'org.apache.commons:com.springsource.org.apache.commons.beanutils:1.8.0'
 -  compile 'org.apache.commons:com.springsource.org.apache.commons.collections:3.2.0'
 -  compile 'org.apache.commons:com.springsource.org.apache.commons.digester:1.8.1'
 -  compile 'org.apache.commons:com.springsource.org.apache.commons.logging:1.1.1'
 -  compile 'commons-lang:commons-lang:2.6'
 -  compile 'org.springframework.ldap:spring-ldap-core:1.3.2.RELEASE'
 -  compile 'org.springframework.security:spring-security-config:3.1.7.RELEASE'
 -  compile 'org.springframework.security:spring-security-core:3.1.7.RELEASE'
 -  compile 'org.springframework.security:spring-security-ldap:3.1.7.RELEASE'
 -  compile 'org.springframework.security:spring-security-web:3.1.7.RELEASE'
 -  compile 'org.springframework:spring-tx:3.2.12.RELEASE'
 -
 -  providedCompile 'commons-logging:commons-logging:1.1.3'
 -  providedCompile 'commons-codec:commons-codec:1.6'
 -  providedCompile 'org.apache.httpcomponents:fluent-hc:4.3.3'
 -  providedCompile 'org.apache.httpcomponents:httpclient:4.3.3'
 -  providedCompile 'org.apache.httpcomponents:httpclient-cache:4.3.3'
 -  providedCompile 'org.apache.httpcomponents:httpcore:4.3.2'
 -  providedCompile 'org.apache.httpcomponents:httpmime:4.3.3'
 -
 -  provided 'org.mortbay.jetty:servlet-api:2.5-20081211'
 -  provided 'com.google.guava:guava:15.0'
++  compile 'commons-beanutils:commons-beanutils:'+project.'commons-beanutils.version'
++  compile 'commons-collections:commons-collections:'+project.'commons-collections.version'
++  compile 'commons-digester:commons-digester:'+project.'commons-digester.version'
++  compile 'commons-lang:commons-lang:'+project.'commons-lang.version'
++  compile 'org.springframework.ldap:spring-ldap-core:'+project.'spring-ldap-core.version'
++  compile 'org.springframework.security:spring-security-config:'+project.'spring-security.version'
++  compile 'org.springframework.security:spring-security-core:'+project.'spring-security.version'
++  compile 'org.springframework.security:spring-security-ldap:'+project.'spring-security.version'
++  compile 'org.springframework.security:spring-security-web:'+project.'spring-security.version'
++  compile 'org.springframework:spring-tx:'+project.'spring-tx.version'
++
++  providedCompile 'commons-logging:commons-logging:'+project.'commons-logging.version'
++
++  provided 'org.mortbay.jetty:servlet-api:'+project.'mortbay-jetty-servlet-api.version'
++  provided 'com.google.guava:guava:'+project.'guava.version'
+ 
+   testCompile project(':geode-junit')
+ 
 -  testCompile 'org.apache.tomcat.embed:tomcat-embed-core:7.0.30'
 -  testCompile 'org.apache.tomcat.embed:tomcat-embed-jasper:7.0.30'
 -  testCompile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:7.0.30'
 -  testCompile 'org.seleniumhq.selenium:selenium-firefox-driver:2.52.0'
 -  testCompile 'org.seleniumhq.selenium:selenium-api:2.52.0'
 -  testCompile 'org.seleniumhq.selenium:selenium-remote-driver:2.52.0'
 -  testCompile 'org.seleniumhq.selenium:selenium-support:2.52.0'
++  testCompile 'org.apache.tomcat.embed:tomcat-embed-core:'+project.'tomcat7.version'
++  testCompile 'org.apache.tomcat.embed:tomcat-embed-jasper:'+project.'tomcat7.version'
++  testCompile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:'+project.'tomcat7.version'
++  testCompile 'org.seleniumhq.selenium:selenium-firefox-driver:'+project.'selenium.version'
++  testCompile 'org.seleniumhq.selenium:selenium-api:'+project.'selenium.version'
++  testCompile 'org.seleniumhq.selenium:selenium-remote-driver:'+project.'selenium.version'
++  testCompile 'org.seleniumhq.selenium:selenium-support:'+project.'selenium.version'
++
++  testRuntime 'com.google.code.gson:gson:'+project.'google-gson.version'
++  testRuntime 'org.apache.commons:commons-exec:'+project.'commons-exec.version'
+ 
 -  testRuntime 'com.google.code.gson:gson:2.3.1'
 -  testRuntime 'org.apache.commons:commons-exec:1.3'
+ }
+ 
+ def generatedResources = "$buildDir/generated-resources/main"
+ 
+ sourceSets {
+   main {
+     output.dir(generatedResources, builtBy: 'copyGemFireVersionFile')
+   }
+ }
+ 
+ task copyGemFireVersionFile(type: Copy) {
+   from project(':geode-core').createVersionPropertiesFile
+   into generatedResources
+ }
+ 
+ jar {
+   from sourceSets.main.output
+ }
+ 
+ eclipse.classpath.file {
+   whenMerged { classpath ->
+     classpath.entries.removeAll { entry -> entry.path.contains('geode-core/build')}
+   }
+ }
+ idea.module.iml {
+   whenMerged {module ->
+     module.dependencies.removeAll { entry -> entry.toString().contains('geode-core/build')}
+   }
+ }
+ 
+ 
+ artifacts {
+   archives war
+ }
+ 
+ war {
+   classpath configurations.runtime
+   classpath project(':geode-core').webJar.archivePath
+ }
+ 
+ uiTest.dependsOn war



[087/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
index 0000000,dd33b15..558ea37
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
@@@ -1,0 -1,2243 +1,2243 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import java.io.IOException;
+ import java.util.Arrays;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ABSTRACT_REGION_ENTRY_FILL_IN_VALUE;
+ import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE;
+ 
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.InvalidDeltaException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.CacheWriterException;
+ import com.gemstone.gemfire.cache.EntryEvent;
+ import com.gemstone.gemfire.cache.EntryNotFoundException;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.TimeoutException;
+ import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
+ import com.gemstone.gemfire.cache.query.QueryException;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexProtocol;
+ import com.gemstone.gemfire.cache.util.GatewayConflictHelper;
+ import com.gemstone.gemfire.cache.util.GatewayConflictResolver;
+ import com.gemstone.gemfire.distributed.internal.DM;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.ByteArrayDataInput;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.InternalDataSerializer;
+ import com.gemstone.gemfire.internal.InternalStatisticsDisabledException;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.lru.LRUClockNode;
+ import com.gemstone.gemfire.internal.cache.lru.NewLRUClockHand;
+ import com.gemstone.gemfire.internal.cache.persistence.DiskStoreID;
+ import com.gemstone.gemfire.internal.cache.versions.ConcurrentCacheModificationException;
+ import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
+ import com.gemstone.gemfire.internal.cache.versions.VersionSource;
+ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventImpl;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.lang.StringUtils;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
 -import com.gemstone.gemfire.internal.offheap.ChunkWithHeapForm;
 -import com.gemstone.gemfire.internal.offheap.GemFireChunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunkWithHeapForm;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.MemoryAllocator;
+ import com.gemstone.gemfire.internal.offheap.OffHeapCachedDeserializable;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
+ import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.internal.util.BlobHelper;
+ import com.gemstone.gemfire.internal.util.Versionable;
+ import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap;
+ import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap.HashEntry;
+ import com.gemstone.gemfire.pdx.PdxInstance;
+ import com.gemstone.gemfire.pdx.PdxSerializable;
+ import com.gemstone.gemfire.pdx.PdxSerializationException;
+ import com.gemstone.gemfire.pdx.PdxSerializer;
+ import com.gemstone.gemfire.pdx.internal.ConvertableToBytes;
+ import com.gemstone.gemfire.pdx.internal.PdxInstanceImpl;
+ 
+ /**
+  * Abstract implementation class of RegionEntry interface.
+  * This is the topmost implementation class so common behavior
+  * lives here.
+  *
+  * @since 3.5.1
+  *
+  * @author Darrel Schneider
+  * @author bruce
+  *
+  */
+ public abstract class AbstractRegionEntry implements RegionEntry,
+     HashEntry<Object, Object> {
+ 
+   private static final Logger logger = LogService.getLogger();
+   
+   /**
+    * Whether to disable last access time update when a put occurs. The default
+    * is false (enable last access time update on put). To disable it, set the
+    * 'gemfire.disableAccessTimeUpdateOnPut' system property.
+    */
+   protected static final boolean DISABLE_ACCESS_TIME_UPDATE_ON_PUT = Boolean
+       .getBoolean("gemfire.disableAccessTimeUpdateOnPut");
+ 
+   /*
+    * Flags for a Region Entry.
+    * These flags are stored in the msb of the long used to also store the lastModicationTime.
+    */
+   private static final long VALUE_RESULT_OF_SEARCH          = 0x01L<<56;
+   private static final long UPDATE_IN_PROGRESS              = 0x02L<<56;
+   private static final long TOMBSTONE_SCHEDULED             = 0x04L<<56;
+   private static final long LISTENER_INVOCATION_IN_PROGRESS = 0x08L<<56;
+   /**  used for LRUEntry instances. */
+   protected static final long RECENTLY_USED = 0x10L<<56;
+   /**  used for LRUEntry instances. */
+   protected static final long EVICTED = 0x20L<<56;
+   /**
+    * Set if the entry is being used by a transactions.
+    * Some features (eviction and expiration) will not modify an entry when a tx is using it
+    * to prevent the tx to fail do to conflict.
+    */
+   protected static final long IN_USE_BY_TX = 0x40L<<56;
+ 
+ 
+   protected static final long MARKED_FOR_EVICTION = 0x80L<<56;
+ //  public Exception removeTrace; // debugging hot loop in AbstractRegionMap.basicPut()
+   
+   protected AbstractRegionEntry(RegionEntryContext context,
+       @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE) Object value) {
+     
+     setValue(context,this.prepareValueForCache(context, value, false),false);
+ //    setLastModified(System.currentTimeMillis()); [bruce] this must be set later so we can use ==0 to know this is a new entry in checkForConflicts
+   }
+   
+   /////////////////////////////////////////////////////////////////////
+   ////////////////////////// instance methods /////////////////////////
+   /////////////////////////////////////////////////////////////////////
+ 
+   @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IMSE_DONT_CATCH_IMSE")
+   public boolean dispatchListenerEvents(final EntryEventImpl event) throws InterruptedException {
+     final LocalRegion rgn = event.getRegion();
+ 
+     if (event.callbacksInvoked()) {
+        return true;
+     }
+ 
+     // don't wait for certain events to reach the head of the queue before
+     // dispatching listeners. However, we must not notify the gateways for
+     // remote-origin ops out of order. Otherwise the other systems will have
+     // inconsistent content.
+ 
+     event.setCallbacksInvokedByCurrentThread();
+ 
+     if (logger.isDebugEnabled()) {
+       logger.debug("{} dispatching event {}", this, event);
+     }
+     // All the following code that sets "thr" is to workaround
+     // spurious IllegalMonitorStateExceptions caused by JVM bugs.
+     try {
+       // call invokeCallbacks while synced on RegionEntry
+       event.invokeCallbacks(rgn, event.inhibitCacheListenerNotification(), false);
+       return true;
+ 
+     } finally {
+       if (isRemoved() && !isTombstone() && !event.isEvicted()) {
+         // Phase 2 of region entry removal is done here. The first phase is done
+         // by the RegionMap. It is unclear why this code is needed. ARM destroy
+         // does this also and we are now doing it as phase3 of the ARM destroy.
+         removePhase2();
+         rgn.getRegionMap().removeEntry(event.getKey(), this, true, event, rgn, rgn.getIndexUpdater());
+       }
+     }
+   }
+ 
+   public long getLastAccessed() throws InternalStatisticsDisabledException {
+     throw new InternalStatisticsDisabledException();
+   }
+     
+   public long getHitCount() throws InternalStatisticsDisabledException {
+     throw new InternalStatisticsDisabledException();
+   }
+     
+   public long getMissCount() throws InternalStatisticsDisabledException {
+     throw new InternalStatisticsDisabledException();
+   }
+ 
+   protected void setLastModified(long lastModified) {
+     _setLastModified(lastModified);
+   }        
+ 
+   public void txDidDestroy(long currTime) {
+     setLastModified(currTime);
+   }
+   
+   public final void updateStatsForPut(long lastModifiedTime) {
+     setLastModified(lastModifiedTime);
+   }
+   
+   public void setRecentlyUsed() {
+     // do nothing by default; only needed for LRU
+   }
+     
+   public void updateStatsForGet(boolean hit, long time) {
+     // nothing needed
+   }
+ 
+   public void resetCounts() throws InternalStatisticsDisabledException {
+     throw new InternalStatisticsDisabledException();
+   }
+     
+   public void _removePhase1() {
+     _setValue(Token.REMOVED_PHASE1);
+     // debugging for 38467 (hot thread in ARM.basicUpdate)
+ //    this.removeTrace = new Exception("stack trace for thread " + Thread.currentThread());
+   }
+   public void removePhase1(LocalRegion r, boolean isClear) throws RegionClearedException {
+     _removePhase1();
+   }
+   
+   public void removePhase2() {
+     _setValue(Token.REMOVED_PHASE2);
+ //    this.removeTrace = new Exception("stack trace for thread " + Thread.currentThread());
+   }
+   
+   public void makeTombstone(LocalRegion r, VersionTag version) throws RegionClearedException {
+     assert r.getVersionVector() != null;
+     assert version != null;
+     if (r.getServerProxy() == null &&
+         r.getVersionVector().isTombstoneTooOld(version.getMemberID(), version.getRegionVersion())) {
+       // distributed gc with higher vector version preempts this operation
+       if (!isTombstone()) {
+         setValue(r, Token.TOMBSTONE);
+         r.incTombstoneCount(1);
+       }
+       r.getRegionMap().removeTombstone(this, version, false, true);
+     } else {
+       if (isTombstone()) {
+         // unschedule the old tombstone
+         r.unscheduleTombstone(this);
+       }
+       setRecentlyUsed();
+       boolean newEntry = (getValueAsToken() == Token.REMOVED_PHASE1);
+       setValue(r, Token.TOMBSTONE);
+       r.scheduleTombstone(this, version);
+       if (newEntry) {
+         // bug #46631 - entry count is decremented by scheduleTombstone but this is a new entry
+         r.getCachePerfStats().incEntryCount(1);
+       }
+     }
+   }
+   
+ 
+   @Override
+   public void setValueWithTombstoneCheck(@Unretained Object v, EntryEvent e) throws RegionClearedException {
+     if (v == Token.TOMBSTONE) {
+       makeTombstone((LocalRegion)e.getRegion(), ((EntryEventImpl)e).getVersionTag());
+     } else {
+       setValue((LocalRegion)e.getRegion(), v, (EntryEventImpl)e);
+     }
+   }
+   
+   /**
+    * Return true if the object is removed.
+    * 
+    * TODO this method does NOT return true if the object
+    * is Token.DESTROYED. dispatchListenerEvents relies on that
+    * fact to avoid removing destroyed tokens from the map.
+    * We should refactor so that this method calls Token.isRemoved,
+    * and places that don't want a destroyed Token can explicitly check
+    * for a DESTROY token.
+    */
+   public final boolean isRemoved() {
+     Token o = getValueAsToken();
+     return (o == Token.REMOVED_PHASE1) || (o == Token.REMOVED_PHASE2) || (o == Token.TOMBSTONE);
+   }
+   
+   public final boolean isDestroyedOrRemoved() {
+     return Token.isRemoved(getValueAsToken());
+   }
+   
+   public final boolean isDestroyedOrRemovedButNotTombstone() {
+     Token o = getValueAsToken();
+     return o == Token.DESTROYED || o == Token.REMOVED_PHASE1 || o == Token.REMOVED_PHASE2;
+   }
+   
+   public final boolean isTombstone() {
+     return getValueAsToken() == Token.TOMBSTONE;
+   }
+   
+   public final boolean isRemovedPhase2() {
+     return getValueAsToken() == Token.REMOVED_PHASE2;
+   }
+   
+   public boolean fillInValue(LocalRegion region,
+                              @Retained(ABSTRACT_REGION_ENTRY_FILL_IN_VALUE) InitialImageOperation.Entry dst,
+                              ByteArrayDataInput in,
+                              DM mgr)
+   {
+     dst.setSerialized(false); // starting default value
+ 
+     @Retained(ABSTRACT_REGION_ENTRY_FILL_IN_VALUE) final Object v;
+     if (isTombstone()) {
+       v = Token.TOMBSTONE;
+     } else {
+       v = getValue(region); // OFFHEAP: need to incrc, copy bytes, decrc
+       if (v == null) {
+         return false;
+       }
+     }
+ 
+     final boolean isEagerDeserialize = dst.isEagerDeserialize();
+     if (isEagerDeserialize) {
+       dst.clearEagerDeserialize();
+     }
+     dst.setLastModified(mgr, getLastModified()); // fix for bug 31059
+     if (v == Token.INVALID) {
+       dst.setInvalid();
+     }
+     else if (v == Token.LOCAL_INVALID) {
+       dst.setLocalInvalid();
+     }
+     else if (v == Token.TOMBSTONE) {
+       dst.setTombstone();
+     }
+     else if (v instanceof CachedDeserializable) {
+       // don't serialize here if it is not already serialized
+ //      if(v instanceof ByteSource && CachedDeserializableFactory.preferObject()) {
+ //        // For SQLFire we prefer eager deserialized
+ //        dst.setEagerDeserialize();         
+ //      }
+       
+       if (v instanceof StoredObject && !((StoredObject) v).isSerialized()) {
+         dst.value = ((StoredObject) v).getDeserializedForReading();
+       } else {
+         /*if (v instanceof ByteSource && CachedDeserializableFactory.preferObject()) {
+           dst.value = v;
+         } else */ {
+           Object tmp = ((CachedDeserializable) v).getValue();
+           if (tmp instanceof byte[]) {
+             byte[] bb = (byte[]) tmp;
+             dst.value = bb;
+           } else {
+             try {
+               HeapDataOutputStream hdos = new HeapDataOutputStream(
+                   Version.CURRENT);
+               BlobHelper.serializeTo(tmp, hdos);
+               hdos.trim();
+               dst.value = hdos;
+             } catch (IOException e) {
+               RuntimeException e2 = new IllegalArgumentException(
+                   LocalizedStrings.AbstractRegionEntry_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING
+                       .toLocalizedString());
+               e2.initCause(e);
+               throw e2;
+             }
+           }
+           dst.setSerialized(true);
+         }
+       }
+     }
+     else if (v instanceof byte[]) {
+       dst.value = v;
+     }
+     else { 
+       Object preparedValue = v;
+       if (preparedValue != null) {
+         preparedValue = prepareValueForGII(preparedValue);
+         if (preparedValue == null) {
+           return false;
+         }
+       }
+     if (CachedDeserializableFactory.preferObject()) {
+       dst.value = preparedValue;
+       dst.setEagerDeserialize();
+     }
+     else {
+       try {
+         HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+         BlobHelper.serializeTo(preparedValue, hdos);
+         hdos.trim();
+         dst.value = hdos;
+         dst.setSerialized(true);
+       } catch (IOException e) {
+         RuntimeException e2 = new IllegalArgumentException(LocalizedStrings.AbstractRegionEntry_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString());
+         e2.initCause(e);
+         throw e2;
+       }
+     }
+     }
+     return true;
+   }
+   
+   /**
+    * To fix bug 49901 if v is a GatewaySenderEventImpl then make
+    * a heap copy of it if it is offheap.
+    * @return the value to provide to the gii request; null if no value should be provided.
+    */
+   public static Object prepareValueForGII(Object v) {
+     assert v != null;
+     if (v instanceof GatewaySenderEventImpl) {
+       return ((GatewaySenderEventImpl) v).makeHeapCopyIfOffHeap();
+     } else {
+       return v;
+     }
+   }
+   
+   public boolean isOverflowedToDisk(LocalRegion r, DistributedRegion.DiskPosition dp) {
+     return false;
+   }
+ 
+   @Override
+   public Object getValue(RegionEntryContext context) {
+     ReferenceCountHelper.createReferenceCountOwner();
+     @Retained Object result = _getValueRetain(context, true);
+     //Asif: If the thread is an Index Creation Thread & the value obtained is 
+     //Token.REMOVED , we can skip  synchronization block. This is required to prevent
+     // the dead lock caused if an Index Update Thread has gone into a wait holding the
+     // lock of the Entry object. There should not be an issue if the Index creation thread
+     // gets the temporary value of token.REMOVED as the  correct value will get indexed
+     // by the Index Update Thread , once the index creation thread has exited.
+     // Part of Bugfix # 33336
+ //    if ((result == Token.REMOVED_PHASE1 || result == Token.REMOVED_PHASE2) && !r.isIndexCreationThread()) {
+ //      synchronized (this) {
+ //        result = _getValue();
+ //      }
+ //    }
+     
+     if (Token.isRemoved(result)) {
+       ReferenceCountHelper.setReferenceCountOwner(null);
+       return null;
+     } else {
+       result = OffHeapHelper.copyAndReleaseIfNeeded(result); // sqlf does not dec ref count in this call
+       ReferenceCountHelper.setReferenceCountOwner(null);
+       setRecentlyUsed();
+       return result;
+     }
+   }
+   
+   @Override
+   @Retained
+   public Object getValueRetain(RegionEntryContext context) {
+     @Retained Object result = _getValueRetain(context, true);
+     if (Token.isRemoved(result)) {
+       return null;
+     } else {
+       setRecentlyUsed();
+       return result;
+     }
+   }
+   
+   @Override
+   @Released
+   public void setValue(RegionEntryContext context, @Unretained Object value) throws RegionClearedException {
+     // @todo darrel: This will mark new entries as being recently used
+     // It might be better to only mark them when they are modified.
+     // Or should we only mark them on reads?
+     setValue(context,value,true);
+   }
+   
+   @Override
+   public void setValue(RegionEntryContext context, Object value, EntryEventImpl event) throws RegionClearedException {
+     setValue(context,value);
+   }
+   
+   @Released
+   protected void setValue(RegionEntryContext context, @Unretained Object value, boolean recentlyUsed) {
+     _setValue(value);
+     if (value != null && context != null && (this instanceof OffHeapRegionEntry) 
+         && context instanceof LocalRegion && ((LocalRegion)context).isThisRegionBeingClosedOrDestroyed()) {
+       ((OffHeapRegionEntry)this).release();
+       ((LocalRegion)context).checkReadiness();
+     }
+     if (recentlyUsed) {
+       setRecentlyUsed();
+     }
+   }
+ 
+   /**
+    * This method determines if the value is in a compressed representation and decompresses it if it is.
+    *
+    * @param context the values context. 
+    * @param value a region entry value.
+    * 
+    * @return the decompressed form of the value parameter.
+    */
+   static Object decompress(RegionEntryContext context,Object value) {
+     if(isCompressible(context, value)) {
+       long time = context.getCachePerfStats().startDecompression();
+       value = EntryEventImpl.deserialize(context.getCompressor().decompress((byte[]) value));
+       context.getCachePerfStats().endDecompression(time);      
+     }
+     
+     return value;
+   }
+   
+   static protected Object compress(RegionEntryContext context,Object value) {
+     return compress(context, value, null);
+   }
+ 
+     /**
+    * This method determines if the value is compressible and compresses it if it is.
+    *
+    * @param context the values context. 
+    * @param value a region entry value.
+    * 
+    * @return the compressed form of the value parameter.
+    */
+   static protected Object compress(RegionEntryContext context,Object value, EntryEventImpl event) {
+     if(isCompressible(context, value)) {
+       long time = context.getCachePerfStats().startCompression();
+       byte[] serializedValue;
+       if (event != null && event.getCachedSerializedNewValue() != null) {
+         serializedValue = event.getCachedSerializedNewValue();
+         if (value instanceof CachedDeserializable) {
+           CachedDeserializable cd = (CachedDeserializable) value;
+           if (!(cd.getValue() instanceof byte[])) {
+             // The cd now has the object form so use the cached serialized form in a new cd.
+             // This serialization is much cheaper than reserializing the object form.
+             serializedValue = EntryEventImpl.serialize(CachedDeserializableFactory.create(serializedValue));
+           } else {
+             serializedValue = EntryEventImpl.serialize(cd);
+           }
+         }
+       } else {
+         serializedValue = EntryEventImpl.serialize(value);
+         if (event != null && !(value instanceof byte[])) {
+           // See if we can cache the serialized new value in the event.
+           // If value is a byte[] then we don't cache it since it is not serialized.
+           if (value instanceof CachedDeserializable) {
+             // For a CacheDeserializable we want to only cache the wrapped value;
+             // not the serialized CacheDeserializable.
+             CachedDeserializable cd = (CachedDeserializable) value;
+             Object cdVal = cd.getValue();
+             if (cdVal instanceof byte[]) {
+               event.setCachedSerializedNewValue((byte[])cdVal);
+             }
+           } else {
+             event.setCachedSerializedNewValue(serializedValue);
+           }
+         }
+       }
+       value = context.getCompressor().compress(serializedValue);
+       context.getCachePerfStats().endCompression(time, serializedValue.length, ((byte []) value).length);
+     }
+     
+     return value;    
+   }
+   
+   private static byte[] compressBytes(RegionEntryContext context, byte[] uncompressedBytes) {
+     byte[] result = uncompressedBytes;
+     if (isCompressible(context, uncompressedBytes)) {
+       long time = context.getCachePerfStats().startCompression();
+       result = context.getCompressor().compress(uncompressedBytes);
+       context.getCachePerfStats().endCompression(time, uncompressedBytes.length, result.length);
+     }
+     return result;
+   }
+   
+   
+   @Retained
+   public final Object getValueInVM(RegionEntryContext context) {
+     ReferenceCountHelper.createReferenceCountOwner();
+     @Retained Object v = _getValueRetain(context, true);
+     
+     if (v == null) { // should only be possible if disk entry
+       v = Token.NOT_AVAILABLE;
+     }
+     @Retained Object result = OffHeapHelper.copyAndReleaseIfNeeded(v); // TODO OFFHEAP keep it offheap?
+     ReferenceCountHelper.setReferenceCountOwner(null);
+     return result;
+   }
+   
+   @Retained
+   public  Object getValueInVMOrDiskWithoutFaultIn(LocalRegion owner) {
+    return getValueInVM(owner);
+   }
+   
+   @Override
+   @Retained
+   public Object getValueOffHeapOrDiskWithoutFaultIn(LocalRegion owner) {
+     @Retained Object result = _getValueRetain(owner, true);
+ //    if (result instanceof ByteSource) {
+ //      // If the ByteSource contains a Delta or ListOfDelta then we want to deserialize it
+ //      Object deserVal = ((CachedDeserializable)result).getDeserializedForReading();
+ //      if (deserVal != result) {
+ //        OffHeapHelper.release(result);
+ //        result = deserVal;
+ //      }
+ //    }
+     return result;
+   }
+   
+   public Object getValueOnDisk(LocalRegion r)
+   throws EntryNotFoundException
+   {
+     throw new IllegalStateException(LocalizedStrings.AbstractRegionEntry_CANNOT_GET_VALUE_ON_DISK_FOR_A_REGION_THAT_DOES_NOT_ACCESS_THE_DISK.toLocalizedString());
+   }
+ 
+   public Object getSerializedValueOnDisk(final LocalRegion r)
+   throws EntryNotFoundException
+   {
+     throw new IllegalStateException(LocalizedStrings.AbstractRegionEntry_CANNOT_GET_VALUE_ON_DISK_FOR_A_REGION_THAT_DOES_NOT_ACCESS_THE_DISK.toLocalizedString());
+   }
+   
+  public Object getValueOnDiskOrBuffer(LocalRegion r)
+   throws EntryNotFoundException
+  {
+   throw new IllegalStateException(LocalizedStrings.AbstractRegionEntry_CANNOT_GET_VALUE_ON_DISK_FOR_A_REGION_THAT_DOES_NOT_ACCESS_THE_DISK.toLocalizedString());
+   // @todo darrel if value is Token.REMOVED || Token.DESTROYED throw EntryNotFoundException
+  }
+ 
+   public final boolean initialImagePut(final LocalRegion region,
+                                        final long lastModifiedTime,
+                                        Object newValue,
+                                        boolean wasRecovered,
+                                        boolean versionTagAccepted) throws RegionClearedException
+   {
+     // note that the caller has already write synced this RegionEntry
+     return initialImageInit(region, lastModifiedTime, newValue, this.isTombstone(), wasRecovered, versionTagAccepted);
+   }
+ 
+   public boolean initialImageInit(final LocalRegion region,
+                                         final long lastModifiedTime,
+                                         final Object newValue,
+                                         final boolean create,
+                                         final boolean wasRecovered,
+                                         final boolean versionTagAccepted) throws RegionClearedException
+   {
+     // note that the caller has already write synced this RegionEntry
+     boolean result = false;
+     // if it has been destroyed then don't do anything
+     Token vTok = getValueAsToken();
+     if (versionTagAccepted || create || (vTok != Token.DESTROYED || vTok != Token.TOMBSTONE)) { // OFFHEAP noop
+       Object newValueToWrite = newValue;
+       boolean putValue = versionTagAccepted || create
+         || (newValueToWrite != Token.LOCAL_INVALID
+             && (wasRecovered || (vTok == Token.LOCAL_INVALID))); // OFFHEAP noop
+     
+       if (region.isUsedForPartitionedRegionAdmin() && newValueToWrite instanceof CachedDeserializable) {
+         // Special case for partitioned region meta data
+         // We do not need the RegionEntry on this case.
+         // Because the pr meta data region will not have an LRU.
+         newValueToWrite = ((CachedDeserializable) newValueToWrite).getDeserializedValue(region, null);
+         if (!create && newValueToWrite instanceof Versionable) {
+           @Retained @Released final Object oldValue = getValueInVM(region); // Heap value should always be deserialized at this point // OFFHEAP will not be deserialized
+           try {
+           // BUGFIX for 35029. If oldValue is null the newValue should be put.
+           if(oldValue == null) {
+           	putValue = true;
+           }
+           else if (oldValue instanceof Versionable) {
+             Versionable nv = (Versionable) newValueToWrite;
+             Versionable ov = (Versionable) oldValue;
+             putValue = nv.isNewerThan(ov);
+           }  
+           } finally {
+             OffHeapHelper.release(oldValue);
+           }
+         }
+       }
+ 
+       if (putValue) {
+         // change to INVALID if region itself has been invalidated,
+         // and current value is recovered
+         if (create || versionTagAccepted) {
+           // At this point, since we now always recover from disk first,
+           // we only care about "isCreate" since "isRecovered" is impossible
+           // if we had a regionInvalidate or regionClear
+           ImageState imageState = region.getImageState();
+           // this method is called during loadSnapshot as well as getInitialImage
+           if (imageState.getRegionInvalidated()) {
+             if (newValueToWrite != Token.TOMBSTONE) {
+               newValueToWrite = Token.INVALID;
+             }
+           }
+           else if (imageState.getClearRegionFlag()) {
+             boolean entryOK = false;
+             RegionVersionVector rvv = imageState.getClearRegionVersionVector();
+             if (rvv != null) { // a filtered clear
+               VersionSource id = getVersionStamp().getMemberID();
+               if (id == null) {
+                 id = region.getVersionMember();
+               }
+               if (!rvv.contains(id, getVersionStamp().getRegionVersion())) {
+                 entryOK = true;
+               }
+             }
+             if (!entryOK) {
+               //Asif: If the region has been issued cleared during
+               // the GII , then those entries loaded before this one would have
+               // been cleared from the Map due to clear operation & for the
+               // currententry whose key may have escaped the clearance , will be
+               // cleansed by the destroy token.
+               newValueToWrite = Token.DESTROYED;
+               imageState.addDestroyedEntry(this.getKey());
+               throw new RegionClearedException(LocalizedStrings.AbstractRegionEntry_DURING_THE_GII_PUT_OF_ENTRY_THE_REGION_GOT_CLEARED_SO_ABORTING_THE_OPERATION.toLocalizedString());
+             }
+           }
+         } 
+         setValue(region, this.prepareValueForCache(region, newValueToWrite, false));
+         result = true;
+ 
+         if (newValueToWrite != Token.TOMBSTONE){
+           if (create) {
+             region.getCachePerfStats().incCreates();
+           }
+           region.updateStatsForPut(this, lastModifiedTime, false);
+         }
+         
+         if (logger.isTraceEnabled()) {
+           if (newValueToWrite instanceof CachedDeserializable) {
+             logger.trace("ProcessChunk: region={}; put a CachedDeserializable ({},{})",
+                 region.getFullPath(), getKey(),((CachedDeserializable)newValueToWrite).getStringForm());
+           }
+           else {
+             logger.trace("ProcessChunk: region={}; put({},{})", region.getFullPath(), getKey(), StringUtils.forceToString(newValueToWrite));
+           }
+         }
+       }
+     }
+     return result;
+   }
+  
+   /**
+    * @throws EntryNotFoundException if expectedOldValue is
+    * not null and is not equal to current value
+    */
+   @Released
+   public final boolean destroy(LocalRegion region,
+                             EntryEventImpl event,
+                             boolean inTokenMode,
+                             boolean cacheWrite,
+                             @Unretained Object expectedOldValue,
+                             boolean forceDestroy,
+                             boolean removeRecoveredEntry)
+     throws CacheWriterException,
+            EntryNotFoundException,
+            TimeoutException,
+            RegionClearedException {
+     boolean proceed = false;
+     {
+     // A design decision was made to not retrieve the old value from the disk
+     // if the entry has been evicted to only have the CacheListener afterDestroy
+     // method ignore it. We don't want to pay the performance penalty. The 
+     // getValueInVM method does not retrieve the value from disk if it has been
+     // evicted. Instead, it uses the NotAvailable token.
+     //
+     // If the region is a WAN queue region, the old value is actually used by the 
+     // afterDestroy callback on a secondary. It is not needed on a primary.
+     // Since the destroy that sets WAN_QUEUE_TOKEN always originates on the primary
+     // we only pay attention to WAN_QUEUE_TOKEN if the event is originRemote.
+     //
+     // :ezoerner:20080814 We also read old value from disk or buffer
+     // in the case where there is a non-null expectedOldValue
+     // see PartitionedRegion#remove(Object key, Object value)
+     ReferenceCountHelper.skipRefCountTracking();
+     @Retained @Released Object curValue = _getValueRetain(region, true);
+     ReferenceCountHelper.unskipRefCountTracking();
+     try {
+     if (curValue == null) curValue = Token.NOT_AVAILABLE;
+     
+     if (curValue == Token.NOT_AVAILABLE) {
+       // In some cases we need to get the current value off of disk.
+       
+       // if the event is transmitted during GII and has an old value, it was
+       // the state of the transmitting cache's entry & should be used here
+       if (event.getCallbackArgument() != null
+           && event.getCallbackArgument().equals(RegionQueue.WAN_QUEUE_TOKEN)
+           && event.isOriginRemote()) { // check originRemote for bug 40508
+         //curValue = getValue(region); can cause deadlock if GII is occurring
+         curValue = getValueOnDiskOrBuffer(region);
+       } 
+       else {
+         FilterProfile fp = region.getFilterProfile();
+         // rdubey: Old value also required for SqlfIndexManager.
+         if (fp != null && ((fp.getCqCount() > 0) || expectedOldValue != null
+             || event.getRegion().getIndexUpdater() != null)) {
+           //curValue = getValue(region); can cause deadlock will fault in the value
+           // and will confuse LRU. rdubey.
+           curValue = getValueOnDiskOrBuffer(region);
+         }      
+       }
+     }
+ 
+     if (expectedOldValue != null) {
+       if (!checkExpectedOldValue(expectedOldValue, curValue, region)) {
+         throw new EntryNotFoundException(
+           LocalizedStrings.AbstractRegionEntry_THE_CURRENT_VALUE_WAS_NOT_EQUAL_TO_EXPECTED_VALUE.toLocalizedString());
+       }
+     }
+ 
+     if (inTokenMode && event.hasOldValue()) {
+       proceed = true;
+     }
+     else {
+       proceed = event.setOldValue(curValue, curValue instanceof GatewaySenderEventImpl) || removeRecoveredEntry
+                 || forceDestroy || region.getConcurrencyChecksEnabled() // fix for bug #47868 - create a tombstone
+                 || (event.getOperation() == Operation.REMOVE // fix for bug #42242
+                     && (curValue == null || curValue == Token.LOCAL_INVALID
+                         || curValue == Token.INVALID));
+     }
+     } finally {
+       OffHeapHelper.releaseWithNoTracking(curValue);
+     }
+     } // end curValue block
+     
+     if (proceed) {
+       //Generate the version tag if needed. This method should only be 
+       //called if we are in fact going to destroy the entry, so it must be
+       //after the entry not found exception above.
+       if(!removeRecoveredEntry) {
+         region.generateAndSetVersionTag(event, this);
+       }
+       if (cacheWrite) {
+         region.cacheWriteBeforeDestroy(event, expectedOldValue);
+         if (event.getRegion().getServerProxy() != null) { // server will return a version tag
+           // update version information (may throw ConcurrentCacheModificationException)
+           VersionStamp stamp = getVersionStamp();
+           if (stamp != null) {
+             stamp.processVersionTag(event);
+           }
+         }
+       }
+       region.recordEvent(event);
+       // don't do index maintenance on a destroy if the value in the
+       // RegionEntry (the old value) is invalid
+       if (!region.isProxy() && !isInvalid()) {
+         IndexManager indexManager = region.getIndexManager();
+         if (indexManager != null) {
+           try {
+             if(isValueNull()) {
+               @Released Object value = getValueOffHeapOrDiskWithoutFaultIn(region);
+               try {
+               _setValue(prepareValueForCache(region, value, false));
+               if (value != null && region != null && (this instanceof OffHeapRegionEntry) && region.isThisRegionBeingClosedOrDestroyed()) {
+                 ((OffHeapRegionEntry)this).release();
+                 region.checkReadiness();
+               }
+               } finally {
+                 OffHeapHelper.release(value);
+               }
+             }
+             indexManager.updateIndexes(this,
+                 IndexManager.REMOVE_ENTRY,
+                 IndexProtocol.OTHER_OP);
+           }
+           catch (QueryException e) {
+             throw new IndexMaintenanceException(e);
+           }
+         }
+       }
+ 
+       boolean removeEntry = false;
+       VersionTag v = event.getVersionTag();
+       if (region.concurrencyChecksEnabled && !removeRecoveredEntry
+           && !event.isFromRILocalDestroy()) { // bug #46780, don't retain tombstones for entries destroyed for register-interest
+         // Destroy will write a tombstone instead 
+         if (v == null || !v.hasValidVersion()) { 
+           // localDestroy and eviction and ops received with no version tag
+           // should create a tombstone using the existing version stamp, as should
+           // (bug #45245) responses from servers that do not have valid version information
+           VersionStamp stamp = this.getVersionStamp();
+           if (stamp != null) {  // proxy has no stamps
+             v = stamp.asVersionTag();
+             event.setVersionTag(v);
+           }
+         }
+         removeEntry = (v == null) || !v.hasValidVersion();
+       } else {
+         removeEntry = true;
+       }
+ 
+       // See #47887, we do not insert a tombstone for evicted HDFS
+       // entries since the value is still present in HDFS
+       // Check if we have to evict or just do destroy.
+       boolean forceRemoveEntry = 
+           (event.isEviction() || event.isExpiration()) 
+           && event.getRegion().isUsedForPartitionedRegionBucket()
+           && event.getRegion().getPartitionedRegion().isHDFSRegion();
+ 
+       if (removeEntry || forceRemoveEntry) {
+         boolean isThisTombstone = isTombstone();
+         if(inTokenMode && !event.getOperation().isEviction()) {
+           setValue(region, Token.DESTROYED);  
+         } else {
+           removePhase1(region, false);
+         }
+         if (isThisTombstone) {
+           region.unscheduleTombstone(this);
+         }
+       } else {
+         makeTombstone(region, v);
+       }
+       
+       return true;
+     }
+     else {
+       return false;
+     }
+   }
+   
+  
+ 
+   static boolean checkExpectedOldValue(@Unretained Object expectedOldValue, @Unretained Object actualValue, LocalRegion lr) {
+     if (Token.isInvalid(expectedOldValue)) {
+       return (actualValue == null) || Token.isInvalid(actualValue);
+     } else {
+       boolean isCompressedOffHeap = lr.getAttributes().getOffHeap() && lr.getAttributes().getCompressor() != null;
+       return checkEquals(expectedOldValue, actualValue, isCompressedOffHeap);
+     }
+   }
+   
+   private static boolean basicEquals(Object v1, Object v2) {
+     if (v2 != null) {
+       if (v2.getClass().isArray()) {
+         // fix for 52093
+         if (v2 instanceof byte[]) {
+           if (v1 instanceof byte[]) {
+             return Arrays.equals((byte[])v2, (byte[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof Object[]) {
+           if (v1 instanceof Object[]) {
+             return Arrays.deepEquals((Object[])v2, (Object[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof int[]) {
+           if (v1 instanceof int[]) {
+             return Arrays.equals((int[])v2, (int[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof long[]) {
+           if (v1 instanceof long[]) {
+             return Arrays.equals((long[])v2, (long[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof boolean[]) {
+           if (v1 instanceof boolean[]) {
+             return Arrays.equals((boolean[])v2, (boolean[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof short[]) {
+           if (v1 instanceof short[]) {
+             return Arrays.equals((short[])v2, (short[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof char[]) {
+           if (v1 instanceof char[]) {
+             return Arrays.equals((char[])v2, (char[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof float[]) {
+           if (v1 instanceof float[]) {
+             return Arrays.equals((float[])v2, (float[])v1);
+           } else {
+             return false;
+           }
+         } else if (v2 instanceof double[]) {
+           if (v1 instanceof double[]) {
+             return Arrays.equals((double[])v2, (double[])v1);
+           } else {
+             return false;
+           }
+         }
+         // fall through and call equals method
+       }
+       return v2.equals(v1);
+     } else {
+       return v1 == null;
+     }
+   }
+   
+   static boolean checkEquals(@Unretained Object v1, @Unretained Object v2, boolean isCompressedOffHeap) {
+     // need to give PdxInstance#equals priority
+     if (v1 instanceof PdxInstance) {
+       return checkPdxEquals((PdxInstance)v1, v2);
+     } else if (v2 instanceof PdxInstance) {
+       return checkPdxEquals((PdxInstance)v2, v1);
+     } else if (v1 instanceof OffHeapCachedDeserializable) {
+       return checkOffHeapEquals((OffHeapCachedDeserializable)v1, v2);
+     } else if (v2 instanceof OffHeapCachedDeserializable) {
+       return checkOffHeapEquals((OffHeapCachedDeserializable)v2, v1);
+     } else if (v1 instanceof CachedDeserializable) {
+       return checkCDEquals((CachedDeserializable)v1, v2, isCompressedOffHeap);
+     } else if (v2 instanceof CachedDeserializable) {
+       return checkCDEquals((CachedDeserializable)v2, v1, isCompressedOffHeap);
+     } else {
+       return basicEquals(v1, v2);
+     }
+   }
+   private static boolean checkOffHeapEquals(@Unretained OffHeapCachedDeserializable cd, @Unretained Object obj) {
+     if (cd.isSerializedPdxInstance()) {
+       PdxInstance pi = InternalDataSerializer.readPdxInstance(cd.getSerializedValue(), GemFireCacheImpl.getForPdx("Could not check value equality"));
+       return checkPdxEquals(pi, obj);
+     }
+     if (obj instanceof OffHeapCachedDeserializable) {
+       return cd.checkDataEquals((OffHeapCachedDeserializable)obj);
+     } else {
+       byte[] serializedObj;
+       if (obj instanceof CachedDeserializable) {
+         if (!cd.isSerialized()) {
+           if (obj instanceof StoredObject && !((StoredObject) obj).isSerialized()) {
+             // both are byte[]
+             // obj must be DataAsAddress since it was not OffHeapCachedDeserializable
+             // so its byte[] will be small.
+             byte[] objBytes = (byte[]) ((StoredObject) obj).getDeserializedForReading();
+             return cd.checkDataEquals(objBytes);
+           } else {
+             return false;
+           }
+         }
+         serializedObj = ((CachedDeserializable) obj).getSerializedValue();
+       } else if (obj instanceof byte[]) {
+         if (cd.isSerialized()) {
+           return false;
+         }
+         serializedObj = (byte[]) obj;
+       } else {
+         if (!cd.isSerialized()) {
+           return false;
+         }
+         if (obj == null || obj == Token.NOT_AVAILABLE
+             || Token.isInvalidOrRemoved(obj)) {
+           return false;
+         }
+         serializedObj = EntryEventImpl.serialize(obj);
+       }
+       return cd.checkDataEquals(serializedObj);
+     }
+   }
+   
+   private static boolean checkCDEquals(CachedDeserializable cd, Object obj, boolean isCompressedOffHeap) {
+     if (cd instanceof StoredObject && !((StoredObject) cd).isSerialized()) {
+       // cd is an actual byte[].
+       byte[] ba2;
+       if (obj instanceof StoredObject) {
+         if (!((StoredObject) obj).isSerialized()) {
+           return false;
+         }
+         ba2 = (byte[]) ((StoredObject) obj).getDeserializedForReading();
+       } else if (obj instanceof byte[]) {
+         ba2 = (byte[]) obj;
+       } else {
+         return false;
+       }
+       byte[] ba1 = (byte[]) cd.getDeserializedForReading();
+       return Arrays.equals(ba1, ba2);
+     }
+     Object cdVal = cd.getValue();
+     if (cdVal instanceof byte[]) {
+       byte[] cdValBytes = (byte[])cdVal;
+       PdxInstance pi = InternalDataSerializer.readPdxInstance(cdValBytes, GemFireCacheImpl.getForPdx("Could not check value equality"));
+       if (pi != null) {
+         return checkPdxEquals(pi, obj);
+       }
+       if (isCompressedOffHeap) { // fix for bug 52248
+         byte[] serializedObj;
+         if (obj instanceof CachedDeserializable) {
+           serializedObj = ((CachedDeserializable) obj).getSerializedValue();
+         } else {
+           serializedObj = EntryEventImpl.serialize(obj); 
+         }
+         return Arrays.equals(cdValBytes, serializedObj); 
+       } else {
+         /**
+          * To be more compatible with previous releases do not compare the serialized forms here.
+          * Instead deserialize and call the equals method.
+          */
+       Object deserializedObj;
+       if (obj instanceof CachedDeserializable) {
+         deserializedObj =((CachedDeserializable) obj).getDeserializedForReading();
+       } else {
+         if (obj == null || obj == Token.NOT_AVAILABLE
+             || Token.isInvalidOrRemoved(obj)) {
+           return false;
+         }
+         // TODO OPTIMIZE: Before serializing all of obj we could get the top
+         // level class name of cdVal and compare it to the top level class name of obj.
+         deserializedObj = obj;
+       }
+       return basicEquals(deserializedObj, cd.getDeserializedForReading());
+       }
+ //      boolean result = Arrays.equals((byte[])cdVal, serializedObj);
+ //      if (!result) {
+ //        try {
+ //          Object o1 = BlobHelper.deserializeBlob((byte[])cdVal);
+ //          Object o2 = BlobHelper.deserializeBlob(serializedObj);
+ //          SimpleMemoryAllocatorImpl.debugLog("checkCDEquals o1=<" + o1 + "> o2=<" + o2 + ">", false);
+ //          if (o1.equals(o2)) {
+ //            SimpleMemoryAllocatorImpl.debugLog("they are equal! a1=<" + Arrays.toString((byte[])cdVal) + "> a2=<" + Arrays.toString(serializedObj) + ">", false);
+ //          }
+ //        } catch (IOException e) {
+ //          // TODO Auto-generated catch block
+ //          e.printStackTrace();
+ //        } catch (ClassNotFoundException e) {
+ //          // TODO Auto-generated catch block
+ //          e.printStackTrace();
+ //        }
+ //      }
+ //      return result;
+     } else {
+       // prefer object form
+       if (obj instanceof CachedDeserializable) {
+         // TODO OPTIMIZE: Before deserializing all of obj we could get the top
+         // class name of cdVal and the top level class name of obj and compare.
+         obj = ((CachedDeserializable) obj).getDeserializedForReading();
+       }
+       return basicEquals(cdVal, obj);
+     }
+   }
+   /**
+    * This method fixes bug 43643
+    */
+   private static boolean checkPdxEquals(PdxInstance pdx, Object obj) {
+     if (!(obj instanceof PdxInstance)) {
+       // obj may be a CachedDeserializable in which case we want to convert it to a PdxInstance even if we are not readSerialized.
+       if (obj instanceof CachedDeserializable) {
+         if (obj instanceof StoredObject && !((StoredObject) obj).isSerialized()) {
+           // obj is actually a byte[] which will never be equal to a PdxInstance
+           return false;
+         }
+         Object cdVal = ((CachedDeserializable) obj).getValue();
+         if (cdVal instanceof byte[]) {
+           byte[] cdValBytes = (byte[]) cdVal;
+           PdxInstance pi = InternalDataSerializer.readPdxInstance(cdValBytes, GemFireCacheImpl.getForPdx("Could not check value equality"));
+           if (pi != null) {
+             return pi.equals(pdx);
+           } else {
+             // since obj is serialized as something other than pdx it must not equal our pdx
+             return false;
+           }
+         } else {
+           // remove the cd wrapper so that obj is the actual value we want to compare.
+           obj = cdVal;
+         }
+       }
+       if (obj.getClass().getName().equals(pdx.getClassName())) {
+         GemFireCacheImpl gfc = GemFireCacheImpl.getForPdx("Could not access Pdx registry");
+         if (gfc != null) {
+           PdxSerializer pdxSerializer;
+           if (obj instanceof PdxSerializable) {
+             pdxSerializer = null;
+           } else {
+             pdxSerializer = gfc.getPdxSerializer();
+           }
+           if (pdxSerializer != null || obj instanceof PdxSerializable) {
+             // try to convert obj to a PdxInstance
+             HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+             try {
+               if (InternalDataSerializer.autoSerialized(obj, hdos) ||
+                   InternalDataSerializer.writePdx(hdos, gfc, obj, pdxSerializer)) {
+                 PdxInstance pi = InternalDataSerializer.readPdxInstance(hdos.toByteArray(), gfc);
+                 if (pi != null) {
+                   obj = pi;
+                 }
+               }
+             } catch (IOException ignore) {
+               // we are not able to convert it so just fall through
+             } catch (PdxSerializationException ignore) {
+               // we are not able to convert it so just fall through
+             }
+           }
+         }
+       }
+     }
+     return basicEquals(obj, pdx);
+   }
+ 
+   
+   /////////////////////////////////////////////////////////////
+   /////////////////////////// fields //////////////////////////
+   /////////////////////////////////////////////////////////////
+   // Do not add any instance fields to this class.
+   // Instead add them to LeafRegionEntry.cpp
+   
+   public static class HashRegionEntryCreator implements
+       CustomEntryConcurrentHashMap.HashEntryCreator<Object, Object> {
+ 
+     public HashEntry<Object, Object> newEntry(final Object key, final int hash,
+         final HashEntry<Object, Object> next, final Object value) {
+       final AbstractRegionEntry entry = (AbstractRegionEntry)value;
+       // if hash is already set then assert that the two should be same
+       final int entryHash = entry.getEntryHash();
+       if (hash == 0 || entryHash != 0) {
+         if (entryHash != hash) {
+           Assert.fail("unexpected mismatch of hash, expected=" + hash
+               + ", actual=" + entryHash + " for " + entry);
+         }
+       }
+       entry.setEntryHash(hash);
+       entry.setNextEntry(next);
+       return entry;
+     }
+ 
+     public int keyHashCode(final Object key, final boolean compareValues) {
+       return CustomEntryConcurrentHashMap.keyHash(key, compareValues);
+     }
+   };
+ 
+   public abstract Object getKey();
+   
+   protected static boolean okToStoreOffHeap(Object v, AbstractRegionEntry e) {
+     if (v == null) return false;
+     if (Token.isInvalidOrRemoved(v)) return false;
+     if (v == Token.NOT_AVAILABLE) return false;
+     if (v instanceof DiskEntry.RecoveredEntry) return false; // The disk layer has special logic that ends up storing the nested value in the RecoveredEntry off heap
+     if (!(e instanceof OffHeapRegionEntry)) return false;
+     // TODO should we check for deltas here or is that a user error?
+     return true;
+   }
+ 
+   /**
+    * Default implementation. Override in subclasses with primitive keys
+    * to prevent creating an Object form of the key for each equality check.
+    */
+   @Override
+   public boolean isKeyEqual(Object k) {
+     return k.equals(getKey());
+   }
+ 
+   private static final long LAST_MODIFIED_MASK = 0x00FFFFFFFFFFFFFFL;
+ 
+   protected final void _setLastModified(long lastModifiedTime) {
+     if (lastModifiedTime < 0 || lastModifiedTime > LAST_MODIFIED_MASK) {
+       throw new IllegalStateException("Expected lastModifiedTime " + lastModifiedTime + " to be >= 0 and <= " + LAST_MODIFIED_MASK);
+     }
+     long storedValue;
+     long newValue;
+     do {
+       storedValue = getlastModifiedField();
+       newValue = storedValue & ~LAST_MODIFIED_MASK;
+       newValue |= lastModifiedTime;
+     } while (!compareAndSetLastModifiedField(storedValue, newValue));
+   }
+   protected abstract long getlastModifiedField();
+   protected abstract boolean compareAndSetLastModifiedField(long expectedValue, long newValue);
+   public final long getLastModified() {
+     return getlastModifiedField() & LAST_MODIFIED_MASK;
+   }
+   protected final boolean areAnyBitsSet(long bitMask) {
+     return ( getlastModifiedField() & bitMask ) != 0L;
+   }
+   /**
+    * Any bits in "bitMask" that are 1 will be set.
+    */
+   protected final void setBits(long bitMask) {
+     boolean done = false;
+     do {
+       long bits = getlastModifiedField();
+       long newBits = bits | bitMask;
+       if (bits == newBits) return;
+       done = compareAndSetLastModifiedField(bits, newBits);
+     } while(!done);
+   }
+   /**
+    * Any bits in "bitMask" that are 0 will be cleared.
+    */
+   protected final void clearBits(long bitMask) {
+     boolean done = false;
+     do {
+       long bits = getlastModifiedField();
+       long newBits = bits & bitMask;
+       if (bits == newBits) return;
+       done = compareAndSetLastModifiedField(bits, newBits);
+     } while(!done);
+   }
+ 
+   @Override
+   @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE)
+   public  Object prepareValueForCache(RegionEntryContext r,
+       @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE) Object val,
+       boolean isEntryUpdate) {
+     return prepareValueForCache(r, val, null, isEntryUpdate);
+   }
+ 
+   @Override
+   @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE)
+   public  Object prepareValueForCache(RegionEntryContext r,
+       @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE) Object val,
+       EntryEventImpl event, boolean isEntryUpdate) {
+     if (r != null && r.getOffHeap() && okToStoreOffHeap(val, this)) {
+       if (val instanceof StoredObject) {
+         // Check to see if val has the same compression settings as this region.
+         // The recursive calls in this section are safe because
+         // we only do it after copy the off-heap value to the heap.
+         // This is needed to fix bug 52057.
+         StoredObject soVal = (StoredObject) val;
+         assert !soVal.isCompressed();
+         if (r.getCompressor() != null) {
+           // val is uncompressed and we need a compressed value.
+           // So copy the off-heap value to the heap in a form that can be compressed.
+           byte[] valAsBytes = soVal.getValueAsHeapByteArray();
+           Object heapValue;
+           if (soVal.isSerialized()) {
+             heapValue = CachedDeserializableFactory.create(valAsBytes);
+           } else {
+             heapValue = valAsBytes;
+           }
+           return prepareValueForCache(r, heapValue, event, isEntryUpdate);
+         }
 -        if (val instanceof Chunk) {
++        if (val instanceof ObjectChunk) {
+           // if the reused guy has a refcount then need to inc it
 -          if (!((Chunk)val).retain()) {
++          if (!((ObjectChunk)val).retain()) {
+             throw new IllegalStateException("Could not use an off heap value because it was freed");
+           }
+         }
+         // else it is DataAsAddress. This code just returns it as prepared.
+         // TODO OFFHEAP: Review the callers to see if they will handle DataAsAddress correctly.
+       } else {
+         byte[] data;
+         boolean isSerialized = !(val instanceof byte[]);
+         if (isSerialized) {
+           if (event != null && event.getCachedSerializedNewValue() != null) {
+             data = event.getCachedSerializedNewValue();
+           } else if (val instanceof CachedDeserializable) {
+             data = ((CachedDeserializable)val).getSerializedValue();
+             // TODO OFFHEAP: cache data in event?
+           } else if (val instanceof PdxInstance) {
+             try {
+               data = ((ConvertableToBytes)val).toBytes();
+               // TODO OFFHEAP: cache data in event?
+             } catch (IOException e) {
+               throw new PdxSerializationException("Could not convert " + val + " to bytes", e);
+             }
+           } else {
+             data = EntryEventImpl.serialize(val);
+             // TODO OFFHEAP: cache data in event?
+           }
+         } else {
+           data = (byte[]) val;
+         }
+         byte[] compressedData = compressBytes(r, data);
+         boolean isCompressed = compressedData != data;
+         ReferenceCountHelper.setReferenceCountOwner(this);
+         MemoryAllocator ma = SimpleMemoryAllocatorImpl.getAllocator(); // fix for bug 47875
 -        val = ma.allocateAndInitialize(compressedData, isSerialized, isCompressed, GemFireChunk.TYPE); // TODO:KIRK:48068 race happens right after this line
++        val = ma.allocateAndInitialize(compressedData, isSerialized, isCompressed); // TODO:KIRK:48068 race happens right after this line
+         ReferenceCountHelper.setReferenceCountOwner(null);
 -        if (val instanceof GemFireChunk) {
 -          val = new com.gemstone.gemfire.internal.offheap.ChunkWithHeapForm((GemFireChunk)val, data);
++        if (val instanceof ObjectChunk) {
++          val = new ObjectChunkWithHeapForm((ObjectChunk)val, data);
+         }
+ //        if (val instanceof Chunk && r instanceof LocalRegion) {
+ //          Chunk c = (Chunk) val;
+ //          LocalRegion lr = (LocalRegion) r;
+ //          SimpleMemoryAllocatorImpl.debugLog("allocated @" + Long.toHexString(c.getMemoryAddress()) + " reg=" + lr.getFullPath(), false);
+ //        }
+       }
+       return val;
+     }
+     @Unretained Object nv = val;
+     if (nv instanceof StoredObject) {
+       // This off heap value is being put into a on heap region.
+       byte[] data = ((StoredObject) nv).getSerializedValue();
+       nv = CachedDeserializableFactory.create(data);
+     }
+     // don't bother checking for SQLFire
+     if (!GemFireCacheImpl.sqlfSystem() && nv instanceof PdxInstanceImpl) {
+       // We do not want to put PDXs in the cache as values.
+       // So get the serialized bytes and use a CachedDeserializable.
+       try {
+         byte[] data = ((ConvertableToBytes)nv).toBytes();
+         byte[] compressedData = compressBytes(r, data);
+         if (data == compressedData) {
+           nv = CachedDeserializableFactory.create(data);
+         } else {
+           nv = compressedData;
+         }
+       } catch (IOException e) {
+         throw new PdxSerializationException("Could not convert " + nv + " to bytes", e);
+       }
+     } else {
+       nv = compress(r, nv, event);
+     }
+     return nv;
+   }
+   
+   @Override
+   @Unretained
+   public final Object _getValue() {
+     return getValueField();
+   }
+ 
+   public final boolean isUpdateInProgress() {
+     return areAnyBitsSet(UPDATE_IN_PROGRESS);
+   }
+ 
+   public final void setUpdateInProgress(final boolean underUpdate) {
+     if (underUpdate) {
+       setBits(UPDATE_IN_PROGRESS);
+     } else {
+       clearBits(~UPDATE_IN_PROGRESS);
+     }
+   }
+ 
+ 
+   public final boolean isCacheListenerInvocationInProgress() {
+     return areAnyBitsSet(LISTENER_INVOCATION_IN_PROGRESS);
+   }
+ 
+   public final void setCacheListenerInvocationInProgress(final boolean listenerInvoked) {
+     if (listenerInvoked) {
+       setBits(LISTENER_INVOCATION_IN_PROGRESS);
+     } else {
+       clearBits(~LISTENER_INVOCATION_IN_PROGRESS);
+     }
+   }
+ 
+   @Override
+   public final boolean isInUseByTransaction() {
+     return areAnyBitsSet(IN_USE_BY_TX);
+   }
+ 
+   @Override
+   public final void setInUseByTransaction(final boolean v) {
+     if (v) {
+       setBits(IN_USE_BY_TX);
+     } else {
+       clearBits(~IN_USE_BY_TX);
+     }
+   }
+   
+   @Override
+   public final synchronized void incRefCount() {
+     TXManagerImpl.incRefCount(this);
+     setInUseByTransaction(true);
+   }
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public final boolean isMarkedForEviction() {
+     return areAnyBitsSet(MARKED_FOR_EVICTION);
+   }
+ 
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public final void setMarkedForEviction() {
+     setBits(MARKED_FOR_EVICTION);
+   }
+ 
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public final void clearMarkedForEviction() {
+     clearBits(~MARKED_FOR_EVICTION);
+   }
+   
+   @Override
+   public final synchronized void decRefCount(NewLRUClockHand lruList, LocalRegion lr) {
+     if (TXManagerImpl.decRefCount(this)) {
+       if (isInUseByTransaction()) {
+         setInUseByTransaction(false);
+         if (lruList != null) {
+           // No more transactions, place in lru list
+           lruList.appendEntry((LRUClockNode)this);
+         }
+         if (lr != null && lr.isEntryExpiryPossible()) {
+           lr.addExpiryTaskIfAbsent(this);
+         }
+       }
+     }
+   }
+ 
+   @Override
+   public final synchronized void resetRefCount(NewLRUClockHand lruList) {
+     if (isInUseByTransaction()) {
+       setInUseByTransaction(false);
+       if (lruList != null) {
+         lruList.appendEntry((LRUClockNode)this);
+       }
+     }
+   }
+   /**
+    * soubhik: this method is overridden in sqlf flavor of entries.
+    * Instead of overriding this method; override areSetValue.
+    */
+   protected final void _setValue(Object val) {
+     setValueField(val);
+   }
+   
+   @Override
+   public Token getValueAsToken() {
+     Object v = getValueField();
+     if (v == null || v instanceof Token) {
+       return (Token)v;
+     } else {
+       return Token.NOT_A_TOKEN;
+     }
+   }
+   
+   /**
+    * Reads the value of this region entry.
+    * Provides low level access to the value field.
+    * @return possible OFF_HEAP_OBJECT (caller uses region entry reference)
+    */
+   @Unretained
+   protected abstract Object getValueField();
+   /**
+    * Set the value of this region entry.
+    * Provides low level access to the value field.
+    * @param v the new value to set
+    */
+   protected abstract void setValueField(@Unretained Object v);
+ 
+   @Retained
+   public Object getTransformedValue() {
+     return _getValueRetain(null, false);
+   }
+   
+   public final boolean getValueWasResultOfSearch() {
+     return areAnyBitsSet(VALUE_RESULT_OF_SEARCH);
+   }
+ 
+   public final void setValueResultOfSearch(boolean v) {
+     if (v) {
+       setBits(VALUE_RESULT_OF_SEARCH);
+     } else {
+       clearBits(~VALUE_RESULT_OF_SEARCH);
+     }
+   }
+   
+   public boolean hasValidVersion() {
+     VersionStamp stamp = (VersionStamp)this;
+     boolean has = stamp.getRegionVersion() != 0 || stamp.getEntryVersion() != 0;
+     return has;
+   }
+ 
+   public boolean hasStats() {
+     // override this in implementations that have stats
+     return false;
+   }
+ 
+   /**
+    * @see HashEntry#getMapValue()
+    */
+   public final Object getMapValue() {
+     return this;
+   }
+ 
+   /**
+    * @see HashEntry#setMapValue(Object)
+    */
+   public final void setMapValue(final Object newValue) {
+     if (this != newValue) {
+       Assert.fail("AbstractRegionEntry#setMapValue: unexpected setMapValue "
+           + "with newValue=" + newValue + ", this=" + this);
+     }
+   }
+ 
+   protected abstract void setEntryHash(int v);
+ 
+   @Override
+   public final String toString() {
+     final StringBuilder sb = new StringBuilder(this.getClass().getSimpleName())
+         .append('@').append(Integer.toHexString(System.identityHashCode(this)))
+         .append(" (");
+     return appendFieldsToString(sb).append(')').toString();
+   }
+ 
+   protected StringBuilder appendFieldsToString(final StringBuilder sb) {
+     sb.append("key=").append(getKey()).append("; rawValue=")
+         .append(_getValue()); // OFFHEAP _getValue ok: the current toString on OffHeapCachedDeserializable is safe to use without incing refcount.
+     VersionStamp stamp = getVersionStamp();
+     if (stamp != null) {
+       sb.append("; version=").append(stamp.asVersionTag()+";member="+stamp.getMemberID());
+   }
+     return sb;
+   }
+   
+   /*
+    * (non-Javadoc)
+    * This generates version tags for outgoing messages for all subclasses
+    * supporting concurrency versioning.  It also sets the entry's version
+    * stamp to the tag's values.
+    * 
+    * @see com.gemstone.gemfire.internal.cache.RegionEntry#generateVersionTag(com.gemstone.gemfire.distributed.DistributedMember, boolean)
+    */
+   public VersionTag generateVersionTag(VersionSource mbr, boolean withDelta, LocalRegion region, EntryEventImpl event) {
+     VersionStamp stamp = this.getVersionStamp();
+     if (stamp != null && region.getServerProxy() == null) { // clients do not generate versions
+       int v = stamp.getEntryVersion()+1;
+       if (v > 0xFFFFFF) {
+         v -= 0x1000000; // roll-over
+       }
+       VersionSource previous = stamp.getMemberID();
+       
+       
+       //For non persistent regions, we allow the member to be null and
+       //when we send a message and the remote side can determine the member
+       //from the sender. For persistent regions, we need to send
+       //the persistent id to the remote side.
+       //
+       //TODO - RVV - optimize the way we send the persistent id to save
+       //space. 
+       if(mbr == null) {
+         VersionSource regionMember = region.getVersionMember();
+         if(regionMember instanceof DiskStoreID) {
+           mbr = regionMember;
+         }
+       }
+       
+       VersionTag tag = VersionTag.create(mbr);
+       tag.setEntryVersion(v);
+       if (region.getVersionVector() != null) {
+         // Use region version if already provided, else generate
+         long nextRegionVersion = event.getNextRegionVersion();
+         if (nextRegionVersion != -1) {
+           // Set on the tag and record it locally
+           tag.setRegionVersion(nextRegionVersion);
+           RegionVersionVector rvv = region.getVersionVector();
+           rvv.recordVersion(rvv.getOwnerId(),nextRegionVersion);
+           if (logger.isDebugEnabled()) {
+             logger.debug("recorded region version {}; region={}", nextRegionVersion, region.getFullPath());
+           }
+         } else {
+           tag.setRegionVersion(region.getVersionVector().getNextVersion());  
+         }
+       }
+       if (withDelta) {
+         tag.setPreviousMemberID(previous);
+       }
+       VersionTag remoteTag = event.getVersionTag();
+       if (remoteTag != null && remoteTag.isGatewayTag()) {
+         // if this event was received from a gateway we use the remote system's
+         // timestamp and dsid.
+         tag.setVersionTimeStamp(remoteTag.getVersionTimeStamp());
+         tag.setDistributedSystemId(remoteTag.getDistributedSystemId());
+         tag.setAllowedByResolver(remoteTag.isAllowedByResolver());
+       } else {
+         long time = region.cacheTimeMillis();
+         int dsid = region.getDistributionManager().getDistributedSystemId();
+         // a locally generated change should always have a later timestamp than
+         // one received from a wan gateway, so fake a timestamp if necessary
+         if (time <= stamp.getVersionTimeStamp() && dsid != tag.getDistributedSystemId()) {
+           time = stamp.getVersionTimeStamp() + 1;
+         }
+         tag.setVersionTimeStamp(time);
+         tag.setDistributedSystemId(dsid);
+       }
+       stamp.setVersions(tag);
+       stamp.setMemberID(mbr);
+       event.setVersionTag(tag);
+       if (logger.isDebugEnabled()) {
+         logger.debug("generated tag {}; key={}; oldvalue={} newvalue={} client={} region={}; rvv={}", tag,
+             event.getKey(), event.getOldValueStringForm(), event.getNewValueStringForm(),
+             (event.getContext() == null? "none" : event.getContext().getDistributedMember().getName()),
+             region.getFullPath(), region.getVersionVector());
+       }
+       return tag;
+     }
+     return null;
+   }
+   
+   /** set/unset the flag noting that a tombstone has been scheduled for this entry */
+   public void setTombstoneScheduled(boolean scheduled) {
+     if (scheduled) {
+       setBits(TOMBSTONE_SCHEDULED);
+     } else {
+       clearBits(~TOMBSTONE_SCHEDULED);
+     }
+   }
+   
+   /**
+    * return the flag noting whether a tombstone has been scheduled for this entry.  This should
+    * be called under synchronization on the region entry if you want an accurate result.
+    */
+   public boolean isTombstoneScheduled() {
+     return areAnyBitsSet(TOMBSTONE_SCHEDULED);
+   }
+ 
+   /*
+    * (non-Javadoc)
+    * This performs a concurrency check.
+    * 
+    * This check compares the version number first, followed by the member ID.
+    * 
+    * Wraparound of the version number is detected and handled by extending the
+    * range of versions by one bit.
+    * 
+    * The normal membership ID comparison method is used.<p>
+    * 
+    * Note that a tag from a remote (WAN) system may be in the event.  If this
+    * is the case this method will either invoke a user plugin that allows/disallows
+    * the event (and may modify the value) or it determines whether to allow
+    * or disallow the event based on timestamps and distributedSystemIDs.
+    * 
+    * @throws ConcurrentCacheModificationException if the event conflicts with
+    * an event that has already been applied to the entry.
+    * 
+    * @see com.gemstone.gemfire.internal.cache.RegionEntry#concurrencyCheck(com.gemstone.gemfire.cache.EntryEvent)
+    */
+   public void processVersionTag(EntryEvent cacheEvent) {
+     processVersionTag(cacheEvent, true);
+   }
+   
+   
+   protected void processVersionTag(EntryEvent cacheEvent, boolean conflictCheck) {
+     EntryEventImpl event = (EntryEventImpl)cacheEvent;
+     VersionTag tag = event.getVersionTag();
+     if (tag == null) {
+       return;
+     }
+     
+     try {
+       if (tag.isGatewayTag()) {
+         // this may throw ConcurrentCacheModificationException or modify the event
+         if (processGatewayTag(cacheEvent)) { 
+           return;
+         }
+         assert false : "processGatewayTag failure - returned false";
+       }
+   
+       if (!tag.isFromOtherMember()) {
+         if (!event.getOperation().isNetSearch()) {
+           // except for netsearch, all locally-generated tags can be ignored
+           return;
+         }
+       }
+   
+       final InternalDistributedMember originator = (InternalDistributedMember)event.getDistributedMember();
+       final VersionSource dmId = event.getRegion().getVersionMember();
+       LocalRegion r = event.getLocalRegion();
+       boolean eventHasDelta = event.getDeltaBytes() != null && event.getRawNewValue() == null;
+ 
+       VersionStamp stamp = getVersionStamp();
+       // bug #46223, an event received from a peer or a server may be from a different
+       // distributed system than the last modification made to this entry so we must
+       // perform a gateway conflict check
+       if (stamp != null && !tag.isAllowedByResolver()) {
+         int stampDsId = stamp.getDistributedSystemId();
+         int tagDsId = tag.getDistributedSystemId();
+         
+         if (stampDsId != 0  &&  stampDsId != tagDsId  &&  stampDsId != -1) {
+           StringBuilder verbose = null;
+           if (logger.isTraceEnabled(LogMarker.TOMBSTONE)) {
+             verbose = new StringBuilder();
+             verbose.append("processing tag for key " + getKey() + ", stamp=" + stamp.asVersionTag() + ", tag=").append(tag);
+           }
+           long stampTime = stamp.getVersionTimeStamp();
+           long tagTime = tag.getVersionTimeStamp();
+           if (stampTime > 0 && (tagTime > stampTime
+               || (tagTime == stampTime  &&  tag.getDistributedSystemId() >= stamp.getDistributedSystemId()))) {
+             if (verbose != null) {
+               verbose.append(" - allowing event");
+               logger.trace(LogMarker.TOMBSTONE, verbose);
+             }
+             // Update the stamp with event's version information.
+             applyVersionTag(r, stamp, tag, originator);
+             return;
+           }
+   
+           if (stampTime > 0) {
+             if (verbose != null) {
+               verbose.append(" - disallowing event");
+               logger.trace(LogMarker.TOMBSTONE, verbose);
+             }
+             r.getCachePerfStats().incConflatedEventsCount();
+             persistConflictingTag(r, tag);
+             throw new ConcurrentCacheModificationException("conflicting event detected");
+           }
+         }
+       }
+ 
+       if (r.getVersionVector() != null &&
+           r.getServerProxy() == null &&
+           (r.getDataPolicy().withPersistence() ||
+               !r.getScope().isLocal())) { // bug #45258 - perf degradation for local regions and RVV
+         VersionSource who = tag.getMemberID();
+         if (who == null) {
+           who = originator;
+         }
+         r.getVersionVector().recordVersion(who, tag);
+       }
+   
+       assert !tag.isFromOtherMember() || tag.getMemberID() != null : "remote tag is missing memberID";
+   
+       
+       // [bruce] for a long time I had conflict checks turned off in clients when
+       // receiving a response from a server and applying it to the cache.  This lowered
+       // the CPU cost of versioning but eventually had to be pulled for bug #45453
+ //      if (r.getServerProxy() != null && conflictCheck) {
+ //        // events coming from servers while a local sync is held on the entry
+ //        // do not require a conflict check.  Conflict checks were already
+ //        // performed on the server and here we just consume whatever was sent back.
+ //        // Event.isFromServer() returns true for client-update messages and
+ //        // for putAll/getAll, which do not hold syncs during the server operation.
+ //        conflictCheck = event.isFromServer();
+ //      }
+ //      else
+       
+       // [bruce] for a very long time we had conflict checks turned off for PR buckets.
+       // Bug 45669 showed a primary dying in the middle of distribution.  This caused
+       // one backup bucket to have a v2.  The other bucket was promoted to primary and
+       // generated a conflicting v2.  We need to do the check so that if this second
+       // v2 loses to the original one in the delta-GII operation that the original v2
+       // will be the winner in both buckets.
+ //      if (r.isUsedForPartitionedRegionBucket()) {
+ //        conflictCheck = false; // primary/secondary model 
+ //      }
+   
+       // The new value in event is not from GII, even it could be tombstone
+       basicProcessVersionTag(r, tag, false, eventHasDelta, dmId, originator, conflictCheck);
+     } catch (ConcurrentCacheModificationException ex) {
+       event.isConcurrencyConflict(true);
+       throw ex;
+     }
+   }
+   
+   protected final void basicProcessVersionTag(LocalRegion region, VersionTag tag, boolean isTombstoneFromGII,
+       boolean deltaCheck, VersionSource dmId, InternalDistributedMember sender, boolean checkForConflict) {
+     
+     StringBuilder verbose = null;
+     
+     if (tag != null) {
+       VersionStamp stamp = getVersionStamp();
+ 
+       if (logger.isTraceEnabled(LogMarker.TOMBSTONE)) {
+         VersionTag stampTag = stamp.asVersionTag();
+         if (stampTag.hasValidVersion() && checkForConflict) { // only be verbose here if there's a possibility we might reject the operation
+           verbose = new StringBuilder();
+           verbose.append("processing tag for key " + getKey() + ", stamp=" + stamp.asVersionTag() + ", tag=").append(tag)
+                  .append(", checkForConflict=").append(checkForConflict); //.append(", current value=").append(_getValue());
+         }
+       }
+       
+       if (stamp == null) {
+         throw new IllegalStateException("message contained a version tag but this region has no version storage");
+       }
+       
+       boolean apply = true;
+ 
+       try {
+         if (checkForConflict) {
+           apply = checkForConflict(region, stamp, tag, isTombstoneFromGII, deltaCheck, dmId, sender, verbose);
+         }
+       } catch (ConcurrentCacheModificationException e) {
+         // Even if we don't apply the operation we should always retain the
+         // highest timestamp in order for WAN conflict checks to work correctly
+         // because the operation may have been sent to other systems and been
+         // applied there
+         if (!tag.isGatewayTag()
+             && stamp.getDistributedSystemId() == tag.getDistributedSystemId()
+             && tag.getVersionTimeStamp() > stamp.getVersionTimeStamp()) {
+           stamp.setVersionTimeStamp(tag.getVersionTimeStamp());
+           tag.setTimeStampApplied(true);
+           if (verbose != null) {
+             verbose.append("\nThough in conflict the tag timestamp was more recent and was recorded.");
+           }
+         }
+         throw e; 
+       } finally {
+         if (verbose != null) {
+           logger.trace(LogMarker.TOMBSTONE, verbose);
+         }
+       }
+       
+       if (apply) {
+         applyVersionTag(region, stamp, tag, sender);
+       }
+     }
+   }
+   
+ 
+   private void applyVersionTag(LocalRegion region, VersionStamp stamp, VersionTag tag, InternalDistributedMember sender) {
+     // stamp.setPreviousMemberID(stamp.getMemberID());
+     VersionSource mbr = tag.getMemberID();
+     if (mbr == null) {
+       mbr = sender;
+     }
+     mbr = region.getVersionVector().getCanonicalId(mbr);
+     tag.setMemberID(mbr);
+     stamp.setVersions(tag);
+     if (tag.hasPreviousMemberID()) {
+       if (tag.getPreviousMemberID() == null) {
+         tag.setPreviousMemberID(stamp.getMemberID());
+       } else {
+         tag.setPreviousMemberID(region.getVersionVector().getCanonicalId(
+             tag.getPreviousMemberID()));
+       }
+     }
+   }
+ 
+   /** perform conflict checking for a stamp/tag */
+   protected boolean checkForConflict(LocalRegion region,
+       VersionStamp stamp, VersionTag tag,
+       boolean isTombstoneFromGII,
+       boolean deltaCheck, VersionSource dmId,
+       InternalDistributedMember sender, StringBuilder verbose) {
+ 
+     int stampVersion = stamp.getEntryVersion();
+     int tagVersion = tag.getEntryVersion();
+     
+     boolean throwex = false;
+     boolean apply = false;
+     
+     if (stamp.getVersionTimeStamp() != 0) { // new entries have no timestamp
+       // check for wrap-around on the version number  
+       long difference = tagVersion - stampVersion;
+       if (0x10000 < difference || difference < -0x10000) {
+         if (verbose != null) {
+           verbose.append("\nversion rollover detected: tag="+tagVersion + " stamp=" + stampVersion);
+         }
+         if (difference < 0) {
+           tagVersion += 0x1000000L;
+         } else {
+           stampVersion += 0x1000000L;
+         }
+       }
+     }
+     if (verbose != null) {
+       verbose.append("\nstamp=v").append(stampVersion)
+              .append(" tag=v").append(tagVersion);
+     }
+ 
+     if (deltaCheck) {
+       checkForDeltaConflict(region, stampVersion, tagVersion, stamp, tag, dmId, sender, verbose);
+     }
+     
+     if (stampVersion == 0  ||  stampVersion < tagVersion) {
+       if (verbose != null) { verbose.append(" - applying change"); }
+       apply = true;
+     } else if (stampVersion > tagVersion) {
+       if (overwritingOldTombstone(region, stamp, tag, verbose)  && tag.getVersionTimeStamp() > stamp.getVersionTimeStamp()) {
+         apply = true;
+       } else {
+         // check for an incoming expired tombstone from an initial image chunk.
+         if (tagVersion > 0
+             && isExpiredTombstone(region, tag.getVersionTimeStamp(), isTombstoneFromGII)
+             && tag.getVersionTimeStamp() > stamp.getVersionTimeStamp()) {
+           // A special case to apply: when remote entry is expired tombstone, then let local vs remote with newer timestamp to win
+           if (verbose != null) { verbose.append(" - applying change in Delta GII"); }
+           apply = true;
+         } else {
+           if (verbose != null) { verbose.append(" - disallowing"); }
+           throwex= true;
+         }
+       }
+     } else {
+       if (overwritingOldTombstone(region, stamp, tag, verbose)) {
+         apply = true;
+       } else {
+         // compare member IDs
+         VersionSource stampID = stamp.getMemberID();
+         if (stampID == null) {
+           stampID = dmId;
+         }
+         VersionSource tagID = tag.getMemberID();
+         if (tagID == null) {
+           tagID = sender;
+         }
+         if (verbose != null) { verbose.append("\ncomparing IDs"); }
+         int compare = stampID.compareTo(tagID);
+         if (compare < 0) {
+           if (verbose != null) { verbose.append(" - applying change"); }
+           apply = true;
+         } else if (compare > 0) {
+           if (verbose != null) { verbose.append(" - disallowing"); }
+           throwex = true;
+         } else if (tag.isPosDup()) {
+           if (verbose != null) { verbose.append(" - disallowing duplicate marked with posdup"); }
+           throwex = true;
+         } else /* if (isTombstoneFromGII && isTombstone()) {
+           if (verbose != null) { verbose.append(" - disallowing duplicate tombstone from GII"); }
+           return false;  // bug #49601 don't schedule tombstones from GII if there's already one here
+         } else */ {
+           if (verbose != null) { verbose.append(" - allowing duplicate"); }
+         }
+       }
+     }
+ 
+     if (!apply && throwex) {
+       region.getCachePerfStats().incConflatedEventsCount();
+       persistConflictingTag(region, tag);
+       throw new ConcurrentCacheModificationException();
+     }
+ 
+     return apply;
+   }
+ 
+   private boolean isExpiredTombstone(LocalRegion region, long timestamp, boolean isTombstone) {
+     return isTombstone && (timestamp + TombstoneService.REPLICATED_TOMBSTONE_TIMEOUT) <= region.cacheTimeMillis();
+   }
+   
+   private boolean overwritingOldTombstone(LocalRegion region, VersionStamp stamp, VersionTag tag, StringBuilder verbose) {
+     // Tombstone GC does not use locking to stop operations when old tombstones
+     // are being removed.  Because of this we might get an operation that was applied
+     // in another VM that has just reaped a tombstone and is now using a reset
+     // entry version number.  Because of this we check the timestamp on the current
+     // local entry and see if it is old enough to have expired.  If this is the case
+     // we accept the change and allow the tag to be recorded
+     long stampTime = stamp.getVersionTimeStamp();
+     if (isExpiredTombstone(region, stampTime, this.isTombstone())) {
+       // no local change since the tombstone would have timed out - accept the change
+       if (verbose != null) { verbose.append(" - accepting because local timestamp is old"); }
+       return true;
+     } else {
+       return false;
+     }
+   }
+ 
+   protected void persistConflictingTag(LocalRegion region, VersionTag tag) {
+     // only persist region needs to persist conflict tag 
+   }
+   
+   /**
+    * for an event containing a delta we must check to see if the tag's
+    * previous member id is the stamp's member id and ensure that the
+    * version is only incremented by 1.  Otherwise the delta is being
+    * applied to a value that does not match the source of the delta.
+    * 
+    * @throws InvalidDeltaException
+    */
+   private void checkForDeltaConflict(LocalRegion region,
+       long stampVersion, long tagVersion,
+       VersionStamp stamp, VersionTag tag,
+       VersionSource dmId, InternalDistributedMember sender,
+       StringBuilder verbose) {
+ 
+     if (tagVersion != stampVersion+1) {
+       if (verbose != null) {
+         verbose.append("\ndelta requires full value due to version mismatch");
+       }
+       region.getCachePerfStats().incDeltaFailedUpdates();
+       throw new InvalidDeltaException("delta cannot be applied due to version mismatch");
+ 
+     } else {
+       // make sure the tag was based on the value in this entry by checking the
+       // tag's previous-changer ID against this stamp's current ID
+       VersionSource stampID = stamp.getMemberID();
+       if (stampID == null) {
+         stampID = dmId;
+       }
+       VersionSource tagID = tag.getPreviousMemberID();
+       if (tagID == null) {
+         tagID = sender;
+       }
+       if (!tagID.equals(stampID)) {
+         if (verbose != null) {
+           verbose.append("\ndelta requires full value.  tag.previous=")
+           .append(tagID).append(" but stamp.current=").append(stampID);
+         }
+         region.getCachePerfStats().incDeltaFailedUpdates();
+         throw new InvalidDeltaException("delta cannot be applied due to version ID mismatch");
+       }
+     }
+   }
+   
+   private boolean processGatewayTag(EntryEvent cacheEvent) {
+     // Gateway tags are installed in the server-side LocalRegion cache
+     // modification methods.  They do not have version numbers or distributed
+     // member IDs.  Instead they only have timestamps and distributed system IDs.
+ 
+     // If there is a resolver plug-in, invoke it.  Otherwise we use the timestamps and
+     // distributed system IDs to determine whether to allow the event to proceed.
+     
+     final boolean isDebugEnabled = logger.isDebugEnabled();
+     
+     if (this.isRemoved() && !this.isTombstone()) {
+       return true; // no conflict on a new entry
+     }
+     EntryEventImpl event = (EntryEventImpl)cacheEvent;
+     VersionTag tag = event.getVersionTag();
+     long stampTime = getVersionStamp().getVersionTimeStamp();
+     long tagTime = tag.getVersionTimeStamp();
+     int stampDsid = getVersionStamp().getDistributedSystemId();
+     int tagDsid = tag.getDistributedSystemId();
+     if (isDebugEnabled) {
+       logger.debug("processing gateway version information for {}.  Stamp dsid={} time={} Tag dsid={} time={}",
+         event.getKey(), stampDsid, stampTime, tagDsid, tagTime);
+     }
+     if (tagTime == VersionTag.ILLEGAL_VERSION_TIMESTAMP) {
+       return true; // no timestamp received from other system - just apply it
+     }
+     if (tagDsid == stampDsid || stampDsid == -1) {
+       return true;
+     }
+     GatewayConflictResolver resolver = event.getRegion().getCache().getGatewayConflictResolver();
+     if (resolver != null) {
+       if (isDebugEnabled) {
+         logger.debug("invoking gateway conflict resolver");
+       }
+       final boolean[] disallow = new boolean[1];
+       final Object[] newValue = new Object[] { this };
+       GatewayConflictHelper helper = new GatewayConflictHelper() {
+         @Override
+         public void disallowEvent() {
+           disallow[0] = true;
+         }
+ 
+         @Override
+         public void changeEventValue(Object v) {
+           newValue[0] = v;
+         }
+       };
+       TimestampedEntryEventImpl timestampedEvent =
+         (TimestampedEntryEventImpl)event.getTimestampedEvent(tagDsid, stampDsid, tagTime, stampTime);
+ 
+       // gateway conflict resolvers will usually want to see the old value
+       if (!time

<TRUNCATED>


[053/100] [abbrv] incubator-geode git commit: GEODE-929: Do not use AvailablePort.getRandomAvailablePort in this test to avoid intermittent PortNotAvailable error.

Posted by ud...@apache.org.
GEODE-929: Do not use AvailablePort.getRandomAvailablePort in this test to avoid intermittent PortNotAvailable error.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/53b6319e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/53b6319e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/53b6319e

Branch: refs/heads/feature/GEODE-870
Commit: 53b6319e4b2c0c08d7c592b797f728f2a3ba0f50
Parents: 53510e5
Author: Jinmei Liao <ji...@pivotal.io>
Authored: Fri Feb 19 08:48:42 2016 -0800
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Fri Feb 19 13:13:52 2016 -0800

----------------------------------------------------------------------
 .../security/ClientMultiUserAuthzDUnitTest.java | 288 +++++++++----------
 .../gemfire/security/SecurityTestUtil.java      |   2 +-
 2 files changed, 144 insertions(+), 146 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/53b6319e/gemfire-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
index 74260ed..dc03990 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
@@ -24,6 +24,7 @@ package com.gemstone.gemfire.security;
 import java.util.Iterator;
 import java.util.Properties;
 
+import com.gemstone.gemfire.test.dunit.VM;
 import security.AuthzCredentialGenerator;
 import security.CredentialGenerator;
 
@@ -81,37 +82,37 @@ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
       // Start servers with all required properties
       Properties serverProps = buildProperties(authenticator, accessor, false,
           extraAuthProps, extraAuthzProps);
-      Integer port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-      Integer port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-      createCacheServers(javaProps, serverProps, port1, port2);
+
+      Integer port1 = createCacheServerOnVM(server1, javaProps, serverProps);
+      Integer port2 = createCacheServerOnVM(server2, javaProps, serverProps);
 
       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
-          OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
-          OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
+              OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
+              OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
           port2)) {
         continue;
       }
       verifyPutsGets();
 
       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
-          OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
-          OperationCode.DESTROY, OperationCode.DESTROY},
+              OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
+              OperationCode.DESTROY, OperationCode.DESTROY},
           javaProps, authInit, port1, port2)) {
         continue;
       }
       verifyContainsKeyDestroys();
 
       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
-          OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
-          OperationCode.INVALIDATE, OperationCode.INVALIDATE},
+              OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
+              OperationCode.INVALIDATE, OperationCode.INVALIDATE},
           javaProps, authInit, port1, port2)) {
         continue;
       }
       verifyContainsKeyInvalidates();
 
       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
-          OperationCode.GET, OperationCode.GET}, new OperationCode[] {
-          OperationCode.REGION_DESTROY, OperationCode.REGION_DESTROY},
+              OperationCode.GET, OperationCode.GET}, new OperationCode[] {
+              OperationCode.REGION_DESTROY, OperationCode.REGION_DESTROY},
           javaProps, authInit, port1, port2)) {
         continue;
       }
@@ -219,11 +220,11 @@ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
 
     // Verify that the gets succeed/fail
     if (isMultiuser) {
-    client2.invoke(SecurityTestUtil.class, "doMultiUserGets", new Object[] {
-        Integer.valueOf(2),
-        Integer.valueOf(2),
-        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+      client2.invoke(SecurityTestUtil.class, "doMultiUserGets", new Object[] {
+          Integer.valueOf(2),
+          Integer.valueOf(2),
+          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+              SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
     } else {
       int expectedResult = (opAllowed) ? SecurityTestUtil.NO_EXCEPTION
           : SecurityTestUtil.NOTAUTHZ_EXCEPTION;
@@ -310,17 +311,17 @@ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
   private void verifyGetAllInTX() {
     server1.invoke(() -> ClientMultiUserAuthzDUnitTest.doPuts());
     client1.invoke(SecurityTestUtil.class, "doMultiUserGetAll", new Object[] {
-      Integer.valueOf(2),
-      new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-          SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Boolean.TRUE/*use TX*/});
+        Integer.valueOf(2),
+        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+            SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Boolean.TRUE/*use TX*/});
   }
 
   private void verifyGetAllRegionDestroys() {
     server1.invoke(() -> ClientMultiUserAuthzDUnitTest.doPuts());
     client1.invoke(SecurityTestUtil.class, "doMultiUserGetAll", new Object[] {
-      Integer.valueOf(2),
-      new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-          SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+        Integer.valueOf(2),
+        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
 
     // Verify that the region destroys succeed/fail
     client2.invoke(SecurityTestUtil.class, "doMultiUserRegionDestroys",
@@ -329,7 +330,7 @@ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
             new Integer[] {SecurityTestUtil.NO_EXCEPTION,
                 SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
   }
-  
+
   public static void doPuts() {
     Region region = GemFireCacheImpl.getInstance().getRegion(SecurityTestUtil.regionName);
     region.put("key1", "value1");
@@ -338,134 +339,132 @@ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
 
   // Test query/function execute
   public void testOps2() throws Exception {
-      AuthzCredentialGenerator gen = getXmlAuthzGenerator();
-      CredentialGenerator cGen = gen.getCredentialGenerator();
-      Properties extraAuthProps = cGen.getSystemProperties();
-      Properties javaProps = cGen.getJavaProperties();
-      Properties extraAuthzProps = gen.getSystemProperties();
-      String authenticator = cGen.getAuthenticator();
-      String authInit = cGen.getAuthInit();
-      String accessor = gen.getAuthorizationCallback();
+    AuthzCredentialGenerator gen = getXmlAuthzGenerator();
+    CredentialGenerator cGen = gen.getCredentialGenerator();
+    Properties extraAuthProps = cGen.getSystemProperties();
+    Properties javaProps = cGen.getJavaProperties();
+    Properties extraAuthzProps = gen.getSystemProperties();
+    String authenticator = cGen.getAuthenticator();
+    String authInit = cGen.getAuthInit();
+    String accessor = gen.getAuthorizationCallback();
+
+    LogWriterUtils.getLogWriter().info("testOps2: Using authinit: " + authInit);
+    LogWriterUtils.getLogWriter().info("testOps2: Using authenticator: " + authenticator);
+    LogWriterUtils.getLogWriter().info("testOps2: Using accessor: " + accessor);
+
+    // Start servers with all required properties
+    Properties serverProps = buildProperties(authenticator, accessor, false,
+        extraAuthProps, extraAuthzProps);
+    Integer port1 = createCacheServerOnVM(server1, javaProps, serverProps);
+    Integer port2 = createCacheServerOnVM(server2, javaProps, serverProps);
+
+    // Start client1 with valid/invalid QUERY credentials
+    Properties[] client1Credentials = new Properties[] {
+        gen.getAllowedCredentials(
+            new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
+            new String[] {regionName},
+            1),
+        gen.getDisallowedCredentials(
+            new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
+            new String[] {regionName},
+            1)
+    };
 
-      LogWriterUtils.getLogWriter().info("testOps2: Using authinit: " + authInit);
-      LogWriterUtils.getLogWriter().info("testOps2: Using authenticator: " + authenticator);
-      LogWriterUtils.getLogWriter().info("testOps2: Using accessor: " + accessor);
+    javaProps = cGen.getJavaProperties();
+    LogWriterUtils.getLogWriter().info(
+        "testOps2: For first client credentials: " + client1Credentials[0]
+            + "\n" + client1Credentials[1]);
+    client1.invoke(SecurityTestUtil.class,
+        "createCacheClientForMultiUserMode", new Object[] {
+            Integer.valueOf(2), authInit, client1Credentials, javaProps,
+            new Integer[] {port1, port2}, null, Boolean.FALSE,
+            SecurityTestUtil.NO_EXCEPTION});
 
-      // Start servers with all required properties
-      Properties serverProps = buildProperties(authenticator, accessor, false,
-          extraAuthProps, extraAuthzProps);
-      Integer port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-      Integer port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-      createCacheServers(javaProps, serverProps, port1, port2);
-
-      // Start client1 with valid/invalid QUERY credentials
-      Properties[] client1Credentials = new Properties[] {
-          gen.getAllowedCredentials(
-                  new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
-                  new String[] {regionName},
-                  1),
-          gen.getDisallowedCredentials(
-                  new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
-                  new String[] {regionName},
-                  1)
-      };
-
-      javaProps = cGen.getJavaProperties();
-      LogWriterUtils.getLogWriter().info(
-          "testOps2: For first client credentials: " + client1Credentials[0]
-              + "\n" + client1Credentials[1]);
-      client1.invoke(SecurityTestUtil.class,
-          "createCacheClientForMultiUserMode", new Object[] {
-              Integer.valueOf(2), authInit, client1Credentials, javaProps,
-              new Integer[] {port1, port2}, null, Boolean.FALSE,
-              SecurityTestUtil.NO_EXCEPTION});
+    // Start client2 with valid/invalid EXECUTE_FUNCTION credentials
+    Properties[] client2Credentials = new Properties[] {
+        gen.getAllowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
+            new String[] {regionName}, 2),
+        gen.getDisallowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
+            new String[] {regionName}, 9)};
 
-      // Start client2 with valid/invalid EXECUTE_FUNCTION credentials
-      Properties[] client2Credentials = new Properties[] {
-          gen.getAllowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
-              new String[] {regionName}, 2),
-          gen.getDisallowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
-              new String[] {regionName}, 9)};
+    javaProps = cGen.getJavaProperties();
+    LogWriterUtils.getLogWriter().info(
+        "testOps2: For second client credentials: " + client2Credentials[0]
+            + "\n" + client2Credentials[1]);
+    client2.invoke(SecurityTestUtil.class,
+        "createCacheClientForMultiUserMode", new Object[] {
+            Integer.valueOf(2), authInit, client2Credentials, javaProps,
+            new Integer[] {port1, port2}, null, Boolean.FALSE,
+            SecurityTestUtil.NO_EXCEPTION});
+    Function function = new TestFunction(true,TestFunction.TEST_FUNCTION1);
+    server1.invoke(PRClientServerTestBase.class,
+        "registerFunction", new Object []{function});
 
-      javaProps = cGen.getJavaProperties();
-      LogWriterUtils.getLogWriter().info(
-          "testOps2: For second client credentials: " + client2Credentials[0]
-              + "\n" + client2Credentials[1]);
-      client2.invoke(SecurityTestUtil.class,
-          "createCacheClientForMultiUserMode", new Object[] {
-              Integer.valueOf(2), authInit, client2Credentials, javaProps,
-              new Integer[] {port1, port2}, null, Boolean.FALSE,
-              SecurityTestUtil.NO_EXCEPTION});
-      Function function = new TestFunction(true,TestFunction.TEST_FUNCTION1);
-      server1.invoke(PRClientServerTestBase.class,
-          "registerFunction", new Object []{function});
-      
-      server2.invoke(PRClientServerTestBase.class,
-          "registerFunction", new Object []{function});
-      
-      // Perform some put operations before verifying queries
-      client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
-          Integer.valueOf(4),
-          Integer.valueOf(2),
-          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-              SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
-      client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
-          new Object[] {
-              Integer.valueOf(2),
-              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
-      client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
-          new Object[] {
-              Integer.valueOf(2),
-              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
+    server2.invoke(PRClientServerTestBase.class,
+        "registerFunction", new Object []{function});
 
-      // Verify that the FE succeeds/fails
-      client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
-          Integer.valueOf(2),
-          function,
-          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-              SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
-          Boolean.FALSE});
+    // Perform some put operations before verifying queries
+    client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
+        Integer.valueOf(4),
+        Integer.valueOf(2),
+        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+    client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
+        new Object[] {
+            Integer.valueOf(2),
+            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
+    client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
+        new Object[] {
+            Integer.valueOf(2),
+            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
 
-      // Failover
-      server1.invoke(() -> SecurityTestUtil.closeCache());
-      Thread.sleep(2000);
+    // Verify that the FE succeeds/fails
+    client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
+        Integer.valueOf(2),
+        function,
+        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+            SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
+        Boolean.FALSE});
 
-      client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
-          Integer.valueOf(4),
-          Integer.valueOf(2),
-          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-              SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+    // Failover
+    server1.invoke(() -> SecurityTestUtil.closeCache());
+    Thread.sleep(2000);
 
-      client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
-          new Object[] {
-              Integer.valueOf(2),
-              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
-      client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
-          new Object[] {
-              Integer.valueOf(2),
-              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
+    client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
+        Integer.valueOf(4),
+        Integer.valueOf(2),
+        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
 
-      // Verify that the FE succeeds/fails
-      client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
-          Integer.valueOf(2),
-          function,
-          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
-              SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
-          Boolean.TRUE});
+    client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
+        new Object[] {
+            Integer.valueOf(2),
+            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
+    client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
+        new Object[] {
+            Integer.valueOf(2),
+            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
+
+    // Verify that the FE succeeds/fails
+    client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
+        Integer.valueOf(2),
+        function,
+        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+            SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
+        Boolean.TRUE});
 
 
   }
 
-  protected void createCacheServers(Properties javaProps,
-      Properties serverProps, Integer port1, Integer port2) {
-    server1.invoke(() -> ClientAuthorizationTestBase.createCacheServer(SecurityTestUtil.getLocatorPort(), port1, serverProps,
-            javaProps));
-    server2.invoke(() -> ClientAuthorizationTestBase.createCacheServer(SecurityTestUtil.getLocatorPort(), port2, serverProps,
-            javaProps));
+
+  protected Integer createCacheServerOnVM(VM server, Properties javaProps, Properties serverProps) {
+    return (Integer)server.invoke(() -> ClientAuthorizationTestBase.createCacheServer(SecurityTestUtil.getLocatorPort(), serverProps,
+        javaProps));
+
   }
 
   public void testOpsWithClientsInDifferentModes() throws Exception {
@@ -488,21 +487,20 @@ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
       // Start servers with all required properties
       Properties serverProps = buildProperties(authenticator, accessor, false,
           extraAuthProps, extraAuthzProps);
-      Integer port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-      Integer port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-      createCacheServers(javaProps, serverProps, port1, port2);
+      Integer port1 = createCacheServerOnVM(server1, javaProps, serverProps);
+      Integer port2 = createCacheServerOnVM(server2, javaProps, serverProps);
 
       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
-          OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
-          OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
+              OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
+              OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
           port2, Boolean.FALSE, Boolean.TRUE)) {
         continue;
       }
       verifyPutsGets(false, true);
 
       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
-          OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
-          OperationCode.DESTROY, OperationCode.DESTROY},
+              OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
+              OperationCode.DESTROY, OperationCode.DESTROY},
           javaProps, authInit, port1, port2, Boolean.FALSE, Boolean.FALSE)) {
         continue;
       }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/53b6319e/gemfire-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java b/gemfire-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
index 6e24398..ad9b3e1 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
@@ -341,7 +341,7 @@ public class SecurityTestUtil extends DistributedTestCase {
     cache.createRegion(regionName, attrs);
     int port;
     if (serverPort == null || serverPort.intValue() <= 0) {
-      port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+      port = 0;
     }
     else {
       port = serverPort.intValue();


[096/100] [abbrv] incubator-geode git commit: GEODE-870: Amending code as per code review Adding wait on CqQueryUsingPoolDUnitTest to make test pass

Posted by ud...@apache.org.
GEODE-870: Amending code as per code review
Adding wait on CqQueryUsingPoolDUnitTest to make test pass


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/cafcf56a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/cafcf56a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/cafcf56a

Branch: refs/heads/feature/GEODE-870
Commit: cafcf56a7103d371c47c53d79e3de7188db47765
Parents: 2d125ff
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Mon Feb 15 10:05:41 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 07:26:42 2016 +1100

----------------------------------------------------------------------
 .../gms/membership/GMSJoinLeaveHelper.java      | 60 -----------------
 .../gms/membership/GMSJoinLeaveTestHelper.java  | 67 ++++++++++++++++++
 .../internal/membership/NetView.java            |  3 -
 .../membership/gms/membership/GMSJoinLeave.java | 25 ++++---
 .../gemfire/distributed/LocatorDUnitTest.java   | 30 ++++-----
 .../gms/membership/GMSJoinLeaveJUnitTest.java   | 71 ++++++++++----------
 .../sanctionedDataSerializables.txt             |  4 +-
 .../cq/dunit/CqQueryUsingPoolDUnitTest.java     |  4 +-
 8 files changed, 135 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java
deleted file mode 100644
index b8311bc..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java
+++ /dev/null
@@ -1,60 +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 com.gemstone.gemfire.distributed.internal.membership.gms.membership;
-
-import com.gemstone.gemfire.distributed.Locator;
-import com.gemstone.gemfire.distributed.internal.DM;
-import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
-import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
-import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
-
-public class GMSJoinLeaveHelper {
-  public static boolean isViewCreator() {
-    GMSJoinLeave gmsJoinLeave = getGmsJoinLeave();
-    if (gmsJoinLeave != null) {
-      GMSJoinLeave.ViewCreator viewCreator = gmsJoinLeave.getViewCreator();
-      if (viewCreator != null && !viewCreator.isShutdown()) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-    throw new RuntimeException("This should not have happened. There should be a JoinLeave for every DS");
-  }
-
-  private static GMSJoinLeave getGmsJoinLeave() {
-    InternalDistributedSystem distributedSystem = getInternalDistributedSystem();
-    DM dm = distributedSystem.getDM();
-    GMSMembershipManager membershipManager = (GMSMembershipManager) dm.getMembershipManager();
-    Services services = membershipManager.getServices();
-    return (GMSJoinLeave) services.getJoinLeave();
-  }
-
-  public static Integer getViewId() {
-    return getGmsJoinLeave().getView().getViewId();
-  }
-
-  private static InternalDistributedSystem getInternalDistributedSystem() {
-    InternalDistributedSystem distributedSystem = InternalDistributedSystem.getAnyInstance();
-    if (distributedSystem == null) {
-      Locator locator = Locator.getLocator();
-      return (InternalDistributedSystem) locator.getDistributedSystem();
-    } else {
-      return distributedSystem;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
new file mode 100644
index 0000000..493c625
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.distributed.internal.membership.gms.membership;
+
+import com.gemstone.gemfire.distributed.Locator;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
+import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
+
+public class GMSJoinLeaveTestHelper {
+
+  public static void becomeCoordinatorForTest(GMSJoinLeave gmsJoinLeave) {
+    synchronized (gmsJoinLeave.getViewInstallationLock()) {
+      gmsJoinLeave.becomeCoordinator();
+    }
+  }
+
+  public static boolean isViewCreator() {
+    GMSJoinLeave gmsJoinLeave = getGmsJoinLeave();
+    if (gmsJoinLeave != null) {
+      GMSJoinLeave.ViewCreator viewCreator = gmsJoinLeave.getViewCreator();
+      if (viewCreator != null && !viewCreator.isShutdown()) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    throw new RuntimeException("This should not have happened. There should be a JoinLeave for every DS");
+  }
+
+  private static GMSJoinLeave getGmsJoinLeave() {
+    InternalDistributedSystem distributedSystem = getInternalDistributedSystem();
+    DM dm = distributedSystem.getDM();
+    GMSMembershipManager membershipManager = (GMSMembershipManager) dm.getMembershipManager();
+    Services services = membershipManager.getServices();
+    return (GMSJoinLeave) services.getJoinLeave();
+  }
+
+  public static Integer getViewId() {
+    return getGmsJoinLeave().getView().getViewId();
+  }
+
+  private static InternalDistributedSystem getInternalDistributedSystem() {
+    InternalDistributedSystem distributedSystem = InternalDistributedSystem.getAnyInstance();
+    if (distributedSystem == null) {
+      Locator locator = Locator.getLocator();
+      return (InternalDistributedSystem) locator.getDistributedSystem();
+    } else {
+      return distributedSystem;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
index af05f82..af4aec3 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
@@ -48,9 +48,6 @@ import com.gemstone.gemfire.internal.Version;
  */
 public class NetView implements DataSerializableFixedID {
 
-  private static final Logger logger = LogService.getLogger();
-
-
   private int viewId;
   private List<InternalDistributedMember> members;
   private int[] failureDetectionPorts = new int[10];

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index 56b644c..8ba4952 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -152,6 +152,9 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   /** the view where quorum was most recently lost */
   NetView quorumLostView;
 
+  /** a flag to mark a coordinator's viewCreator for shutdown */
+  private boolean markViewCreatorForShutdown = false;
+
   static class SearchState {
     Set<InternalDistributedMember> alreadyTried = new HashSet<>();
     Set<InternalDistributedMember> registrants = new HashSet<>();
@@ -172,6 +175,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     }
   }
 
+  Object getViewInstallationLock() {
+    return viewInstallationLock;
+  }
+
   /**
    * attempt to join the distributed system
    * loop
@@ -581,12 +588,6 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     becomeCoordinator(null);
   }
 
-  public void becomeCoordinatorForTest() {
-    synchronized (viewInstallationLock) {
-      becomeCoordinator();
-    }
-  }
-
   /**
    * Test hook for delaying the creation of new views.
    * This should be invoked before this member becomes coordinator
@@ -640,6 +641,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         viewCreator.setInitialView(newView, newView.getNewMembers(), newView.getShutdownMembers(), newView.getCrashedMembers());
       }
       viewCreator.setDaemon(true);
+      logger.info("ViewCreator starting on:" + localAddress);
       viewCreator.start();
     }
   }
@@ -715,9 +717,9 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     } else {
       //Added a check in the view processor to turn off the ViewCreator
       //if another server is the coordinator - GEODE-870
-      if(!localAddress.equals(view.getCoordinator()) && getViewCreator() != null)
-      {
-        stopCoordinatorServices();
+      if (isCoordinator && !localAddress.equals(view.getCoordinator()) && getViewCreator() != null) {
+        markViewCreatorForShutdown = true;
+        this.isCoordinator = false;
       }
       installView(view);
     }
@@ -2077,7 +2079,6 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         }
 
         logger.debug("unresponsive members that could not be reached: {}", unresponsive);
-
         List<InternalDistributedMember> failures = new ArrayList<>(currentView.getCrashedMembers().size() + unresponsive.size());
 
         if (conflictingView != null && !conflictingView.getCreator().equals(localAddress) && conflictingView.getViewId() > newView.getViewId()
@@ -2150,6 +2151,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
       sendView(newView, joinReqs);
 
+      if (markViewCreatorForShutdown && getViewCreator() != null) {
+        shutdown = true;
+      }
+
       // after sending a final view we need to stop this thread if
       // the GMS is shutting down
       if (isStopping()) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index d5fe5f8..2cf50a0 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@ -39,14 +39,13 @@ import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
 import com.gemstone.gemfire.distributed.internal.membership.NetView;
 import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
-import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeaveHelper;
+import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeaveTestHelper;
 import com.gemstone.gemfire.internal.Assert;
 import com.gemstone.gemfire.internal.AvailablePort;
 import com.gemstone.gemfire.internal.AvailablePortHelper;
 import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 import com.gemstone.gemfire.internal.logging.LocalLogWriter;
 import com.gemstone.gemfire.internal.tcp.Connection;
-import com.gemstone.gemfire.test.dunit.*;
 
 import java.io.File;
 import java.io.IOException;
@@ -1334,7 +1333,6 @@ public class LocatorDUnitTest extends DistributedTestCase {
     dsProps.setProperty("locators", locators);
     dsProps.setProperty("mcast-port", "0");
     dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
-    final String uniqueName = getUniqueName();
 
     vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
       public void run() {
@@ -1452,7 +1450,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     final Properties dsProps = new Properties();
     dsProps.setProperty("locators", locators);
     dsProps.setProperty("mcast-port", "0");
-    dsProps.setProperty("log-level", "FINE");
+    dsProps.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
     dsProps.setProperty("enable-network-partition-detection", "true");
     dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 
@@ -1468,7 +1466,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
                 Properties props = new Properties();
                 props.setProperty("mcast-port", "0");
                 props.setProperty("locators", locators);
-                props.setProperty("log-level", "FINE");
+                props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
                 props.setProperty("enable-network-partition-detection", "true");
                 DistributedSystem.connect(props);
               }
@@ -1527,9 +1525,9 @@ public class LocatorDUnitTest extends DistributedTestCase {
             host0 + "[" + port3 + "]";
         dsProps.setProperty("locators", newLocators);
 
-        assertTrue(vm3.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        assertTrue(vm3.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator()));
         //Given the start up order of servers, this server is the elder server
-        assertTrue(vm3.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        assertTrue(vm3.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator()));
 
         startLocatorAsync(vm1, new Object[] { port2, dsProps });
         startLocatorAsync(vm2, new Object[] { port3, dsProps });
@@ -1551,17 +1549,17 @@ public class LocatorDUnitTest extends DistributedTestCase {
         };
         Wait.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
 
-        int netviewId = vm1.invoke(() -> GMSJoinLeaveHelper.getViewId());
-        assertEquals(netviewId, (int) vm2.invoke(() -> GMSJoinLeaveHelper.getViewId()));
-        assertEquals(netviewId, (int) vm3.invoke(() -> GMSJoinLeaveHelper.getViewId()));
-        assertEquals(netviewId, (int) vm4.invoke(() -> GMSJoinLeaveHelper.getViewId()));
-        assertFalse(vm4.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        int netviewId = vm1.invoke(() -> GMSJoinLeaveTestHelper.getViewId());
+        assertEquals(netviewId, (int) vm2.invoke(() -> GMSJoinLeaveTestHelper.getViewId()));
+        assertEquals(netviewId, (int) vm3.invoke(() -> GMSJoinLeaveTestHelper.getViewId()));
+        assertEquals(netviewId, (int) vm4.invoke(() -> GMSJoinLeaveTestHelper.getViewId()));
+        assertFalse(vm4.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator()));
         //Given the start up order of servers, this server is the elder server
-        assertFalse(vm3.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
-        if (vm1.invoke(() -> GMSJoinLeaveHelper.isViewCreator())) {
-          assertFalse(vm2.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        assertFalse(vm3.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator()));
+        if (vm1.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator())) {
+          assertFalse(vm2.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator()));
         } else {
-          assertTrue(vm2.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+          assertTrue(vm2.invoke(() -> GMSJoinLeaveTestHelper.isViewCreator()));
         }
 
       } finally {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
index 79aa02a..202888c 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
@@ -214,7 +214,7 @@ public class GMSJoinLeaveJUnitTest {
   @Test
   public void testViewWithoutMemberInitiatesForcedDisconnect() throws Exception {
     initMocks();
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     List<InternalDistributedMember> members = Arrays.asList(mockMembers);
     NetView v = new NetView(mockMembers[0], 2, members);
     InstallViewMessage message = new InstallViewMessage(v, null);
@@ -329,7 +329,7 @@ public class GMSJoinLeaveJUnitTest {
         any(String.class), any(Boolean.class))).thenReturn(true);
     
     gmsJoinLeave.delayViewCreationForTest(5000); // ensures multiple requests are queued for a view change
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
 
     NetView oldView = null;
     long giveup = System.currentTimeMillis() + viewInstallationTime;
@@ -422,9 +422,8 @@ public class GMSJoinLeaveJUnitTest {
     String reason = "testing";
     initMocks();
     gmsJoinLeave.unitTesting.add("noRandomViewChange");
-    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
-    gmsJoinLeave.getView().add(gmsJoinLeaveMemberId);
-    gmsJoinLeave.becomeCoordinatorForTest();
+    prepareAndInstallView(gmsJoinLeaveMemberId, createMemberList(gmsJoinLeaveMemberId,mockMembers[0]));
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
 
     LeaveRequestMessage msg = new LeaveRequestMessage(gmsJoinLeave.getMemberID(), mockMembers[0], reason);
     msg.setSender(mockMembers[0]);
@@ -446,11 +445,10 @@ public class GMSJoinLeaveJUnitTest {
   public void testDuplicateRemoveRequestDoesNotCauseNewView() throws Exception {
     String reason = "testing";
     initMocks();
-    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
-    gmsJoinLeave.getView().add(gmsJoinLeaveMemberId);
+    prepareAndInstallView(gmsJoinLeaveMemberId, createMemberList(gmsJoinLeaveMemberId,mockMembers[0]));
     gmsJoinLeave.getView().add(mockMembers[1]);
     gmsJoinLeave.unitTesting.add("noRandomViewChange");
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     RemoveMemberMessage msg = new RemoveMemberMessage(gmsJoinLeave.getMemberID(), mockMembers[0], reason);
     msg.setSender(mockMembers[0]);
     gmsJoinLeave.processMessage(msg);
@@ -474,10 +472,9 @@ public class GMSJoinLeaveJUnitTest {
     when(healthMonitor.checkIfAvailable(any(InternalDistributedMember.class),
         any(String.class), any(Boolean.class))).thenReturn(true);
     gmsJoinLeave.unitTesting.add("noRandomViewChange");
-    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
-    gmsJoinLeave.getView().add(gmsJoinLeaveMemberId);
+    prepareAndInstallView(gmsJoinLeaveMemberId, createMemberList(gmsJoinLeaveMemberId,mockMembers[0]));
     gmsJoinLeave.getView().add(mockMembers[1]);
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     JoinRequestMessage msg = new JoinRequestMessage(gmsJoinLeaveMemberId, mockMembers[2], null, -1);
     msg.setSender(mockMembers[2]);
     gmsJoinLeave.processMessage(msg);
@@ -522,7 +519,7 @@ public class GMSJoinLeaveJUnitTest {
   public void testRemoveCausesForcedDisconnect() throws Exception {
     String reason = "testing";
     initMocks();
-    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId)); 
+    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
     gmsJoinLeave.getView().add(mockMembers[1]);
     RemoveMemberMessage msg = new RemoveMemberMessage(mockMembers[0], gmsJoinLeave.getMemberID(), reason);
     msg.setSender(mockMembers[1]);
@@ -534,8 +531,7 @@ public class GMSJoinLeaveJUnitTest {
   public void testLeaveCausesForcedDisconnect() throws Exception {
     String reason = "testing";
     initMocks();
-    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
-    gmsJoinLeave.getView().add(gmsJoinLeaveMemberId);
+    prepareAndInstallView(gmsJoinLeaveMemberId, createMemberList(gmsJoinLeaveMemberId,mockMembers[0]));
     gmsJoinLeave.getView().add(mockMembers[1]);
     LeaveRequestMessage msg = new LeaveRequestMessage(gmsJoinLeave.getMemberID(), gmsJoinLeave.getMemberID(), reason);
     msg.setSender(mockMembers[1]);
@@ -558,7 +554,7 @@ public class GMSJoinLeaveJUnitTest {
   @Test
   public void testBecomeCoordinatorOnStartup() throws Exception {
     initMocks();
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     long giveup = System.currentTimeMillis() + 20000;
     while (System.currentTimeMillis() < giveup && !gmsJoinLeave.isCoordinator()) {
       Thread.sleep(1000);
@@ -616,7 +612,7 @@ public class GMSJoinLeaveJUnitTest {
     NetView oldView = gmsJoinLeave.getView();
     oldView.add(gmsJoinLeaveMemberId);
     InternalDistributedMember creator = oldView.getCreator();
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     NetView view = new NetView(2, gmsJoinLeave.getView().getViewId()+1);
     view.setCreator(creator);
     view.add(creator);
@@ -665,7 +661,7 @@ public class GMSJoinLeaveJUnitTest {
   @Test
   public void testNetworkPartitionMessageReceived() throws Exception {
     initMocks();
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     NetworkPartitionMessage message = new NetworkPartitionMessage();
     gmsJoinLeave.processMessage(message);
     verify(manager).forceDisconnect(any(String.class));
@@ -838,7 +834,7 @@ public class GMSJoinLeaveJUnitTest {
     gmsJoinLeaveMemberId.setVmViewId(1);
     members.add(gmsJoinLeaveMemberId);
     prepareAndInstallView(gmsJoinLeaveMemberId, members);
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     GMSJoinLeave.ViewBroadcaster b = gmsJoinLeave.new ViewBroadcaster();
     b.run();
     verify(messenger).sendUnreliably(isA(InstallViewMessage.class));
@@ -945,20 +941,22 @@ public class GMSJoinLeaveJUnitTest {
         System.getProperties().remove(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY);
       }
   }
-  
-  @Test
-  public void testJoinResponseMsgWithBecomeCoordinator() throws Exception {
-    initMocks(false);
-    gmsJoinLeaveMemberId.getNetMember().setPreferredForCoordinator(false);
-    JoinRequestMessage reqMsg = new JoinRequestMessage(gmsJoinLeaveMemberId, mockMembers[0], null, 56734);
-    InternalDistributedMember ids = new InternalDistributedMember("localhost", 97898);
-    ids.getNetMember().setPreferredForCoordinator(true);
-    gmsJoinLeave.processMessage(reqMsg);
-    ArgumentCaptor<JoinResponseMessage> ac = ArgumentCaptor.forClass(JoinResponseMessage.class);
-    verify(messenger).send(ac.capture());
-    
-    assertTrue("Should have asked for becoming a coordinator", ac.getValue().getBecomeCoordinator());
-  }
+
+//  With the removal of the JoinResponse message from GMSJoinLeave.processJoinRequest (GEODE-870)
+//  This test now seems to be invalid
+//  @Test
+//  public void testJoinResponseMsgWithBecomeCoordinator() throws Exception {
+//    initMocks(false);
+//    gmsJoinLeaveMemberId.getNetMember().setPreferredForCoordinator(false);
+//    JoinRequestMessage reqMsg = new JoinRequestMessage(gmsJoinLeaveMemberId, mockMembers[0], null, 56734);
+//    InternalDistributedMember ids = new InternalDistributedMember("localhost", 97898);
+//    ids.getNetMember().setPreferredForCoordinator(true);
+//    gmsJoinLeave.processMessage(reqMsg);
+//    ArgumentCaptor<JoinResponseMessage> ac = ArgumentCaptor.forClass(JoinResponseMessage.class);
+//    verify(messenger).send(ac.capture());
+//
+//    assertTrue("Should have asked for becoming a coordinator", ac.getValue().getBecomeCoordinator());
+//  }
   
   @Test
   public void testNetworkPartionMessage() throws Exception {
@@ -1004,8 +1002,7 @@ public class GMSJoinLeaveJUnitTest {
   @Test
   public void testPreparedViewFoundDuringBecomeCoordinator() throws Exception {
     initMocks(false);
-    prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
-    
+    prepareAndInstallView(gmsJoinLeaveMemberId, createMemberList(gmsJoinLeaveMemberId,mockMembers[0]));
     // a new member is joining
     NetView preparedView = new NetView(gmsJoinLeave.getView(), gmsJoinLeave.getView().getViewId()+5);
     mockMembers[1].setVmViewId(preparedView.getViewId());
@@ -1014,7 +1011,7 @@ public class GMSJoinLeaveJUnitTest {
     InstallViewMessage msg = new InstallViewMessage(preparedView, null, true);
     gmsJoinLeave.processMessage(msg);
     
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
 
     Thread.sleep(2000);
     ViewCreator vc = gmsJoinLeave.getViewCreator();
@@ -1152,7 +1149,7 @@ public class GMSJoinLeaveJUnitTest {
   public void testRemoveRequestWhileWaitingForFinalResponse() throws Exception {
     initMocks(true, true);
     
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     
     installView();
     
@@ -1174,7 +1171,7 @@ public class GMSJoinLeaveJUnitTest {
   public void testLeaveRequestWhileWaitingForFinalResponse() throws Exception {
     initMocks(true, true);
     
-    gmsJoinLeave.becomeCoordinatorForTest();
+    GMSJoinLeaveTestHelper.becomeCoordinatorForTest(gmsJoinLeave);
     
     installView();
     

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedDataSerializables.txt
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedDataSerializables.txt b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedDataSerializables.txt
index 472d821..dd48df4 100644
--- a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedDataSerializables.txt
+++ b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedDataSerializables.txt
@@ -365,8 +365,8 @@ fromData,22,2a2bb900130100b500022a2bb80014c00015b50003b1
 toData,19,2b2ab40002b9001102002ab400032bb80012b1
 
 com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage,2
-fromData,39,2a2bb700102ab800112bb90012010032b500042a2bb80013c00014b500022a2bb80013b50005b1
-toData,35,2a2bb7000c2b2ab40004b6000db9000e02002ab400022bb8000f2ab400052bb8000fb1
+fromData,49,2a2bb700122a2bb900130100b500072ab800142bb90013010032b500042a2bb80015c00016b500022a2bb80015b50005b1
+toData,45,2a2bb7000e2b2ab40007b9000f02002b2ab40004b60010b9000f02002ab400022bb800112ab400052bb80011b1
 
 com/gemstone/gemfire/distributed/internal/membership/gms/messages/JoinRequestMessage,2
 fromData,38,2a2bb80019c0001ab500042a2bb80019b500052a2bb8001bb500022a2bb9001c0100b6001db1

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/cafcf56a/geode-cq/src/test/java/com/gemstone/gemfire/cache/query/cq/dunit/CqQueryUsingPoolDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-cq/src/test/java/com/gemstone/gemfire/cache/query/cq/dunit/CqQueryUsingPoolDUnitTest.java b/geode-cq/src/test/java/com/gemstone/gemfire/cache/query/cq/dunit/CqQueryUsingPoolDUnitTest.java
index 680112b..f333b77 100644
--- a/geode-cq/src/test/java/com/gemstone/gemfire/cache/query/cq/dunit/CqQueryUsingPoolDUnitTest.java
+++ b/geode-cq/src/test/java/com/gemstone/gemfire/cache/query/cq/dunit/CqQueryUsingPoolDUnitTest.java
@@ -2807,7 +2807,9 @@ public class CqQueryUsingPoolDUnitTest extends CacheTestCase {
     VM server2 = host.getVM(1);
     VM client1 = host.getVM(2);
     VM client2 = host.getVM(3);
-    
+
+    Wait.pause(3 * 1000);
+
     createServer(server1);
     
     final int port1 = server1.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());


[009/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientMembershipDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientMembershipDUnitTest.java
index dbbaaa8,0000000..23386a7
mode 100755,000000..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientMembershipDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientMembershipDUnitTest.java
@@@ -1,1669 -1,0 +1,1659 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.io.IOException;
 +import java.net.InetAddress;
 +import java.net.InetSocketAddress;
 +import java.net.Socket;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.InternalGemFireException;
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.Statistics;
 +import com.gemstone.gemfire.StatisticsType;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.Pool;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DurableClientAttributes;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.cache.tier.InternalClientMembership;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 +import com.gemstone.gemfire.internal.logging.LocalLogWriter;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.management.membership.ClientMembership;
 +import com.gemstone.gemfire.management.membership.ClientMembershipEvent;
 +import com.gemstone.gemfire.management.membership.ClientMembershipListener;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * Tests the ClientMembership API including ClientMembershipListener.
 + *
 + * @author Kirk Lund
 + * @since 4.2.1
 + */
 +public class ClientMembershipDUnitTest extends ClientServerTestCase {
 +
 +  protected static final boolean CLIENT = true;
 +  protected static final boolean SERVER = false;
 +  
 +  protected static final int JOINED = 0;
 +  protected static final int LEFT = 1;
 +  protected static final int CRASHED = 2;
 +    
 +  public ClientMembershipDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  public void setUp() throws Exception {
 +    super.setUp();
 +  }
 +  
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    InternalClientMembership.unregisterAllListeners();
 +  }
 +
 +  private void waitForAcceptsInProgressToBe(final int target)
 +    throws Exception {
 +    WaitCriterion ev = new WaitCriterion() {
 +      String excuse;
 +      public boolean done() {
 +        int actual = getAcceptsInProgress();
 +        if (actual == getAcceptsInProgress()) {
 +          return true;
 +        }
 +        excuse = "accepts in progress (" + actual + ") never became " + target;
 +        return false;
 +      }
 +      public String description() {
 +        return excuse;
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 60 * 1000, 200, true);
 +  }
 +  
 +  protected int getAcceptsInProgress() {
 +    StatisticsType st = InternalDistributedSystem.getAnyInstance().findType("CacheServerStats");
 +    Statistics[] s = InternalDistributedSystem.getAnyInstance().findStatisticsByType(st);
 +    return s[0].getInt("acceptsInProgress");
 +  }
 +
 +  protected static Socket meanSocket;
 +
 +  /** test that a server times out waiting for a handshake that
 +      never arrives. 
 +   */
 +  public void testConnectionTimeout() throws Exception {
 +    IgnoredException.addIgnoredException("failed accepting client connection");
 +    final Host host = Host.getHost(0);
 +    final String hostName = NetworkUtils.getServerHostName(host);
 +    final VM vm0 = host.getVM(0);
 +    System.setProperty(AcceptorImpl.ACCEPT_TIMEOUT_PROPERTY_NAME, "1000");
 +    try {
 +    final int port = startBridgeServer(0);
 +//    AsyncInvocation ai = null;
 +    try {
 +      assertTrue(port != 0);
 +      SerializableRunnable createMeanSocket = new CacheSerializableRunnable("Connect to server with socket") {
 +        public void run2() throws CacheException {
 +          getCache(); // create a cache so we have stats
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("connecting to cache server with socket");
 +          try {
 +            InetAddress addr = InetAddress.getByName(hostName);
 +            meanSocket = new Socket(addr, port);
 +          }
 +          catch (Exception e) {
 +            throw new RuntimeException("Test failed to connect or was interrupted", e);
 +          }
 +        }
 +      };
 +      SerializableRunnable closeMeanSocket = new CacheSerializableRunnable("close mean socket") {
 +        public void run2() throws CacheException {
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("closing mean socket");
 +          try {
 +            meanSocket.close();
 +          }
 +          catch (IOException ignore) {
 +          }
 +        }
 +      };
 +
 +      assertEquals(0, getAcceptsInProgress());
 +      
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("creating mean socket");
 +      vm0.invoke(createMeanSocket);
 +      try {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("waiting to see it connect on server");
 +        waitForAcceptsInProgressToBe(1);
 +      } finally {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("closing mean socket");
 +        vm0.invoke(closeMeanSocket);
 +      }
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("waiting to see accept to go away on server");
 +      waitForAcceptsInProgressToBe(0);
 +
 +      // now try it without a close. Server should timeout the mean connect
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("creating mean socket 2");
 +      vm0.invoke(createMeanSocket);
 +      try {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("waiting to see it connect on server 2");
 +        waitForAcceptsInProgressToBe(1);
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("waiting to see accept to go away on server without us closing");
 +        waitForAcceptsInProgressToBe(0);
 +      } finally {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("closing mean socket 2");
 +        vm0.invoke(closeMeanSocket);
 +      }
 +
 +//       SerializableRunnable denialOfService = new CacheSerializableRunnable("Do lots of connects") {
 +//         public void run2() throws CacheException {
 +//           int connectionCount = 0;
 +//           ArrayList al = new ArrayList(60000);
 +//           try {
 +//             InetAddress addr = InetAddress.getLocalHost();
 +//             for (;;) {
 +//               Socket s = new Socket(addr, port);
 +//               al.add(s);
 +//               connectionCount++;
 +//               getLogWriter().info("connected # " + connectionCount + " s=" + s);
 +// //               try {
 +// //                 s.close();
 +// //               } catch (IOException ignore) {}
 +//             }
 +//           }
 +//           catch (Exception e) {
 +//             getLogWriter().info("connected # " + connectionCount
 +//                                 + " stopped because of exception " + e);
 +//             Iterator it = al.iterator();
 +//             while (it.hasNext()) {
 +//               Socket s = (Socket)it.next();
 +//               try {
 +//                 s.close();
 +//               } catch (IOException ignore) {}
 +//             }
 +//           }
 +//         }
 +//       };
 +//       // now pretend to do a denial of service attack by doing a bunch of connects
 +//       // really fast and see what that does to the server's fds.
 +//       getLogWriter().info("doing denial of service attach");
 +//       vm0.invoke(denialOfService);
 +//       // @todo darrel: check fd limit?
 +    }
 +    finally {
 +      stopBridgeServers(getCache());
 +    }
 +    }
 +    finally {
 +      System.getProperties().remove(AcceptorImpl.ACCEPT_TIMEOUT_PROPERTY_NAME);
 +    }
 +  }
 +
 +  public void testSynchronousEvents() throws Exception {
 +    getSystem();
 +    InternalClientMembership.setForceSynchronous(true);
 +    try {
 +      doTestBasicEvents();
 +    }
 +    finally {
 +      InternalClientMembership.setForceSynchronous(false);
 +    }
 +  }
 +  
 +  /**
 +   * Tests event notification methods on ClientMembership.
 +   */
 +  public void testBasicEvents() throws Exception {
 +    getSystem();
 +    doTestBasicEvents();
 +  }
 +  
 +  public void doTestBasicEvents() throws Exception {
 +    final boolean[] fired = new boolean[3];
 +    final DistributedMember[] member = new DistributedMember[3];
 +    final String[] memberId = new String[3];
 +    final boolean[] isClient = new boolean[3];
 +    
 +    ClientMembershipListener listener = new ClientMembershipListener() {
 +      public synchronized void memberJoined(ClientMembershipEvent event) {
 +        fired[JOINED] = true;
 +        member[JOINED] = event.getMember();
 +        memberId[JOINED] = event.getMemberId();
 +        isClient[JOINED] = event.isClient();
 +        notify();
 +      }
 +      public synchronized void memberLeft(ClientMembershipEvent event) {
 +        fired[LEFT] = true;
 +        member[LEFT] = event.getMember();
 +        memberId[LEFT] = event.getMemberId();
 +        isClient[LEFT] = event.isClient();
 +        notify();
 +      }
 +      public synchronized void memberCrashed(ClientMembershipEvent event) {
 +        fired[CRASHED] = true;
 +        member[CRASHED] = event.getMember();
 +        memberId[CRASHED] = event.getMemberId();
 +        isClient[CRASHED] = event.isClient();
 +        notify();
 +      }
 +    };
 +    ClientMembership.registerClientMembershipListener(listener);
 +    
 +    // test JOIN for server
 +    DistributedMember serverJoined = new TestDistributedMember("serverJoined");
 +    InternalClientMembership.notifyJoined(serverJoined, SERVER);
 +    synchronized(listener) {
 +      if (!fired[JOINED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertTrue(fired[JOINED]);
 +    assertEquals(serverJoined, member[JOINED]);
 +    assertEquals(serverJoined.getId(), memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    // test JOIN for client
 +    DistributedMember clientJoined = new TestDistributedMember("clientJoined");
 +    InternalClientMembership.notifyJoined(clientJoined, CLIENT);
 +    synchronized(listener) {
 +      if (!fired[JOINED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertTrue(fired[JOINED]);
 +    assertEquals(clientJoined, member[JOINED]);
 +    assertEquals(clientJoined.getId(), memberId[JOINED]);
 +    assertTrue(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    // test LEFT for server
 +    DistributedMember serverLeft = new TestDistributedMember("serverLeft");
 +    InternalClientMembership.notifyLeft(serverLeft, SERVER);
 +    synchronized(listener) {
 +      if (!fired[LEFT]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertFalse(fired[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertTrue(fired[LEFT]);
 +    assertEquals(serverLeft, member[LEFT]);
 +    assertEquals(serverLeft.getId(), memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    // test LEFT for client
 +    DistributedMember clientLeft = new TestDistributedMember("clientLeft");
 +    InternalClientMembership.notifyLeft(clientLeft, CLIENT);
 +    synchronized(listener) {
 +      if (!fired[LEFT]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertFalse(fired[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertTrue(fired[LEFT]);
 +    assertEquals(clientLeft, member[LEFT]);
 +    assertEquals(clientLeft.getId(), memberId[LEFT]);
 +    assertTrue(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    // test CRASHED for server
 +    DistributedMember serverCrashed = new TestDistributedMember("serverCrashed");
 +    InternalClientMembership.notifyCrashed(serverCrashed, SERVER);
 +    synchronized(listener) {
 +      if (!fired[CRASHED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertFalse(fired[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertTrue(fired[CRASHED]);
 +    assertEquals(serverCrashed, member[CRASHED]);
 +    assertEquals(serverCrashed.getId(), memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    // test CRASHED for client
 +    DistributedMember clientCrashed = new TestDistributedMember("clientCrashed");
 +    InternalClientMembership.notifyCrashed(clientCrashed, CLIENT);
 +    synchronized(listener) {
 +      if (!fired[CRASHED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertFalse(fired[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertTrue(fired[CRASHED]);
 +    assertEquals(clientCrashed, member[CRASHED]);
 +    assertEquals(clientCrashed.getId(), memberId[CRASHED]);
 +    assertTrue(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +  }
 +  
 +  /**
 +   * Resets all elements of arrays used for listener testing. Boolean values
 +   * are reset to false. String values are reset to null.
 +   */
 +  private void resetArraysForTesting(boolean[] fired, 
 +                                     DistributedMember[] member,
 +                                     String[] memberId, 
 +                                     boolean[] isClient) {
 +    for (int i = 0; i < fired.length; i++) {
 +      fired[i] = false;
 +      member[i] = null;
 +      memberId[i] = null;
 +      isClient[i] = false;
 +    }
 +  }
 +  
 +  /**
 +   * Tests unregisterClientMembershipListener to ensure that no further events
 +   * are delivered to unregistered listeners.
 +   */
 +  public void testUnregisterClientMembershipListener() throws Exception {
 +    final boolean[] fired = new boolean[1];
 +    final DistributedMember[] member = new DistributedMember[1];
 +    final String[] memberId = new String[1];
 +    final boolean[] isClient = new boolean[1];
 +    
 +    getSystem();
 +
 +    ClientMembershipListener listener = new ClientMembershipListener() {
 +      public synchronized void memberJoined(ClientMembershipEvent event) {
 +        fired[0] = true;
 +        member[0] = event.getMember();
 +        memberId[0] = event.getMemberId();
 +        isClient[0] = event.isClient();
 +        notify();
 +      }
 +      public void memberLeft(ClientMembershipEvent event) {
 +      }
 +      public void memberCrashed(ClientMembershipEvent event) {
 +      }
 +    };
 +    ClientMembership.registerClientMembershipListener(listener);
 +    
 +    // fire event to make sure listener is registered
 +    DistributedMember clientJoined = new TestDistributedMember("clientJoined");
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listener) {
 +      if (!fired[0]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertTrue(fired[0]);
 +    assertEquals(clientJoined, member[0]);
 +    assertEquals(clientJoined.getId(), memberId[0]);
 +    assertTrue(isClient[0]);
 +
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    assertFalse(fired[0]);
 +    assertNull(memberId[0]);
 +    assertFalse(isClient[0]);
 +
 +    // unregister and verify listener is not notified
 +    ClientMembership.unregisterClientMembershipListener(listener);
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listener) {
 +      listener.wait(20);
 +    }
 +    assertFalse(fired[0]);
 +    assertNull(member[0]);
 +    assertNull(memberId[0]);
 +    assertFalse(isClient[0]);
 +  }
 +  
 +  public void testMultipleListeners() throws Exception {
 +    final int NUM_LISTENERS = 4;
 +    final boolean[] fired = new boolean[NUM_LISTENERS];
 +    final DistributedMember[] member = new DistributedMember[NUM_LISTENERS];
 +    final String[] memberId = new String[NUM_LISTENERS];
 +    final boolean[] isClient = new boolean[NUM_LISTENERS];
 +    
 +    getSystem();
 +
 +    final ClientMembershipListener[] listeners = new ClientMembershipListener[NUM_LISTENERS];
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      final int whichListener = i;
 +      listeners[i] = new ClientMembershipListener() {
 +        public synchronized void memberJoined(ClientMembershipEvent event) {
 +          assertFalse(fired[whichListener]);
 +          assertNull(member[whichListener]);
 +          assertNull(memberId[whichListener]);
 +          assertFalse(isClient[whichListener]);
 +          fired[whichListener] = true;
 +          member[whichListener] = event.getMember();
 +          memberId[whichListener] = event.getMemberId();
 +          isClient[whichListener] = event.isClient();
 +          notify();
 +        }
 +        public void memberLeft(ClientMembershipEvent event) {
 +        }
 +        public void memberCrashed(ClientMembershipEvent event) {
 +        }
 +      };
 +    }
 +    
 +    final DistributedMember clientJoined = new TestDistributedMember("clientJoined");
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      synchronized(listeners[i]) {
 +        listeners[i].wait(20);
 +      }
 +      assertFalse(fired[i]);
 +      assertNull(member[i]);
 +      assertNull(memberId[i]);
 +      assertFalse(isClient[i]);
 +    }
 +    
 +    // attempt to register same listener twice... 2nd reg should be ignored
 +    // failure would cause an assertion failure in memberJoined impl
 +    ClientMembership.registerClientMembershipListener(listeners[0]);
 +    ClientMembership.registerClientMembershipListener(listeners[0]);
 +    
 +    ClientMembershipListener[] registeredListeners = 
 +      ClientMembership.getClientMembershipListeners();
 +    assertEquals(1, registeredListeners.length);
 +    assertEquals(listeners[0], registeredListeners[0]);
 +    
 +    ClientMembership.registerClientMembershipListener(listeners[1]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(2, registeredListeners.length);
 +    assertEquals(listeners[0], registeredListeners[0]);
 +    assertEquals(listeners[1], registeredListeners[1]);
 +
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[1]) {
 +      if (!fired[1]) {
 +        listeners[1].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      if (i < 2) {
 +        assertTrue(fired[i]);
 +        assertEquals(clientJoined, member[i]);
 +        assertEquals(clientJoined.getId(), memberId[i]);
 +        assertTrue(isClient[i]);
 +      } else {
 +        assertFalse(fired[i]);
 +        assertNull(member[i]);
 +        assertNull(memberId[i]);
 +        assertFalse(isClient[i]);
 +      }
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +        
 +    ClientMembership.unregisterClientMembershipListener(listeners[0]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(1, registeredListeners.length);
 +    assertEquals(listeners[1], registeredListeners[0]);
 +    
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[1]) {
 +      if (!fired[1]) {
 +        listeners[1].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      if (i == 1) {
 +        assertTrue(fired[i]);
 +        assertEquals(clientJoined, member[i]);
 +        assertEquals(clientJoined.getId(), memberId[i]);
 +        assertTrue(isClient[i]);
 +      } else {
 +        assertFalse(fired[i]);
 +        assertNull(member[i]);
 +        assertNull(memberId[i]);
 +        assertFalse(isClient[i]);
 +      }
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    ClientMembership.registerClientMembershipListener(listeners[2]);
 +    ClientMembership.registerClientMembershipListener(listeners[3]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(3, registeredListeners.length);
 +    assertEquals(listeners[1], registeredListeners[0]);
 +    assertEquals(listeners[2], registeredListeners[1]);
 +    assertEquals(listeners[3], registeredListeners[2]);
 +
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[3]) {
 +      if (!fired[3]) {
 +        listeners[3].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      if (i != 0) {
 +        assertTrue(fired[i]);
 +        assertEquals(clientJoined, member[i]);
 +        assertEquals(clientJoined.getId(), memberId[i]);
 +        assertTrue(isClient[i]);
 +      } else {
 +        assertFalse(fired[i]);
 +        assertNull(member[i]);
 +        assertNull(memberId[i]);
 +        assertFalse(isClient[i]);
 +      }
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    ClientMembership.registerClientMembershipListener(listeners[0]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(4, registeredListeners.length);
 +    assertEquals(listeners[1], registeredListeners[0]);
 +    assertEquals(listeners[2], registeredListeners[1]);
 +    assertEquals(listeners[3], registeredListeners[2]);
 +    assertEquals(listeners[0], registeredListeners[3]);
 +
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[0]) {
 +      if (!fired[0]) {
 +        listeners[0].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      assertTrue(fired[i]);
 +      assertEquals(clientJoined, member[i]);
 +      assertEquals(clientJoined.getId(), memberId[i]);
 +      assertTrue(isClient[i]);
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    ClientMembership.unregisterClientMembershipListener(listeners[3]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(3, registeredListeners.length);
 +    assertEquals(listeners[1], registeredListeners[0]);
 +    assertEquals(listeners[2], registeredListeners[1]);
 +    assertEquals(listeners[0], registeredListeners[2]);
 +    
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[0]) {
 +      if (!fired[0]) {
 +        listeners[0].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      if (i < 3) {
 +        assertTrue(fired[i]);
 +        assertEquals(clientJoined, member[i]);
 +        assertEquals(clientJoined.getId(), memberId[i]);
 +        assertTrue(isClient[i]);
 +      } else {
 +        assertFalse(fired[i]);
 +        assertNull(member[i]);
 +        assertNull(memberId[i]);
 +        assertFalse(isClient[i]);
 +      }
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    ClientMembership.unregisterClientMembershipListener(listeners[2]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(2, registeredListeners.length);
 +    assertEquals(listeners[1], registeredListeners[0]);
 +    assertEquals(listeners[0], registeredListeners[1]);
 +    
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[0]) {
 +      if (!fired[0]) {
 +        listeners[0].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      if (i < 2) {
 +        assertTrue(fired[i]);
 +        assertEquals(clientJoined, member[i]);
 +        assertEquals(clientJoined.getId(), memberId[i]);
 +        assertTrue(isClient[i]);
 +      } else {
 +        assertFalse(fired[i]);
 +        assertNull(member[i]);
 +        assertNull(memberId[i]);
 +        assertFalse(isClient[i]);
 +      }
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    ClientMembership.unregisterClientMembershipListener(listeners[1]);
 +    ClientMembership.unregisterClientMembershipListener(listeners[0]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(0, registeredListeners.length);
 +    
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      synchronized(listeners[i]) {
 +        listeners[i].wait(20);
 +      }
 +      assertFalse(fired[i]);
 +      assertNull(member[i]);
 +      assertNull(memberId[i]);
 +      assertFalse(isClient[i]);
 +    }
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    ClientMembership.registerClientMembershipListener(listeners[1]);
 +    registeredListeners = ClientMembership.getClientMembershipListeners();
 +    assertEquals(1, registeredListeners.length);
 +    assertEquals(listeners[1], registeredListeners[0]);
 +    
 +    InternalClientMembership.notifyJoined(clientJoined, true);
 +    synchronized(listeners[1]) {
 +      if (!fired[1]) {
 +        listeners[1].wait(2000);
 +      }
 +    }
 +    for (int i = 0; i < NUM_LISTENERS; i++) {
 +      if (i == 1) {
 +        assertTrue(fired[i]);
 +        assertEquals(clientJoined, member[i]);
 +        assertEquals(clientJoined.getId(), memberId[i]);
 +        assertTrue(isClient[i]);
 +      } else {
 +        assertFalse(fired[i]);
 +        assertNull(member[i]);
 +        assertNull(memberId[i]);
 +        assertFalse(isClient[i]);
 +      }
 +    }
 +  }
 + 
 +  protected static int testClientMembershipEventsInClient_port;
 +  private static int getTestClientMembershipEventsInClient_port() {
 +    return testClientMembershipEventsInClient_port;
 +  }
 +  /**
 +   * Tests notification of events in client process. Bridge clients detect
 +   * server joins when the client connects to the server. If the server
 +   * crashes or departs gracefully, the client will detect this as a crash.
 +   */
 +  public void testClientMembershipEventsInClient() throws Exception {
 +    getSystem();
 +    IgnoredException.addIgnoredException("IOException");
 +    final boolean[] fired = new boolean[3];
 +    final DistributedMember[] member = new DistributedMember[3];
 +    final String[] memberId = new String[3];
 +    final boolean[] isClient = new boolean[3];
 +    
 +    // create and register ClientMembershipListener in controller vm...
 +    ClientMembershipListener listener = new ClientMembershipListener() {
 +      public synchronized void memberJoined(ClientMembershipEvent event) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] memberJoined: " + event);
 +        fired[JOINED] = true;
 +        member[JOINED] = event.getMember();
 +        memberId[JOINED] = event.getMemberId();
 +        isClient[JOINED] = event.isClient();
 +        notifyAll();
 +      }
 +      public synchronized void memberLeft(ClientMembershipEvent event) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] memberLeft: " + event);
 +//        fail("Please update testClientMembershipEventsInClient to handle memberLeft for BridgeServer.");
 +      }
 +      public synchronized void memberCrashed(ClientMembershipEvent event) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] memberCrashed: " + event);
 +        fired[CRASHED] = true;
 +        member[CRASHED] = event.getMember();
 +        memberId[CRASHED] = event.getMemberId();
 +        isClient[CRASHED] = event.isClient();
 +        notifyAll();
 +      }
 +    };
 +    ClientMembership.registerClientMembershipListener(listener);
 +
 +    final VM vm0 = Host.getHost(0).getVM(0);
 +    final String name = this.getUniqueName();
 +    final int[] ports = new int[1];
 +
 +    // create BridgeServer in vm0...
 +    vm0.invoke(new CacheSerializableRunnable("Create BridgeServer") {
 +      public void run2() throws CacheException {
 +        try {
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] Create BridgeServer");
 +          getSystem();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          Region region = createRegion(name, factory.create());
 +          assertNotNull(region);
 +          assertNotNull(getRootRegion().getSubregion(name));
 +          testClientMembershipEventsInClient_port = startBridgeServer(0);
 +        }
 +        catch(IOException e) {
 +          getSystem().getLogWriter().fine(new Exception(e));
 +          fail("Failed to start CacheServer on VM1: " + e.getMessage());
 +        }
 +      }
 +    });
 +    
 +    // gather details for later creation of ConnectionPool...
-     ports[0] = vm0.invokeInt(ClientMembershipDUnitTest.class, 
-                              "getTestClientMembershipEventsInClient_port");
++    ports[0] = vm0.invoke(() -> ClientMembershipDUnitTest.getTestClientMembershipEventsInClient_port());
 +    assertTrue(ports[0] != 0);
 +
-     DistributedMember serverMember = (DistributedMember) vm0.invoke(ClientMembershipDUnitTest.class,
-     "getDistributedMember");
++    DistributedMember serverMember = (DistributedMember) vm0.invoke(() -> ClientMembershipDUnitTest.getDistributedMember());
 +
-     String serverMemberId = (String) vm0.invoke(ClientMembershipDUnitTest.class,
-                                                 "getMemberId");
++    String serverMemberId = (String) vm0.invoke(() -> ClientMembershipDUnitTest.getMemberId());
 +
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] ports[0]=" + ports[0]);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] serverMember=" + serverMember);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] serverMemberId=" + serverMemberId);
 +
 +    assertFalse(fired[JOINED]);
 +    assertNull(member[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    
 +    // sanity check...
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] sanity check");
 +    DistributedMember test = new TestDistributedMember("test");
 +    InternalClientMembership.notifyJoined(test, SERVER);
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[CRASHED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    
 +    assertTrue(fired[JOINED]);
 +    assertEquals(test, member[JOINED]);
 +    assertEquals(test.getId(), memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    // create bridge client in controller vm...
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] create bridge client");
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    getSystem(config);
 +    
 +    try {
 +      getCache();
 +      AttributesFactory factory = new AttributesFactory();
 +      factory.setScope(Scope.LOCAL);
 +      ClientServerTestCase.configureConnectionPool(factory, NetworkUtils.getServerHostName(Host.getHost(0)), ports, true, -1, -1, null);
 +      createRegion(name, factory.create());
 +      assertNotNull(getRootRegion().getSubregion(name));
 +    }
 +    catch (CacheException ex) {
 +      Assert.fail("While creating Region on Edge", ex);
 +    }
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[CRASHED]) {
 +        listener.wait(60 * 1000);
 +      }
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] assert client detected server join");
 +    
 +    // first check the getCurrentServers() result
 +    ClientCache clientCache = (ClientCache)getCache();
 +    Set<InetSocketAddress> servers = clientCache.getCurrentServers();
 +    assertTrue(!servers.isEmpty());
 +    InetSocketAddress serverAddr = servers.iterator().next();
 +    InetSocketAddress expectedAddr = new InetSocketAddress(serverMember.getHost(), ports[0]);
 +    assertEquals(expectedAddr, serverAddr);
 +    
 +    // now check listener results
 +    assertTrue(fired[JOINED]);
 +    assertNotNull(member[JOINED]);
 +    assertNotNull(memberId[JOINED]);
 +    assertEquals(serverMember, member[JOINED]);
 +    assertEquals(serverMemberId, memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    vm0.invoke(new SerializableRunnable("Stop BridgeServer") {
 +      public void run() {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] Stop BridgeServer");
 +        stopBridgeServers(getCache());
 +      }
 +    });
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[CRASHED]) {
 +        listener.wait(60 * 1000);
 +      }
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] assert client detected server departure");
 +    assertFalse(fired[JOINED]);
 +    assertNull(member[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertTrue(fired[CRASHED]);
 +    assertNotNull(member[CRASHED]);
 +    assertNotNull(memberId[CRASHED]);
 +    assertEquals(serverMember, member[CRASHED]);
 +    assertEquals(serverMemberId, memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    //now test that we redisover the bridge server
 +    vm0.invoke(new CacheSerializableRunnable("Recreate BridgeServer") {
 +      public void run2() throws CacheException {
 +        try {
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] restarting BridgeServer");
 +          startBridgeServer(ports[0]);
 +        }
 +        catch(IOException e) {
 +          getSystem().getLogWriter().fine(new Exception(e));
 +          fail("Failed to start CacheServer on VM1: " + e.getMessage());
 +        }
 +      }
 +    });
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[CRASHED]) {
 +        listener.wait(60 * 1000);
 +      }
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInClient] assert client detected server recovery");
 +    assertTrue(fired[JOINED]);
 +    assertNotNull(member[JOINED]);
 +    assertNotNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertEquals(serverMember, member[JOINED]);
 +    assertEquals(serverMemberId, memberId[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +  }
 +  
 +  /**
 +   * Tests notification of events in server process. Bridge servers detect
 +   * client joins when the client connects to the server.
 +   */
 +  public void testClientMembershipEventsInServer() throws Exception {
 +    final boolean[] fired = new boolean[3];
 +    final DistributedMember[] member = new DistributedMember[3];
 +    final String[] memberId = new String[3];
 +    final boolean[] isClient = new boolean[3];
 +    
 +    // create and register ClientMembershipListener in controller vm...
 +    ClientMembershipListener listener = new ClientMembershipListener() {
 +      public synchronized void memberJoined(ClientMembershipEvent event) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] memberJoined: " + event);
 +        fired[JOINED] = true;
 +        member[JOINED] = event.getMember();
 +        memberId[JOINED] = event.getMemberId();
 +        isClient[JOINED] = event.isClient();
 +        notifyAll();
 +        assertFalse(fired[LEFT] || fired[CRASHED]);
 +      }
 +      public synchronized void memberLeft(ClientMembershipEvent event) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] memberLeft: " + event);
 +        fired[LEFT] = true;
 +        member[LEFT] = event.getMember();
 +        memberId[LEFT] = event.getMemberId();
 +        isClient[LEFT] = event.isClient();
 +        notifyAll();
 +        assertFalse(fired[JOINED] || fired[CRASHED]);
 +      }
 +      public synchronized void memberCrashed(ClientMembershipEvent event) {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] memberCrashed: " + event);
 +        fired[CRASHED] = true;
 +        member[CRASHED] = event.getMember();
 +        memberId[CRASHED] = event.getMemberId();
 +        isClient[CRASHED] = event.isClient();
 +        notifyAll();
 +        assertFalse(fired[JOINED] || fired[LEFT]);
 +      }
 +    };
 +    ClientMembership.registerClientMembershipListener(listener);
 +
 +    final VM vm0 = Host.getHost(0).getVM(0);
 +    final String name = this.getUniqueName();
 +    final int[] ports = new int[1];
 +
 +    // create BridgeServer in controller vm...
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] Create BridgeServer");
 +    getSystem();
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +    Region region = createRegion(name, factory.create());
 +    assertNotNull(region);
 +    assertNotNull(getRootRegion().getSubregion(name));
 +    
 +    ports[0] = startBridgeServer(0);
 +    assertTrue(ports[0] != 0);
 +    String serverMemberId = getMemberId();
 +    DistributedMember serverMember = getDistributedMember();
 +
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] ports[0]=" + ports[0]);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] serverMemberId=" + serverMemberId);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] serverMember=" + serverMember);
 +
 +    assertFalse(fired[JOINED]);
 +    assertNull(member[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    
 +    // sanity check...
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] sanity check");
 +    DistributedMember test = new TestDistributedMember("test");
 +    InternalClientMembership.notifyJoined(test, CLIENT);
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[LEFT] && !fired[CRASHED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertTrue(fired[JOINED]);
 +    assertEquals(test, member[JOINED]);
 +    assertEquals(test.getId(), memberId[JOINED]);
 +    assertTrue(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    final Host host = Host.getHost(0);
 +    SerializableRunnable createConnectionPool =
 +    new CacheSerializableRunnable("Create connectionPool") {
 +      public void run2() throws CacheException {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] create bridge client");
 +        Properties config = new Properties();
 +        config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +        config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +        getSystem(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, NetworkUtils.getServerHostName(host), ports, true, -1, 2, null);
 +        createRegion(name, factory.create());
 +        assertNotNull(getRootRegion().getSubregion(name));
 +      }
 +    };
 +
 +    // create bridge client in vm0...
 +    vm0.invoke(createConnectionPool);
-     String clientMemberId = (String) vm0.invoke(ClientMembershipDUnitTest.class,
-                                                 "getMemberId");
-     DistributedMember clientMember = (DistributedMember) vm0.invoke(ClientMembershipDUnitTest.class,
-                                                 "getDistributedMember");
++    String clientMemberId = (String) vm0.invoke(() -> ClientMembershipDUnitTest.getMemberId());
++    DistributedMember clientMember = (DistributedMember) vm0.invoke(() -> ClientMembershipDUnitTest.getDistributedMember());
 +                                                
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[LEFT] && !fired[CRASHED]) {
 +        listener.wait(60000);
 +      }
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] assert server detected client join");
 +    assertTrue(fired[JOINED]);
 +    assertEquals(member[JOINED] + " should equal " + clientMember,
 +      clientMember, member[JOINED]);
 +    assertEquals(memberId[JOINED] + " should equal " + clientMemberId,
 +      clientMemberId, memberId[JOINED]);
 +    assertTrue(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    pauseForClientToJoin();
 +    
 +    vm0.invoke(new SerializableRunnable("Stop bridge client") {
 +      public void run() {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] Stop bridge client");
 +        getRootRegion().getSubregion(name).close();
 +        Map m = PoolManager.getAll();
 +        Iterator mit = m.values().iterator();
 +        while(mit.hasNext()) {
 +          Pool p = (Pool)mit.next();
 +          p.destroy();
 +        }
 +      }
 +    });
 +
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[LEFT] && !fired[CRASHED]) {
 +        listener.wait(60000);
 +      }
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] assert server detected client left");
 +    assertFalse(fired[JOINED]);
 +    assertNull(member[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    assertTrue(fired[LEFT]);
 +    assertEquals(clientMember, member[LEFT]);
 +    assertEquals(clientMemberId, memberId[LEFT]);
 +    assertTrue(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +
 +    // reconnect bridge client to test for crashed event
 +    vm0.invoke(createConnectionPool);
-     clientMemberId = (String) vm0.invoke(ClientMembershipDUnitTest.class,
-                                          "getMemberId");
++    clientMemberId = (String) vm0.invoke(() -> ClientMembershipDUnitTest.getMemberId());
 +                                                
 +    synchronized(listener) {
 +      if (!fired[JOINED] && !fired[LEFT] && !fired[CRASHED]) {
 +        listener.wait(60000);
 +      }
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] assert server detected client re-join");
 +    assertTrue(fired[JOINED]);
 +    assertEquals(clientMember, member[JOINED]);
 +    assertEquals(clientMemberId, memberId[JOINED]);
 +    assertTrue(isClient[JOINED]);
 +    assertFalse(fired[LEFT]);
 +    assertNull(member[LEFT]);
 +    assertNull(memberId[LEFT]);
 +    assertFalse(isClient[LEFT]);
 +    assertFalse(fired[CRASHED]);
 +    assertNull(member[CRASHED]);
 +    assertNull(memberId[CRASHED]);
 +    assertFalse(isClient[CRASHED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    pauseForClientToJoin();
 +
 +    ServerConnection.setForceClientCrashEvent(true);
 +    try {
 +      vm0.invoke(new SerializableRunnable("Stop bridge client") {
 +        public void run() {
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] Stop bridge client");
 +          getRootRegion().getSubregion(name).close();
 +          Map m = PoolManager.getAll();
 +          Iterator mit = m.values().iterator();
 +          while(mit.hasNext()) {
 +            Pool p = (Pool)mit.next();
 +            p.destroy();
 +          }
 +        }
 +      });
 +  
 +      synchronized(listener) {
 +        if (!fired[JOINED] && !fired[LEFT] && !fired[CRASHED]) {
 +          listener.wait(60000);
 +        }
 +      }
 +      
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testClientMembershipEventsInServer] assert server detected client crashed");
 +      assertFalse(fired[JOINED]);
 +      assertNull(member[JOINED]);
 +      assertNull(memberId[JOINED]);
 +      assertFalse(isClient[JOINED]);
 +      assertFalse(fired[LEFT]);
 +      assertNull(member[LEFT]);
 +      assertNull(memberId[LEFT]);
 +      assertFalse(isClient[LEFT]);
 +      assertTrue(fired[CRASHED]);
 +      assertEquals(clientMember, member[CRASHED]);
 +      assertEquals(clientMemberId, memberId[CRASHED]);
 +      assertTrue(isClient[CRASHED]);
 +    }
 +    finally {
 +      ServerConnection.setForceClientCrashEvent(false);
 +    }
 +  }
 +  
 +  /**
 +   * The joined event fires when the first client handshake is processed.
 +   * This pauses long enough to allow the rest of the client sockets to
 +   * complete handshaking before making the client leave. Without doing this
 +   * subsequent socket handshakes that are processed could fire join events
 +   * after departure events and then a departure event again. If you see
 +   * failures in testClientMembershipEventsInServer, try increasing this
 +   * timeout.
 +   */
 +  private void pauseForClientToJoin() {
 +    Wait.pause(2000);
 +  }
 +  
 +  /** 
 +   * Tests registration and event notification in conjunction with 
 +   * disconnecting and reconnecting to DistributedSystem. 
 +   */
 +  public void testLifecycle() throws Exception {
 +    final boolean[] fired = new boolean[3];
 +    final DistributedMember[] member = new DistributedMember[3];
 +    final String[] memberId = new String[3];
 +    final boolean[] isClient = new boolean[3];
 +    
 +    // create and register ClientMembershipListener in controller vm...
 +    ClientMembershipListener listener = new ClientMembershipListener() {
 +      public synchronized void memberJoined(ClientMembershipEvent event) {
 +        assertFalse(fired[JOINED]);
 +        assertNull(member[JOINED]);
 +        assertNull(memberId[JOINED]);
 +        assertFalse(isClient[JOINED]);
 +        fired[JOINED] = true;
 +        member[JOINED] = event.getMember();
 +        memberId[JOINED] = event.getMemberId();
 +        isClient[JOINED] = event.isClient();
 +        notifyAll();
 +      }
 +      public synchronized void memberLeft(ClientMembershipEvent event) {
 +      }
 +      public synchronized void memberCrashed(ClientMembershipEvent event) {
 +      }
 +    };
 +    ClientMembership.registerClientMembershipListener(listener);
 +    
 +    // create loner in controller vm...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    getSystem(config);
 +    
 +    // assert that event is fired while connected
 +    DistributedMember serverJoined = new TestDistributedMember("serverJoined");
 +    InternalClientMembership.notifyJoined(serverJoined, SERVER);
 +    synchronized(listener) {
 +      if (!fired[JOINED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertTrue(fired[JOINED]);
 +    assertEquals(serverJoined, member[JOINED]);
 +    assertEquals(serverJoined.getId(), memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    // assert that event is NOT fired while disconnected
 +    disconnectFromDS();
 +    
 +
 +    InternalClientMembership.notifyJoined(serverJoined, SERVER);
 +    synchronized(listener) {
 +      listener.wait(20);
 +    }
 +    assertFalse(fired[JOINED]);
 +    assertNull(member[JOINED]);
 +    assertNull(memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +    resetArraysForTesting(fired, member, memberId, isClient);
 +    
 +    // assert that event is fired again after reconnecting
 +    InternalDistributedSystem sys = getSystem(config);
 +    assertTrue(sys.isConnected());
 +
 +    InternalClientMembership.notifyJoined(serverJoined, SERVER);
 +    synchronized(listener) {
 +      if (!fired[JOINED]) {
 +        listener.wait(2000);
 +      }
 +    }
 +    assertTrue(fired[JOINED]);
 +    assertEquals(serverJoined, member[JOINED]);
 +    assertEquals(serverJoined.getId(), memberId[JOINED]);
 +    assertFalse(isClient[JOINED]);
 +  }
 +  
 +  /**
 +   * Starts up server in controller vm and 4 clients, then calls and tests
 +   * ClientMembership.getConnectedClients(). 
 +   */
 +  public void testGetConnectedClients() throws Exception {
 +    final String name = this.getUniqueName();
 +    final int[] ports = new int[1];
 +    
 +    IgnoredException.addIgnoredException("ConnectException");
 +
 +    // create BridgeServer in controller vm...
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedClients] Create BridgeServer");
 +    getSystem();
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +    Region region = createRegion(name, factory.create());
 +    assertNotNull(region);
 +    assertNotNull(getRootRegion().getSubregion(name));
 +    
 +    ports[0] = startBridgeServer(0);
 +    assertTrue(ports[0] != 0);
 +    String serverMemberId = getMemberId();
 +
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedClients] ports[0]=" + ports[0]);
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedClients] serverMemberId=" + serverMemberId);
 +
 +    final Host host = Host.getHost(0);
 +    SerializableRunnable createPool =
 +    new CacheSerializableRunnable("Create connection pool") {
 +      public void run2() throws CacheException {
 +        com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedClients] create bridge client");
 +        Properties config = new Properties();
 +        config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +        config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +        // 11/30/2015 this test is periodically failing during distributedTest runs
 +        // so we are setting the log-level to fine to figure out what's going on
 +        config.setProperty(DistributionConfig.LOG_LEVEL_NAME, "fine");
 +        getSystem(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        Pool p = ClientServerTestCase.configureConnectionPool(factory, NetworkUtils.getServerHostName(host), ports, true, -1, -1, null);
 +        createRegion(name, factory.create());
 +        assertNotNull(getRootRegion().getSubregion(name));
 +        assertTrue(p.getServers().size() > 0);
 +      }
 +    };
 +
 +    // create bridge client in vm0...
 +    final String[] clientMemberIdArray = new String[host.getVMCount()];
 +    
 +    for (int i = 0; i < host.getVMCount(); i++) { 
 +      final VM vm = Host.getHost(0).getVM(i);
 +      System.out.println("creating pool in vm_"+i);
 +      vm.invoke(createPool);
-       clientMemberIdArray[i] =  String.valueOf(vm.invoke(
-         ClientMembershipDUnitTest.class, "getMemberId"));
++      clientMemberIdArray[i] =  String.valueOf(vm.invoke(() -> ClientMembershipDUnitTest.getMemberId()));
 +    }
 +    Collection clientMemberIds = Arrays.asList(clientMemberIdArray);
 +                                                
 +    {
 +      final int expectedClientCount = clientMemberIds.size();
 +      WaitCriterion wc = new WaitCriterion() {
 +        public String description() {
 +          return "wait for clients";
 +        }
 +        public boolean done() {
 +          Map connectedClients = InternalClientMembership.getConnectedClients(false);
 +          if (connectedClients == null) {
 +            return false;
 +          }
 +          if (connectedClients.size() != expectedClientCount) {
 +            return false;
 +          }
 +          return true;
 +        }
 +      };
 +      Wait.waitForCriterion(wc, 30000, 100, false);
 +    }
 +    
 +    Map connectedClients = InternalClientMembership.getConnectedClients(false);
 +    assertNotNull(connectedClients);
 +    assertEquals(clientMemberIds.size(), connectedClients.size());
 +    for (Iterator iter = connectedClients.keySet().iterator(); iter.hasNext();) {
 +      String connectedClient = (String)iter.next();
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedClients] checking for client " + connectedClient);
 +      assertTrue(clientMemberIds.contains(connectedClient));
 +      Object[] result = (Object[])connectedClients.get(connectedClient);
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedClients] result: " + 
 +                          (result==null? "none"
 +                              : String.valueOf(result[0])+"; connections="+result[1]));
 +    }
 +  }
 +
 +  /**
 +   * Starts up 4 server and the controller vm as a client, then calls and tests
 +   * ClientMembership.getConnectedServers(). 
 +   */
 +  public void testGetConnectedServers() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final String name = this.getUniqueName();
 +    final int[] ports = new int[host.getVMCount()];
 +    
 +    for (int i = 0; i < host.getVMCount(); i++) { 
 +      final int whichVM = i;
 +      final VM vm = Host.getHost(0).getVM(i);
 +      vm.invoke(new CacheSerializableRunnable("Create bridge server") {
 +        public void run2() throws CacheException {
 +          // create BridgeServer in controller vm...
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedServers] Create BridgeServer");
 +          getSystem();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          Region region = createRegion(name+"_"+whichVM, factory.create());
 +          assertNotNull(region);
 +          assertNotNull(getRootRegion().getSubregion(name+"_"+whichVM));
 +          region.put("KEY-1", "VAL-1");
 +          
 +          try {
 +            testGetConnectedServers_port = startBridgeServer(0);
 +          }
 +          catch (IOException e) {
 +            com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().error("startBridgeServer threw IOException", e);
 +            fail("startBridgeServer threw IOException " + e.getMessage());
 +          }
 +          
 +          assertTrue(testGetConnectedServers_port != 0);
 +      
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedServers] port=" + 
 +            ports[whichVM]);
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedServers] serverMemberId=" + 
 +            getDistributedMember());
 +        }
 +      });
-       ports[whichVM] = vm.invokeInt(ClientMembershipDUnitTest.class, 
-                                     "getTestGetConnectedServers_port");
++      ports[whichVM] = vm.invoke(() -> ClientMembershipDUnitTest.getTestGetConnectedServers_port());
 +      assertTrue(ports[whichVM] != 0);
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedServers] create bridge client");
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    getSystem(config);
 +    getCache();
 +    
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +
 +    for (int i = 0; i < ports.length; i++) {
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedServers] creating connectionpool for " + 
 +        NetworkUtils.getServerHostName(host) + " " + ports[i]);
 +      int[] thisServerPorts = new int[] { ports[i] };
 +      ClientServerTestCase.configureConnectionPoolWithName(factory, NetworkUtils.getServerHostName(host), thisServerPorts, false, -1, -1, null,"pooly"+i);
 +      Region region = createRegion(name+"_"+i, factory.create());
 +      assertNotNull(getRootRegion().getSubregion(name+"_"+i));
 +      region.get("KEY-1");
 +    }
 +
 +    {
 +      final int expectedVMCount = host.getVMCount();
 +      WaitCriterion wc = new WaitCriterion() {
 +        public String description() {
 +          return "wait for pools and servers";
 +        }
 +        public boolean done() {
 +          if (PoolManager.getAll().size() != expectedVMCount) {
 +            return false;
 +          }
 +          Map connectedServers = InternalClientMembership.getConnectedServers();
 +          if (connectedServers == null) {
 +            return false;
 +          }
 +          if (connectedServers.size() != expectedVMCount) {
 +            return false;
 +          }
 +          return true;
 +        }
 +      };
 +      Wait.waitForCriterion(wc, 60000, 100, false);
 +    }
 +
 +    {
 +      assertEquals(host.getVMCount(), PoolManager.getAll().size());
 +      
 +    }
 +    
 +    Map connectedServers = InternalClientMembership.getConnectedServers();
 +    assertNotNull(connectedServers);
 +    assertEquals(host.getVMCount(), connectedServers.size());
 +    for (Iterator iter = connectedServers.keySet().iterator(); iter.hasNext();) {
 +      String connectedServer = (String) iter.next();
 +      com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetConnectedServers]  value for connectedServer: " + 
 +                          connectedServers.get(connectedServer));
 +    }
 +  }
 +
 +  protected static int testGetConnectedServers_port;
 +  private static int getTestGetConnectedServers_port() {
 +    return testGetConnectedServers_port;
 +  }
 +
 +  /**
 +   * Tests getConnectedClients(boolean onlyClientsNotifiedByThisServer) where
 +   * onlyClientsNotifiedByThisServer is true.
 +   */
 +  public void testGetNotifiedClients() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final String name = this.getUniqueName();
 +    final int[] ports = new int[host.getVMCount()];
 +    
 +    for (int i = 0; i < host.getVMCount(); i++) { 
 +      final int whichVM = i;
 +      final VM vm = Host.getHost(0).getVM(i);
 +      vm.invoke(new CacheSerializableRunnable("Create bridge server") {
 +        public void run2() throws CacheException {
 +          // create BridgeServer in controller vm...
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetNotifiedClients] Create BridgeServer");
 +          getSystem();
 +          AttributesFactory factory = new AttributesFactory();
 +          Region region = createRegion(name, factory.create());
 +          assertNotNull(region);
 +          assertNotNull(getRootRegion().getSubregion(name));
 +          region.put("KEY-1", "VAL-1");
 +          
 +          try {
 +            testGetNotifiedClients_port = startBridgeServer(0);
 +          }
 +          catch (IOException e) {
 +            com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().error("startBridgeServer threw IOException", e);
 +            fail("startBridgeServer threw IOException " + e.getMessage());
 +          }
 +          
 +          assertTrue(testGetNotifiedClients_port != 0);
 +      
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetNotifiedClients] port=" + 
 +            ports[whichVM]);
 +          com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetNotifiedClients] serverMemberId=" + 
 +            getMemberId());
 +        }
 +      });
-       ports[whichVM] = vm.invokeInt(ClientMembershipDUnitTest.class, 
-                                     "getTestGetNotifiedClients_port");
++      ports[whichVM] = vm.invoke(() -> ClientMembershipDUnitTest.getTestGetNotifiedClients_port());
 +      assertTrue(ports[whichVM] != 0);
 +    }
 +    
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetNotifiedClients] create bridge client");
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    getSystem(config);
 +    getCache();
 +    
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +
 +    com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("[testGetNotifiedClients] creating connection pool");
 +    ClientServerTestCase.configureConnectionPool(factory, NetworkUtils.getServerHostName(host), ports, true, -1, -1, null);
 +    Region region = createRegion(name, factory.create());
 +    assertNotNull(getRootRegion().getSubregion(name));
 +    region.registerInterest("KEY-1");
 +    region.get("KEY-1");
 +
 +    final String clientMemberId = getMemberId();
 +    
 +    pauseForClientToJoin();
 +    
 +    // assertions go here
 +    int[] clientCounts = new int[host.getVMCount()];
 +    
 +    // only one server vm will have that client for updating
 +    for (int i = 0; i < host.getVMCount(); i++) { 
 +      final int whichVM = i;
 +      final VM vm = Host.getHost(0).getVM(i);
 +      vm.invoke(new CacheSerializableRunnable("Create bridge server") {
 +        public void run2() throws CacheException {
 +          Map clients = InternalClientMembership.getConnectedClients(true);
 +          assertNotNull(clients);
 +          testGetNotifiedClients_clientCount = clients.size();
 +          if (testGetNotifiedClients_clientCount > 0) {
 +            // assert that the clientMemberId matches
 +            assertEquals(clientMemberId, clients.keySet().iterator().next());
 +          }
 +        }
 +      });
-       clientCounts[whichVM] = vm.invokeInt(ClientMembershipDUnitTest.class, 
-                               "getTestGetNotifiedClients_clientCount");
++      clientCounts[whichVM] = vm.invoke(() -> ClientMembershipDUnitTest.getTestGetNotifiedClients_clientCount());
 +    }
 +    
 +    // only one server should have a notifier for this client...
 +    int totalClientCounts = 0;
 +    for (int i = 0; i < clientCounts.length; i++) {
 +      totalClientCounts += clientCounts[i];
 +    }
 +    // this assertion fails because the count is 4
 +    //assertEquals(1, totalClientCounts);
 +  }
 +  protected static int testGetNotifiedClients_port;
 +  private static int getTestGetNotifiedClients_port() {
 +    return testGetNotifiedClients_port;
 +  }
 +  protected static int testGetNotifiedClients_clientCount;
 +  private static int getTestGetNotifiedClients_clientCount() {
 +    return testGetNotifiedClients_clientCount;
 +  }
 +
 +  // Simple DistributedMember implementation
 +  static final class TestDistributedMember implements DistributedMember {
 +    
 +    private String host;
 +    
 +    public TestDistributedMember(String host) {
 +      this.host = host;
 +    }
 +
 +    public String getName() {
 +      return "";
 +    }
 +
 +    public String getHost() {
 +      return this.host;
 +    }
 +
 +    public Set getRoles() {
 +      return new HashSet();
 +    }
 +
 +    public int getProcessId() {
 +      return 0;
 +    }
 +
 +    public String getId() {
 +      return this.host;
 +    }
 +    
 +    public int compareTo(DistributedMember o) {
 +      if ((o == null) || !(o instanceof TestDistributedMember)) {
 +        throw new InternalGemFireException("Invalidly comparing TestDistributedMember to " + o);
 +      }
 +      
 +      TestDistributedMember tds = (TestDistributedMember) o;
 +      return getHost().compareTo(tds.getHost());
 +    }
 +    
 +    public boolean equals(Object obj) {
 +      if ((obj == null) || !(obj instanceof TestDistributedMember)) {
 +        return false;
 +      }
 +      return compareTo((TestDistributedMember)obj) == 0;
 +    }
 +    
 +    public int hashCode() {
 +      return getHost().hashCode();
 +    }
 +    
 +    public DurableClientAttributes getDurableClientAttributes() {
 +      
 +      return null;
 +    }
 +
 +    public List<String> getGroups() {
 +      return Collections.emptyList();
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientRegisterInterestDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientRegisterInterestDUnitTest.java
index a734a10,0000000..f7e2277
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientRegisterInterestDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClientRegisterInterestDUnitTest.java
@@@ -1,429 -1,0 +1,426 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.io.IOException;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.internal.PoolImpl;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
 +
 +/**
 + * Tests the client register interest
 + *
 + * @author Kirk Lund
 + * @since 4.2.3
 + */
 +public class ClientRegisterInterestDUnitTest extends ClientServerTestCase {
 +
 +  public ClientRegisterInterestDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    disconnectAllFromDS(); // cleans up bridge server and client and lonerDS
 +  }
 +  
 +  /**
 +   * Tests for Bug 35381 Calling register interest if 
 +   * establishCallbackConnection is not set causes bridge server NPE.
 +   */
 +  public void testBug35381() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final String name = this.getUniqueName();
 +    final int[] ports = new int[1]; // 1 server in this test
 +    
 +    final int whichVM = 0;
 +    final VM vm = Host.getHost(0).getVM(whichVM);
 +    vm.invoke(new CacheSerializableRunnable("Create bridge server") {
 +      public void run2() throws CacheException {
 +        LogWriterUtils.getLogWriter().info("[testBug35381] Create BridgeServer");
 +        getSystem();
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        Region region = createRegion(name, factory.create());
 +        assertNotNull(region);
 +        assertNotNull(getRootRegion().getSubregion(name));
 +        region.put("KEY-1", "VAL-1");
 +        
 +        try {
 +          bridgeServerPort = startBridgeServer(0);
 +        }
 +        catch (IOException e) {
 +          LogWriterUtils.getLogWriter().error("startBridgeServer threw IOException", e);
 +          fail("startBridgeServer threw IOException " + e.getMessage());
 +        }
 +        
 +        assertTrue(bridgeServerPort != 0);
 +    
 +        LogWriterUtils.getLogWriter().info("[testBug35381] port=" + bridgeServerPort);
 +        LogWriterUtils.getLogWriter().info("[testBug35381] serverMemberId=" + getMemberId());
 +      }
 +    });
-     ports[whichVM] = vm.invokeInt(ClientRegisterInterestDUnitTest.class, 
-                                   "getBridgeServerPort");
++    ports[whichVM] = vm.invoke(() -> ClientRegisterInterestDUnitTest.getBridgeServerPort());
 +    assertTrue(ports[whichVM] != 0);
 +    
 +    LogWriterUtils.getLogWriter().info("[testBug35381] create bridge client");
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    getSystem(config);
 +    getCache();
 +    
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +
 +    LogWriterUtils.getLogWriter().info("[testBug35381] creating connection pool");
 +    boolean establishCallbackConnection = false; // SOURCE OF BUG 35381
 +    ClientServerTestCase.configureConnectionPool(factory, NetworkUtils.getServerHostName(host), ports, establishCallbackConnection, -1, -1, null);
 +    Region region = createRegion(name, factory.create());
 +    assertNotNull(getRootRegion().getSubregion(name));
 +    try {
 +      region.registerInterest("KEY-1");
 +      fail("registerInterest failed to throw SubscriptionNotEnabledException with establishCallbackConnection set to false"); 
 +    }
 +    catch (SubscriptionNotEnabledException expected) {
 +    }
 +  }
 +  protected static int bridgeServerPort;
 +  private static int getBridgeServerPort() {
 +    return bridgeServerPort;
 +  }
 +  
 +  /**
 +   * Tests failover of register interest from client point of view. Related
 +   * bugs include:
 +   *
 +   * <p>Bug 35654 "failed re-registration may never be detected and thus
 +   * may never re-re-register"
 +   *
 +   * <p>Bug 35639 "registerInterest re-registration happens everytime a healthy
 +   * server is detected"
 +   *
 +   * <p>Bug 35655 "a single failed re-registration causes all other pending
 +   * re-registrations to be cancelled"
 +   */
 +  public void _testRegisterInterestFailover() throws Exception {
 +    // controller is bridge client
 +    
 +    final Host host = Host.getHost(0);
 +    final String name = this.getUniqueName();
 +    final String regionName1 = name+"-1";
 +    final String regionName2 = name+"-2";
 +    final String regionName3 = name+"-3";
 +    final String key1 = "KEY-"+regionName1+"-1";
 +    final String key2 = "KEY-"+regionName1+"-2";
 +    final String key3 = "KEY-"+regionName1+"-3";
 +    final int[] ports = new int[3]; // 3 servers in this test
 +    
 +    // create first bridge server with region for client...
 +    final int firstServerIdx = 0;
 +    final VM firstServerVM = Host.getHost(0).getVM(firstServerIdx);
 +    firstServerVM.invoke(new CacheSerializableRunnable("Create first bridge server") {
 +      public void run2() throws CacheException {
 +        LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] Create first bridge server");
 +        getSystem();
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        Region region1 = createRootRegion(regionName1, factory.create());
 +        Region region2 = createRootRegion(regionName2, factory.create());
 +        Region region3 = createRootRegion(regionName3, factory.create());
 +        region1.put(key1, "VAL-1");
 +        region2.put(key2, "VAL-1");
 +        region3.put(key3, "VAL-1");
 +        
 +        try {
 +          bridgeServerPort = startBridgeServer(0);
 +        }
 +        catch (IOException e) {
 +          LogWriterUtils.getLogWriter().error("startBridgeServer threw IOException", e);
 +          fail("startBridgeServer threw IOException " + e.getMessage());
 +        }
 +        
 +        assertTrue(bridgeServerPort != 0);
 +    
 +        LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] " +
 +          "firstServer port=" + bridgeServerPort);
 +        LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] " +
 +          "firstServer memberId=" + getMemberId());
 +      }
 +    });
 +
 +    // create second bridge server missing region for client...
 +    final int secondServerIdx = 1;
 +    final VM secondServerVM = Host.getHost(0).getVM(secondServerIdx);
 +    secondServerVM.invoke(new CacheSerializableRunnable("Create second bridge server") {
 +      public void run2() throws CacheException {
 +        LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] Create second bridge server");
 +        getSystem();
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        Region region1 = createRootRegion(regionName1, factory.create());
 +        Region region3 = createRootRegion(regionName3, factory.create());
 +        region1.put(key1, "VAL-2");
 +        region3.put(key3, "VAL-2");
 +        
 +        try {
 +          bridgeServerPort = startBridgeServer(0);
 +        }
 +        catch (IOException e) {
 +          LogWriterUtils.getLogWriter().error("startBridgeServer threw IOException", e);
 +          fail("startBridgeServer threw IOException " + e.getMessage());
 +        }
 +        
 +        assertTrue(bridgeServerPort != 0);
 +    
 +        LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] " +
 +          "secondServer port=" + bridgeServerPort);
 +        LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] " +
 +          "secondServer memberId=" + getMemberId());
 +      }
 +    });
 +
 +    // get the bridge server ports...
-     ports[firstServerIdx] = firstServerVM.invokeInt(
-       ClientRegisterInterestDUnitTest.class, "getBridgeServerPort");
++    ports[firstServerIdx] = firstServerVM.invoke(() -> ClientRegisterInterestDUnitTest.getBridgeServerPort());
 +    assertTrue(ports[firstServerIdx] != 0);
-     ports[secondServerIdx] = secondServerVM.invokeInt(
-       ClientRegisterInterestDUnitTest.class, "getBridgeServerPort");
++    ports[secondServerIdx] = secondServerVM.invoke(() -> ClientRegisterInterestDUnitTest.getBridgeServerPort());
 +    assertTrue(ports[secondServerIdx] != 0);
 +    assertTrue(ports[firstServerIdx] != ports[secondServerIdx]);
 +    
 +    // stop second and third servers
 +    secondServerVM.invoke(new CacheSerializableRunnable("Stop second bridge server") {
 +      public void run2() throws CacheException {
 +        stopBridgeServers(getCache());
 +      }
 +    });
 +    
 +    // create the bridge client
 +    LogWriterUtils.getLogWriter().info("[testBug35654] create bridge client");
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    getSystem(config);
 +    getCache();
 +    
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +
 +    LogWriterUtils.getLogWriter().info("[testRegisterInterestFailover] creating connection pool");
 +    boolean establishCallbackConnection = true;
 +    final PoolImpl p = (PoolImpl)ClientServerTestCase.configureConnectionPool(factory, NetworkUtils.getServerHostName(host), ports, establishCallbackConnection, -1, -1, null);
 +
 +    final Region region1 = createRootRegion(regionName1, factory.create());
 +    final Region region2 = createRootRegion(regionName2, factory.create());
 +    final Region region3 = createRootRegion(regionName3, factory.create());
 +
 +    assertTrue(region1.getInterestList().isEmpty());
 +    assertTrue(region2.getInterestList().isEmpty());
 +    assertTrue(region3.getInterestList().isEmpty());
 +
 +    region1.registerInterest(key1);
 +    region2.registerInterest(key2);
 +    region3.registerInterest(key3);
 +
 +    assertTrue(region1.getInterestList().contains(key1));
 +    assertTrue(region2.getInterestList().contains(key2));
 +    assertTrue(region3.getInterestList().contains(key3));
 +    
 +    assertTrue(region1.getInterestListRegex().isEmpty());
 +    assertTrue(region2.getInterestListRegex().isEmpty());
 +    assertTrue(region3.getInterestListRegex().isEmpty());
 +    
 +    // get ConnectionProxy and wait until connected to first server
 +    WaitCriterion ev = new WaitCriterion() {
 +      public boolean done() {
 +        return p.getPrimaryPort() != -1;
 +      }
 +      public String description() {
 +        return "primary port remained invalid";
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 10 * 1000, 200, true);
 +    assertEquals(ports[firstServerIdx], p.getPrimaryPort()); 
 +    
 +    // assert intial values
 +    assertEquals("VAL-1", region1.get(key1));
 +    assertEquals("VAL-1", region2.get(key2));
 +    assertEquals("VAL-1", region3.get(key3));
 +    
 +    // do puts on server1 and make sure values come thru for all 3 registrations
 +    firstServerVM.invoke(new CacheSerializableRunnable("Puts from first bridge server") {
 +      public void run2() throws CacheException {
 +        Region region1 = getCache().getRegion(regionName1);
 +        region1.put(key1, "VAL-1-1");
 +        Region region2 = getCache().getRegion(regionName2);
 +        region2.put(key2, "VAL-1-1");
 +        Region region3 = getCache().getRegion(regionName3);
 +        region3.put(key3, "VAL-1-1");
 +      }
 +    });
 +
 +    ev = new WaitCriterion() {
 +      public boolean done() {
 +        if (!"VAL-1-1".equals(region1.get(key1)) || 
 +            !"VAL-1-1".equals(region2.get(key2)) ||
 +            !"VAL-1-1".equals(region3.get(key3))
 +            ) return  false;
 +        return true;
 +      }
 +      public String description() {
 +        return null;
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 10 * 1000, 200, true);
 +    assertEquals("VAL-1-1", region1.get(key1));
 +    assertEquals("VAL-1-1", region2.get(key2));
 +    assertEquals("VAL-1-1", region3.get(key3));
 +    
 +    // force failover to server 2
 +    secondServerVM.invoke(new CacheSerializableRunnable("Start second bridge server") {
 +      public void run2() throws CacheException {
 +        try {
 +          startBridgeServer(ports[secondServerIdx]);
 +        }
 +        catch (IOException e) {
 +          LogWriterUtils.getLogWriter().error("startBridgeServer threw IOException", e);
 +          fail("startBridgeServer threw IOException " + e.getMessage());
 +        }
 +      }
 +    });
 +   
 +    firstServerVM.invoke(new CacheSerializableRunnable("Stop first bridge server") {
 +      public void run2() throws CacheException {
 +        stopBridgeServers(getCache());
 +      }
 +    });
 +
 +    // wait for failover to second server
 +    ev = new WaitCriterion() {
 +      public boolean done() {
 +        return ports[secondServerIdx] == p.getPrimaryPort();
 +      }
 +      public String description() {
 +        return "primary port never became " + ports[secondServerIdx];
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 100 * 1000, 200, true);
 +    
 +    try {
 +      assertEquals(null, region2.get(key2));
 +      fail("CacheLoaderException expected");
 +    }
 +    catch (com.gemstone.gemfire.cache.CacheLoaderException e) {
 +    }
 +  
 +    // region2 registration should be gone now
 +    // do puts on server2 and make sure values come thru for only 2 registrations
 +    secondServerVM.invoke(new CacheSerializableRunnable("Puts from second bridge server") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRootRegion(regionName2, factory.create());
 +      }
 +    });
 +    
 +    // assert that there is no actively registered interest on region2
 +    assertTrue(region2.getInterestList().isEmpty());
 +    assertTrue(region2.getInterestListRegex().isEmpty());
 +
 +    region2.put(key2, "VAL-0");
 +    
 +    secondServerVM.invoke(new CacheSerializableRunnable("Put from second bridge server") {
 +      public void run2() throws CacheException {
 +        Region region1 = getCache().getRegion(regionName1);
 +        region1.put(key1, "VAL-2-2");
 +        Region region2 = getCache().getRegion(regionName2);
 +        region2.put(key2, "VAL-2-1");
 +        Region region3 = getCache().getRegion(regionName3);
 +        region3.put(key3, "VAL-2-2");
 +      }
 +    });
 +    
 +    // wait for updates to come thru
 +    ev = new WaitCriterion() {
 +      public boolean done() {
 +        if (!"VAL-2-2".equals(region1.get(key1)) || 
 +            !"VAL-2-2".equals(region3.get(key3)))
 +          return false;
 +        return true;
 +      }
 +      public String description() {
 +        return null;
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 100 * 1000, 200, true);
 +    assertEquals("VAL-2-2", region1.get(key1));
 +    assertEquals("VAL-0",   region2.get(key2));
 +    assertEquals("VAL-2-2", region3.get(key3));
 +
 +    // assert again that there is no actively registered interest on region2
 +    assertTrue(region2.getInterestList().isEmpty());
 +
 +    // register interest again on region2 and make
 +    region2.registerInterest(key2);
 +    assertEquals("VAL-2-1", region2.get(key2));
 +    
 +    secondServerVM.invoke(new CacheSerializableRunnable("Put from second bridge server") {
 +      public void run2() throws CacheException {
 +        Region region1 = getCache().getRegion(regionName1);
 +        region1.put(key1, "VAL-2-3");
 +        Region region2 = getCache().getRegion(regionName2);
 +        region2.put(key2, "VAL-2-2");
 +        Region region3 = getCache().getRegion(regionName3);
 +        region3.put(key3, "VAL-2-3");
 +      }
 +    });
 +    
 +    // wait for updates to come thru
 +    ev = new WaitCriterion() {
 +      public boolean done() {
 +        if (!"VAL-2-3".equals(region1.get(key1)) || 
 +            !"VAL-2-2".equals(region2.get(key2)) ||
 +            !"VAL-2-3".equals(region3.get(key3)))
 +          return false;
 +        return true;
 +      }
 +      public String description() {
 +        return null;
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 100 * 1000, 200, true);
 +    assertEquals("VAL-2-3", region1.get(key1));
 +    assertEquals("VAL-2-2", region2.get(key2));
 +    assertEquals("VAL-2-3", region3.get(key3));
 +
 +    // assert public methods report actively registered interest on region2
 +    assertTrue(region2.getInterestList().contains(key2));
 +  }
 +  
 +}
 +



[028/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheServerHelper.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheServerHelper.java
index b120b57,0000000..b0b0be1
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheServerHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheServerHelper.java
@@@ -1,187 -1,0 +1,193 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
 +
++import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.Version;
++import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.util.BlobHelper;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.ByteArrayOutputStream;
 +import java.io.IOException;
 +import java.io.ObjectInputStream;
 +import java.io.ObjectOutputStream;
 +import java.io.UTFDataFormatException;
 +import java.io.UnsupportedEncodingException;
 +
 +import java.util.zip.GZIPInputStream;
 +import java.util.zip.GZIPOutputStream;
 +
 +/**
 + * <code>CacheServerHelper</code> is a static class that provides helper methods
 + * for the CacheServer classes.
 + *
 + * @author Barry Oglesby
 + * @since 3.5
 + */
- public class CacheServerHelper
-   {
-   public static byte[] serialize(Object obj) throws IOException
-   {
++public class CacheServerHelper {
++  
++  public static void setIsDefaultServer(CacheServer server) {
++    if (server instanceof CacheServerImpl) {
++      ((CacheServerImpl)server).setIsDefaultServer();
++    }
++  }
++  
++  public static boolean isDefaultServer(CacheServer server) {
++    if ( !(server instanceof CacheServerImpl) ) {
++      return false;
++    }
++    return ((CacheServerImpl)server).isDefaultServer();
++  }
++  
++  public static byte[] serialize(Object obj) throws IOException {
 +    return serialize(obj, false);
 +  }
 +
-   public static byte[] serialize(Object obj, boolean zipObject) throws IOException
-   {
++  public static byte[] serialize(Object obj, boolean zipObject) throws IOException {
 +    return zipObject
 +      ? zip(obj)
 +      : BlobHelper.serializeToBlob(obj);
 +  }
 +
-   public static Object deserialize(byte[] blob) throws IOException, ClassNotFoundException
-   {
++  public static Object deserialize(byte[] blob) throws IOException, ClassNotFoundException {
 +    return deserialize(blob, false);
 +  }
 +
-   public static Object deserialize(byte[] blob, boolean unzipObject) throws IOException, ClassNotFoundException
-   {
++  public static Object deserialize(byte[] blob, boolean unzipObject) throws IOException, ClassNotFoundException {
 +    return unzipObject
 +      ? unzip(blob)
 +      : BlobHelper.deserializeBlob(blob);
 +  }
 +
-   public static Object deserialize(byte[] blob, Version version, boolean unzipObject) throws IOException, ClassNotFoundException
-   {
++  public static Object deserialize(byte[] blob, Version version, boolean unzipObject) throws IOException, ClassNotFoundException {
 +    return unzipObject
 +      ? unzip(blob)
 +      : BlobHelper.deserializeBlob(blob, version, null);
 +  }
 +  
-   public static byte[] zip(Object obj) throws IOException
-   {
++  public static byte[] zip(Object obj) throws IOException {
 +//logger.info("CacheServerHelper: Zipping object to blob: " + obj);
 +    ByteArrayOutputStream baos = new ByteArrayOutputStream();
 +    GZIPOutputStream gz = new GZIPOutputStream(baos);
 +    ObjectOutputStream oos = new ObjectOutputStream(gz);
 +    oos.writeObject(obj);
 +    oos.flush();
 +    oos.close();
 +    byte[] blob = baos.toByteArray();
 +//logger.info("CacheServerHelper: Zipped object to blob: " + blob);
 +    return blob;
 +  }
 +
-   public static Object unzip(byte[] blob) throws IOException, ClassNotFoundException
-   {
++  public static Object unzip(byte[] blob) throws IOException, ClassNotFoundException {
 +//logger.info("CacheServerHelper: Unzipping blob to object: " + blob);
 +    ByteArrayInputStream bais = new ByteArrayInputStream(blob);
 +    GZIPInputStream gs = new GZIPInputStream(bais);
 +    ObjectInputStream ois = new ObjectInputStream(gs);
 +    Object obj = ois.readObject();
 +//logger.info("CacheServerHelper: Unzipped blob to object: " + obj);
 +    ois.close();
 +    bais.close();
 +    return obj;
 +  }
 +
 +
 +  /**
 +   * The logic used here is based on java's DataInputStream.writeUTF() from the version 1.6.0_10.
 +   * 
 +   * @param s
 +   * @return byte[]
 +   */
-   public static byte[] toUTF(String s)
-   {
++  public static byte[] toUTF(String s) {
 +    HeapDataOutputStream hdos = new HeapDataOutputStream(s);
 +    return hdos.toByteArray();
 +  }
 +
 +  /**
 +   * The logic used here is based on java's DataInputStream.readUTF() from the version 1.6.0_10.
 +   * @param bytearr
 +   * @return String 
 +   */
-   public static String fromUTF(byte[] bytearr)
-   {
++  public static String fromUTF(byte[] bytearr) {
 +    int utflen = bytearr.length;
 +    int c, char2, char3;
 +    int count = 0;
 +    int chararr_count=0;
 +
 +    char[] chararr = new char[utflen];
 +
 +    while (count < utflen) {
 +      c = (int) bytearr[count] & 0xff;
 +      if (c > 127) break;
 +      count++;
 +      chararr[chararr_count++]=(char)c;
 +    }
 +
 +    while (count < utflen) {
 +      c = (int) bytearr[count] & 0xff;
 +      switch (c >> 4) {
 +        case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
 +          /* 0xxxxxxx*/
 +          count++;
 +          chararr[chararr_count++]=(char)c;
 +          break;
 +        case 12: case 13:
 +          /* 110x xxxx   10xx xxxx*/
 +          count += 2;
 +          if (count > utflen) {
 +            throw new RuntimeException(LocalizedStrings.CacheServerHelper_UTF8_EXCEPTION.toLocalizedString(), 
 +                new UTFDataFormatException("malformed input: partial character at end"));
 +          }
 +          char2 = (int) bytearr[count-1];
 +          if ((char2 & 0xC0) != 0x80)
 +            throw new RuntimeException(
 +                "malformed input around byte " + count);
 +          chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
 +              (char2 & 0x3F));
 +          break;
 +        case 14:
 +          /* 1110 xxxx  10xx xxxx  10xx xxxx */
 +          count += 3;
 +          if (count > utflen){
 +            throw new RuntimeException(LocalizedStrings.CacheServerHelper_UTF8_EXCEPTION.toLocalizedString(), 
 +                new UTFDataFormatException("malformed input: partial character at end")); 
 +          }
 +          char2 = (int) bytearr[count-2];
 +          char3 = (int) bytearr[count-1];
 +          if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)){
 +            throw new RuntimeException(LocalizedStrings.CacheServerHelper_UTF8_EXCEPTION.toLocalizedString(), 
 +                new UTFDataFormatException("malformed input around byte " + (count-1)));
 +          }
 +          chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
 +              ((char2 & 0x3F) << 6)  |
 +              ((char3 & 0x3F) << 0));
 +          break;
 +        default:
 +          /* 10xx xxxx,  1111 xxxx */
 +          throw new RuntimeException(LocalizedStrings.CacheServerHelper_UTF8_EXCEPTION.toLocalizedString(), 
 +              new UTFDataFormatException("malformed input around byte " + count));
 +      }
 +    }
 +    // The number of chars produced may be less than utflen
 +    return new String(chararr, 0, chararr_count);
 +  }
 +
 +  private CacheServerHelper() {}
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
index f6866bf,0000000..4bfd44b
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
@@@ -1,1190 -1,0 +1,1100 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
 +
 +import java.io.EOFException;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.OutputStream;
 +import java.net.Socket;
 +import java.net.SocketTimeoutException;
 +import java.nio.ByteBuffer;
 +import java.nio.channels.SocketChannel;
 +import java.util.concurrent.Semaphore;
 +import java.util.concurrent.TimeUnit;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.SerializationException;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.SocketUtils;
 +import com.gemstone.gemfire.internal.Version;
- import com.gemstone.gemfire.internal.cache.CachedDeserializable;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.offheap.StoredObject;
- import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 +import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 +import com.gemstone.gemfire.internal.util.BlobHelper;
 +
 +/**
 + * This class encapsulates the wire protocol. It provides accessors to
 + * encode and decode a message and  serialize it out to the wire.
 + *
 + * <PRE>
 + * msgType       - int   - 4 bytes type of message, types enumerated below
 + *
 + * msgLength     - int - 4 bytes   total length of variable length payload
 + *
 + * numberOfParts - int - 4 bytes   number of elements (LEN-BYTE* pairs)
 + *                     contained in the payload. Message can
 + *                       be a multi-part message
 + *
 + * transId       - int - 4 bytes  filled in by the requestor, copied back into
 + *                    the response
 + *
-  * earlyAck      - byte- 1 byte   filled in by the requestor
++ * flags         - byte- 1 byte   filled in by the requestor
 + * len1
 + * part1
 + * .
 + * .
 + * .
 + * lenn
 + * partn
 + * </PRE>
 + *
 + * We read the fixed length 16 bytes into a byte[] and populate a bytebuffer
 + * We read the fixed length header tokens from the header
 + * parse the header and use information contained in there to read the payload.
 + *
 + * <P>
 + *
 + * See also <a href="package-summary.html#messages">package description</a>.
 + *
 + * @see com.gemstone.gemfire.internal.cache.tier.MessageType
 + *
-  * @author Sudhir Menon
-  * @since 2.0.2
 + */
 +public class Message  {
 +
 +  private static final Logger logger = LogService.getLogger();
 +  
-   @Override
-   public String toString() {
-     StringBuffer sb = new StringBuffer();
-     sb.append("type=" + MessageType.getString(msgType));
-     sb.append("; payloadLength=" + payloadLength);
-     sb.append("; numberOfParts=" + numberOfParts);
-     sb.append("; transactionId=" + transactionId);
-     //sb.append("; bufferLength=" + bufferLength);
-     sb.append("; currentPart=" + currentPart);
-     sb.append("; messageModified=" + messageModified);
-     sb.append("; earlyAck=" + earlyAck);
-     for (int i = 0; i < numberOfParts; i ++) {
-       sb.append("; part[" + i + "]={");
-       sb.append(this.partsList[i].toString());
-       sb.append("}");
-     }
-     return sb.toString();
-   }
++  private static final int PART_HEADER_SIZE = 5; // 4 bytes for length, 1 byte for isObject
++  
++  private static final int FIXED_LENGTH = 17;
++
++  private static final ThreadLocal<ByteBuffer> tlCommBuffer = new ThreadLocal<>();
 +
-   protected final static int FIXED_LENGTH = 17;
 +  protected int msgType;
 +  protected int payloadLength=0;
 +  protected int numberOfParts =0;
 +  protected int transactionId = TXManagerImpl.NOTX;
 +  protected int currentPart = 0;
 +  protected Part[] partsList = null;
 +  protected ByteBuffer cachedCommBuffer;
 +  protected Socket socket = null;
 +  protected SocketChannel sockCh = null;
 +  protected OutputStream os = null;
 +  protected InputStream is = null;
 +  protected boolean messageModified = true;
 +  /** is this message a retry of a previously sent message? */
 +  protected boolean isRetry;
-   private byte earlyAck = 0x00;
++  private byte flags = 0x00;
 +  protected MessageStats msgStats = null;
 +  protected ServerConnection sc = null;
-   private int MAX_DATA = -1;
++  private int maxIncomingMessageLength = -1;
 +  private Semaphore dataLimiter = null;
 +//  private int MAX_MSGS = -1;
 +  private Semaphore msgLimiter = null;
 +  private boolean hdrRead = false;  
 +  private int chunkSize = 1024;//Default Chunk Size.
 +
 +  protected Part securePart = null;
++  private boolean isMetaRegion = false;
++
 +
-   // These two statics are fields shoved into the earlyAck byte for transmission.
++  // These two statics are fields shoved into the flags byte for transmission.
 +  // The MESSAGE_IS_RETRY bit is stripped out during deserialization but the other
 +  // is left in place
 +  public static final byte MESSAGE_HAS_SECURE_PART = (byte)0x02;
 +  public static final byte MESSAGE_IS_RETRY = (byte)0x04;
 +  
 +  public static final byte MESSAGE_IS_RETRY_MASK = (byte)0xFB;
 +
 +  // Tentative workaround to avoid OOM stated in #46754.
 +  public static final ThreadLocal<Integer> messageType = new ThreadLocal<Integer>();
 +  
 +  Version version;
 +  
 +  /**
 +   * Creates a new message with the given number of parts
 +   */
 +  public Message(int numberOfParts, Version destVersion) {
 +    this.version = destVersion;
 +    Assert.assertTrue(destVersion != null, "Attempt to create an unversioned message");
 +    partsList = new Part[numberOfParts];
 +    this.numberOfParts = numberOfParts;
 +    for (int i=0;i<partsList.length;i++) {
 +      partsList[i] = new Part();
 +    }
 +  }
 +
 +  public boolean isSecureMode() {    
 +    return securePart != null;
 +  }
 +  
 +  public byte[] getSecureBytes()
 +    throws IOException, ClassNotFoundException {
 +    return (byte[])this.securePart.getObject();
 +  }
 +  
 +  public void setMessageType(int msgType) {
 +    this.messageModified = true;
 +    if (!MessageType.validate(msgType)) {
 +      throw new IllegalArgumentException(LocalizedStrings.Message_INVALID_MESSAGETYPE.toLocalizedString());
 +    }
 +    this.msgType = msgType;
 +  }
 +  
 +  public void setVersion(Version clientVersion) {
 +    this.version = clientVersion;
 +  }
 +
-   /**
-    * Sets whether this message is early-ack
-    * @param earlyAck whether this message is early-ack
-    */
-   public void setEarlyAck(boolean earlyAck) {
-     if (earlyAck) {
-       this.earlyAck = 0x01;
-     } else {
-       this.earlyAck = 0x00;
-     }
++  public void setMessageHasSecurePartFlag() {
++    this.flags = (byte)(this.flags | MESSAGE_HAS_SECURE_PART);
 +  }
- 
-   // TODO (ashetkar) To be removed later.
-   public void setEarlyAck(byte earlyAck) {
-     // Check that the passed in value is within the acceptable range.
-     if (0x00 <= earlyAck && earlyAck <= 0x02) {
-       this.earlyAck |= earlyAck;
-     }
++  
++  public void clearMessageHasSecurePartFlag() {
++    this.flags = (byte)(this.flags & MESSAGE_HAS_SECURE_PART);
 +  }
 +
-   /*
-    * public void setPayloadLength(int payloadLength) {
-      this.payloadLength = payloadLength;
-   }*/
- 
 +  /**
 +   *  Sets and builds the {@link Part}s that are sent
 +   *  in the payload of the Message
 +   * @param numberOfParts
 +   */
 +  public void setNumberOfParts(int numberOfParts) {
 +    //TODO:hitesh need to add security header here from server
 +    //need to insure it is not chunked message
 +    //should we look message type to avoid internal message like ping
 +    this.messageModified = true;
 +    this.currentPart=0;
 +    this.numberOfParts = numberOfParts;
 +    if (numberOfParts > this.partsList.length) {
 +      Part[] newPartsList = new Part[numberOfParts];
 +      for (int i=0;i<numberOfParts;i++) {
 +        if (i < this.partsList.length) {
 +          newPartsList[i] = this.partsList[i];
 +        } else {
 +          newPartsList[i] = new Part();
 +        }
 +      }
 +      this.partsList = newPartsList;
 +    }
 +  }
 +
 +  public void setTransactionId(int transactionId) {
 +    this.messageModified = true;
 +    this.transactionId = transactionId;
 +  }
 +  
 +  public void setIsRetry() {
 +    this.isRetry = true;
 +  }
 +  
 +  /**
 +   * This returns true if the message has been marked as having been previously
 +   * transmitted to a different server.
 +   */
 +  public boolean isRetry() {
 +    return this.isRetry;
 +  }
 +
 +  /*Sets size for HDOS chunk.*/
 +  public void setChunkSize(int chunkSize) {
 +    this.chunkSize = chunkSize;
 +  }
++  
++  /**
++   * When building a Message this will return the number of the
++   * next Part to be added to the message
++   */
++  public int getNextPartNumber() {
++    return this.currentPart;
++  }
 +
 +  public void addStringPart(String str) {
 +    if (str==null) {
 +      addRawPart((byte[])null, false);
 +    }
 +    else {
 +      HeapDataOutputStream hdos = new HeapDataOutputStream(str);
 +      this.messageModified = true;
 +      Part part = partsList[this.currentPart];
 +      part.setPartState(hdos, false);
 +      this.currentPart++;
 +    }
 +  }
 +
-   /**
-    * Sets whether or not a
-    * <code>DataOutputStream</code>/<code>DataOutputStream</code>
-    * should be used to send/receive data.
-       public void setUseDataStream (boolean useDataStream) {
-         this.useDataStream = useDataStream;
-     }
-    */
- 
 +  /*
 +   * Adds a new part to this message that contains a <code>byte</code>
 +   * array (as opposed to a serialized object).
 +   *
 +   * @see #addPart(byte[], boolean)
 +   */
 +  public void addBytesPart(byte[] newPart) {
 +    addRawPart(newPart, false);
 +  }
 +
 +  public void addStringOrObjPart(Object o) {
 +    if (o instanceof String || o == null) {
 +      addStringPart((String)o);
 +    } else {
 +      // Note even if o is a byte[] we need to serialize it.
 +      // This could be cleaned up but it would require C client code to change.
 +      serializeAndAddPart(o, false);
 +    }
 +  }
 +
-   public void addDeltaPart(HeapDataOutputStream hdos) { // TODO: Amogh- Should it be just DataOutput?
++  public void addDeltaPart(HeapDataOutputStream hdos) {
 +    this.messageModified = true;
 +    Part part = partsList[this.currentPart];
 +    part.setPartState(hdos, false);
 +    this.currentPart++;
 +  }
 +
 +  public void addObjPart(Object o) {
 +    addObjPart(o, false);
 +  }
 +  /**
 +   * Like addObjPart(Object) but also prefers to reference
 +   * objects in the part instead of copying them into a byte buffer.
 +   */
 +  public void addObjPartNoCopying(Object o) {
 +    if (o == null || o instanceof byte[]) {
 +      addRawPart((byte[])o, false);
 +    } else {
 +      serializeAndAddPartNoCopying(o);
 +    }
 +  }
 +  public void addObjPart(Object o, boolean zipValues) {
 +    if (o == null || o instanceof byte[]) {
 +      addRawPart((byte[])o, false);
 +    } else {
 +      serializeAndAddPart(o, zipValues);
 +    }
 +  }
 +  public void addPartInAnyForm(@Unretained Object o, boolean isObject) {
 +    if (o == null) {
 +      addRawPart((byte[])o, false);
 +    } else if (o instanceof byte[]) {
 +      addRawPart((byte[])o, isObject);
 +    } else if (o instanceof StoredObject) {
 +      // It is possible it is an off-heap StoredObject that contains a simple non-object byte[].
 +      this.messageModified = true;
 +      Part part = partsList[this.currentPart];
 +      part.setPartState((StoredObject)o, isObject);
 +      this.currentPart++;
 +    } else {
 +      serializeAndAddPart(o, false);
 +    }
 +  }
 +  
 +  private void serializeAndAddPartNoCopying(Object o) {
 +    HeapDataOutputStream hdos;
 +    Version v = version;
 +    if (version.equals(Version.CURRENT)){
 +      v = null;
 +    }
 +    // create the HDOS with a flag telling it that it can keep any byte[] or ByteBuffers/ByteSources passed to it.
 +    hdos = new HeapDataOutputStream(chunkSize, v, true);
 +    // TODO OFFHEAP: Change Part to look for an HDOS and just pass a reference to its DirectByteBuffer.
 +    // Then change HDOS sendTo(SocketChannel...) to use the GatheringByteChannel to write a bunch of bbs.
 +    // TODO OFFHEAP This code optimizes one part which works pretty good for getAll since all the values are
 +    // returned in one part. But the following seems even better...
 +    // BETTER: change Message to consolidate all the part hdos bb lists into a single bb array and have it do the GatheringByteChannel write.
 +    // Message can use slice for the small parts (msg header and part header) that are not in the parts data (its a byte array, Chunk, or HDOS).
 +    // EVEN BETTER: the message can have a single HDOS which owns a direct comm buffer. It can reserve space if it does not yet know the value to write (for example the size of the message or part).
 +    // If we write something to the HDOS that is direct then it does not need to be copied.
 +    // But large heap byte arrays will need to be copied to the hdos (the socket write does this anyway).
 +    // If the direct buffer is full then we can allocate another one. If a part is already in a heap byte array
 +    // then we could defer copying it by slicing the current direct bb and then adding the heap byte array
 +    // as bb using ByteBuffer.wrap. Once we have all the data in the HDOS we can finally generate the header
 +    // and then start working on sending the ByteBuffers to the channel. If we have room in a direct bb then
 +    // we can copy a heap bb to it. Otherwise we can write the bb ahead of it which would free up room to copy
 +    // the heap bb to the existing direct bb without needing to allocate extra direct bbs.
 +    // Delaying the flush uses more direct memory but reduces the number of system calls.
 +    try {
- //      logger.fine("hitesh before serializatino: " );
- //      
- //      if (o != null ){
- //        logger.fine("hitesh before serializatino: " + o.toString());
- //        logger.fine("hitesh before serializatino: " + o.getClass().getName());
- //      }
 +      BlobHelper.serializeTo(o, hdos);
 +    } catch (IOException ex) {
 +      throw new SerializationException("failed serializing object", ex);
 +    }
 +    this.messageModified = true;
 +    Part part = partsList[this.currentPart];
 +    part.setPartState(hdos, true);
 +    this.currentPart++;
 +    
 +  }
 +
 +  private void serializeAndAddPart(Object o, boolean zipValues) {
 +    if (zipValues) {
 +      throw new UnsupportedOperationException("zipValues no longer supported");    
 +      
- //       byte[] b = CacheServerHelper.serialize(o, zipValues);
- //       addRawPart(b, true);
 +    } else {
 +      HeapDataOutputStream hdos;
 +      Version v = version;
 +      if (version.equals(Version.CURRENT)){
 +        v = null;
 +      }
 +      hdos = new HeapDataOutputStream(chunkSize, v);
 +      try {
- //        logger.fine("hitesh before serializatino: " );
- //        
- //        if (o != null ){
- //          logger.fine("hitesh before serializatino: " + o.toString());
- //          logger.fine("hitesh before serializatino: " + o.getClass().getName());
- //        }
 +        BlobHelper.serializeTo(o, hdos);
 +      } catch (IOException ex) {
 +        throw new SerializationException("failed serializing object", ex);
 +      }
 +      this.messageModified = true;
 +      Part part = partsList[this.currentPart];
 +      part.setPartState(hdos, true);
 +      this.currentPart++;
 +    }
 +  }
 +
 +  public void addIntPart(int v) {
 +    this.messageModified = true;
 +    Part part = partsList[this.currentPart];
 +    part.setInt(v);
 +    this.currentPart++;
 +  }
 +  
 +  public void addLongPart(long v) {
 +    this.messageModified = true;
 +    Part part = partsList[this.currentPart];
 +    part.setLong(v);
 +    this.currentPart++;
 +  }
 +  
 +  /**
 +   * Adds a new part to this message that may contain a serialized
 +   * object.
 +   */
 +  public void addRawPart(byte[] newPart,boolean isObject) {
 +    this.messageModified = true;
 +    Part part = partsList[this.currentPart];
 +    part.setPartState(newPart, isObject);
 +    this.currentPart++;
 +  }
 +
 +  public int getMessageType() {
 +    return this.msgType;
 +  }
 +
 +  public int getPayloadLength() {
 +    return this.payloadLength;
 +  }
 +
 +  public int getHeaderLength() {
 +    return FIXED_LENGTH;
 +  }
 +
 +  public int getNumberOfParts() {
 +    return this.numberOfParts;
 +  }
 +
 +  public int getTransactionId() {
 +    return this.transactionId;
 +  }
 +  
 +  public Part getPart(int index) {
 +    if (index < this.numberOfParts) {
 +      Part p = partsList[index];
 +      if (this.version != null) {
 +        p.setVersion(this.version);
 +      }
 +      return p;
 +    }
 +    return null;
 +  }
 +
-   public boolean getEarlyAck() {
-     return this.earlyAck == 0x01 ? true: false;
-   }
- 
-   // TODO (ashetkar) To be removed
-   public byte getEarlyAckByte() {
-     return this.earlyAck;
-   }
- 
-   private static ThreadLocal tlCommBuffer = new ThreadLocal();
- 
 +  public static ByteBuffer setTLCommBuffer(ByteBuffer bb) {
-     ByteBuffer result = (ByteBuffer)tlCommBuffer.get();
++    ByteBuffer result = tlCommBuffer.get();
 +    tlCommBuffer.set(bb);
 +    return result;
 +  }
 +
 +  public ByteBuffer getCommBuffer() {
 +    if (this.cachedCommBuffer != null) {
 +      return this.cachedCommBuffer;
 +    }
 +    else {
-       return (ByteBuffer)tlCommBuffer.get();
++      return tlCommBuffer.get();
 +    }
 +  }
 +
 +  public void clear() {
 +    this.isRetry = false;
 +    int len = this.payloadLength;
 +    if (len != 0) {
 +      this.payloadLength = 0;
 +    }
 +    if (this.hdrRead) {
 +      if (this.msgStats != null) {
 +        this.msgStats.decMessagesBeingReceived(len);
 +      }
 +    }
-     if (this.socket != null) {
-       getCommBuffer().clear();
++    ByteBuffer buffer = getCommBuffer();
++    if (buffer != null) {
++      buffer.clear();
 +    }
 +    clearParts();
 +    if (len != 0 && this.dataLimiter != null) {
 +      this.dataLimiter.release(len);
 +      this.dataLimiter = null;
-       this.MAX_DATA = 0;
++      this.maxIncomingMessageLength = 0;
 +    }
 +    if (this.hdrRead) {
 +      if (this.msgLimiter != null) {
 +        this.msgLimiter.release(1);
 +        this.msgLimiter = null;
 +      }
 +      this.hdrRead = false;
 +    }
++    this.flags = 0;
 +  }
 +
 +  protected void packHeaderInfoForSending(int msgLen, boolean isSecurityHeader) {
-     //TODO:hitesh setting second bit of early ack for client 
++    //TODO:hitesh setting second bit of flags byte for client 
 +    //this is not require but this makes all changes easily at client side right now
 +    //just see this bit and process security header
-     byte eAck = this.earlyAck;
++    byte flagsByte = this.flags;
 +    if (isSecurityHeader) {
-       eAck |= MESSAGE_HAS_SECURE_PART;
++      flagsByte |= MESSAGE_HAS_SECURE_PART;
 +    }
 +    if (this.isRetry) {
-       eAck |= MESSAGE_IS_RETRY;
++      flagsByte |= MESSAGE_IS_RETRY;
 +    }
 +    getCommBuffer()
 +      .putInt(this.msgType)
 +      .putInt(msgLen)
 +      .putInt(this.numberOfParts)
 +      .putInt(this.transactionId)
-       .put(eAck);
++      .put(flagsByte);
 +  }
 +
-   private static final int PART_HEADER_SIZE = 5; // 4 bytes for length, 1 byte for isObject
-   
 +  protected Part getSecurityPart() {
 +    if (this.sc != null ) {
 +      //look types right put get etc
 +     return this.sc.updateAndGetSecurityPart(); 
 +    }
 +    return null;
 +  }
 +
 +  public void setSecurePart(byte[] bytes) {
 +    this.securePart = new Part();
 +    this.securePart.setPartState(bytes, false);
 +  }
 +
-   private boolean m_isMetaRegion = false;
- 
 +  public void setMetaRegion(boolean isMetaRegion) {
-     this.m_isMetaRegion = isMetaRegion;
++    this.isMetaRegion = isMetaRegion;
 +  }
 +
 +  public boolean getAndResetIsMetaRegion() {
-     boolean isMetaRegion = this.m_isMetaRegion;
-     this.m_isMetaRegion = false;
++    boolean isMetaRegion = this.isMetaRegion;
++    this.isMetaRegion = false;
 +    return isMetaRegion;
 +  }
 +
 +  /**
 +   * Sends this message out on its socket.
 +   */
 +  protected void sendBytes(boolean clearMessage) throws IOException {
 +    if (this.sc != null) {
 +      // Keep track of the fact that we are making progress.
 +      this.sc.updateProcessingMessage();
 +    }
 +    if (this.socket != null) {
 +      final ByteBuffer cb = getCommBuffer();
 +      if (cb == null) {
 +        throw new IOException("No buffer");
 +      }
 +      synchronized(cb) {
 +        int numOfSecureParts = 0;
 +        Part securityPart = this.getSecurityPart();
 +        boolean isSecurityHeader = false;
 +        
 +        if (securityPart != null) {
 +          isSecurityHeader = true;
 +          numOfSecureParts = 1;
 +        }
 +        else if (this.securePart != null) {
 +          // This is a client sending this message.
 +          securityPart = this.securePart;
 +          isSecurityHeader = true;
 +          numOfSecureParts = 1;          
 +        }
 +
-         //this.logger.fine("hitesh sendbytes forServer_SecurityPart " + numOfSecureParts);
 +        int totalPartLen = 0;
 +        for (int i=0;i<this.numberOfParts;i++){
 +          Part part = this.partsList[i];
 +          totalPartLen += part.getLength();
 +        }
 +
 +        if(numOfSecureParts == 1) {
 +          totalPartLen += securityPart.getLength();
 +        }
 +        int msgLen = (PART_HEADER_SIZE * (this.numberOfParts + numOfSecureParts)) + totalPartLen;
 +        cb.clear();
 +        packHeaderInfoForSending(msgLen, isSecurityHeader);
 +        for (int i=0;i<this.numberOfParts + numOfSecureParts;i++) {
 +          Part part = null;
 +          if(i == this.numberOfParts) {
 +            part = securityPart;
 +          }
 +          else {
 +            part = partsList[i];
 +          }
 +          if (cb.remaining() < PART_HEADER_SIZE) {
 +            flushBuffer();
 +          }
 +          int partLen = part.getLength();
 +          cb.putInt(partLen);
 +          cb.put(part.getTypeCode());
 +          if (partLen <= cb.remaining()) {
 +            part.sendTo(cb);
 +          } else {
 +            flushBuffer();
 +            // send partBytes
 +            if (this.sockCh != null) {
 +              part.sendTo(this.sockCh, cb);
 +            } else {
 +              part.sendTo(this.os, cb);
 +            }
 +            if (this.msgStats != null) {
 +              this.msgStats.incSentBytes(partLen);
 +            }
 +          }
 +        }
 +        if (cb.position() != 0) {
 +          flushBuffer();
 +        }
 +        this.messageModified = false;
 +        if (this.sockCh == null) {
 +          this.os.flush();
 +        }
 +      }
 +      if(clearMessage) {
 +        clearParts();
 +      }
 +    }
 +    else {
 +      throw new IOException(LocalizedStrings.Message_DEAD_CONNECTION.toLocalizedString());
 +    }
 +  }
 +
 +  protected void flushBuffer() throws IOException {
 +    final ByteBuffer cb = getCommBuffer();
 +    if (this.sockCh != null) {
 +      cb.flip();
 +      do {
 +        this.sockCh.write(cb);
 +      } while (cb.remaining() > 0);
 +    } else {
 +      this.os.write(cb.array(), 0, cb.position());
 +    }
 +    if (this.msgStats != null) {
 +      this.msgStats.incSentBytes(cb.position());
 +    }
 +    cb.clear();
 +  }
 +
 +  private void read()
 +  throws IOException {
 +    clearParts();
 +    //TODO:Hitesh ??? for server changes make sure sc is not null as this class also used by client :(
 +    readHeaderAndPayload();
 +  }
 +
 +  /**
 +   * Read the actual bytes of the header off the socket
 +   */
 +  protected final void fetchHeader() throws IOException {
 +    final ByteBuffer cb = getCommBuffer();
 +    cb.clear();
 +    // msgType is invalidated here and can be used as an indicator
 +    // of problems reading the message
 +    this.msgType = MessageType.INVALID;
 +
 +    int hdr = 0;
 +
 +    final int headerLength = getHeaderLength();
 +    if (this.sockCh != null) {
 +      cb.limit(headerLength);
 +      do {
 +        int bytesRead = this.sockCh.read(cb);
 +        //System.out.println("DEBUG: fetchHeader read " + bytesRead + " bytes commBuffer=" + cb);
 +        if (bytesRead == -1) {
 +          throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_HEADER.toLocalizedString());
 +        }
 +        if (this.msgStats != null) {
 +          this.msgStats.incReceivedBytes(bytesRead);
 +        }
 +      } while (cb.remaining() > 0);
 +      cb.flip();
 +    } else {
 +      do {
 +        int bytesRead = -1;
 +        try {
 +          bytesRead = this.is.read(cb.array(),hdr, headerLength-hdr);
 +        }
 +        catch (SocketTimeoutException e) {
 +//          bytesRead = 0;
 +          // TODO add a cancellation check
 +          throw e;
 +        }
 +        if (bytesRead == -1) {
 +          throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_HEADER.toLocalizedString());
 +        }
 +        hdr += bytesRead;
 +        if (this.msgStats != null) {
 +          this.msgStats.incReceivedBytes(bytesRead);
 +        }
 +      } while (hdr < headerLength);
 +
 +      // now setup the commBuffer for the caller to parse it
 +      cb.rewind();
 +    }
 +  }
 +
 +  private void readHeaderAndPayload()
 +  throws IOException {
 +    //TODO:Hitesh ???
 +    fetchHeader();
 +    final ByteBuffer cb = getCommBuffer();
 +    final int type = cb.getInt();
 +    final int len = cb.getInt();
 +    final int numParts = cb.getInt();
 +    final int txid = cb.getInt();
-     byte early = cb.get();
++    byte bits = cb.get();
 +    cb.clear();
 +
 +    if (!MessageType.validate(type)) {
 +      throw new IOException(LocalizedStrings.Message_INVALID_MESSAGE_TYPE_0_WHILE_READING_HEADER.toLocalizedString(Integer.valueOf(type)));
 +    }
 +    int timeToWait = 0;
 +    if (this.sc != null) {
 +      // Keep track of the fact that a message is being processed.
 +      this.sc.setProcessingMessage();
 +      timeToWait = sc.getClientReadTimeout();
 +    }
 +    this.hdrRead = true;
 +    if (this.msgLimiter != null) {
 +        for (;;) {
 +          this.sc.getCachedRegionHelper().checkCancelInProgress(null);
 +          boolean interrupted = Thread.interrupted();
 +          try {
 +            if (timeToWait == 0) {
 +              this.msgLimiter.acquire(1);
 +            } 
 +            else {
 +              if (!this.msgLimiter.tryAcquire(1, timeToWait, TimeUnit.MILLISECONDS)) {
 +                if (this.msgStats != null
 +                    && this.msgStats instanceof CacheServerStats) {
 +                  ((CacheServerStats)this.msgStats).incConnectionsTimedOut();
 +                }
 +                throw new IOException(LocalizedStrings.Message_OPERATION_TIMED_OUT_ON_SERVER_WAITING_ON_CONCURRENT_MESSAGE_LIMITER_AFTER_WAITING_0_MILLISECONDS.toLocalizedString(Integer.valueOf(timeToWait)));
 +              }
 +            }
 +            break;
 +          }
 +          catch (InterruptedException e) {
 +            interrupted = true;
 +          }
 +          finally {
 +            if (interrupted) {
 +              Thread.currentThread().interrupt();
 +            }
 +          }
 +        } // for
 +    }
 +    if (len > 0) {
-       if (this.MAX_DATA > 0 && len > this.MAX_DATA) {
-         throw new IOException(LocalizedStrings.Message_MESSAGE_SIZE_0_EXCEEDED_MAX_LIMIT_OF_1.toLocalizedString(new Object[] {Integer.valueOf(len), Integer.valueOf(this.MAX_DATA)}));
++      if (this.maxIncomingMessageLength > 0 && len > this.maxIncomingMessageLength) {
++        throw new IOException(LocalizedStrings.Message_MESSAGE_SIZE_0_EXCEEDED_MAX_LIMIT_OF_1.toLocalizedString(new Object[] {Integer.valueOf(len), Integer.valueOf(this.maxIncomingMessageLength)}));
 +      }
 +      if (this.dataLimiter != null) {
 +        for (;;) {
 +          if (sc != null) {
 +            this.sc.getCachedRegionHelper().checkCancelInProgress(null);
 +          }
 +          boolean interrupted = Thread.interrupted();
 +          try {
 +            if (timeToWait == 0) {
 +              this.dataLimiter.acquire(len);
 +            } 
 +            else {
 +              int newTimeToWait = timeToWait;
 +              if (this.msgLimiter != null) {
 +                // may have waited for msg limit so recalc time to wait
 +                newTimeToWait -= (int)sc.getCurrentMessageProcessingTime();
 +              }
 +              if (newTimeToWait <= 0 || !this.msgLimiter.tryAcquire(1, newTimeToWait, TimeUnit.MILLISECONDS)) {
 +                throw new IOException(LocalizedStrings.Message_OPERATION_TIMED_OUT_ON_SERVER_WAITING_ON_CONCURRENT_DATA_LIMITER_AFTER_WAITING_0_MILLISECONDS.toLocalizedString(timeToWait));
 +              }
 +            }
 +            this.payloadLength = len; // makes sure payloadLength gets set now so we will release the semaphore
 +            break; // success
 +          }
 +          catch (InterruptedException e) {
 +            interrupted = true;
 +          }
 +          finally {
 +            if (interrupted) {
 +              Thread.currentThread().interrupt();
 +            }
 +          }
 +        }
 +      }
 +    }
 +    if (this.msgStats != null) {
 +      this.msgStats.incMessagesBeingReceived(len);
 +      this.payloadLength = len; // makes sure payloadLength gets set now so we will dec on clear
 +    }
 +    
-     this.isRetry = (early & MESSAGE_IS_RETRY) != 0;
-     early = (byte)(early & MESSAGE_IS_RETRY_MASK);
- 
-     //TODO:hitesh it was below ??
-     this.earlyAck = early;
++    this.isRetry = (bits & MESSAGE_IS_RETRY) != 0;
++    bits = (byte)(bits & MESSAGE_IS_RETRY_MASK);
++    this.flags = bits;
++    // TODO why is the msgType set twice, here and after reading the payload fields?
 +    this.msgType = type;
-     //this.logger.fine("Before reading message parts, earlyAck already read as " + this.earlyAck);
++
 +    readPayloadFields(numParts, len);
 +
 +    // Set the header and payload fields only after receiving all the
 +    // socket data, providing better message consistency in the face
 +    // of exceptional conditions (e.g. IO problems, timeouts etc.)
 +    this.msgType = type;
 +    this.payloadLength = len;
 +    // this.numberOfParts = numParts;  Already set in setPayloadFields via setNumberOfParts
 +    this.transactionId = txid;
-     this.earlyAck = early;
++    this.flags = bits;
 +    if (this.sc != null) {
 +      // Keep track of the fact that a message is being processed.
 +      this.sc.updateProcessingMessage();
 +    }
 +  }
 +
- //   static final int MAX_PART_BUFFERS = 2;
- //   static final int MIN_PART_BUFFER_SIZE = 999;
- //   static final int MAX_PART_BUFFER_SIZE = 1024*1024*11;
- //   static ArrayList partBuffers = new ArrayList(2);
- //   static int partBufferIdx = 0;
- //   static {
- //     for (int i=0; i < MAX_PART_BUFFERS; i++) {
- //       partBuffers.add(i, null);
- //     }
- //   }
- 
- //   private static synchronized byte[] getPartBuffer(int size) {
- //     byte[] result;
- //     synchronized (partBuffers) {
- //       result = (byte[])partBuffers.get(partBufferIdx);
- //       if (result == null) {
- //         result = new byte[size];
- //         partBuffers.add(partBufferIdx, result);
- //       } else if (result.length != size) {
- //         // can't use a cached one
- //         return null;
- //       }
- //       partBufferIdx++;
- //       if (partBufferIdx >= MAX_PART_BUFFERS) {
- //         partBufferIdx = 0;
- //       }
- //     }
- //     return result;
- //   }
- 
 +  protected void readPayloadFields(final int numParts, final int len)
 +  throws IOException {
 +    //TODO:Hitesh
 +    if (len > 0 && numParts <= 0 ||
 +        len <= 0 && numParts > 0) {
 +      throw new IOException(LocalizedStrings.Message_PART_LENGTH_0_AND_NUMBER_OF_PARTS_1_INCONSISTENT.toLocalizedString(
 +            new Object[] {Integer.valueOf(len), Integer.valueOf(numParts)}));
 +    }
 +
 +    Integer msgType = messageType.get();
 +    if (msgType != null && msgType == MessageType.PING) {
 +      messageType.set(null); // set it to null right away.
 +      int pingParts = 10; // Some number which will not throw OOM but still be acceptable for a ping operation.
 +      if (numParts > pingParts) {
 +        throw new IOException("Part length ( " + numParts
 +            + " ) is  inconsistent for " + MessageType.getString(msgType)
 +            + " operation.");
 +      }
 +    }
 +    setNumberOfParts(numParts);
 +    if (numParts <= 0)
 +      return;
 +  
 +    if (len < 0) {
 +      logger.info(LocalizedMessage.create(LocalizedStrings.Message_RPL_NEG_LEN__0, len));
 +      throw new IOException(LocalizedStrings.Message_DEAD_CONNECTION.toLocalizedString());
 +    }    
 +    
 +    final ByteBuffer cb = getCommBuffer();
 +    cb.clear();
 +    cb.flip();
 +
 +    int readSecurePart = 0;
 +    //TODO:Hitesh look if securePart can be cached here
-     //this.logger.fine("readPayloadFields() early ack = " + this.earlyAck);
 +    readSecurePart = checkAndSetSecurityPart();
 +    
 +    int bytesRemaining = len;
-     //this.logger.fine("readPayloadFields() : numParts=" + numParts + " len=" + len);
 +    for (int i = 0; ((i < numParts + readSecurePart) || ((readSecurePart == 1) && (cb
 +        .remaining() > 0))); i++) {
 +      int bytesReadThisTime = readPartChunk(bytesRemaining);
 +      bytesRemaining -= bytesReadThisTime;
 +
 +      Part part;
 +      
 +      if(i < numParts) {
 +        part = this.partsList[i];
 +      }
 +      else {
 +        part = this.securePart;
 +      }
 +      
 +      int partLen = cb.getInt();
 +      byte partType = cb.get();
 +      byte[] partBytes = null;
- //      this.logger.fine("readPayloadFields(): partLen=" + partLen + " partType=" + partType);
 +      if (partLen > 0) {
- //         if (partLen >= MIN_PART_BUFFER_SIZE && partLen <= MAX_PART_BUFFER_SIZE) {
- //           partBytes = getPartBuffer(partLen);
- //         }
- //         if (partBytes == null) {
-           partBytes = new byte[partLen];
- //         }
++        partBytes = new byte[partLen];
 +        int alreadyReadBytes = cb.remaining();
 +        if (alreadyReadBytes > 0) {
 +          if (partLen < alreadyReadBytes) {
 +            alreadyReadBytes = partLen;
 +          }
 +          cb.get(partBytes, 0, alreadyReadBytes);
 +        }
 +        // now we need to read partLen - alreadyReadBytes off the wire
 +        int off = alreadyReadBytes;
 +        int remaining = partLen - off;
 +        while (remaining > 0) {
 +          if (this.sockCh != null) {
 +            int bytesThisTime = remaining;
 +            cb.clear();
 +            if (bytesThisTime > cb.capacity()) {
 +              bytesThisTime = cb.capacity();
 +            }
 +            cb.limit(bytesThisTime);
 +            int res = this.sockCh.read(cb);
-             //System.out.println("DEBUG: part read " + res + " bytes commBuffer=" + cb);
 +            if (res != -1) {
 +              cb.flip();
 +              bytesRemaining -= res;
 +              remaining -= res;
 +              cb.get(partBytes, off, res);
 +              off += res;
 +              if (this.msgStats != null) {
 +                this.msgStats.incReceivedBytes(res);
 +              }
 +            } else {
 +              throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_A_PART.toLocalizedString());
 +            }
 +          } else {
 +            int res = 0;
 +            try {
 +              res = this.is.read(partBytes, off, remaining);
 +            }
 +            catch (SocketTimeoutException e) {
- //              res = 0;
 +              // TODO: add cancellation check
 +              throw e;
 +            }
 +            if (res != -1) {
 +              bytesRemaining -= res;
 +              remaining -= res;
 +              off += res;
 +              if (this.msgStats != null) {
 +                this.msgStats.incReceivedBytes(res);
 +              }
 +            } else {
 +              throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_A_PART.toLocalizedString());
 +            }
 +          }
 +        }
 +      }
 +      part.init(partBytes, partType);
 +    }
 +  }
 +
 +  protected int checkAndSetSecurityPart() {
-     if ((this.earlyAck | MESSAGE_HAS_SECURE_PART) == this.earlyAck) {
++    if ((this.flags | MESSAGE_HAS_SECURE_PART) == this.flags) {
 +      this.securePart = new Part();
 +      return 1;
 +    }
 +    else {
 +      this.securePart = null;
 +      return 0;
 +    }
 +  }
 +
 +  /**
 +   * @param bytesRemaining the most bytes we can read
 +   * @return the number of bytes read into commBuffer
 +   */
 +  private int readPartChunk(int bytesRemaining) throws IOException {
 +    final ByteBuffer cb = getCommBuffer();
-     //this.logger.info("DEBUG: commBuffer.remaining=" + cb.remaining());
 +    if (cb.remaining() >= PART_HEADER_SIZE) {
 +      // we already have the next part header in commBuffer so just return
 +      return 0;
 +    }
 +    if (cb.position() != 0) {
 +      cb.compact();
 +    } else {
 +      cb.position(cb.limit());
 +      cb.limit(cb.capacity());
 +    }
 +    int bytesRead = 0;
 +    if (this.sc != null) {
 +      // Keep track of the fact that we are making progress
 +      this.sc.updateProcessingMessage();
 +    }
 +    if (this.sockCh != null) {
 +      int remaining = cb.remaining();
 +      if (remaining > bytesRemaining) {
 +        remaining = bytesRemaining;
 +        cb.limit(cb.position()+bytesRemaining);
 +      }
 +      while (remaining > 0) {
 +        int res = this.sockCh.read(cb);
-         //System.out.println("DEBUG: partChunk read " + res + " bytes commBuffer=" + cb);
 +        if (res != -1) {
 +          remaining -= res;
 +          bytesRead += res;
 +          if (this.msgStats != null) {
 +            this.msgStats.incReceivedBytes(res);
 +          }
 +        } else {
 +          throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_PAYLOAD.toLocalizedString());
 +        }
 +      }
 +
 +    } else {
 +      int bufSpace = cb.capacity() - cb.position();
 +      int bytesToRead = bufSpace;
 +      if (bytesRemaining < bytesToRead) {
 +        bytesToRead = bytesRemaining;
 +      }
 +      int pos = cb.position();
 +      while (bytesToRead > 0) {
 +        int res = 0;
 +        try {
 +          res = this.is.read(cb.array(), pos, bytesToRead);
 +        }
 +        catch (SocketTimeoutException e) {
- //          res = 0;
 +          // TODO add a cancellation check
 +          throw e;
 +        }
 +        if (res != -1) {
 +          bytesToRead -= res;
 +          pos += res;
 +          bytesRead += res;
 +          if (this.msgStats != null) {
 +            this.msgStats.incReceivedBytes(res);
 +          }
 +        } else {
 +          throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_PAYLOAD.toLocalizedString());
 +        }
 +      }
 +      cb.position(pos);
 +    }
 +    cb.flip();
 +    return bytesRead;
 +  }
 +
 +  /**
 +   * Gets rid of all the parts that have been added to this message.
 +   */
 +  public void clearParts() {
 +    for (int i=0; i< partsList.length; i++){
 +      partsList[i].clear();
 +    }
 +    this.currentPart=0;
 +  }
++
++  @Override
++  public String toString() {
++    StringBuffer sb = new StringBuffer();
++    sb.append("type=").append(MessageType.getString(msgType));
++    sb.append("; payloadLength=").append(payloadLength);
++    sb.append("; numberOfParts=").append(numberOfParts);
++    sb.append("; transactionId=").append(transactionId);
++    sb.append("; currentPart=").append(currentPart);
++    sb.append("; messageModified=").append(messageModified);
++    sb.append("; flags=").append(Integer.toHexString(flags));
++    for (int i = 0; i < numberOfParts; i ++) {
++      sb.append("; part[").append(i).append("]={");
++      sb.append(this.partsList[i].toString());
++      sb.append("}");
++    }
++    return sb.toString();
++  }
++
++  
 +  public void setComms(ServerConnection sc, Socket socket, ByteBuffer bb, MessageStats msgStats) throws IOException {
 +    this.sc = sc;
 +    setComms(socket, bb, msgStats);
 +  }
 +
 +  public void setComms(Socket socket, ByteBuffer bb, MessageStats msgStats) throws IOException {
 +    this.sockCh = socket.getChannel();
 +    if (this.sockCh == null) {
 +      setComms(socket, SocketUtils.getInputStream(socket), SocketUtils.getOutputStream(socket), bb, msgStats);
 +    } else {
 +      setComms(socket, null, null,  bb, msgStats);
 +    }
 +  }
 +  
 +  public void setComms(Socket socket, InputStream is, OutputStream os, ByteBuffer bb, MessageStats msgStats)
 +    throws IOException
 +  {
 +    Assert.assertTrue(socket != null);
 +    this.socket = socket;
 +    this.sockCh = socket.getChannel();
 +    this.is = is;
 +    this.os = os;
 +    this.cachedCommBuffer = bb;
 +    this.msgStats = msgStats;
 +  }
 +  /**
 +   * Undo any state changes done by setComms.
 +   * @since 5.7
 +   */
 +  public void unsetComms() {
 +    this.socket = null;
 +    this.sockCh = null;
 +    this.is = null;
 +    this.os = null;
 +    this.cachedCommBuffer = null;
 +    this.msgStats = null;
 +  }
 +
 +  /**
 +   * Sends this message to its receiver over its
 +   * setOutputStream?? output stream.
 +   */
 +  public void send()
 +  throws IOException {
 +    send(true);
 +  }
 +  
 +  public void send(ServerConnection servConn)
 +  throws IOException {
 +    if (this.sc != servConn) throw new IllegalStateException("this.sc was not correctly set");
 +    send(true);
 +  }
 +  
 +  /**
 +   * Sends this message to its receiver over its
 +   * setOutputStream?? output stream.
 +   */
 +  public void send(boolean clearMessage)
 +  throws IOException {
 +    sendBytes(clearMessage);
 +  }
 +
 +  /**
 +   *  Populates the stats of this <code>Message</code> with information
 +   *  received via its socket
 +   */
 +  public void recv()
 +  throws IOException {
 +    if (this.socket != null) {
 +      synchronized(getCommBuffer()) {
 +        read();
 +      }
 +    }
 +    else {
 +      throw new IOException(LocalizedStrings.Message_DEAD_CONNECTION.toLocalizedString());
 +    }
 +  }
-   public void recv(ServerConnection sc, int MAX_DATA, Semaphore dataLimiter, int MAX_MSGS, Semaphore msgLimiter)
++  public void recv(ServerConnection sc, int maxMessageLength, Semaphore dataLimiter, Semaphore msgLimiter)
 +  throws IOException {
 +    this.sc = sc;
-     this.MAX_DATA = MAX_DATA;
++    this.maxIncomingMessageLength = maxMessageLength;
 +    this.dataLimiter = dataLimiter;
- //    this.MAX_MSGS = MAX_MSGS;
 +    this.msgLimiter = msgLimiter;
 +    recv();
 +  }
 +
-   public boolean canStartRemoteTransaction() {
-     return true;
-   }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
index 5418c68,0000000..f5f6326
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
@@@ -1,457 -1,0 +1,452 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
 +
 +import com.gemstone.gemfire.internal.*;
 +import com.gemstone.gemfire.internal.cache.CachedDeserializable;
 +import com.gemstone.gemfire.internal.offheap.Chunk;
 +import com.gemstone.gemfire.internal.offheap.DataAsAddress;
 +import com.gemstone.gemfire.internal.offheap.StoredObject;
 +import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
 +
 +import java.io.*;
 +import java.nio.*;
 +import java.nio.channels.*;
 +
 +/**
 + * Represents one unit of information (essentially a <code>byte</code>
 + * array) in the wire protocol.  Each server connection runs in its
 + * own thread to maximize concurrency and improve response times to
 + * edge requests
 + *
 + * @see Message
 + *
 + * @author Sudhir Menon
 + * @since 2.0.2
 + */
 +public class Part {
 +  private static final byte BYTE_CODE = 0;
 +  private static final byte OBJECT_CODE = 1;
 +  
 +  private Version version;
 +  /**
 +   * Used to represent and empty byte array for bug 36279
 +   * @since 5.1
 +   */
 +  private static final byte EMPTY_BYTEARRAY_CODE = 2;
 +  private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
 +
 +  /** The payload of this part.
 +   * Could be null, a byte[] or a HeapDataOutputStream on the send side.
 +   * Could be null, or a byte[] on the receiver side.
 +   */
 +  private Object part;
 +
 +  /** Is the payload (<code>part</code>) a serialized object? */
 +  private byte typeCode;
 +
 +  public void init(byte[] v, byte tc) {
 +    if (tc == EMPTY_BYTEARRAY_CODE) {
 +      this.part = EMPTY_BYTE_ARRAY;
 +    }
 +    else {
 +      this.part = v;
 +    }
 +    this.typeCode = tc;
 +  }
 +
- //   public void init(HeapDataOutputStream os, byte typeCode) {
- //     this.part = os;
- //     this.typeCode = typeCode;
- //   }
 +
 +  public void clear() {
 +    this.part = null;
 +    this.typeCode = BYTE_CODE;
 +  }
 +
 +  public boolean isNull() {
 +    if (this.part == null) {
 +      return true;
 +    }
 +    if (isObject() && this.part instanceof byte[]) {
 +      byte[] b = (byte[])this.part;
 +      if (b.length == 1 && b[0] == DSCODE.NULL) {
 +        return true;
 +      }
 +    }
 +    return false;
 +  }
 +  public boolean isObject() {
 +    return this.typeCode == OBJECT_CODE;
 +  }
 +  public boolean isBytes() {
 +    return this.typeCode == BYTE_CODE || this.typeCode == EMPTY_BYTEARRAY_CODE;
 +  }
- //   public boolean isString() {
- //     return this.typeCode == STRING_CODE;
- //   }
++
 +  public void setPartState(byte[] b, boolean isObject) {
 +    if (isObject) {
 +      this.typeCode = OBJECT_CODE;
 +    } else if (b != null && b.length == 0) {
 +      this.typeCode = EMPTY_BYTEARRAY_CODE;
 +      b = EMPTY_BYTE_ARRAY;
 +    } else {
 +      this.typeCode = BYTE_CODE;
 +    }
 +    this.part = b;
 +  }
++  
 +  public void setPartState(HeapDataOutputStream os, boolean isObject) {
 +    if (isObject) {
 +      this.typeCode = OBJECT_CODE;
 +      this.part = os;
 +    } else if (os != null && os.size() == 0) {
 +      this.typeCode = EMPTY_BYTEARRAY_CODE;
 +      this.part = EMPTY_BYTE_ARRAY;
 +    } else {
 +      this.typeCode = BYTE_CODE;
 +      this.part = os;
 +    }
 +  }
 +  public void setPartState(StoredObject so, boolean isObject) {
 +    if (isObject) {
 +      this.typeCode = OBJECT_CODE;
 +    } else if (so.getValueSizeInBytes() == 0) {
 +      this.typeCode = EMPTY_BYTEARRAY_CODE;
 +      this.part = EMPTY_BYTE_ARRAY;
 +      return;
 +    } else {
 +      this.typeCode = BYTE_CODE;
 +    }
 +    if (so instanceof DataAsAddress) {
 +      this.part = ((DataAsAddress)so).getRawBytes();
 +    } else {
 +      this.part = (Chunk)so;
 +    }
 +  }
 +  public byte getTypeCode() {
 +    return this.typeCode;
 +  }
 +  /**
 +   * Return the length of the part. The length is the number of bytes needed
 +   * for its serialized form.
 +   */
 +  public int getLength() {
 +    if (this.part == null) {
 +      return 0;
 +    } else if (this.part instanceof byte[]) {
 +      return ((byte[])this.part).length;
 +    } else if (this.part instanceof Chunk) {
 +      return ((Chunk) this.part).getValueSizeInBytes();
 +    } else {
 +      return ((HeapDataOutputStream)this.part).size();
 +    }
 +  }
 +  public String getString() {
 +    if (this.part == null) {
 +      return null;
 +    }
 +    if (!isBytes()) {
 +      Assert.assertTrue(false, "expected String part to be of type BYTE, part ="
 +          + this.toString());
 +    }
 +    return CacheServerHelper.fromUTF((byte[])this.part);
 +  }
 +  
 +  public int getInt() {
 +    if (!isBytes()) {
 +      Assert.assertTrue(false, "expected int part to be of type BYTE, part = "
 +          + this.toString()); 
 +    }
 +    if (getLength() != 4) {
 +      Assert.assertTrue(false, 
 +          "expected int length to be 4 but it was " + getLength()
 +          + "; part = " + this.toString());
 +    }
 +    byte[] bytes = getSerializedForm();
 +    return decodeInt(bytes, 0);
 +  }
 +
 +  public static int decodeInt(byte[] bytes, int offset) {
 +    return (((bytes[offset + 0]) << 24) & 0xFF000000)
 +        | (((bytes[offset + 1]) << 16) & 0x00FF0000)
 +        | (((bytes[offset + 2]) << 8) & 0x0000FF00)
 +        | ((bytes[offset + 3]) & 0x000000FF);
 +  }
 +
 +  public void setInt(int v) {
 +    byte[] bytes = new byte[4];
 +    encodeInt(v, bytes);
 +    this.typeCode = BYTE_CODE;
 +    this.part = bytes;
 +  }
 +
 +  /**
 +   * @since 5.7
 +   */
 +  public static void encodeInt(int v, byte[] bytes) {
 +    encodeInt(v, bytes, 0);
 +  }
 +
 +  public static void encodeInt(int v, byte[] bytes, int offset) {
 +    // encode an int into the given byte array
 +    bytes[offset + 0] = (byte) ((v & 0xFF000000) >> 24);
 +    bytes[offset + 1] = (byte) ((v & 0x00FF0000) >> 16);
 +    bytes[offset + 2] = (byte) ((v & 0x0000FF00) >> 8 );
 +    bytes[offset + 3] = (byte) (v & 0x000000FF);
 +  }
 +  
 +  public void setLong(long v) {
 +    byte[] bytes = new byte[8];
 +    bytes[0] = (byte) ((v & 0xFF00000000000000l) >> 56);
 +    bytes[1] = (byte) ((v & 0x00FF000000000000l) >> 48);
 +    bytes[2] = (byte) ((v & 0x0000FF0000000000l) >> 40);
 +    bytes[3] = (byte) ((v & 0x000000FF00000000l) >> 32);
 +    bytes[4] = (byte) ((v & 0x00000000FF000000l) >> 24);
 +    bytes[5] = (byte) ((v & 0x0000000000FF0000l) >> 16);
 +    bytes[6] = (byte) ((v & 0x000000000000FF00l) >>  8);
 +    bytes[7] = (byte) (v & 0xFF);
 +    this.typeCode = BYTE_CODE;
 +    this.part = bytes;
 +  }
 +
 +  public long getLong() {
 +    if (!isBytes()) {
 +      Assert.assertTrue(false, "expected long part to be of type BYTE, part = "
 +          + this.toString()); 
 +    }
 +    if (getLength() != 8) {
 +      Assert.assertTrue(false, 
 +          "expected long length to be 8 but it was " + getLength()
 +          + "; part = " + this.toString());
 +    }
 +    byte[] bytes = getSerializedForm();
 +    return ((((long)bytes[0]) << 56) & 0xFF00000000000000l) |
 +           ((((long)bytes[1]) << 48) & 0x00FF000000000000l) |
 +           ((((long)bytes[2]) << 40) & 0x0000FF0000000000l) |
 +           ((((long)bytes[3]) << 32) & 0x000000FF00000000l) |
 +           ((((long)bytes[4]) << 24) & 0x00000000FF000000l) |
 +           ((((long)bytes[5]) << 16) & 0x0000000000FF0000l) |
 +           ((((long)bytes[6]) <<  8) & 0x000000000000FF00l) |
 +           (        bytes[7]         & 0x00000000000000FFl);
 +  }
 +
 +
 +  public byte[] getSerializedForm() {
 +    if (this.part == null) {
 +      return null;
 +    } else if (this.part instanceof byte[]) {
 +      return (byte[])this.part;
 +    } else {
 +      return null; // should not be called on sender side?
 +    }
 +  }
 +  public Object getObject(boolean unzip) throws IOException, ClassNotFoundException {
 +    if (isBytes()) {
 +      return this.part;
 +    }
 +    else {
 +      if (this.version != null) {
 +        return CacheServerHelper.deserialize((byte[])this.part, this.version,
 +            unzip);
 +      }
 +      else {
 +        return CacheServerHelper.deserialize((byte[])this.part, unzip);
 +      }
 +    }
 +  }
 +  public Object getObject() throws IOException, ClassNotFoundException {
 +    return getObject(false);
 +  }
 +
 +  public Object getStringOrObject() throws IOException, ClassNotFoundException {
 +    if (isObject()) {
 +      return getObject();
 +    } else {
 +      return getString();
 +    }
 +  }
 +  
 +  /**
 +   * Write the contents of this part to the specified output stream.
 +   * This is only called for parts that will not fit into the commBuffer
 +   * so they need to be written directly to the stream.
 +   * A stream is used because the client is configured for old IO (instead of nio).
 +   * @param buf the buffer to use if any data needs to be copied to one
 +   */
 +  public final void sendTo(OutputStream out, ByteBuffer buf) throws IOException {
 +    if (getLength() > 0) {
 +      if (this.part instanceof byte[]) {
 +        byte[] bytes = (byte[])this.part;
 +        out.write(bytes, 0, bytes.length);
 +      } else if (this.part instanceof Chunk) {
 +        Chunk c = (Chunk) this.part;
 +        ByteBuffer cbb = c.createDirectByteBuffer();
 +        if (cbb != null) {
 +          HeapDataOutputStream.writeByteBufferToStream(out,  buf, cbb);
 +        } else {
 +          int bytesToSend = c.getDataSize();
 +          long addr = c.getAddressForReading(0, bytesToSend);
 +          while (bytesToSend > 0) {
 +            if (buf.remaining() == 0) {
 +              HeapDataOutputStream.flushStream(out,  buf);
 +            }
 +            buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
 +            addr++;
 +            bytesToSend--;
 +          }
 +        }
 +      } else {
 +        HeapDataOutputStream hdos = (HeapDataOutputStream)this.part;
 +        hdos.sendTo(out, buf);
 +        hdos.rewind();
 +      }
 +    }
 +  }
 +  /**
 +   * Write the contents of this part to the specified byte buffer.
 +   * Precondition: caller has already checked the length of this part
 +   * and it will fit into "buf".
 +   */
 +  public final void sendTo(ByteBuffer buf) {
 +    if (getLength() > 0) {
 +      if (this.part instanceof byte[]) {
 +        buf.put((byte[])this.part);
 +      } else if (this.part instanceof Chunk) {
 +        Chunk c = (Chunk) this.part;
 +        ByteBuffer bb = c.createDirectByteBuffer();
 +        if (bb != null) {
 +          buf.put(bb);
 +        } else {
 +          int bytesToSend = c.getDataSize();
 +          long addr = c.getAddressForReading(0, bytesToSend);
 +          while (bytesToSend > 0) {
 +            buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
 +            addr++;
 +            bytesToSend--;
 +          }
 +        }
 +      } else {
 +        HeapDataOutputStream hdos = (HeapDataOutputStream)this.part;
 +        hdos.sendTo(buf);
 +        hdos.rewind();
 +      }
 +    }
 +  }
 +  /**
 +   * Write the contents of this part to the specified socket channel
 +   * using the specified byte buffer.
 +   * This is only called for parts that will not fit into the commBuffer
 +   * so they need to be written directly to the socket.
 +   * Precondition: buf contains nothing that needs to be sent
 +   */
 +  public final void sendTo(SocketChannel sc, ByteBuffer buf) throws IOException {
 +    if (getLength() > 0) {
 +      final int BUF_MAX = buf.capacity();
 +      if (this.part instanceof byte[]) {
 +        final byte[] bytes = (byte[])this.part;
 +        int off = 0;
 +        int len = bytes.length;
 +        buf.clear();
 +        while (len > 0) {
 +          int bytesThisTime = len;
 +          if (bytesThisTime > BUF_MAX) {
 +            bytesThisTime = BUF_MAX;
 +          }
 +          buf.put(bytes, off, bytesThisTime);
 +          len -= bytesThisTime;
 +          off += bytesThisTime;
 +          buf.flip();
 +          while (buf.remaining() > 0) {
 +            sc.write(buf);
 +          }
 +          buf.clear();
 +        }
 +      } else if (this.part instanceof Chunk) {
 +        // instead of copying the Chunk to buf try to create a direct ByteBuffer and
 +        // just write it directly to the socket channel.
 +        Chunk c = (Chunk) this.part;
 +        ByteBuffer bb = c.createDirectByteBuffer();
 +        if (bb != null) {
 +          while (bb.remaining() > 0) {
 +            sc.write(bb);
 +          }
 +        } else {
 +          int len = c.getDataSize();
 +          long addr = c.getAddressForReading(0, len);
 +          buf.clear();
 +          while (len > 0) {
 +            int bytesThisTime = len;
 +            if (bytesThisTime > BUF_MAX) {
 +              bytesThisTime = BUF_MAX;
 +            }
 +            len -= bytesThisTime;
 +            while (bytesThisTime > 0) {
 +              buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
 +              addr++;
 +              bytesThisTime--;
 +            }
 +            buf.flip();
 +            while (buf.remaining() > 0) {
 +              sc.write(buf);
 +            }
 +            buf.clear();
 +          }
 +        }
 +      } else {
 +        HeapDataOutputStream hdos = (HeapDataOutputStream)this.part;
 +        hdos.sendTo(sc, buf);
 +        hdos.rewind();
 +      }
 +    }
 +  }
 +  
 +  static private String typeCodeToString(byte c) {
 +    switch (c) {
 +    case BYTE_CODE:
 +      return "BYTE_CODE";
 +    case OBJECT_CODE:
 +      return "OBJECT_CODE";
 +    case EMPTY_BYTEARRAY_CODE:
 +      return "EMPTY_BYTEARRAY_CODE";
 +    default:
 +      return "unknown code " + c;
 +    }
 +  }
 +
 +  @Override
 +  public String toString() {
 +    StringBuffer sb = new StringBuffer();
 +    sb.append("partCode=");
 +    sb.append(typeCodeToString(this.typeCode));
 +    sb.append(" partLength=" + getLength());
 +//    sb.append(" partBytes=");
 +//    byte[] b = getSerializedForm();
 +//    if (b == null) {
 +//      sb.append("null");
 +//    }
 +//    else {
 +//      sb.append("(");
 +//      for (int i = 0; i < b.length; i ++) {
 +//        sb.append(Integer.toString(b[i]));
 +//        sb.append(" ");
 +//      }
 +//      sb.append(")");
 +//    }
 +    return sb.toString();
 +  }
 +
 +  public void setVersion(Version clientVersion) {
 +    this.version = clientVersion;
 +  }
 +}


[020/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
index e90b724,0000000..1f7e7a9
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
@@@ -1,717 -1,0 +1,717 @@@
 +/*
 + * 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 com.gemstone.gemfire.redis;
 +
 +import io.netty.bootstrap.ServerBootstrap;
 +import io.netty.buffer.PooledByteBufAllocator;
 +import io.netty.channel.Channel;
 +import io.netty.channel.ChannelFuture;
 +import io.netty.channel.ChannelInitializer;
 +import io.netty.channel.ChannelOption;
 +import io.netty.channel.ChannelPipeline;
 +import io.netty.channel.EventLoopGroup;
 +import io.netty.channel.ServerChannel;
 +import io.netty.channel.nio.NioEventLoopGroup;
 +import io.netty.channel.oio.OioEventLoopGroup;
 +import io.netty.channel.socket.SocketChannel;
 +import io.netty.channel.socket.nio.NioServerSocketChannel;
 +import io.netty.channel.socket.oio.OioServerSocketChannel;
 +import io.netty.util.concurrent.Future;
 +
 +import java.io.IOException;
 +import java.net.InetAddress;
 +import java.net.InetSocketAddress;
 +import java.net.UnknownHostException;
 +import java.util.Collection;
 +import java.util.Map.Entry;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentMap;
 +import java.util.concurrent.Executors;
 +import java.util.concurrent.ScheduledExecutorService;
 +import java.util.concurrent.ScheduledFuture;
 +import java.util.concurrent.ThreadFactory;
 +import java.util.concurrent.atomic.AtomicInteger;
 +
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.redis.ByteArrayWrapper;
 +import com.gemstone.gemfire.internal.redis.ByteToCommandDecoder;
 +import com.gemstone.gemfire.internal.redis.Coder;
 +import com.gemstone.gemfire.internal.redis.ExecutionHandlerContext;
 +import com.gemstone.gemfire.internal.redis.RedisDataType;
 +import com.gemstone.gemfire.internal.redis.RegionProvider;
- import com.gemstone.gemfire.internal.redis.executor.hll.HyperLogLogPlus;
++import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
 +
 +/**
 + * The GemFireRedisServer is a server that understands the Redis protocol. As
 + * commands are sent to the server, each command is picked up by a thread,
 + * interpreted and then executed and a response is sent back to the client. The
 + * default connection port is 6379 but that can be altered when run through GFSH
 + * or started through the provided static main class.
 + * <p>
 + * Each Redis data type instance is stored in a separate {@link Region} except
 + * for the Strings and HyperLogLogs which are collectively stored in one Region
 + * respectively. That Region along with a meta data region used internally are 
 + * protected so the client may not store keys with the name {@link GemFireRedisServer#REDIS_META_DATA_REGION}
 + * or {@link GemFireRedisServer#STRING_REGION}. The default Region type is 
 + * {@link RegionShortcut#PARTITION} although this can be changed by specifying the
 + * SystemProperty {@value #DEFAULT_REGION_SYS_PROP_NAME} to a type defined by {@link RegionShortcut}.
 + * If the {@link GemFireRedisServer#NUM_THREADS_SYS_PROP_NAME} system property is set to 0,
 + * one thread per client will be created. Otherwise a worker thread pool of specified size is
 + * used or a default size of 4 * {@link Runtime#availableProcessors()} if the property is not set.
 + * <p>
 + * Setting the AUTH password requires setting the property "redis-password" just as "redis-port"
 + * would be in xml or through GFSH.
 + * <p>
 + * The supported commands are as follows:
 + * <p>
 + * Supported String commands - APPEND, BITCOUNT, BITOP, BITPOS, DECR, DECRBY, 
 + * GET, GETBIT, GETRANGE, GETSET, INCR, INCRBY, INCRBYFLOAT, MGET, MSET, MSETNX,
 + * PSETEX, SET, SETBIT, SETEX, SETNX, STRLEN
 + * <p>
 + * Supported List commands - LINDEX, LLEN, LPOP, LPUSH, LPUSHX, LRANGE,
 + * LREM, LSET, LTRIM, RPOP, RPUSH, RPUSHX
 + * <p>
 + * Supported Hash commands - HDEL, HEXISTS, HGET, HGETALL, HINCRBY, HINCRBYFLOAT,
 + * HKEYS, HMGET, HMSET, HSETNX, HLEN, HSCAN, HSET, HVALS
 + * <p>
 + * Supported Set commands - SADD, SCARD, SDIFF, SDIFFSTORE, SINTER,
 + * SINTERSTORE, SISMEMBER, SMEMBERS, SMOVE, SREM, SPOP, SRANDMEMBER, 
 + * SCAN, SUNION, SUNIONSTORE
 + * <p>
 + * Supported SortedSet commands - ZADD, ZCARD, ZCOUNT, ZINCRBY, ZLEXCOUNT,
 + * ZRANGE, ZRANGEBYLEX, ZRANGEBYSCORE, ZRANK, ZREM, ZREMRANGEBYLEX,
 + * ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZREVRANGE, ZREVRANGEBYSCORE, ZREVRANK,
 + * ZSCAN, ZSCORE
 + * <p>
 + * Supported HyperLogLog commands - PFADD, PFCOUNT, PFMERGE
 + * <p>
 + * Supported Keys commands - DEL, DBSIZE, EXISTS, EXPIRE, EXPIREAT, FLUSHDB, FLUSHALL, 
 + * KEYS, PERSIST, PEXPIRE, PEXPIREAT, PTTL, SCAN, TTL
 + * <p>
 + * Supported Transaction commands - DISCARD, EXEC, MULTI
 + * <P>
 + * Supported Server commands - AUTH, ECHO, PING, TIME, QUIT
 + * <p>
 + * <p>
 + * The command executors are not explicitly documented but the functionality
 + * can be found at <a href="http://redis.io/commands">Redis Commands</a>
 + * <p>
 + * Exceptions to the Redis Commands Documents:<p>
 + * <ul>
 + * <li>Any command that removes keys and returns a count of removed
 + * entries will not return a total remove count but rather a count of how
 + * many entries have been removed that existed on the local vm, though 
 + * all entries will be removed</li>
 + * <li>Any command that returns a count of newly set members has an
 + * unspecified return value. The command will work just as the Redis protocol
 + * states but the count will not necessary reflect the number set compared
 + * to overridden.</li>
 + * <li>Transactions work just as they would on a Redis instance, they are local
 + * transaction. Transactions cannot be executed on data that is not local to the 
 + * executing server, that is on a partitioned region in a different server 
 + * instance or on a persistent region that does not have transactions enabled.
 + * Also, you cannot watch or unwatch keys as all keys within a GemFire 
 + * transaction are watched by default.</li>
 + * </ul>
 + * @author Vitaliy Gavrilov
 + *
 + */
 +
 +public class GemFireRedisServer {
 +
 +  /**
 +   * Thread used to start main method
 +   */
 +  private static Thread mainThread = null;
 +
 +  /**
 +   * The default Redis port as specified by their protocol, {@value #DEFAULT_REDIS_SERVER_PORT}
 +   */
 +  public static final int DEFAULT_REDIS_SERVER_PORT = 6379;
 +
 +  /**
 +   * The number of threads that will work on handling requests
 +   */
 +  private final int numWorkerThreads;
 +
 +  /**
 +   * The number of threads that will work socket selectors
 +   */
 +  private final int numSelectorThreads;
 +
 +  /**
 +   * The actual port being used by the server
 +   */
 +  private final int serverPort;
 +
 +  /**
 +   * The address to bind to
 +   */
 +  private final String bindAddress;
 +
 +  /**
 +   * Connection timeout in milliseconds
 +   */
 +  private static final int connectTimeoutMillis = 1000;
 +
 +  /**
 +   * Temporary constant whether to use old single thread per connection
 +   * model for worker group
 +   */
 +  private boolean singleThreadPerConnection;
 +
 +  /**
 +   * Logging level
 +   */
 +  private final String logLevel;
 +
 +  /**
 +   * The cache instance pointer on this vm
 +   */
 +  private Cache cache;
 +
 +  /**
 +   * Channel to be closed when shutting down
 +   */
 +  private Channel serverChannel;
 +
 +  /**
 +   * Gem logwriter
 +   */
 +  private LogWriter logger;
 +
 +  private RegionProvider regionCache;
 +
 +  private final MetaCacheListener metaListener;
 +
 +  private EventLoopGroup bossGroup;
 +  private EventLoopGroup workerGroup;
 +  private final static int numExpirationThreads = 1;
 +  private final ScheduledExecutorService expirationExecutor;
 +
 +  /**
 +   * Map of futures to be executed for key expirations
 +   */
 +  private final ConcurrentMap<ByteArrayWrapper, ScheduledFuture<?>> expirationFutures;
 +
 +
 +  /**
 +   * The field that defines the name of the {@link Region} which holds all of
 +   * the strings. The current value of this field is {@value #STRING_REGION}.
 +   */
 +  public static final String STRING_REGION = "__StRiNgS";
 +
 +  /**
 +   * The field that defines the name of the {@link Region} which holds all of
 +   * the HyperLogLogs. The current value of this field is {@value #HLL_REGION}.
 +   */
 +  public static final String HLL_REGION = "__HlL";
 +
 +  /**
 +   * The field that defines the name of the {@link Region} which holds all of
 +   * the Redis meta data. The current value of this field is {@value #REDIS_META_DATA_REGION}.
 +   */
 +  public static final String REDIS_META_DATA_REGION = "__ReDiS_MeTa_DaTa";
 +
 +  /**
 +   * The system property name used to set the default {@link Region} creation
 +   * type. The property name is {@value #DEFAULT_REGION_SYS_PROP_NAME} and the
 +   * acceptable values are types defined by {@link RegionShortcut}, 
 +   * i.e. "PARTITION" would be used for {@link RegionShortcut#PARTITION}.
 +   */
 +  public static final String DEFAULT_REGION_SYS_PROP_NAME = "gemfireredis.regiontype";
 +
 +  /**
 +   * System property name that can be used to set the number of threads to be
 +   * used by the GemFireRedisServer
 +   */
 +  public static final String NUM_THREADS_SYS_PROP_NAME = "gemfireredis.numthreads";
 +
 +  /**
 +   * The actual {@link RegionShortcut} type specified by the system property
 +   * {@value #DEFAULT_REGION_SYS_PROP_NAME}.
 +   */
 +  public final RegionShortcut DEFAULT_REGION_TYPE;
 +
 +  private boolean shutdown;
 +  private boolean started;
 +
 +  /**
 +   * Determine the {@link RegionShortcut} type from a String value.
 +   * If the String value doesn't map to a RegionShortcut type then 
 +   * {@link RegionShortcut#PARTITION} will be used by default.
 +   * 
 +   * @return {@link RegionShortcut}
 +   */
 +  private static RegionShortcut setRegionType() {
 +    String regionType = System.getProperty(DEFAULT_REGION_SYS_PROP_NAME, "PARTITION");
 +    RegionShortcut type;
 +    try {
 +      type = RegionShortcut.valueOf(regionType);
 +    } catch (Exception e) {
 +      type = RegionShortcut.PARTITION;
 +    }
 +    return type;
 +  }
 +
 +  /**
 +   * Helper method to set the number of worker threads
 +   * 
 +   * @return If the System property {@value #NUM_THREADS_SYS_PROP_NAME} is set then that number
 +   * is used, otherwise 4 * # of cores
 +   */
 +  private int setNumWorkerThreads() {
 +    String prop = System.getProperty(NUM_THREADS_SYS_PROP_NAME);
 +    int numCores = Runtime.getRuntime().availableProcessors();
 +    int def = 4 * numCores;
 +    if (prop == null || prop.isEmpty())
 +      return def;
 +    int threads;
 +    try {
 +      threads = Integer.parseInt(prop);
 +    } catch (NumberFormatException e) {
 +      return def;
 +    }
 +    return threads;
 +  }
 +
 +  /**
 +   * Constructor for {@link GemFireRedisServer} that will start the
 +   * server on the given port and bind to the first non-loopback address
 +   * 
 +   * @param port The port the server will bind to, will use {@value #DEFAULT_REDIS_SERVER_PORT} by default
 +   */
 +  public GemFireRedisServer(int port) {
 +    this(null, port, null);
 +  }
 +
 +  /**
 +   * Constructor for {@link GemFireRedisServer} that will start the
 +   * server and bind to the given address and port
 +   * 
 +   * @param bindAddress The address to which the server will attempt to bind to
 +   * @param port The port the server will bind to, will use {@value #DEFAULT_REDIS_SERVER_PORT} by default if argument is less than or equal to 0
 +   */
 +  public GemFireRedisServer(String bindAddress, int port) {
 +    this(bindAddress, port, null);
 +  }
 +
 +
 +  /**
 +   * Constructor for {@link GemFireRedisServer} that will start the
 +   * server and bind to the given address and port. Keep in mind that the
 +   * log level configuration will only be set if a {@link Cache} does not already
 +   * exist, if one already exists then setting that property will have no effect.
 +   * 
 +   * @param bindAddress The address to which the server will attempt to bind to
 +   * @param port The port the server will bind to, will use {@value #DEFAULT_REDIS_SERVER_PORT} by default if argument is less than or equal to 0
 +   * @param logLevel The logging level to be used by GemFire
 +   */
 +  public GemFireRedisServer(String bindAddress, int port, String logLevel) {
 +    if (port <= 0)
 +      this.serverPort = DEFAULT_REDIS_SERVER_PORT;
 +    else
 +      this.serverPort = port;
 +    this.bindAddress = bindAddress;
 +    this.logLevel = logLevel;
 +    this.numWorkerThreads = setNumWorkerThreads();
 +    if (this.numWorkerThreads == 0)
 +      this.singleThreadPerConnection = true;
 +    this.numSelectorThreads = 1;
 +    this.metaListener = new MetaCacheListener();
 +    this.expirationFutures = new ConcurrentHashMap<ByteArrayWrapper, ScheduledFuture<?>>();
 +    this.expirationExecutor = Executors.newScheduledThreadPool(numExpirationThreads, new ThreadFactory() {
 +      private final AtomicInteger counter = new AtomicInteger();
 +      @Override
 +      public Thread newThread(Runnable r) {
 +        Thread t = new Thread(r);
 +        t.setName("GemFireRedis-ScheduledExecutor-" + counter.incrementAndGet());
 +        t.setDaemon(true);
 +        return t;
 +      }
 +
 +    });
 +    this.DEFAULT_REGION_TYPE = setRegionType();
 +    this.shutdown = false;
 +    this.started = false;
 +  }
 +
 +  /**
 +   * Helper method to get the host name to bind to
 +   * 
 +   * @return The InetAddress to bind to
 +   * @throws UnknownHostException
 +   */
 +  private InetAddress getBindAddress() throws UnknownHostException {
 +    return this.bindAddress == null || this.bindAddress.isEmpty()
 +        ? SocketCreator.getLocalHost()
 +            : InetAddress.getByName(this.bindAddress);
 +  }
 +
 +  /**
 +   * This is function to call on a {@link GemFireRedisServer} instance
 +   * to start it running
 +   */
 +  public synchronized void start() {
 +    if (!started) {
 +      try {
 +        startGemFire();
 +        initializeRedis();
 +        startRedisServer();
 +      } catch (IOException e) {
 +        throw new RuntimeException("Could not start Server", e);
 +      } catch (InterruptedException e) {
 +        throw new RuntimeException("Could not start Server", e);
 +      }
 +      started = true;
 +    }
 +  }
 +
 +  /**
 +   * Initializes the {@link Cache}, and creates Redis necessities
 +   * Region and protects declares that {@link Region} to be protected. 
 +   * Also, every {@link GemFireRedisServer} will check for entries already in the 
 +   * meta data Region.
 +   */
 +  private void startGemFire() {
 +    Cache c = GemFireCacheImpl.getInstance();
 +    if (c == null) {
 +      synchronized (GemFireRedisServer.class) {
 +        c = GemFireCacheImpl.getInstance();
 +        if (c == null) {
 +          CacheFactory cacheFactory = new CacheFactory();
 +          if (logLevel != null)
 +            cacheFactory.set("log-level", logLevel);
 +          c = cacheFactory.create();
 +        }
 +      }
 +    }
 +    this.cache = c;
 +    this.logger = c.getLogger();
 +  }
 +
 +  private void initializeRedis() {
 +    synchronized (this.cache) {
 +      RegionFactory<String, RedisDataType> rfMeta = cache.createRegionFactory(RegionShortcut.REPLICATE);
 +      rfMeta.addCacheListener(this.metaListener);
 +      RegionFactory<ByteArrayWrapper, ByteArrayWrapper> rfString = cache.createRegionFactory(DEFAULT_REGION_TYPE);
 +      RegionFactory<ByteArrayWrapper, HyperLogLogPlus> rfHLL = cache.createRegionFactory(DEFAULT_REGION_TYPE);
 +      Region<ByteArrayWrapper, ByteArrayWrapper> stringsRegion;
 +      if ((stringsRegion = this.cache.getRegion(STRING_REGION)) == null)
 +        stringsRegion = rfString.create(GemFireRedisServer.STRING_REGION);
 +      Region<ByteArrayWrapper, HyperLogLogPlus> hLLRegion;
 +      if ((hLLRegion = this.cache.getRegion(HLL_REGION)) == null)
 +        hLLRegion = rfHLL.create(HLL_REGION);
 +      Region<String, RedisDataType> redisMetaData;
 +      if ((redisMetaData = this.cache.getRegion(REDIS_META_DATA_REGION)) == null)
 +        redisMetaData = rfMeta.create(REDIS_META_DATA_REGION);
 +      this.regionCache = new RegionProvider(stringsRegion, hLLRegion, redisMetaData, expirationFutures, expirationExecutor, this.DEFAULT_REGION_TYPE);
 +      redisMetaData.put(REDIS_META_DATA_REGION, RedisDataType.REDIS_PROTECTED);
 +      redisMetaData.put(HLL_REGION, RedisDataType.REDIS_PROTECTED);
 +      redisMetaData.put(STRING_REGION, RedisDataType.REDIS_PROTECTED);
 +    }
 +    checkForRegions();
 +  }
 +
 +  private void checkForRegions() {
 +    Collection<Entry<String, RedisDataType>> entrySet = this.regionCache.metaEntrySet();
 +    for (Entry<String, RedisDataType> entry: entrySet) {
 +      String regionName = entry.getKey();
 +      RedisDataType type = entry.getValue();
 +      Region<?, ?> newRegion = cache.getRegion(regionName);
 +      if (newRegion == null && type != RedisDataType.REDIS_STRING && type != RedisDataType.REDIS_HLL && type != RedisDataType.REDIS_PROTECTED) {
 +        try {
 +          this.regionCache.createRemoteRegionReferenceLocally(Coder.stringToByteArrayWrapper(regionName), type);
 +        } catch (Exception e) {
 +          if (logger.errorEnabled())
 +            logger.error(e);
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Helper method to start the server listening for connections. The
 +   * server is bound to the port specified by {@link GemFireRedisServer#serverPort}
 +   * 
 +   * @throws IOException
 +   * @throws InterruptedException
 +   */
 +  private void startRedisServer() throws IOException, InterruptedException {
 +    ThreadFactory selectorThreadFactory = new ThreadFactory() {
 +      private final AtomicInteger counter = new AtomicInteger();
 +      @Override
 +      public Thread newThread(Runnable r) {
 +        Thread t = new Thread(r);
 +        t.setName("GemFireRedisServer-SelectorThread-" + counter.incrementAndGet());
 +        t.setDaemon(true);
 +        return t;
 +      }
 +
 +    };
 +
 +    ThreadFactory workerThreadFactory = new ThreadFactory() {
 +      private final AtomicInteger counter = new AtomicInteger();
 +      @Override
 +      public Thread newThread(Runnable r) {
 +        Thread t = new Thread(r);
 +        t.setName("GemFireRedisServer-WorkerThread-" + counter.incrementAndGet());
 +        return t;
 +      }
 +
 +    };
 +
 +    bossGroup = null;
 +    workerGroup = null;
 +    Class<? extends ServerChannel> socketClass = null;
 +    if (singleThreadPerConnection) {
 +      bossGroup = new OioEventLoopGroup(Integer.MAX_VALUE, selectorThreadFactory);
 +      workerGroup = new OioEventLoopGroup(Integer.MAX_VALUE, workerThreadFactory);
 +      socketClass = OioServerSocketChannel.class;
 +    } else {
 +      bossGroup = new NioEventLoopGroup(this.numSelectorThreads, selectorThreadFactory);
 +      workerGroup = new NioEventLoopGroup(this.numWorkerThreads, workerThreadFactory);
 +      socketClass = NioServerSocketChannel.class;
 +    }
 +    InternalDistributedSystem system = (InternalDistributedSystem) cache.getDistributedSystem();
 +    String pwd = system.getConfig().getRedisPassword();
 +    final byte[] pwdB = Coder.stringToBytes(pwd);
 +    ServerBootstrap b = new ServerBootstrap();
 +    b.group(bossGroup, workerGroup)
 +    .channel(socketClass)
 +    .childHandler(new ChannelInitializer<SocketChannel>() {
 +      @Override
 +      public void initChannel(SocketChannel ch) throws Exception {
 +        if (logger.fineEnabled())
 +          logger.fine("GemFireRedisServer-Connection established with " + ch.remoteAddress());
 +        ChannelPipeline p = ch.pipeline();
 +        p.addLast(ByteToCommandDecoder.class.getSimpleName(), new ByteToCommandDecoder());
 +        p.addLast(ExecutionHandlerContext.class.getSimpleName(), new ExecutionHandlerContext(ch, cache, regionCache, GemFireRedisServer.this, pwdB));
 +      }
 +    })
 +    .option(ChannelOption.SO_REUSEADDR, true)
 +    .option(ChannelOption.SO_RCVBUF, getBufferSize())
 +    .childOption(ChannelOption.SO_KEEPALIVE, true)
 +    .childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, GemFireRedisServer.connectTimeoutMillis)
 +    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
 +
 +    // Bind and start to accept incoming connections.
 +    ChannelFuture f = b.bind(new InetSocketAddress(getBindAddress(), serverPort)).sync();
 +    if (this.logger.infoEnabled()) {
 +      String logMessage = "GemFireRedisServer started {" + getBindAddress() + ":" + serverPort + "}, Selector threads: " + this.numSelectorThreads;
 +      if (this.singleThreadPerConnection)
 +        logMessage += ", One worker thread per connection";
 +      else
 +        logMessage += ", Worker threads: " + this.numWorkerThreads;
 +      this.logger.info(logMessage);
 +    }
 +    this.serverChannel = f.channel();
 +  }
 +
 +  /**
 +   * Takes an entry event and processes it. If the entry denotes that a
 +   * {@link RedisDataType#REDIS_LIST} or {@link RedisDataType#REDIS_SORTEDSET}
 +   * was created then this function will call the necessary calls to create the 
 +   * parameterized queries for those keys.
 +   * 
 +   * @param event EntryEvent from meta data region
 +   */
 +  private void afterKeyCreate(EntryEvent<String, RedisDataType> event) {
 +    if (event.isOriginRemote()) {
 +      final String key = (String) event.getKey();
 +      final RedisDataType value = event.getNewValue();
 +      if (value != RedisDataType.REDIS_STRING && value != RedisDataType.REDIS_HLL && value != RedisDataType.REDIS_PROTECTED) {
 +        try {
 +          this.regionCache.createRemoteRegionReferenceLocally(Coder.stringToByteArrayWrapper(key), value);
 +        } catch (RegionDestroyedException ignore) { // Region already destroyed, ignore
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * When a key is removed then this function will make sure the associated
 +   * queries with the key are also removed from each vm to avoid unnecessary
 +   * data retention
 +   */
 +  private void afterKeyDestroy(EntryEvent<String, RedisDataType> event) {
 +    if (event.isOriginRemote()) {
 +      final String key = (String) event.getKey();
 +      final RedisDataType value = event.getOldValue();
 +      if (value != null && value != RedisDataType.REDIS_STRING && value != RedisDataType.REDIS_HLL && value != RedisDataType.REDIS_PROTECTED) {
 +        ByteArrayWrapper kW = Coder.stringToByteArrayWrapper(key);
 +        Region<?, ?> r = this.regionCache.getRegion(kW);
 +        if (r != null) { 
 +          this.regionCache.removeRegionReferenceLocally(kW, value);
 +        }
 +      }
 +    }
 +  }
 +
 +  private final class MetaCacheListener extends CacheListenerAdapter<String, RedisDataType> {
 +
 +    @Override
 +    public void afterCreate(EntryEvent<String, RedisDataType> event) {
 +      afterKeyCreate(event);
 +    }
 +
 +    @Override
 +    public void afterDestroy(EntryEvent<String, RedisDataType> event) {
 +      afterKeyDestroy(event);
 +    }
 +  }
 +
 +  /**
 +   * Helper method to get GemFire set socket buffer size,
 +   * possibly a default of 32k
 +   * 
 +   * @return Buffer size to use for server
 +   */
 +  private int getBufferSize() {
 +    InternalDistributedSystem system = (InternalDistributedSystem) cache.getDistributedSystem();
 +    return system.getConfig().getSocketBufferSize();
 +  }
 +
 +  /**
 +   * Shutdown method for {@link GemFireRedisServer}. This closes the {@link Cache},
 +   * interrupts all execution and forcefully closes all connections.
 +   */
 +  public synchronized void shutdown() {
 +    if (!shutdown) {
 +      if (logger.infoEnabled())
 +        logger.info("GemFireRedisServer shutting down");
 +      ChannelFuture closeFuture = this.serverChannel.closeFuture();
 +      Future<?> c = workerGroup.shutdownGracefully();
 +      Future<?> c2 = bossGroup.shutdownGracefully();
 +      this.serverChannel.close();
 +      c.syncUninterruptibly();
 +      c2.syncUninterruptibly();
 +      this.regionCache.close();
 +      if (mainThread != null)
 +        mainThread.interrupt();
 +      for (ScheduledFuture<?> f : this.expirationFutures.values())
 +        f.cancel(true);
 +      this.expirationFutures.clear();
 +      this.expirationExecutor.shutdownNow();
 +      closeFuture.syncUninterruptibly();
 +      shutdown = true;
 +    }
 +  }
 +
 +  /**
 +   * Static main method that allows the {@link GemFireRedisServer} to be 
 +   * started from the command line. The supported command line arguments are
 +   * <p>-port=
 +   * <br>-bind-address=
 +   * <br>-log-level=
 +   * 
 +   * @param args Command line args
 +   */
 +  public static void main(String[] args) {
 +    int port = DEFAULT_REDIS_SERVER_PORT;
 +    String bindAddress = null;
 +    String logLevel = null;
 +    for (String arg: args) {
 +      if (arg.startsWith("-port"))
 +        port = getPort(arg);
 +      else if (arg.startsWith("-bind-address"))
 +        bindAddress = getBindAddress(arg);
 +      else if (arg.startsWith("-log-level"))
 +        logLevel = getLogLevel(arg);
 +    }
 +    mainThread = Thread.currentThread();
 +    GemFireRedisServer server = new GemFireRedisServer(bindAddress, port, logLevel);
 +    server.start();
 +    while(true) {
 +      try {
 +        Thread.sleep(Long.MAX_VALUE);
 +      } catch (InterruptedException e1) { 
 +        break;
 +      } catch (Exception e) {
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Helper method to parse the port to a number
 +   * 
 +   * @param arg String where the argument is
 +   * @return The port number when the correct syntax was used, 
 +   * otherwise will return {@link #DEFAULT_REDIS_SERVER_PORT}
 +   */
 +  private static int getPort(String arg) {
 +    int port = DEFAULT_REDIS_SERVER_PORT;
 +    if (arg != null && arg.length() > 6) {
 +      if (arg.startsWith("-port")) {
 +        String p = arg.substring(arg.indexOf('=') + 1);
 +        p = p.trim();
 +        try {
 +          port = Integer.parseInt(p);
 +        } catch (NumberFormatException e) {
 +          System.out.println("Unable to parse port, using default port");
 +        }
 +      }
 +    }
 +    return port;
 +  }
 +
 +  /**
 +   * Helper method to parse bind address
 +   * 
 +   * @param arg String holding bind address
 +   * @return Bind address
 +   */
 +  private static String getBindAddress(String arg) {
 +    String address = null;
 +    if (arg != null && arg.length() > 14) {
 +      if (arg.startsWith("-bind-address")) {
 +        String p = arg.substring(arg.indexOf('=') + 1);
 +        address = p.trim();
 +      }
 +    }
 +    return address;
 +  }
 +
 +  /**
 +   * Helper method to parse log level
 +   * 
 +   * @param arg String holding log level
 +   * @return Log level
 +   */
 +  private static String getLogLevel(String arg) {
 +    String logLevel = null;
 +    if (arg != null && arg.length() > 11) {
 +      if (arg.startsWith("-log-level")) {
 +        String p = arg.substring(arg.indexOf('=') + 1);
 +        logLevel = p.trim();
 +      }
 +    }
 +    return logLevel;
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/CacheRegionClearStatsDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/CacheRegionClearStatsDUnitTest.java
index 7ea3565,0000000..88a32a3
mode 100755,000000..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/CacheRegionClearStatsDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/CacheRegionClearStatsDUnitTest.java
@@@ -1,248 -1,0 +1,240 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache;
 +
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.client.internal.PoolImpl;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +/**
 + * verifies the count of clear operation
 + *  
 + * @author aingle
 + */
 +public class CacheRegionClearStatsDUnitTest extends DistributedTestCase {
 +  /** the cache */
 +  private static GemFireCacheImpl cache = null;
 +
-   private static VM server1 = null;
++  private VM server1 = null;
 +
 +  private static VM client1 = null;
 +
 +  /** name of the test region */
 +  private static final String REGION_NAME = "CacheRegionClearStatsDUnitTest_Region";
 +
 +  private static final String k1 = "k1";
 +
 +  private static final String k2 = "k2";
 +
 +  private static final String client_k1 = "client-k1";
 +
 +  private static final String client_k2 = "client-k2";
 +  
 +  private static final int clearOp = 2;
 +  
 +  /** constructor */
 +  public CacheRegionClearStatsDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    final Host host = Host.getHost(0);
 +    server1 = host.getVM(0);
 +    client1 = host.getVM(1);
 +  }
 +
 +  private void createCache(Properties props) throws Exception {
 +    DistributedSystem ds = getSystem(props);
 +    ds.disconnect();
 +    ds = getSystem(props);
 +    assertNotNull(ds);
 +    cache = (GemFireCacheImpl)CacheFactory.create(ds);
 +    assertNotNull(cache);
 +  }
 +
 +  public static void createClientCache(String host, Integer port1)
 +      throws Exception {
 +    new CacheRegionClearStatsDUnitTest("temp");
 +    Properties props = new Properties();
 +    props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    props.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    new CacheRegionClearStatsDUnitTest("temp").createCache(props);
 +    PoolImpl p = (PoolImpl)PoolManager.createFactory().addServer(host,
 +        port1.intValue()).setSubscriptionEnabled(false)
 +        .setThreadLocalConnections(true).setMinConnections(1).setReadTimeout(
 +            20000).setPingInterval(10000).setRetryAttempts(1)
 +        .create("CacheRegionClearStatsDUnitTest");
 +
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setPoolName(p.getName());
 +
 +    RegionAttributes attrs = factory.create();
 +    Region region = cache.createRegion(REGION_NAME, attrs);
 +    //region.registerInterest("ALL_KEYS");
 +  }
 +
 +  public static Integer createServerCacheDisk() throws Exception {
 +    return createCache(DataPolicy.PERSISTENT_REPLICATE);
 +  }
 +
 +  private static Integer createCache(DataPolicy dataPolicy) throws Exception {
 +    new CacheRegionClearStatsDUnitTest("temp").createCache(new Properties());
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setDataPolicy(dataPolicy);
 +    RegionAttributes attrs = factory.create();
 +    cache.createRegion(REGION_NAME, attrs);
 +    int port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    CacheServer server1 = cache.addCacheServer();
 +    server1.setPort(port);
 +    server1.setNotifyBySubscription(true);
 +    server1.start();
 +    return new Integer(server1.getPort());
 +  }
 +
 +  public static Integer createServerCache() throws Exception {
 +    return createCache(DataPolicy.REPLICATE);
 +  }
 +
 +  public static void createClientCacheDisk(String host, Integer port1)
 +      throws Exception {
 +    new CacheRegionClearStatsDUnitTest("temp");
 +    Properties props = new Properties();
 +    props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    props.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    new CacheRegionClearStatsDUnitTest("temp").createCache(props);
 +    PoolImpl p = (PoolImpl)PoolManager.createFactory().addServer(host,
 +        port1.intValue()).setSubscriptionEnabled(false)
 +        .setThreadLocalConnections(true).setMinConnections(1).setReadTimeout(
 +            20000).setPingInterval(10000).setRetryAttempts(1).create(
 +            "CacheRegionClearStatsDUnitTest");
 +
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setPoolName(p.getName());
 +    factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
 +    RegionAttributes attrs = factory.create();
 +    Region region = cache.createRegion(REGION_NAME, attrs);
 +    //region.registerInterest("ALL_KEYS");
 +  }
 +  /**
 +   * This test does the following (<b> clear stats counter </b>):<br>
 +   * 1)Verifies that clear operation count matches with stats count<br>
 +   */
 +  public void testClearStatsWithNormalRegion(){
-     Integer port1 = ((Integer)server1.invoke(
-         CacheRegionClearStatsDUnitTest.class, "createServerCache"));
++    Integer port1 = ((Integer)server1.invoke(() -> CacheRegionClearStatsDUnitTest.createServerCache()));
 +
-     client1.invoke(CacheRegionClearStatsDUnitTest.class,
-         "createClientCache", new Object[] {
-             NetworkUtils.getServerHostName(server1.getHost()), port1 });
-     client1.invoke(CacheRegionClearStatsDUnitTest.class, "put");
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.createClientCache(
++            NetworkUtils.getServerHostName(server1.getHost()), port1 ));
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.put());
 +    
 +    try{
 +      Thread.sleep(10000);
 +    }catch(Exception e){
 +      // sleep 
 +    }
 +    
-     client1.invoke(CacheRegionClearStatsDUnitTest.class,
-         "validationClearStat");
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.validationClearStat());
 +    
-     server1.invoke(CacheRegionClearStatsDUnitTest.class,
-     "validationClearStat");
++    server1.invoke(() -> CacheRegionClearStatsDUnitTest.validationClearStat());
 +  }
 +  /**
 +   * This test does the following (<b> clear stats counter when disk involved </b>):<br>
 +   * 1)Verifies that clear operation count matches with stats count <br>
 +   */
 +  public void testClearStatsWithDiskRegion(){
-     Integer port1 = ((Integer)server1.invoke(
-         CacheRegionClearStatsDUnitTest.class, "createServerCacheDisk"));
++    Integer port1 = ((Integer)server1.invoke(() -> CacheRegionClearStatsDUnitTest.createServerCacheDisk()));
 +
-     client1.invoke(CacheRegionClearStatsDUnitTest.class,
-         "createClientCacheDisk", new Object[] {
-             NetworkUtils.getServerHostName(server1.getHost()), port1 });
-     client1.invoke(CacheRegionClearStatsDUnitTest.class, "put");
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.createClientCacheDisk(
++            NetworkUtils.getServerHostName(server1.getHost()), port1 ));
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.put());
 +    
 +    try{
 +      Thread.sleep(10000);
 +    }catch(Exception e){
 +      // sleep 
 +    }
 +    
-     client1.invoke(CacheRegionClearStatsDUnitTest.class,
-         "validationClearStat");
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.validationClearStat());
 +    
-     server1.invoke(CacheRegionClearStatsDUnitTest.class,
-     "validationClearStat");
++    server1.invoke(() -> CacheRegionClearStatsDUnitTest.validationClearStat());
 +  }
 +  
 +  @Override
 +  protected final void preTearDown() throws Exception {
-     client1.invoke(CacheRegionClearStatsDUnitTest.class, "closeCache");
++    client1.invoke(() -> CacheRegionClearStatsDUnitTest.closeCache());
 +    // then close the servers
-     server1.invoke(CacheRegionClearStatsDUnitTest.class, "closeCache");
++    server1.invoke(() -> CacheRegionClearStatsDUnitTest.closeCache());
 +  }
 +
 +  public static void closeCache() {
 +    if (cache != null && !cache.isClosed()) {
 +      cache.close();
 +      cache.getDistributedSystem().disconnect();
 +    }
 +  }
 +  
 +  public static void put() {
 +    try {
 +      Region r1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
 +      assertNotNull(r1);
 +
 +      r1.put(k1, client_k1);
 +      assertEquals(r1.getEntry(k1).getValue(), client_k1);
 +      r1.put(k2, client_k2);
 +      assertEquals(r1.getEntry(k2).getValue(), client_k2);
 +      try{
 +        Thread.sleep(10000);
 +      }catch(Exception e){
 +        // sleep 
 +      }
 +      r1.clear();
 +      
 +      r1.put(k1, client_k1);
 +      assertEquals(r1.getEntry(k1).getValue(), client_k1);
 +      r1.put(k2, client_k2);
 +      assertEquals(r1.getEntry(k2).getValue(), client_k2);
 +      try{
 +        Thread.sleep(10000);
 +      }catch(Exception e){
 +        // sleep 
 +      }
 +      r1.clear();
 +    }
 +    catch (Exception ex) {
 +      Assert.fail("failed while put", ex);
 +    }
 +  }
 +  
 +  public static void validationClearStat(){
 +    assertEquals(cache.getCachePerfStats().getClearCount(), clearOp);
 +  }
 +  
 +  
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/ClientServerTimeSyncDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/ClientServerTimeSyncDUnitTest.java
index 8166318,0000000..8b04ab5
mode 100755,000000..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/ClientServerTimeSyncDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/ClientServerTimeSyncDUnitTest.java
@@@ -1,203 -1,0 +1,203 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache;
 +
 +import java.io.IOException;
 +import java.util.Properties;
 +
 +import org.junit.Ignore;
 +
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.distributed.internal.DSClock;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +public class ClientServerTimeSyncDUnitTest extends CacheTestCase {
 +
 +  public ClientServerTimeSyncDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  @Ignore("Bug 52327")
 +  public void DISABLED_testClientTimeAdvances() {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0); // Server
 +    VM vm1 = host.getVM(1); // Client
 +
 +    final String regionName = "testRegion";
 +    final long TEST_OFFSET = 10000;
 +
 +    ClientCache cache = null;
 +    
 +    try {
 +
 +      final int serverPort = (Integer)vm0.invoke(new SerializableCallable("Start server with a region") {
 +        
 +        @Override
 +        public Object call() {
 +          Cache cache = getCache();
 +          cache.createRegionFactory(RegionShortcut.REPLICATE).create(regionName);
 +          LogWriterUtils.getLogWriter().info("Done creating region, now creating CacheServer");
 +          CacheServer server = null;
 +          try {
 +            server = cache.addCacheServer();
 +            server.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
 +            server.start();
 +          } catch (IOException e) {
 +            Assert.fail("Starting cache server failed.", e);
 +          }
 +  
 +          // now set an artificial time offset for the test
 +          system.getClock().setCacheTimeOffset(null, TEST_OFFSET, true);
 +          
 +          LogWriterUtils.getLogWriter().info("Done creating and starting CacheServer on port " + server.getPort());
 +          return server.getPort();
 +        }
 +      });
 +      
 +      final String hostName = NetworkUtils.getServerHostName(vm0.getHost());
 +  
 +      // Start client with proxy region and register interest
 +        
 +      disconnectFromDS();
 +      Properties props = new Properties();
 +      props.setProperty("locators", "");
 +      props = getSystem(props).getProperties();
 +      cache = new ClientCacheFactory(props).setPoolSubscriptionEnabled(true)
 +          .addPoolServer(hostName, serverPort)
 +          .setPoolPingInterval(5000)
 +          .create();
 +      Region proxyRegion = cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create(regionName);
 +  
 +      proxyRegion.registerInterestRegex(".*");
 +  
 +      proxyRegion.put("testkey", "testValue1");
 +          
 +      final DSClock clock = ((GemFireCacheImpl)cache).getSystem().getClock();
 +      WaitCriterion wc = new WaitCriterion() {
 +        public boolean done() {
 +          long clientTimeOffset = clock.getCacheTimeOffset();
 +          LogWriterUtils.getLogWriter().info("Client node's new time offset is: " + clientTimeOffset);
 +          return clientTimeOffset >= TEST_OFFSET;
 +        }
 +        public String description() {
 +          return "Waiting for cacheTimeOffset to be non-zero.  PingOp should have set it to something";
 +        }
 +      };
 +      Wait.waitForCriterion(wc, 60000, 1000, true);
 +    } finally {
 +      cache.close();
-       vm1.invoke(CacheTestCase.class, "disconnectFromDS");
++      vm1.invoke(() -> CacheTestCase.disconnectFromDS());
 +    }
 +  }
 +  
 +  public void testNothing() {
 +    // place-holder to keep dunit runner from barfing
 +  }
 +
 +  @Ignore("not yet implemented")
 +  public void DISABLED_testClientTimeSlowsDown() {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0); // Server
 +    VM vm1 = host.getVM(1); // Client
 +
 +    final String regionName = "testRegion";
 +    final long TEST_OFFSET = 10000;
 +
 +    ClientCache cache = null;
 +    
 +    try {
 +
 +      final int serverPort = (Integer)vm0.invoke(new SerializableCallable("Start server with a region") {
 +        
 +        @Override
 +        public Object call() {
 +          Cache cache = getCache();
 +          cache.createRegionFactory(RegionShortcut.REPLICATE).create(regionName);
 +          LogWriterUtils.getLogWriter().info("Done creating region, now creating CacheServer");
 +          CacheServer server = null;
 +          try {
 +            server = cache.addCacheServer();
 +            server.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
 +            server.start();
 +          } catch (IOException e) {
 +            Assert.fail("Starting cache server failed.", e);
 +          }
 +  
 +          // now set an artificial time offset for the test
 +          system.getClock().setCacheTimeOffset(null, -TEST_OFFSET, true);
 +          
 +          LogWriterUtils.getLogWriter().info("Done creating and starting CacheServer on port " + server.getPort());
 +          return server.getPort();
 +        }
 +      });
 +      
 +      Wait.pause((int)TEST_OFFSET);  // let cacheTimeMillis consume the time offset
 +      
 +      final String hostName = NetworkUtils.getServerHostName(vm0.getHost());
 +  
 +      // Start client with proxy region and register interest
 +        
 +      disconnectFromDS();
 +      Properties props = new Properties();
 +      props.setProperty("locators", "");
 +      props = getSystem(props).getProperties();
 +      cache = new ClientCacheFactory(props).setPoolSubscriptionEnabled(true)
 +          .addPoolServer(hostName, serverPort)
 +          .setPoolPingInterval(5000)
 +          .create();
 +      Region proxyRegion = cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY).create(regionName);
 +  
 +      proxyRegion.registerInterestRegex(".*");
 +  
 +      proxyRegion.put("testkey", "testValue1");
 +          
 +      final DSClock clock = ((GemFireCacheImpl)cache).getSystem().getClock();
 +      WaitCriterion wc = new WaitCriterion() {
 +        public boolean done() {
 +          long clientTimeOffset = clock.getCacheTimeOffset();
 +          LogWriterUtils.getLogWriter().info("Client node's new time offset is: " + clientTimeOffset);
 +          if (clientTimeOffset >= 0) {
 +            return false;
 +          }
 +          long cacheTime = clock.cacheTimeMillis();
 +          return Math.abs(System.currentTimeMillis() - (cacheTime - clientTimeOffset)) < 5;
 +        }
 +        public String description() {
 +          return "Waiting for cacheTimeOffset to be negative and cacheTimeMillis to stabilize";
 +        }
 +      };
 +      Wait.waitForCriterion(wc, 60000, 1000, true);
 +    } finally {
 +      cache.close();
-       vm1.invoke(CacheTestCase.class, "disconnectFromDS");
++      vm1.invoke(() -> CacheTestCase.disconnectFromDS());
 +    }
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceDUnitTest.java
index b0f3b59,0000000..03368de
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceDUnitTest.java
@@@ -1,598 -1,0 +1,598 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.Serializable;
 +import java.net.InetSocketAddress;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import junit.framework.Assert;
 +
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.client.NoAvailableLocatorsException;
 +import com.gemstone.gemfire.cache.client.NoAvailableServersException;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.internal.ServerLocation;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.management.membership.ClientMembership;
 +import com.gemstone.gemfire.management.membership.ClientMembershipEvent;
 +import com.gemstone.gemfire.management.membership.ClientMembershipListenerAdapter;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +
 +/**
 + * Tests cases that are particular for the auto connection source
 + * - dynamically discovering servers, locators, handling 
 + * locator disappearance, etc.
 + * @author dsmith
 + *
 + */
 +public class AutoConnectionSourceDUnitTest extends LocatorTestBase {
 +  
 +  protected static final Object BRIDGE_LISTENER = "BRIDGE_LISTENER";
 +  private static final long MAX_WAIT = 60000;
 +  
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    IgnoredException.addIgnoredException("NoAvailableLocatorsException");
 +  }
 +
 +  public AutoConnectionSourceDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  public void testDiscoverBridgeServers() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    
 +    String locators = NetworkUtils.getServerHostName(vm0.getHost())+ "[" + locatorPort + "]";
 +    
 +    startBridgeServerInVM(vm1, null, locators);
 +
 +    startBridgeClientInVM(vm2, null, NetworkUtils.getServerHostName(vm0.getHost()), locatorPort);
 +
 +    putAndWaitForSuccess(vm2, REGION_NAME, "key", "value");
 +    
 +    Assert.assertEquals("value", getInVM(vm1, "key"));
 +  }
 +
 +  public void testNoLocators() {
 +    
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    
 +    try {
 +      startBridgeClientInVM(vm0, null, NetworkUtils.getServerHostName(vm0.getHost()), AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET));
 +      putInVM(vm0, "key", "value");
 +      fail("Client cache should not have been able to start");
 +    } catch(Exception e) {
 +      //expected an exception
 +    }
 +  }
 +  
 +  public void testNoBridgeServer() {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    try { 
 +      startBridgeClientInVM(vm1, null, NetworkUtils.getServerHostName(vm0.getHost()), locatorPort);
 +      putInVM(vm0, "key", "value");
 +      fail("Client cache should not have been able to start");
 +    } catch(Exception e) {
 +      //expected an exception
 +    }
 +  }
 +  
 +  public void testDynamicallyFindBridgeServer() throws Exception  {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    
 +    String locators = NetworkUtils.getServerHostName(vm0.getHost()) + "[" + locatorPort + "]";
 +    
 +    startBridgeServerInVM(vm1, null, locators);
 +    
 +    startBridgeClientInVM(vm2, null, NetworkUtils.getServerHostName(vm0.getHost()), locatorPort);
 +    
 +    putAndWaitForSuccess(vm2, REGION_NAME, "key", "value");
 +    
 +    startBridgeServerInVM(vm3, null, locators);
 +    
 +    stopBridgeMemberVM(vm1);
 +    
 +    putAndWaitForSuccess(vm2, REGION_NAME, "key2", "value2");
 +    
 +    Assert.assertEquals("value2", getInVM(vm3, "key2"));
 +  }
 +  
 +  public void testDynamicallyFindLocators() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final String hostName = NetworkUtils.getServerHostName(host);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(3);
 +    
 +    final int locatorPort0 = ports[0];
 +    final int locatorPort1 = ports[1];
 +    final int locatorPort3 = ports[2];
 +    String locators = getLocatorString(host, new int[] { locatorPort0, locatorPort1, locatorPort3});
 +    startLocatorInVM(vm0, locatorPort0, locators);
 +    
 +    startLocatorInVM(vm1, locatorPort1, locators);
 +    startBridgeClientInVM(vm2, null, NetworkUtils.getServerHostName(vm0.getHost()), locatorPort0);
 +    
 +    InetSocketAddress locatorToWaitFor= new InetSocketAddress(hostName, locatorPort1);
 +    waitForLocatorDiscovery(vm2, locatorToWaitFor);
 +    
 +    stopLocatorInVM(vm0);
 +    startBridgeServerInVM(vm0, null, locators);
 +    
 +    putAndWaitForSuccess(vm2, REGION_NAME, "key", "value");
 +    Assert.assertEquals("value", getInVM(vm0, "key"));
 +    
 +    startLocatorInVM(vm3, locatorPort3, locators);
 +    stopBridgeMemberVM(vm0);
 +    locatorToWaitFor= new InetSocketAddress(hostName, locatorPort3);
 +    waitForLocatorDiscovery(vm2, locatorToWaitFor);
 +    stopLocatorInVM(vm1);
 +    startBridgeServerInVM(vm1, null, locators);
 +    putAndWaitForSuccess(vm2, REGION_NAME, "key2", "value2");
 +    Assert.assertEquals("value2", getInVM(vm1, "key2"));
 +    
 +  }
 +  
 +  public void testEmbeddedLocator() throws Exception  {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    
 +    String locators = NetworkUtils.getServerHostName(vm0.getHost()) + "[" + locatorPort + "]";
 +    
 +    startBridgeServerWithEmbeddedLocator(vm0, null, locators, new String[] {REGION_NAME}, CacheServer.DEFAULT_LOAD_PROBE);
 +    
 +    startBridgeClientInVM(vm2, null, NetworkUtils.getServerHostName(vm0.getHost()), locatorPort);
 +    
 +    putAndWaitForSuccess(vm2, REGION_NAME, "key", "value");
 +    
 +    Assert.assertEquals("value", getInVM(vm2, "key"));
 +  }
 +
 +  private void waitForLocatorDiscovery(VM vm,
 +      final InetSocketAddress locatorToWaitFor) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws InterruptedException {
 +        MyLocatorCallback callback = (MyLocatorCallback) remoteObjects.get(CALLBACK_KEY);
 +        
 +        boolean discovered = callback.waitForDiscovery(locatorToWaitFor, MAX_WAIT);
 +        Assert.assertTrue("Waited " + MAX_WAIT + " for " + locatorToWaitFor
 +            + " to be discovered on client. List is now: "
 +            + callback.getDiscovered(), discovered);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  public void testServerGroups() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    
 +    String locators = NetworkUtils.getServerHostName(vm0.getHost()) + "[" + locatorPort + "]";
 +    
 +    startBridgeServerInVM(vm1, new String[] {"group1", "group2"} , locators, new String[] {"A", "B"});
 +    startBridgeServerInVM(vm2, new String[] {"group2", "group3"}, locators, new String[] {"B", "C"});
 +
 +    
 +    startBridgeClientInVM(vm3, "group1", NetworkUtils.getServerHostName(vm0.getHost()), locatorPort, new String [] {"A", "B", "C"});
 +    putAndWaitForSuccess(vm3, "A", "key", "value");
 +    Assert.assertEquals("value", getInVM(vm1, "A", "key"));
 +    try {
 +      putInVM(vm3, "C", "key2", "value2");
 +      fail("Should not have been able to find Region C on the server");
 +    } catch(Exception expected) {}
 +    
 +    stopBridgeMemberVM(vm3);
 +    
 +    startBridgeClientInVM(vm3, "group3", NetworkUtils.getServerHostName(vm0.getHost()), locatorPort, new String [] {"A", "B", "C"});
 +    try {
 +      putInVM(vm3, "A", "key3", "value");
 +      fail("Should not have been able to find Region A on the server");
 +    } catch(Exception expected) {}
 +    putInVM(vm3, "C", "key4", "value");
 +    Assert.assertEquals("value", getInVM(vm2, "C", "key4"));
 +    
 +    stopBridgeMemberVM(vm3);
 +    
 +    startBridgeClientInVM(vm3, "group2", NetworkUtils.getServerHostName(vm0.getHost()), locatorPort, new String [] {"A", "B", "C"});
 +    putInVM(vm3, "B", "key5", "value");
 +    Assert.assertEquals("value", getInVM(vm1, "B", "key5"));
 +    Assert.assertEquals("value", getInVM(vm2, "B", "key5"));
 +    
 +    stopBridgeMemberVM(vm1);
 +    putInVM(vm3, "B", "key6", "value");
 +    Assert.assertEquals("value", getInVM(vm2, "B", "key6"));
 +    startBridgeServerInVM(vm1, new String[] {"group1", "group2"} , locators, new String[] {"A", "B"});
 +    stopBridgeMemberVM(vm2);
 +    
 +    putInVM(vm3, "B", "key7", "value");
 +    Assert.assertEquals("value", getInVM(vm1, "B", "key7"));
 +  }
 +  
-   public void testTwoServersInSameVM() {
++  public void testTwoServersInSameVM() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +//    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    
 +    startLocatorInVM(vm0, locatorPort, "");
 +    
 +    final String locators = NetworkUtils.getServerHostName(vm0.getHost()) + "[" + locatorPort + "]";
 +    
 +    final int serverPort1 =startBridgeServerInVM(vm1, new String[] {"group1"}, locators);
 +    final int serverPort2 =addCacheServerInVM(vm1, new String[] {"group2"});
 +    
 +    startBridgeClientInVM(vm2, "group2", NetworkUtils.getServerHostName(vm0.getHost()), locatorPort);
 +    
 +    checkEndpoints(vm2, new int[] {serverPort2});
 +    
 +    stopBridgeMemberVM(vm2);
 +
 +    startBridgeClientInVM(vm2, "group1", NetworkUtils.getServerHostName(vm0.getHost()), locatorPort);
 +    
 +    checkEndpoints(vm2, new int[] {serverPort1});
 +  }
 +  
 +  public void testClientMembershipListener() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM locatorVM = host.getVM(0);
 +    VM bridge1VM = host.getVM(1);
 +    VM bridge2VM = host.getVM(2);
 +    VM clientVM = host.getVM(3);
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(locatorVM, locatorPort, "");
 +    String locators = NetworkUtils.getServerHostName(locatorVM.getHost()) + "[" + locatorPort + "]";
 +
 +    //start a bridge server with a listener
 +    addBridgeListener(bridge1VM);
 +    int serverPort1 = startBridgeServerInVM(bridge1VM, null, locators);
 +
 +    //start a bridge client with a listener
 +    addBridgeListener(clientVM);
 +    startBridgeClientInVM(clientVM, null, NetworkUtils.getServerHostName(locatorVM.getHost()), locatorPort);
 +    // wait for client to connect
 +    checkEndpoints(clientVM, new int[] {serverPort1});
 +    
 +    //make sure the client and bridge server both noticed each other
 +    waitForJoin(bridge1VM);
 +    MyListener serverListener = getBridgeListener(bridge1VM);
 +    Assert.assertEquals(0, serverListener.getCrashes());
 +    Assert.assertEquals(0, serverListener.getDepartures());
 +    Assert.assertEquals(1, serverListener.getJoins());
 +    resetBridgeListener(bridge1VM);
 +    
 +    waitForJoin(clientVM);
 +    MyListener clientListener= getBridgeListener(clientVM);
 +    Assert.assertEquals(0, clientListener.getCrashes());
 +    Assert.assertEquals(0, clientListener.getDepartures());
 +    Assert.assertEquals(1, clientListener.getJoins());
 +    resetBridgeListener(clientVM);
 +    
 +    checkEndpoints(clientVM, new int[] {serverPort1});
 +
 +    //start another bridge server and make sure it is detected by the client
 +    int serverPort2 = startBridgeServerInVM(bridge2VM, null, locators);
 +    
 +    checkEndpoints(clientVM, new int[] {serverPort1, serverPort2});
 +    serverListener = getBridgeListener(bridge1VM);
 +    Assert.assertEquals(0, serverListener.getCrashes());
 +    Assert.assertEquals(0, serverListener.getDepartures());
 +    Assert.assertEquals(0, serverListener.getJoins());
 +    resetBridgeListener(bridge1VM);
 +    waitForJoin(clientVM);
 +    clientListener= getBridgeListener(clientVM);
 +    Assert.assertEquals(0, clientListener.getCrashes());
 +    Assert.assertEquals(0, clientListener.getDepartures());
 +    Assert.assertEquals(1, clientListener.getJoins());
 +    resetBridgeListener(clientVM);
 +    
 +    //stop the second bridge server and make sure it is detected by the client
 +    stopBridgeMemberVM(bridge2VM);
 +    
 +    checkEndpoints(clientVM, new int[] {serverPort1});
 +    serverListener = getBridgeListener(bridge1VM);
 +    Assert.assertEquals(0, serverListener.getCrashes());
 +    Assert.assertEquals(0, serverListener.getDepartures());
 +    Assert.assertEquals(0, serverListener.getJoins());
 +    resetBridgeListener(bridge1VM);
 +    waitForCrash(clientVM);
 +    clientListener= getBridgeListener(clientVM);
 +    Assert.assertEquals(1, clientListener.getCrashes());
 +    Assert.assertEquals(0, clientListener.getDepartures());
 +    Assert.assertEquals(0, clientListener.getJoins());
 +    resetBridgeListener(clientVM);
 +    
 +    //stop the client and make sure the bridge server notices
 +    stopBridgeMemberVM(clientVM);
 +    waitForDeparture(bridge1VM);
 +    serverListener = getBridgeListener(bridge1VM);
 +    Assert.assertEquals(0, serverListener.getCrashes());
 +    Assert.assertEquals(1, serverListener.getDepartures());
 +    Assert.assertEquals(0, serverListener.getJoins());
 +  }
 +
 +  protected Object getInVM(VM vm, final Serializable key) {
 +    return getInVM(vm, REGION_NAME, key);
 +  }
 +  
 +  protected Object getInVM(VM vm, final String regionName, final Serializable key) {
 +    return vm.invoke(new SerializableCallable("Get in VM") {
 +      public Object call() throws Exception {
 +        Cache cache = (Cache) remoteObjects.get(CACHE_KEY);
 +        Region region = cache.getRegion(regionName);
 +        return region.get(key);
 +      }
 +    });
 +  }
 +  
 +  protected void putAndWaitForSuccess(VM vm,  final String regionName, final Serializable key, final Serializable value) throws InterruptedException
 +  {
 +    long endTime = System.currentTimeMillis() + MAX_WAIT;
 +    long remaining = MAX_WAIT;
 +    int i = 0;
 +    while(true) {
 +      try {
 +        System.err.println("Attempt: " + (i++));
 +        putInVM(vm, regionName, key, value);
 +        break;
 +      } catch (NoAvailableLocatorsException | com.gemstone.gemfire.test.dunit.RMIException e) {
 +        if( !(e instanceof NoAvailableLocatorsException)
 +            && !(e.getCause() instanceof NoAvailableServersException)) {
 +          throw e;
 +        }
 +        if(remaining <= 0) {
 +          throw e;
 +        }
 +        Wait.pause(100);
 +        remaining = endTime - System.currentTimeMillis();
 +      }
 +    }
 +  }
 +
 +  protected void putInVM(VM vm, final Serializable key, final Serializable value) {
 +    putInVM(vm, REGION_NAME, key, value);
 +  }
 +  
 +  
 +  
 +  protected void putInVM(VM vm,  final String regionName, final Serializable key, final Serializable value) {
 +    vm.invoke(new SerializableCallable("Put in VM") {
 +      public Object call() throws Exception {
 +        Cache cache = (Cache) remoteObjects.get(CACHE_KEY);
 +        Region region = cache.getRegion(regionName);
 +        return region.put(key, value);
 +      }
 +    });
 +  }
 +  
 +  /**
 +   * Assert that there is one endpoint with the given host in port
 +   * on the client vm.
 +   * @param vm - the vm the client is running in
 +   * @param expectedPorts - The server ports we expect the client to be connected to.
 +   */
 +  protected void checkEndpoints(VM vm, final int[] expectedPorts) {
 +    vm.invoke(new SerializableRunnable("Check endpoint") {
 +      public void run() {
 +        PoolImpl pool = (PoolImpl) PoolManager.find(POOL_NAME);
 +        int retryCount = 50;
 +        List/*<ServerLocation>*/ endpoints;
 +        HashSet actualEndpointPorts;
 +        HashSet expectedEndpointPorts = new HashSet();
 +        for(int i = 0; i < expectedPorts.length; i++) {
 +          expectedEndpointPorts.add(new Integer(expectedPorts[i]));
 +        }
 +        do {
 +          endpoints = pool.getCurrentServers();
 +          actualEndpointPorts = new HashSet();
 +          for(Iterator itr = endpoints.iterator(); itr.hasNext();) {
 +            ServerLocation sl = (ServerLocation)itr.next();
 +            actualEndpointPorts.add(new Integer(sl.getPort()));
 +          }
 +          if (expectedEndpointPorts.size() == actualEndpointPorts.size()) {
 +            break;
 +          } else {
 +            Wait.pause(100);
 +          }
 +        } while(retryCount-- > 0);
 +        Assert.assertEquals(expectedEndpointPorts, actualEndpointPorts);
 +      }
 +    });
 +  }
 +  
 +  protected void addBridgeListener(VM vm) {
 +    vm.invoke(new SerializableRunnable("Add membership listener") {
 +      public void run() {
 +        MyListener listener = new MyListener();
 +        ClientMembership.registerClientMembershipListener(listener);
 +        remoteObjects.put(BRIDGE_LISTENER, listener);
 +      }
 +    });
 +  }
 +  
 +  protected void resetBridgeListener(VM vm) {
 +    vm.invoke(new SerializableRunnable("Add membership listener") {
 +      public void run() {
 +        MyListener listener = (MyListener) remoteObjects.get(BRIDGE_LISTENER);
 +        listener.reset();
 +      }
 +    });
 +  }
 +  
 +  private MyListener getBridgeListener(VM vm) {
 +    return (MyListener) vm.invoke(new SerializableCallable("Add membership listener") {
 +      public Object call() {
 +        return remoteObjects.get(BRIDGE_LISTENER);
 +      }
 +    });
 +  }
 +  
 +  private void waitForJoin(VM vm) {
 +    vm.invoke(new SerializableRunnable() {
 +      public void run() {
 +        MyListener listener = (MyListener) remoteObjects.get(BRIDGE_LISTENER);
 +        synchronized(listener) {
 +          long end = System.currentTimeMillis() + 10000;
 +          while (listener.joins == 0) {
 +            try {
 +              long remaining = end - System.currentTimeMillis();
 +              if(remaining < 0) {
 +                break;
 +              }
 +              listener.wait(remaining);
 +            } catch (InterruptedException e) {
 +              fail("interrupted");
 +            }
 +          }
 +        }
 +      }
 +    });
 +  }
 +  
 +  private void waitForCrash(VM vm) {
 +    vm.invoke(new SerializableRunnable() {
 +      public void run() {
 +        MyListener listener = (MyListener) remoteObjects.get(BRIDGE_LISTENER);
 +        synchronized(listener) {
 +          long end = System.currentTimeMillis() + 10000;
 +          while (listener.crashes== 0) {
 +            try {
 +              long remaining = end - System.currentTimeMillis();
 +              if(remaining < 0) {
 +                break;
 +              }
 +              listener.wait(remaining);
 +            } catch (InterruptedException e) {
 +              fail("interrupted");
 +            }
 +          }
 +        }
 +      }
 +    });
 +  }
 +  
 +  private void waitForDeparture(VM vm) {
 +    vm.invoke(new SerializableRunnable() {
 +      public void run() {
 +        MyListener listener = (MyListener) remoteObjects.get(BRIDGE_LISTENER);
 +        synchronized(listener) {
 +          long end = System.currentTimeMillis() + 10000;
 +          while (listener.departures == 0) {
 +            try {
 +              long remaining = end - System.currentTimeMillis();
 +              if(remaining < 0) {
 +                break;
 +              }
 +              listener.wait(remaining);
 +            } catch (InterruptedException e) {
 +              fail("interrupted");
 +            }
 +          }
 +        }
 +      }
 +    });
 +  }
 +  
 +  public static class MyListener extends ClientMembershipListenerAdapter implements Serializable {
 +    protected int crashes = 0;
 +    protected int joins = 0;
 +    protected int departures= 0;
 +
 +    @Override
 +    public synchronized void memberCrashed(ClientMembershipEvent event) {
 +      crashes++;
 +      notifyAll();
 +    }
 +
 +    public synchronized void reset() {
 +      crashes = 0;
 +      joins = 0;
 +      departures = 0;
 +    }
 +
 +    @Override
 +    public synchronized void memberJoined(ClientMembershipEvent event) {
 +      joins++;
 +      notifyAll();
 +    }
 +
 +    @Override
 +    public synchronized void memberLeft(ClientMembershipEvent event) {
 +      departures++;
 +      notifyAll();
 +    }
 +
 +    public synchronized int getCrashes() {
 +      return crashes;
 +    }
 +
 +    public synchronized int getJoins() {
 +      return joins;
 +    }
 +
 +    public synchronized int  getDepartures() {
 +      return departures;
 +    }
 +  }
 +}


[033/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
index 92b585a,0000000..f3e730a
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
@@@ -1,4303 -1,0 +1,4311 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ABSTRACT_REGION_ENTRY_FILL_IN_VALUE;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.CopyOnWriteArraySet;
 +import java.util.concurrent.RejectedExecutionException;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +import java.util.concurrent.locks.Condition;
 +import java.util.concurrent.locks.Lock;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.InvalidDeltaException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.DiskAccessException;
 +import com.gemstone.gemfire.cache.EntryNotFoundException;
 +import com.gemstone.gemfire.cache.LossAction;
 +import com.gemstone.gemfire.cache.MembershipAttributes;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.RegionAccessException;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.RegionDistributionException;
 +import com.gemstone.gemfire.cache.RegionMembershipListener;
 +import com.gemstone.gemfire.cache.ResumptionAction;
 +import com.gemstone.gemfire.cache.RoleException;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.cache.TransactionId;
 +import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueImpl;
 +import com.gemstone.gemfire.cache.execute.Function;
 +import com.gemstone.gemfire.cache.execute.FunctionException;
 +import com.gemstone.gemfire.cache.execute.ResultCollector;
 +import com.gemstone.gemfire.cache.execute.ResultSender;
 +import com.gemstone.gemfire.cache.persistence.PersistentReplicatesOfflineException;
 +import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
 +import com.gemstone.gemfire.cache.wan.GatewaySender;
 +import com.gemstone.gemfire.distributed.DistributedLockService;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.LockServiceDestroyedException;
 +import com.gemstone.gemfire.distributed.Role;
 +import com.gemstone.gemfire.distributed.internal.DM;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisee;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.ProfileVisitor;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.MembershipListener;
 +import com.gemstone.gemfire.distributed.internal.ReplyProcessor21;
 +import com.gemstone.gemfire.distributed.internal.locks.DLockRemoteToken;
 +import com.gemstone.gemfire.distributed.internal.locks.DLockService;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.CacheProfile;
 +import com.gemstone.gemfire.internal.cache.InitialImageOperation.GIIStatus;
 +import com.gemstone.gemfire.internal.cache.RemoteFetchVersionMessage.FetchVersionResponse;
 +import com.gemstone.gemfire.internal.cache.control.InternalResourceManager.ResourceType;
 +import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
 +import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionExecutor;
 +import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionResultSender;
 +import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionResultWaiter;
 +import com.gemstone.gemfire.internal.cache.execute.FunctionStats;
 +import com.gemstone.gemfire.internal.cache.execute.LocalResultCollector;
 +import com.gemstone.gemfire.internal.cache.execute.RegionFunctionContextImpl;
 +import com.gemstone.gemfire.internal.cache.execute.ServerToClientFunctionResultSender;
 +import com.gemstone.gemfire.internal.cache.lru.LRUEntry;
 +import com.gemstone.gemfire.internal.cache.persistence.CreatePersistentRegionProcessor;
 +import com.gemstone.gemfire.internal.cache.persistence.PersistenceAdvisor;
 +import com.gemstone.gemfire.internal.cache.persistence.PersistenceAdvisorImpl;
 +import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberID;
 +import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberManager;
 +import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberView;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
 +import com.gemstone.gemfire.internal.cache.versions.ConcurrentCacheModificationException;
 +import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
 +import com.gemstone.gemfire.internal.cache.versions.VersionSource;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
 +import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
 +import com.gemstone.gemfire.internal.cache.wan.AsyncEventQueueConfigurationException;
 +import com.gemstone.gemfire.internal.cache.wan.GatewaySenderConfigurationException;
 +import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewaySenderQueue;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.offheap.Chunk;
 +import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 +import com.gemstone.gemfire.internal.offheap.annotations.Released;
 +import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 +import com.gemstone.gemfire.internal.sequencelog.RegionLogger;
 +import com.gemstone.gemfire.internal.util.concurrent.StoppableCountDownLatch;
 +import com.gemstone.gemfire.i18n.StringId;
 +/**
 + * 
 + * @author Eric Zoerner
 + * @author Sudhir Menon
 + */
 +@SuppressWarnings("deprecation")
 +public class DistributedRegion extends LocalRegion implements 
 +    CacheDistributionAdvisee
 +{
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  /** causes cache profile to be added to afterRemoteRegionCreate notification for testing */
 +  public static boolean TEST_HOOK_ADD_PROFILE = false;
 +  
 +  /** Used to sync accesses to this.dlockService to allow lazy construction */
 +  private final Object dlockMonitor = new Object();
 +
 +  final CacheDistributionAdvisor distAdvisor;
 +
 +  /**
 +   * @guarded.By {@link #dlockMonitor}
 +   */
 +  private DistributedLockService dlockService;
 +
 +  protected final AdvisorListener advisorListener = new AdvisorListener();
 +
 +  /** Set of currently missing required roles */
 +  protected final HashSet missingRequiredRoles = new HashSet();
 +
 +  /** True if this region is currently missing any required roles */
 +  protected volatile boolean isMissingRequiredRoles = false;
 +  
 +  /**
 +   * True if this region is has any required roles defined and the LossAction is
 +   * either NO_ACCESS or LIMITED_ACCESS. Reliability checks will only happen if
 +   * this is true.
 +   */
 +  private final boolean requiresReliabilityCheck;
 +
 +  /**
 +   * Provides a queue for reliable message delivery
 +   * 
 +   * @since 5.0
 +   */
 +  protected final ReliableMessageQueue rmq;
 +
 +  /**
 +   * Latch that is opened after initialization waits for required roles up to
 +   * the <a href="DistributedSystem#member-timeout">member-timeout </a>.
 +   */
 +  protected final StoppableCountDownLatch initializationLatchAfterMemberTimeout; 
 +
 +  private final PersistenceAdvisor persistenceAdvisor;
 +  
 +  private final PersistentMemberID persistentId;
 +
 +  /**
 +   * This boolean is set to false when this region
 +   * is non-persistent, but there are persistent members in the distributed system
 +   * to which all region modifications should be forwarded
 +   * see bug 45186
 +   */
 +  private volatile boolean generateVersionTag = true;
 +
 +  /** Tests can set this to true and ignore reliability triggered reconnects */
 +  public static boolean ignoreReconnect = false;
 +  
 +  /**
 +   * Lock to prevent multiple threads on this member from performing
 +   * a clear at the same time.
 +   */
 +  private final Object clearLock = new Object();
 +
 +  private static AtomicBoolean loggedNetworkPartitionWarning = new AtomicBoolean(false);
 +
 +  /** Creates a new instance of DistributedRegion */
 +  protected DistributedRegion(String regionName, RegionAttributes attrs,
 +      LocalRegion parentRegion, GemFireCacheImpl cache,
 +      InternalRegionArguments internalRegionArgs) {
 +    super(regionName, attrs, parentRegion, cache, internalRegionArgs);
 +    this.initializationLatchAfterMemberTimeout = new StoppableCountDownLatch(
 +        getCancelCriterion(), 1);
 +    this.distAdvisor = createDistributionAdvisor(internalRegionArgs);
 +    
 +    if (getDistributionManager().getConfig().getEnableNetworkPartitionDetection()
 +        && !isInternalRegion() && !attrs.getScope().isAck() && !doesNotDistribute() && attrs.getDataPolicy().withStorage()) {
 +      logger.warn(LocalizedMessage.create(LocalizedStrings.DistributedRegion_REGION_0_1_SPLITBRAIN_CONFIG_WARNING,
 +          new Object[] { regionName, attrs.getScope() })); 
 +    }
 +    if (!getDistributionManager().getConfig().getEnableNetworkPartitionDetection() 
 +        && attrs.getDataPolicy().withPersistence() && !loggedNetworkPartitionWarning.getAndSet(true)) {
 +      logger.warn(LocalizedMessage.create(
 +          LocalizedStrings.DistributedRegion_REGION_0_ENABLE_NETWORK_PARTITION_WARNING,
 +          new Object[] { regionName, attrs.getScope() }));
 +    }
 +
 +    boolean setRequiresReliabilityCheck = attrs.getMembershipAttributes()
 +        .hasRequiredRoles()
 +        &&
 +        // note that the following includes NO_ACCESS, LIMITED_ACCESS,
 +        !attrs.getMembershipAttributes().getLossAction().isAllAccess()
 +        && !attrs.getMembershipAttributes().getLossAction().isReconnect();
 +
 +    // this optimization is safe for as long as Roles and Required Roles are
 +    // immutable
 +    // if this VM fulfills all required roles, make requiresReliabilityCheck
 +    // false
 +    Set reqRoles = new HashSet(attrs.getMembershipAttributes()
 +        .getRequiredRoles());
 +    reqRoles.removeAll(getSystem().getDistributedMember().getRoles());
 +    if (reqRoles.isEmpty()) {
 +      setRequiresReliabilityCheck = false;
 +    }
 +
 +    this.requiresReliabilityCheck = setRequiresReliabilityCheck;
 +
 +    {
 +      ReliableMessageQueue tmp = null;
 +      if (this.requiresReliabilityCheck) {
 +        //         if
 +        // (attrs.getMembershipAttributes().getLossAction().isAllAccessWithQueuing())
 +        // {
 +        //           tmp = cache.getReliableMessageQueueFactory().create(this);
 +        //         }
 +      }
 +      this.rmq = tmp;
 +    }
 +
 +    if(internalRegionArgs.isUsedForPartitionedRegionBucket()) {
 +      this.persistenceAdvisor = internalRegionArgs.getPersistenceAdvisor();
 +    } else if (this.allowsPersistence()){
 +      //TODO prpersist - using this lock service is a hack. Maybe? Or maybe
 +      //it's ok if we have one (rarely used) lock service for many operations?
 +      //What does the resource manager do?
 +      DistributedLockService dl = cache.getPartitionedRegionLockService();
 +      try {
 +        //TODO prpersist - this is just a quick and dirty storage mechanism so that
 +        //I can test the storage.
 +        DiskRegionStats diskStats;
 +        PersistentMemberView storage;
 +        if(getDataPolicy().withPersistence()) {
 +          storage = getDiskRegion();
 +          diskStats = getDiskRegion().getStats();
 +        } else {
 +          storage = new InMemoryPersistentMemberView();
 +          diskStats = null;
 +        }
 +        PersistentMemberManager memberManager = cache.getPersistentMemberManager();
 +        this.persistenceAdvisor = new PersistenceAdvisorImpl(distAdvisor, dl, storage, this.getFullPath(), diskStats, memberManager);
 +      } catch (Exception e) {
 +        throw new InternalGemFireError("Couldn't recover persistence");
 +      }
 +    } else {
 +      this.persistenceAdvisor = null;
 +    }
 +    if(this.persistenceAdvisor != null) {
 +      this.persistentId = persistenceAdvisor.generatePersistentID();
 +    } else {
 +      this.persistentId = null;
 +    }
 +    
 +  }
 +  
 +  @Override
 +  public void createEventTracker() {
 +    this.eventTracker = new EventTracker(this);
 +    this.eventTracker.start();
 +  }
 +  
 +  /**
 +   * Intended for used during construction of a DistributedRegion
 +   *  
 +   * @return the advisor to be used by the region
 +   */
 +  protected CacheDistributionAdvisor createDistributionAdvisor(InternalRegionArguments internalRegionArgs) {
 +    return CacheDistributionAdvisor.createCacheDistributionAdvisor(this);  // Warning: potential early escape of object before full construction
 +  }
 +  
 +  /**
 +   * Does this region support persistence?
 +   */
 +  public boolean allowsPersistence() {
 +    return true;
 +  }
 +
 +  @Override
 +  public boolean requiresOneHopForMissingEntry(EntryEventImpl event) {
 +    // received from another member - don't use one-hop
 +    if (event.isOriginRemote()) {
 +      return false; 
 +    }
 +    // local ops aren't distributed
 +    if (event.getOperation().isLocal()) {
 +      return false;
 +    }
 +    // if it already has a valid version tag it can go out with a DistributedCacheOperation
 +    if (event.getVersionTag() != null && event.getVersionTag().getRegionVersion() > 0) {
 +      return false;
 +    }
 +    // if we're not allowed to generate a version tag we need to send it to someone who can
 +    if (!this.generateVersionTag) {
 +      return true;
 +    }
 +    return this.concurrencyChecksEnabled &&
 +        (this.srp == null) &&
 +        !isTX() &&
 +        this.scope.isDistributed() &&
 +        !this.dataPolicy.withReplication();
 +  }
 +  
 +  
 +  /**
 +   * @see LocalRegion#virtualPut(EntryEventImpl, boolean, boolean, Object, 
 +   * boolean, long, boolean)
 +   */
 +  @Override
 +  protected
 +  boolean virtualPut(EntryEventImpl event,
 +                     boolean ifNew,
 +                     boolean ifOld,
 +                     Object expectedOldValue,
 +                     boolean requireOldValue,
 +                     long lastModified,
 +                     boolean overwriteDestroyed)
 +  throws TimeoutException,
 +         CacheWriterException {
 +    final boolean isTraceEnabled = logger.isTraceEnabled();
 +    
 +    Lock dlock = null;
 +    if (this.scope.isGlobal() && // lock only applies to global scope
 +        !event.isOriginRemote() && // only if operation originating locally
 +        !event.isNetSearch() && // search and load processor handles own locking
 +        !event.isNetLoad() &&
 +        // @todo darrel/kirk: what about putAll?
 +        !event.isLocalLoad() &&
 +        !event.isSingleHopPutOp()) { // Single Hop Op means dlock is already taken at origin node.
 +      dlock = this.getDistributedLockIfGlobal(event.getKey());
 +    }
 +    if (isTraceEnabled) {
 +      logger.trace("virtualPut invoked for event {}", event);
 +    }
 +    try {
 +      if (!hasSeenEvent(event)) {
 +        if (this.requiresOneHopForMissingEntry(event)) {
 +          // bug #45704: see if a one-hop must be done for this operation
 +          RegionEntry re = getRegionEntry(event.getKey());
 +          if (re == null /*|| re.isTombstone()*/ || !this.generateVersionTag) {
 +            if (!event.isBulkOpInProgress() || this.dataPolicy.withStorage()) {
 +              // putAll will send a single one-hop for empty regions.  for other missing entries
 +              // we need to get a valid version number before modifying the local cache 
 +              boolean didDistribute = RemotePutMessage.distribute(event, lastModified,
 +                  false, false, expectedOldValue, requireOldValue, !this.generateVersionTag);
 +
 +              if (!didDistribute && isTraceEnabled) {
 +                logger.trace("Unable to perform one-hop messaging");
 +              }
 +              if (!this.generateVersionTag && !didDistribute) {
 +                throw new PersistentReplicatesOfflineException();
 +              }
 +              if (didDistribute) {
 +                if (isTraceEnabled) {
 +                  logger.trace("Event after remotePut operation: {}", event);
 +                }
 +                if (event.getVersionTag() == null) {
 +                  // if the event wasn't applied by the one-hop replicate it will not have a version tag
 +                  // and so should not be applied to this cache
 +                  return false;
 +                }
 +              }
 +            }
 +          }
 +        }
 +        return super.virtualPut(event,
 +                                ifNew,
 +                                ifOld,
 +                                expectedOldValue,
 +                                requireOldValue,
 +                                lastModified,
 +                                overwriteDestroyed);
 +      }
 +      else {
 +        if (event.getDeltaBytes() != null && event.getRawNewValue() == null) {
 +          // This means that this event has delta bytes but no full value.
 +          // Request the full value of this event.
 +          // The value in this vm may not be same as this event's value.
 +          throw new InvalidDeltaException(
 +              "Cache encountered replay of event containing delta bytes for key "
 +                  + event.getKey());
 +        }
 +        // if the listeners have already seen this event, then it has already
 +        // been successfully applied to the cache.  Distributed messages and
 +        // return
 +        if (isTraceEnabled) {
 +          logger.trace("DR.virtualPut: this cache has already seen this event {}", event);
 +        }
 +        
 +        // Gester, Fix 39014: when hasSeenEvent, put will still distribute
 +        // event, but putAll did not. We add the logic back here, not to put 
 +        // back into DR.distributeUpdate() because we moved this part up into 
 +        // LR.basicPutPart3 in purpose. Reviewed by Bruce.  
 +        if (event.isBulkOpInProgress() && !event.isOriginRemote()) {
 +          event.getPutAllOperation().addEntry(event, true);
 +        }
 +
 +        /* doing this so that other VMs will apply this no matter what. If it 
 +         * is an "update" they will not apply it if they don't have the key.
 +         * Because this is probably a retry, it will never get applied to this 
 +         * local AbstractRegionMap, and so will never be flipped to a 'create'
 +         */
 +        event.makeCreate();
-         distributeUpdate(event, lastModified, ifNew, ifOld, expectedOldValue, requireOldValue);
-         event.invokeCallbacks(this,true, true);
++        if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++          distributeUpdate(event, lastModified, ifNew, ifOld, expectedOldValue, requireOldValue);
++          event.invokeCallbacks(this,true, true);
++        }
 +        return true;
 +      }
 +    }
 +    finally {
 +      if (dlock != null) {
 +        dlock.unlock();
 +      }
 +    }
 +  }
 +  
 +  @Override
 +  protected RegionEntry basicPutEntry(EntryEventImpl event, long lastModified)
 +      throws TimeoutException, CacheWriterException {
 +    
 +    final boolean isTraceEnabled = logger.isTraceEnabled();
 +    
 +    if (isTraceEnabled) {
 +      logger.trace("basicPutEntry invoked for event {}", event);
 +    }
 +    if (this.requiresOneHopForMissingEntry(event)) {
 +      // bug #45704: see if a one-hop must be done for this operation
 +      RegionEntry re = getRegionEntry(event.getKey());
 +      if (re == null /*|| re.isTombstone()*/ || !this.generateVersionTag) {
 +        final boolean ifNew = false;
 +        final boolean ifOld = false;
 +        boolean didDistribute = RemotePutMessage.distribute(event, lastModified,
 +            ifNew, ifOld, null, false, !this.generateVersionTag);
 +        if (!this.generateVersionTag && !didDistribute) {
 +          throw new PersistentReplicatesOfflineException();
 +        }
 +        if (didDistribute && isTraceEnabled) {
 +          logger.trace("Event after remotePut for basicPutEntry: {}", event);
 +        }
 +      }
 +    }
 +    return super.basicPutEntry(event, lastModified);
 +  }
 +
 +  @Override
 +  public void performPutAllEntry(EntryEventImpl event) {
 +	  /*
 +	   * force shared data view so that we just do the virtual op, accruing things in the put all operation for later
 +	   */
 +	if(isTX()) {
 +		event.getPutAllOperation().addEntry(event);
 +	} else {
 +		getSharedDataView().putEntry(event, false, false, null, false, 0L, false);
 +	}
 +  }
 +  
 +  @Override
 +  public void performRemoveAllEntry(EntryEventImpl event) {
 +    // force shared data view so that we just do the virtual op, accruing things in the bulk operation for later
 +    if(isTX()) {
 +      event.getRemoveAllOperation().addEntry(event);
 +    } else {
 +      basicDestroy(event, true, null);
 +      //getSharedDataView().destroyExistingEntry(event, true, null);
 +    }
 +  }
 +  
 +  /**
 +   * distribution and listener notification
 +   */
 +  @Override
 +  public void basicPutPart3(EntryEventImpl event, RegionEntry entry,
 +      boolean isInitialized, long lastModified, boolean invokeCallbacks,
 +      boolean ifNew, boolean ifOld, Object expectedOldValue,
 +      boolean requireOldValue) {
 +    
 +    distributeUpdate(event, lastModified, false, false, null, false);
 +    super.basicPutPart3(event, entry, isInitialized, lastModified,
 +        invokeCallbacks, ifNew, ifOld, expectedOldValue, requireOldValue);
 +  }
 +
 +  /** distribute an update operation */
 +  protected void distributeUpdate(EntryEventImpl event, long lastModified, boolean ifNew, boolean ifOld, Object expectedOldValue, boolean requireOldValue) {
 +    // an update from a netSearch is not distributed
 +    if (!event.isOriginRemote() && !event.isNetSearch() && !event.isBulkOpInProgress()) {
 +      boolean distribute = true;
 +        if (event.getInhibitDistribution()) {
 +          // this has already been distributed by a one-hop operation
 +          distribute = false;
 +        }
 +        if (distribute) {
 +          UpdateOperation op = new UpdateOperation(event, lastModified);
 +          if (logger.isTraceEnabled()) {
 +            logger.trace("distributing operation for event : {} : for region : {}", event, this.getName());
 +          }
 +          op.distribute();
 +        }
 +    }
 +  }
 +
 +  protected void setGeneratedVersionTag(boolean generateVersionTag) {
 +    // there is at-least one other persistent member, so turn on concurrencyChecks
 +    enableConcurrencyChecks();
 +    
 +    this.generateVersionTag = generateVersionTag;
 +  }
 +
 +  protected boolean getGenerateVersionTag() {
 +    return this.generateVersionTag;
 +  }
 +
 +  @Override
 +  protected boolean shouldGenerateVersionTag(RegionEntry entry, EntryEventImpl event) {
 +    if (logger.isTraceEnabled()) {
 +      logger.trace("shouldGenerateVersionTag this.generateVersionTag={} ccenabled={} dataPolicy={} event:{}",
 +          this.generateVersionTag, this.concurrencyChecksEnabled, this.dataPolicy, event);
 +    }
 +    if (!this.concurrencyChecksEnabled || this.dataPolicy == DataPolicy.EMPTY || !this.generateVersionTag) {
 +      return false;
 +    }
 +    if (this.srp != null) { // client
 +      return false;
 +    }
 +    if (event.getVersionTag() != null && !event.getVersionTag().isGatewayTag()) {
 +      return false;
 +    }
 +    if (event.getOperation().isLocal()) { // bug #45402 - localDestroy generated a version tag
 +      return false;
 +    }
 +    if (!event.isOriginRemote() && this.dataPolicy.withReplication()) {
 +      return true;
 +    }
 +    if (!this.dataPolicy.withReplication() && !this.dataPolicy.withPersistence()) {
 +      if (!entry.getVersionStamp().hasValidVersion()) {
 +        // do not generate a version stamp in a region that has no replication if it's not based
 +        // on an existing version from a replicate region
 +        return false;
 +      }
 +      return true;
 +    }
 +    if (!event.isOriginRemote() && event.getDistributedMember() != null) {
 +      if (!event.getDistributedMember().equals(this.getMyId())) {
 +        return event.getVersionTag() == null; // one-hop remote message
 +      }
 +    }
 +    return false;
 +  }
 +  /**
 +   * Throws RegionAccessException if required roles are missing and the
 +   * LossAction is NO_ACCESS
 +   * 
 +   * @throws RegionAccessException
 +   *           if required roles are missing and the LossAction is NO_ACCESS
 +   */
 +  @Override
 +  protected void checkForNoAccess()
 +  {
 +    if (this.requiresReliabilityCheck && this.isMissingRequiredRoles) {
 +      if (getMembershipAttributes().getLossAction().isNoAccess()) {
 +        synchronized (this.missingRequiredRoles) {
 +          if (!this.isMissingRequiredRoles)
 +            return;
 +          Set roles = Collections.unmodifiableSet(new HashSet(
 +              this.missingRequiredRoles));
 +          throw new RegionAccessException(LocalizedStrings.DistributedRegion_OPERATION_IS_DISALLOWED_BY_LOSSACTION_0_BECAUSE_THESE_REQUIRED_ROLES_ARE_MISSING_1.toLocalizedString(new Object[] {getMembershipAttributes().getLossAction(), roles}), getFullPath(), roles);
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Throws RegionAccessException is required roles are missing and the
 +   * LossAction is either NO_ACCESS or LIMITED_ACCESS.
 +   * 
 +   * @throws RegionAccessException
 +   *           if required roles are missing and the LossAction is either
 +   *           NO_ACCESS or LIMITED_ACCESS
 +   */
 +  @Override
 +  protected void checkForLimitedOrNoAccess()
 +  {
 +    if (this.requiresReliabilityCheck && this.isMissingRequiredRoles) {
 +      if (getMembershipAttributes().getLossAction().isNoAccess()
 +          || getMembershipAttributes().getLossAction().isLimitedAccess()) {
 +        synchronized (this.missingRequiredRoles) {
 +          if (!this.isMissingRequiredRoles)
 +            return;
 +          Set roles = Collections.unmodifiableSet(new HashSet(
 +              this.missingRequiredRoles));
 +          Assert.assertTrue(!roles.isEmpty());
 +          throw new RegionAccessException(LocalizedStrings.DistributedRegion_OPERATION_IS_DISALLOWED_BY_LOSSACTION_0_BECAUSE_THESE_REQUIRED_ROLES_ARE_MISSING_1
 +              .toLocalizedString(new Object[] { getMembershipAttributes().getLossAction(), roles}), getFullPath(), roles);
 +        }
 +      }
 +    }
 +  }
 +  
 +  @Override
 +  protected void handleReliableDistribution(ReliableDistributionData data,
 +      Set successfulRecipients) {
 +    handleReliableDistribution(data, successfulRecipients,
 +        Collections.EMPTY_SET, Collections.EMPTY_SET);
 +  }
 +
 +  protected void handleReliableDistribution(ReliableDistributionData data,
 +      Set successfulRecipients, Set otherRecipients1, Set otherRecipients2)
 +  {
 +    if (this.requiresReliabilityCheck) {
 +      MembershipAttributes ra = getMembershipAttributes();
 +      Set recipients = successfulRecipients;
 +      // determine the successful roles
 +      Set roles = new HashSet();
 +      for (Iterator iter = recipients.iterator(); iter.hasNext();) {
 +        InternalDistributedMember mbr = (InternalDistributedMember)iter.next();
 +        if (mbr != null) {
 +          roles.addAll(mbr.getRoles());
 +        }
 +      }
 +      for (Iterator iter = otherRecipients1.iterator(); iter.hasNext();) {
 +        InternalDistributedMember mbr = (InternalDistributedMember)iter.next();
 +        if (mbr != null) {
 +          roles.addAll(mbr.getRoles());
 +        }
 +      }
 +      for (Iterator iter = otherRecipients2.iterator(); iter.hasNext();) {
 +        InternalDistributedMember mbr = (InternalDistributedMember)iter.next();
 +        if (mbr != null) {
 +          roles.addAll(mbr.getRoles());
 +        }
 +      }
 +      // determine the missing roles
 +      Set failedRoles = new HashSet(ra.getRequiredRoles());
 +      failedRoles.removeAll(roles);
 +      if (failedRoles.isEmpty())
 +        return;
 +//       if (rp.isAllAccessWithQueuing()) {
 +//         this.rmq.add(data, failedRoles);
 +//       } else {
 +
 +      throw new RegionDistributionException(LocalizedStrings.DistributedRegion_OPERATION_DISTRIBUTION_MAY_HAVE_FAILED_TO_NOTIFY_THESE_REQUIRED_ROLES_0.toLocalizedString(failedRoles), getFullPath(), failedRoles);
 +//       }
 +    }
 +  }
 +
 +  /**
 +   * 
 +   * Called when we do a distributed operation and don't have anyone to
 +   * distributed it too. Since this is only called when no distribution was done
 +   * (i.e. no recipients) we do not check isMissingRequiredRoles because it
 +   * might not longer be true due to race conditions
 +   * 
 +   * @return false if this region has at least one required role and queuing is
 +   *         configured. Returns true if sending to no one is ok.
 +   * @throws RoleException
 +   *           if a required role is missing and the LossAction is either
 +   *           NO_ACCESS or LIMITED_ACCESS.
 +   * @since 5.0
 +   */
 +  protected boolean isNoDistributionOk()
 +  {
 +    if (this.requiresReliabilityCheck) {
 +      MembershipAttributes ra = getMembershipAttributes();
 +      //       if (ra.getLossAction().isAllAccessWithQueuing()) {
 +      //         return !ra.hasRequiredRoles();
 +      //       } else {
 +      Set failedRoles = ra.getRequiredRoles();
 +      throw new RegionDistributionException(LocalizedStrings.DistributedRegion_OPERATION_DISTRIBUTION_WAS_NOT_DONE_TO_THESE_REQUIRED_ROLES_0.toLocalizedString(failedRoles), getFullPath(), failedRoles);
 +      //       }
 +    }
 +    return true;
 +  }
 +  
 +  /**
 +   * returns true if this Region does not distribute its operations to other
 +   * members.
 +   * @since 6.0
 +   * @see HARegion#localDestroyNoCallbacks(Object)
 +   */
 +  public boolean doesNotDistribute() {
 +    return false;
 +  }
 +
 +  
 +  @Override
 +  public boolean shouldSyncForCrashedMember(InternalDistributedMember id) {
 +    return !doesNotDistribute() && super.shouldSyncForCrashedMember(id);
 +  }
 +  
 +  
 +  /**
 +   * Adjust the specified set of recipients by removing any of them that are
 +   * currently having their data queued.
 +   * 
 +   * @param recipients
 +   *          the set of recipients that a message is to be distributed too.
 +   *          Recipients that are currently having their data queued will be
 +   *          removed from this set.
 +   * @return the set, possibly null, of recipients that are currently having
 +   *         their data queued.
 +   * @since 5.0
 +   */
 +  protected Set adjustForQueuing(Set recipients)
 +  {
 +    Set result = null;
 +    //     if (this.requiresReliabilityCheck) {
 +    //       MembershipAttributes ra = getMembershipAttributes();
 +    //       if (ra.getLossAction().isAllAccessWithQueuing()) {
 +    //         Set currentQueuedRoles = this.rmq.getQueuingRoles();
 +    //         if (currentQueuedRoles != null) {
 +    //           // foreach recipient see if any of his roles are queued and if
 +    //           // they are remove him from recipients and add him to result
 +    //           Iterator it = recipients.iterator();
 +    //           while (it.hasNext()) {
 +    //             DistributedMember dm = (DistributedMember)it.next();
 +    //             Set dmRoles = dm.getRoles();
 +    //             if (!dmRoles.isEmpty()) {
 +    //               if (intersects(dmRoles, currentQueuedRoles)) {
 +    //                 it.remove(); // fix for bug 34447
 +    //                 if (result == null) {
 +    //                   result = new HashSet();
 +    //                 }
 +    //                 result.add(dm);
 +    //               }
 +    //             }
 +    //           }
 +    //         }
 +    //       }
 +    //     }
 +    return result;
 +  }
 +
 +  /**
 +   * Returns true if the two sets intersect
 +   * 
 +   * @param a
 +   *          a non-null non-empty set
 +   * @param b
 +   *          a non-null non-empty set
 +   * @return true if sets a and b intersect; false if not
 +   * @since 5.0
 +   */
 +  public static boolean intersects(Set a, Set b)
 +  {
 +    Iterator it;
 +    Set target;
 +    if (a.size() <= b.size()) {
 +      it = a.iterator();
 +      target = b;
 +    }
 +    else {
 +      it = b.iterator();
 +      target = a;
 +    }
 +    while (it.hasNext()) {
 +      if (target.contains(it.next()))
 +        return true;
 +    }
 +    return false;
 +  }
 +
 +  @Override
 +  public boolean requiresReliabilityCheck()
 +  {
 +    return this.requiresReliabilityCheck;
 +  }
 +
 +  /**
 +   * Returns true if the ExpiryTask is currently allowed to expire.
 +   * <p>
 +   * If the region is in NO_ACCESS due to reliability configuration, then no
 +   * expiration actions are allowed.
 +   * <p>
 +   * If the region is in LIMITED_ACCESS due to reliability configuration, then
 +   * only non-distributed expiration actions are allowed.
 +   */
 +  @Override
 +  protected boolean isExpirationAllowed(ExpiryTask expiry)
 +  {
 +    if (this.requiresReliabilityCheck && this.isMissingRequiredRoles) {
 +      if (getMembershipAttributes().getLossAction().isNoAccess()) {
 +        return false;
 +      }
 +      if (getMembershipAttributes().getLossAction().isLimitedAccess()
 +          && expiry.isDistributedAction()) {
 +        return false;
 +      }
 +    }
 +    return true;
 +  }
 +
 +  /**
 +   * Performs the resumption action when reliability is resumed.
 +   * 
 +   * @return true if asynchronous resumption is triggered
 +   */
 +  protected boolean resumeReliability(InternalDistributedMember id,
 +      Set newlyAcquiredRoles)
 +  {
 +    boolean async = false;
 +    try {
 +      ResumptionAction ra = getMembershipAttributes().getResumptionAction();
 +      if (ra.isNone()) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Reliability resumption for action of none");
 +        }
 +        resumeExpiration();
 +      }
 +      else if (ra.isReinitialize()) {
 +        async = true;
 +        asyncResumeReliability(id, newlyAcquiredRoles);
 +      }
 +    }
 +    catch (Exception e) {
 +      logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
 +    }
 +    return async;
 +  }
 +
 +  /**
 +   * Handles asynchronous ResumptionActions such as region reinitialize.
 +   */
 +  private void asyncResumeReliability(final InternalDistributedMember id,
 +                                      final Set newlyAcquiredRoles)
 +                               throws RejectedExecutionException {
 +    final ResumptionAction ra = getMembershipAttributes().getResumptionAction();
 +    getDistributionManager().getWaitingThreadPool().execute(new Runnable() {
 +      public void run()
 +      {
 +        try {
 +          if (ra.isReinitialize()) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Reliability resumption for action of reinitialize");
 +            }
 +            if (!isDestroyed() && !cache.isClosed()) {
 +              RegionEventImpl event = new RegionEventImpl(
 +                  DistributedRegion.this, Operation.REGION_REINITIALIZE, null,
 +                  false, getMyId(), generateEventID());
 +              reinitialize(null, event);
 +            }
 +            synchronized (missingRequiredRoles) {
 +              // any number of threads may be waiting on missingRequiredRoles
 +              missingRequiredRoles.notifyAll();
 +              if (hasListener() && id != null) {
 +                // fire afterRoleGain event
 +                RoleEventImpl relEvent = new RoleEventImpl(
 +                    DistributedRegion.this, Operation.REGION_CREATE, null,
 +                    true, id, newlyAcquiredRoles);
 +                dispatchListenerEvent(EnumListenerEvent.AFTER_ROLE_GAIN,
 +                    relEvent);
 +              }
 +            }
 +          }
 +        }
 +        catch (Exception e) {
 +          logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
 +        }
 +      }
 +    });
 +  }
 +
 +  /** Reschedules expiry tasks when reliability is resumed. */
 +  private void resumeExpiration()
 +  {
 +    boolean isNoAccess = getMembershipAttributes().getLossAction().isNoAccess();
 +    boolean isLimitedAccess = getMembershipAttributes().getLossAction()
 +        .isLimitedAccess();
 +    if (!(isNoAccess || isLimitedAccess)) {
 +      return; // early out: expiration was never affected by reliability
 +    }
 +
 +    if (getEntryTimeToLive().getTimeout() > 0
 +        && (isNoAccess || (isLimitedAccess && getEntryTimeToLive().getAction()
 +            .isDistributed()))) {
 +      rescheduleEntryExpiryTasks();
 +    }
 +    else 
 +    if (getEntryIdleTimeout().getTimeout() > 0
 +        && (isNoAccess || (isLimitedAccess && getEntryIdleTimeout().getAction()
 +            .isDistributed()))) {
 +      rescheduleEntryExpiryTasks();
 +    }
 +    else
 +    if (getCustomEntryTimeToLive() != null || getCustomEntryIdleTimeout() != null) {
 +      // Force all entries to be rescheduled
 +      rescheduleEntryExpiryTasks();
 +    }
 +
 +    if (getRegionTimeToLive().getTimeout() > 0
 +        && (isNoAccess || (isLimitedAccess && getRegionTimeToLive().getAction()
 +            .isDistributed()))) {
 +      addTTLExpiryTask();
 +    }
 +    if (getRegionIdleTimeout().getTimeout() > 0
 +        && (isNoAccess || (isLimitedAccess && getRegionIdleTimeout()
 +            .getAction().isDistributed()))) {
 +      addIdleExpiryTask();
 +    }
 +  }
 +
 +  /**
 +   * A boolean used to indicate if its the intialization time i.e the
 +   * distributed Region is created for the first time. The variable is used at
 +   * the time of lost reliablility.
 +   */
 +  private boolean isInitializingThread = false;
 +
 +  /**
 +   * Called when reliability is lost. If MembershipAttributes are configured
 +   * with {@link LossAction#RECONNECT}then DistributedSystem reconnect will be
 +   * called asynchronously.
 +   * 
 +   * @return true if asynchronous resumption is triggered
 +   */
 +  protected boolean lostReliability(final InternalDistributedMember id,
 +      final Set newlyMissingRoles)
 +  {
 +    if (DistributedRegion.ignoreReconnect)
 +      return false;
 +    boolean async = false;
 +    try {
 +      if (getMembershipAttributes().getLossAction().isReconnect()) {
 +        async = true;
 +        if (isInitializingThread) {
 +          doLostReliability(true, id, newlyMissingRoles);
 +        }
 +        else {
 +          doLostReliability(false, id, newlyMissingRoles);
 +        }
 +        // we don't do this in the waiting pool because we're going to
 +        // disconnect
 +        // the distributed system, and it will wait for the pool to empty
 +        /*
 +         * moved to a new method called doLostReliablity. Thread t = new
 +         * Thread("Reconnect Distributed System") { public void run() { try { //
 +         * TODO: may need to check isReconnecting and checkReadiness...
 +         * initializationLatchAfterMemberTimeout.await(); // TODO:
 +         * call reconnect here
 +         * getSystem().tryReconnect((GemFireCache)getCache()); // added for
 +         * reconnect. synchronized (missingRequiredRoles) { // any number of
 +         * threads may be waiting on missingRequiredRoles
 +         * missingRequiredRoles.notifyAll(); // need to fire an event if id is
 +         * not null if (hasListener() && id != null) { RoleEventImpl relEvent =
 +         * new RoleEventImpl( DistributedRegion.this, Operation.CACHE_RECONNECT,
 +         * null, true, id, newlyMissingRoles); dispatchListenerEvent(
 +         * EnumListenerEvent.AFTER_ROLE_LOSS, relEvent); } } } catch (Exception
 +         * e) { } } };
 +         * t.setDaemon(true); t.start();
 +         */
 +      }
 +    }
 +    catch (CancelException cce) {
 +      throw cce;
 +    }
 +    catch (Exception e) {
 +      logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
 +    }
 +    return async;
 +  }
 +
 +  private void doLostReliability(boolean isInitializing,
 +      final InternalDistributedMember id, final Set newlyMissingRoles)
 +  {
 +    try {
 +      if (!isInitializing) {
 +        // moved code to a new thread.
 +        Thread t = new Thread(LocalizedStrings.DistributedRegion_RECONNECT_DISTRIBUTED_SYSTEM.toLocalizedString()) {
 +          @Override
 +          public void run()
 +          {
 +            try {
 +              // TODO: may need to check isReconnecting and checkReadiness...
 +              if (logger.isDebugEnabled()) {
 +                logger.debug("Reliability loss with policy of reconnect and membership thread doing reconnect");
 +              }
 +              initializationLatchAfterMemberTimeout.await();
 +              getSystem().tryReconnect(false, "Role Loss", getCache());
 +              synchronized (missingRequiredRoles) {
 +                // any number of threads may be waiting on missingRequiredRoles
 +                missingRequiredRoles.notifyAll();
 +                // need to fire an event if id is not null
 +                if (hasListener() && id != null) {
 +                  RoleEventImpl relEvent = new RoleEventImpl(
 +                      DistributedRegion.this, Operation.CACHE_RECONNECT, null,
 +                      true, id, newlyMissingRoles);
 +                  dispatchListenerEvent(EnumListenerEvent.AFTER_ROLE_LOSS,
 +                      relEvent);
 +                }
 +              }
 +            }
 +            catch (Exception e) {
 +              logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
 +            }
 +          }
 +        };
 +        t.setDaemon(true);
 +        t.start();
 +
 +      }
 +      else {
 +        getSystem().tryReconnect(false, "Role Loss", getCache()); // added for
 +        // reconnect.
 +        synchronized (missingRequiredRoles) {
 +          // any number of threads may be waiting on missingRequiredRoles
 +          missingRequiredRoles.notifyAll();
 +          // need to fire an event if id is not null
 +          if (hasListener() && id != null) {
 +            RoleEventImpl relEvent = new RoleEventImpl(DistributedRegion.this,
 +                Operation.CACHE_RECONNECT, null, true, id, newlyMissingRoles);
 +            dispatchListenerEvent(EnumListenerEvent.AFTER_ROLE_LOSS, relEvent);
 +          }
 +        }
 +        // } catch (CancelException cce){
 +
 +        // }
 +
 +      }
 +    }
 +    catch (CancelException ignor) {
 +      throw ignor;
 +    }
 +    catch (Exception e) {
 +      logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
 +    }
 +
 +  }
 +
 +  protected void lockCheckReadiness()
 +  {
 +    // fix for bug 32610
 +    cache.getCancelCriterion().checkCancelInProgress(null);
 +    checkReadiness();
 +  }
 +
 +  @Override
 +  public final Object validatedDestroy(Object key, EntryEventImpl event)
 +      throws TimeoutException, EntryNotFoundException, CacheWriterException {
 +    Lock dlock = this.getDistributedLockIfGlobal(key);
 +    try {
 +      return super.validatedDestroy(key, event);
 +    } finally {
 +      if (dlock != null) {
 +        dlock.unlock();
 +      }
 +    }
 +  }
 +
 +  /**
 +   * @see LocalRegion#localDestroyNoCallbacks(Object)
 +   */
 +  @Override
 +  public void localDestroyNoCallbacks(Object key)
 +  {
 +    super.localDestroyNoCallbacks(key);
 +    if (getScope().isGlobal()) {
 +      try {
 +        this.getLockService().freeResources(key);
 +      }
 +      catch (LockServiceDestroyedException ignore) {
 +      }
 +    }
 +  }
 +
 +  /**
 +   * @see LocalRegion#localDestroy(Object, Object)
 +   */
 +  @Override
 +  public void localDestroy(Object key, Object aCallbackArgument)
 +      throws EntryNotFoundException
 +  {
 +    super.localDestroy(key, aCallbackArgument);
 +    if (getScope().isGlobal()) {
 +      try {
 +        this.getLockService().freeResources(key);
 +      }
 +      catch (LockServiceDestroyedException ignore) {
 +      }
 +    }
 +  }
 +
 +  /**
 +   * @see LocalRegion#invalidate(Object, Object)
 +   */
 +  @Override
 +  public void invalidate(Object key, Object aCallbackArgument)
 +      throws TimeoutException, EntryNotFoundException
 +  {
 +    validateKey(key);
 +    validateCallbackArg(aCallbackArgument);
 +    checkReadiness();
 +    checkForLimitedOrNoAccess();
 +    Lock dlock = this.getDistributedLockIfGlobal(key);
 +    try {
 +      super.validatedInvalidate(key, aCallbackArgument);
 +    }
 +    finally {
 +      if (dlock != null)
 +        dlock.unlock();
 +    }
 +  }
 +
 +  @Override
 +  public Lock getRegionDistributedLock() throws IllegalStateException
 +  {
 +    lockCheckReadiness();
 +    checkForLimitedOrNoAccess();
 +    if (!this.scope.isGlobal()) {
 +      throw new IllegalStateException(LocalizedStrings.DistributedRegion_DISTRIBUTION_LOCKS_ARE_ONLY_SUPPORTED_FOR_REGIONS_WITH_GLOBAL_SCOPE_NOT_0.toLocalizedString(this.scope));
 +    }
 +    return new RegionDistributedLock();
 +  }
 +
 +  @Override
 +  public Lock getDistributedLock(Object key) throws IllegalStateException
 +  {
 +    validateKey(key);
 +    lockCheckReadiness();
 +    checkForLimitedOrNoAccess();
 +    if (!this.scope.isGlobal()) {
 +      throw new IllegalStateException(LocalizedStrings.DistributedRegion_DISTRIBUTION_LOCKS_ARE_ONLY_SUPPORTED_FOR_REGIONS_WITH_GLOBAL_SCOPE_NOT_0.toLocalizedString(this.scope));
 +    }
 +    if (isLockingSuspendedByCurrentThread()) {
 +      throw new IllegalStateException(LocalizedStrings.DistributedRegion_THIS_THREAD_HAS_SUSPENDED_ALL_LOCKING_FOR_THIS_REGION.toLocalizedString());
 +    }
 +    return new DistributedLock(key);
 +  }
 +
 +  /**
 +   * Called while NOT holding lock on parent's subregions
 +   * 
 +   * @throws IllegalStateException
 +   *           if region is not compatible with a region in another VM.
 +   * 
 +   * @see LocalRegion#initialize(InputStream, InternalDistributedMember, InternalRegionArguments)
 +   */
 +  @Override
 +  protected void initialize(InputStream snapshotInputStream,
 +      InternalDistributedMember imageTarget, InternalRegionArguments internalRegionArgs) throws TimeoutException,
 +      IOException, ClassNotFoundException
 +  {
 +    Assert.assertTrue(!isInitialized());
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("DistributedRegion.initialize BEGIN: {}", getFullPath());
 +    }
 +
 +    // if we're versioning entries we need a region-level version vector
 +    if (this.scope.isDistributed() && this.concurrencyChecksEnabled) {
 +      createVersionVector();
 +    }
 +
 +    if (this.scope.isGlobal()) {
 +      getLockService(); // create lock service eagerly now
 +    }
 +
 +    final IndexUpdater indexUpdater = getIndexUpdater();
 +    boolean sqlfGIILockTaken = false;
 +    // this try block is to release the SQLF GII lock in finally
 +    // which should be done after bucket status will be set
 +    // properly in LocalRegion#initialize()
 +    try {
 +     try {
 +      try {
 +        // take the GII lock to avoid missing entries while updating the
 +        // index list for SQLFabric (#41330 and others)
 +        if (indexUpdater != null) {
 +          indexUpdater.lockForGII();
 +          sqlfGIILockTaken = true;
 +        }
 +        
 +        PersistentMemberID persistentId = null;
 +        boolean recoverFromDisk = isRecoveryNeeded();
 +        DiskRegion dskRgn = getDiskRegion();
 +        if (recoverFromDisk) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("DistributedRegion.getInitialImageAndRecovery: Starting Recovery");
 +          }
 +          dskRgn.initializeOwner(this); // do recovery
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("DistributedRegion.getInitialImageAndRecovery: Finished Recovery");
 +          }
 +          persistentId = dskRgn.getMyPersistentID();
 +        }
 +        
 +        // Create OQL indexes before starting GII.
 +        createOQLIndexes(internalRegionArgs, recoverFromDisk);
 + 
 +        if (getDataPolicy().withReplication()
 +            || getDataPolicy().withPreloaded()) {
 +          getInitialImageAndRecovery(snapshotInputStream, imageTarget,
 +              internalRegionArgs, recoverFromDisk, persistentId);
 +        }
 +        else {
 +          new CreateRegionProcessor(this).initializeRegion();
 +          if (snapshotInputStream != null) {
 +            releaseBeforeGetInitialImageLatch();
 +            loadSnapshotDuringInitialization(snapshotInputStream);
 +          }
 +        }
 +      }
 +      catch (DiskAccessException dae) {
 +        this.handleDiskAccessException(dae, true);
 +        throw dae;
 +      }
 +
 +      initMembershipRoles();
 +      isInitializingThread = false;
 +      super.initialize(null, null, null); // makes sure all latches are released if they haven't been already
 +     } finally {
 +      if (this.eventTracker != null) {
 +        this.eventTracker.setInitialized();
 +      }
 +     }
 +    } finally {
 +      if (sqlfGIILockTaken) {
 +        indexUpdater.unlockForGII();
 +      }
 +    }
 +  }
 +
 +  @Override
 +  public void initialized() {
 +    new UpdateAttributesProcessor(this).distribute(false);
 +  }
 +
 +  /** True if GII was impacted by missing required roles */
 +  private boolean giiMissingRequiredRoles = false;
 +
 +  /**
 +   * A reference counter to protected the memoryThresholdReached boolean
 +   */
 +  private final Set<DistributedMember> memoryThresholdReachedMembers =
 +    new CopyOnWriteArraySet<DistributedMember>();
 +
 +  private ConcurrentParallelGatewaySenderQueue hdfsQueue;
 +
 +  /** Sets and returns giiMissingRequiredRoles */
 +  private boolean checkInitialImageForReliability(
 +      InternalDistributedMember imageTarget,
 +      CacheDistributionAdvisor.InitialImageAdvice advice)
 +  {
 +    // assumption: required roles are interesting to GII only if Reinitialize...
 +//    if (true)
 +      return false;
 +//    if (getMembershipAttributes().hasRequiredRoles()
 +//        && getMembershipAttributes().getResumptionAction().isReinitialize()) {
 +//      // are any required roles missing for GII with Reinitialize?
 +//      Set missingRR = new HashSet(getMembershipAttributes().getRequiredRoles());
 +//      missingRR.removeAll(getSystem().getDistributedMember().getRoles());
 +//      for (Iterator iter = advice.replicates.iterator(); iter.hasNext();) {
 +//        DistributedMember member = (DistributedMember)iter.next();
 +//        missingRR.removeAll(member.getRoles());
 +//      }
 +//      for (Iterator iter = advice.others.iterator(); iter.hasNext();) {
 +//        DistributedMember member = (DistributedMember)iter.next();
 +//        missingRR.removeAll(member.getRoles());
 +//      }
 +//      for (Iterator iter = advice.preloaded.iterator(); iter.hasNext();) {
 +//        DistributedMember member = (DistributedMember)iter.next();
 +//        missingRR.removeAll(member.getRoles());
 +//      }
 +//      if (!missingRR.isEmpty()) {
 +//        // entering immediate loss condition, which will cause reinit on resume
 +//        this.giiMissingRequiredRoles = true;
 +//      }
 +//    }
 +//    return this.giiMissingRequiredRoles;
 +  }
 +
 +  private void getInitialImageAndRecovery(InputStream snapshotInputStream,
 +      InternalDistributedMember imageSrc, InternalRegionArguments internalRegionArgs,
 +      boolean recoverFromDisk, PersistentMemberID persistentId) throws TimeoutException
 +  {
 +    logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_0, this.getName()));
 +  
 +    ImageState imgState = getImageState();
 +    imgState.init();
 +    boolean targetRecreated = internalRegionArgs.getRecreateFlag();
 +    Boolean isCBool = (Boolean)isConversion.get();
 +    boolean isForConversion = isCBool!=null?isCBool.booleanValue():false;
 +
 +    if (recoverFromDisk && snapshotInputStream != null && !isForConversion) {
 +      throw new InternalGemFireError(LocalizedStrings.DistributedRegion_IF_LOADING_A_SNAPSHOT_THEN_SHOULD_NOT_BE_RECOVERING_ISRECOVERING_0_SNAPSHOTSTREAM_1.toLocalizedString(new Object[] {Boolean.valueOf(recoverFromDisk), snapshotInputStream}));
 +    }
 +
 +    ProfileExchangeProcessor targetProvider;
 +    if (dataPolicy.withPersistence()) {
 +      targetProvider = new CreatePersistentRegionProcessor(this,
 +          getPersistenceAdvisor(), recoverFromDisk);
 +    }
 +    else {
 +      // this will go in the advisor profile
 +      targetProvider = new CreateRegionProcessor(this);
 +    }
 +    imgState.setInRecovery(false);
 +    RegionVersionVector recovered_rvv = null;
 +    if (dataPolicy.withPersistence()) {
 +      recovered_rvv = (this.getVersionVector()==null?null:this.getVersionVector().getCloneForTransmission());
 +    }
 +      // initializeRegion will send out our profile
 +    targetProvider.initializeRegion();
 +    
 +    if(persistenceAdvisor != null) {
 +      persistenceAdvisor.initialize();
 +    }
 +    
 +    // Register listener here so that the remote members are known
 +    // since registering calls initializeCriticalMembers (which needs to know about
 +    // remote members
 +    if (!isInternalRegion()) {
 +      if (!this.isDestroyed) {
 +        cache.getResourceManager().addResourceListener(ResourceType.MEMORY, this);
 +      }
 +    }
 +    
 +    releaseBeforeGetInitialImageLatch();
 +
 +    // allow GII to invoke test hooks.  Do this just after releasing the
 +    // before-gii latch for bug #48962.  See ConcurrentLeaveDuringGIIDUnitTest
 +    InitialImageOperation.beforeGetInitialImage(this);
 +    
 +    if (snapshotInputStream != null) {
 +      try {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("DistributedRegion.getInitialImageAndRecovery: About to load snapshot, isInitialized={}; {}",
 +              isInitialized(), getFullPath());
 +        }
 +        loadSnapshotDuringInitialization(snapshotInputStream);
 +      }
 +      catch (IOException e) {
 +        throw new RuntimeException(e); // @todo change this exception?
 +      }
 +      catch (ClassNotFoundException e) {
 +        throw new RuntimeException(e); // @todo change this exception?
 +      }
 +      cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
 +      return;
 +    }
 +    
 +    // No snapshot provided, use the imageTarget(s)
 +
 +    // if we were given a recommended imageTarget, use that first, and
 +    // treat it like it is a replicate (regardless of whether it actually is
 +    // or not)
 +
 +    InitialImageOperation iiop = new InitialImageOperation(this, this.entries);
 +    // [defunct] Special case GII for PR admin regions (which are always
 +    // replicates and always writers
 +    // bruce: this was commented out after adding the GIIAckRequest logic to
 +    // force
 +    //        consistency before the gii operation begins
 +    //      if (isUsedForPartitionedRegionAdmin() ||
 +    // isUsedForPartitionedRegionBucket()) {
 +    //        releaseBeforeGetInitialImageLatch();
 +    //        iiop.getFromAll(this.distAdvisor.adviseGeneric(), false);
 +    //        cleanUpDestroyedTokens();
 +    //        return;
 +    //      }
 +
 +
 +    CacheDistributionAdvisor.InitialImageAdvice advice = null;
 +    boolean done = false;
 +    while(!done && !isDestroyed()) {
 +      advice = targetProvider.getInitialImageAdvice(advice);
 +      checkInitialImageForReliability(imageSrc, advice);
 +      boolean attemptGetFromOne = 
 +        imageSrc != null // we were given a specific member
 +        || this.dataPolicy.withPreloaded()
 +           && !advice.preloaded.isEmpty() // this is a preloaded region
 +        || (!advice.replicates.isEmpty());
 +      // That is: if we have 0 or 1 giiProvider then we can do a getFromOne gii;
 +      // if we have 2 or more giiProviders then we must do a getFromAll gii.
 +
 +      if (attemptGetFromOne) {
 +        if (recoverFromDisk) {
 +          if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER){
 +            CacheObserverHolder.getInstance().afterMarkingGIIStarted();
 +          }
 +        }
 +        {
 +          // If we have an imageSrc and the target is reinitializing mark the
 +          // getInitialImage so that it will wait until the target region is fully initialized
 +          // before responding to the get image request. Otherwise, the
 +          // source may respond with no data because it is still initializing,
 +          // e.g. loading a snapshot.
 +
 +          // Plan A: use specified imageSrc, if specified
 +          if (imageSrc != null) {
 +            try {
 +              GIIStatus ret = iiop.getFromOne(Collections.singleton(imageSrc),
 +                  targetRecreated, advice, recoverFromDisk, recovered_rvv);
 +              if (GIIStatus.didGII(ret)) {
 +                this.giiMissingRequiredRoles = false;
 +                cleanUpDestroyedTokensAndMarkGIIComplete(ret);
 +                done = true;
 +                return;
 +              }
 +            } finally {
 +              imageSrc = null;
 +            }
 +          }
 +
 +          // Plan C: use a replicate, if one exists
 +          GIIStatus ret = iiop.getFromOne(advice.replicates, false, advice, recoverFromDisk, recovered_rvv);
 +          if (GIIStatus.didGII(ret)) {
 +            cleanUpDestroyedTokensAndMarkGIIComplete(ret);
 +            done = true;
 +            return;
 +          }
 +
 +          // Plan D: if this is a PRELOADED region, fetch from another PRELOADED
 +          if (this.dataPolicy.isPreloaded()) {
 +            GIIStatus ret_preload = iiop.getFromOne(advice.preloaded, false, advice, recoverFromDisk, recovered_rvv);
 +            if (GIIStatus.didGII(ret_preload)) {
 +              cleanUpDestroyedTokensAndMarkGIIComplete(ret_preload);
 +              done = true;
 +              return;
 +            }
 +          } // isPreloaded
 +        }
 +
 +        //If we got to this point, we failed in the GII. Cleanup
 +        //any partial image we received
 +        cleanUpAfterFailedGII(recoverFromDisk);
 +
 +      } // attemptGetFromOne
 +      else {
 +        if(!isDestroyed()) {
 +          if(recoverFromDisk) {
 +            logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZED_FROM_DISK,
 +                new Object[] {this.getFullPath(), persistentId, getPersistentID()}));
 +            if(persistentId != null) {
 +              RegionLogger.logRecovery(this.getFullPath(), persistentId,
 +                  getDistributionManager().getDistributionManagerId());
 +            }
 +          } else {
 +            RegionLogger.logCreate(this.getFullPath(),
 +                getDistributionManager().getDistributionManagerId());
 +            
 +            if (getPersistentID() != null) {
 +              RegionLogger.logPersistence(this.getFullPath(),
 +                  getDistributionManager().getDistributionManagerId(),
 +                  getPersistentID());
 +              logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_NEW_PERSISTENT_REGION_CREATED,
 +                  new Object[] {this.getFullPath(), getPersistentID()}));
 +            }
 +          }
 +          
 +          /* no more union GII
 +            // do union getInitialImage
 +            Set rest = new HashSet();
 +            rest.addAll(advice.others);
 +            rest.addAll(advice.preloaded);
 +            // push profile w/ recovery flag turned off at same time that we
 +            // do a union getInitialImage
 +            boolean pushProfile = recoverFromDisk;
 +            iiop.getFromAll(rest, pushProfile);
 +           */
 +          cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
 +          done = true;
 +          return;
 +        }
 +        break;
 +      }
 +    }
 +
 +    return;
 +  }
 +  
 +  private void synchronizeWith(InternalDistributedMember target, 
 +      VersionSource idToRecover) {
 +    InitialImageOperation op = new InitialImageOperation(this, this.entries);
 +    op.synchronizeWith(target, idToRecover, null);
 +  }
 +  
 +  /**
 +   * If this region has concurrency controls enabled this will pull any missing
 +   * changes from other replicates using InitialImageOperation and a filtered
 +   * chunking protocol.
 +   */
 +  public void synchronizeForLostMember(InternalDistributedMember
 +      lostMember, VersionSource lostVersionID) {
 +    if (this.concurrencyChecksEnabled == false) {
 +      return;
 +    }
 +    CacheDistributionAdvisor advisor = getCacheDistributionAdvisor();
 +    Set<InternalDistributedMember> targets = advisor.adviseInitializedReplicates();
 +    for (InternalDistributedMember target: targets) {
 +      synchronizeWith(target, lostVersionID, lostMember);
 +    }
 +  }
 +  
 +  /**
 +   * synchronize with another member wrt messages from the given "lost" member.
 +   * This can be used when a primary bucket crashes to ensure that interrupted
 +   * message distribution is mended.
 +   */
 +  private void synchronizeWith(InternalDistributedMember target,
 +      VersionSource versionMember, InternalDistributedMember lostMember) {
 +    InitialImageOperation op = new InitialImageOperation(this, this.entries);
 +    op.synchronizeWith(target, versionMember, lostMember);
 +  }
 +
 +  /**
 +   * invoked just before an initial image is requested from another member
 +   */
 +  /** remove any partial entries received in a failed GII */
 +  protected void cleanUpAfterFailedGII(boolean recoverFromDisk) {
 +    DiskRegion dskRgn = getDiskRegion();
 +    //if we have a persistent region, instead of deleting everything on disk,
 +    //we will just reset the "recovered from disk" flag. After
 +    //the next GII we will delete these entries if they do not come
 +    //in as part of the GII.
 +    if (recoverFromDisk && dskRgn != null && dskRgn.isBackup()) {
 +      dskRgn.resetRecoveredEntries(this);
 +      return;
 +    }
 +
 +    if (!this.entries.isEmpty()) {
 +      closeEntries();
 +      if (getDiskRegion() != null) {
 +        getDiskRegion().clear(this, null);
 +      }
 +      // clear the left-members and version-tags sets in imageState
 +      getImageState().getLeftMembers();
 +      getImageState().getVersionTags();
 +      // Clear OQL indexes
 +      if (this.indexManager != null) {
 +        try {
 +          this.indexManager.rerunIndexCreationQuery();
 +        } catch (Exception ex){
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Exception while clearing indexes after GII failure.", ex);
 +          }
 +        }
 +      }
 +    }
 +  }
 +
 +  private void initMembershipRoles()
 +  {
 +    synchronized (this.advisorListener) {
 +      // hold sync to prevent listener from changing initial members
 +      Set others = this.distAdvisor
 +          .addMembershipListenerAndAdviseGeneric(this.advisorListener);
 +      this.advisorListener.addMembers(others);
 +      // initialize missing required roles with initial member info
 +      if (getMembershipAttributes().hasRequiredRoles()) {
 +        // AdvisorListener will also sync on missingRequiredRoles
 +        synchronized (this.missingRequiredRoles) {
 +          this.missingRequiredRoles.addAll(getMembershipAttributes()
 +              .getRequiredRoles());
 +          // remove all the roles we are playing since they will never be
 +          // missing
 +          this.missingRequiredRoles.removeAll(getSystem()
 +              .getDistributedMember().getRoles());
 +          for (Iterator iter = others.iterator(); iter.hasNext();) {
 +            DistributedMember other = (DistributedMember)iter.next();
 +            this.missingRequiredRoles.removeAll(other.getRoles());
 +          }
 +        }
 +      }
 +    }
 +    if (getMembershipAttributes().hasRequiredRoles()) {
 +      // wait up to memberTimeout for required roles...
 +//      boolean requiredRolesAreMissing = false;
 +      int memberTimeout = getSystem().getConfig().getMemberTimeout();
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Waiting up to {} for required roles.", memberTimeout);
 +      }
 +      try {
 +        if (this.giiMissingRequiredRoles) {
 +          // force reliability loss and possibly resumption
 +          isInitializingThread = true;
 +          synchronized (this.advisorListener) {
 +            synchronized (this.missingRequiredRoles) {
 +              // forcing state of loss because of bad GII
 +              this.isMissingRequiredRoles = true;
 +              getCachePerfStats().incReliableRegionsMissing(1);
 +              if (getMembershipAttributes().getLossAction().isAllAccess())
 +                getCachePerfStats().incReliableRegionsMissingFullAccess(1); // rahul
 +              else if (getMembershipAttributes().getLossAction()
 +                  .isLimitedAccess())
 +                getCachePerfStats().incReliableRegionsMissingLimitedAccess(1);
 +              else if (getMembershipAttributes().getLossAction().isNoAccess())
 +                getCachePerfStats().incReliableRegionsMissingNoAccess(1);
 +              // pur code to increment the stats.
 +              if (logger.isDebugEnabled()) {
 +                logger.debug("GetInitialImage had missing required roles.");
 +              }
 +              // TODO: will this work with RECONNECT and REINITIALIZE?
 +              isInitializingThread = true;
 +              lostReliability(null, null);
 +              if (this.missingRequiredRoles.isEmpty()) {
 +                // all required roles are present so force resumption
 +                this.isMissingRequiredRoles = false;
 +                getCachePerfStats().incReliableRegionsMissing(-1);
 +                if (getMembershipAttributes().getLossAction().isAllAccess())
 +                  getCachePerfStats().incReliableRegionsMissingFullAccess(-1); // rahul
 +                else if (getMembershipAttributes().getLossAction()
 +                    .isLimitedAccess())
 +                  getCachePerfStats()
 +                      .incReliableRegionsMissingLimitedAccess(-1);
 +                else if (getMembershipAttributes().getLossAction().isNoAccess())
 +                  getCachePerfStats().incReliableRegionsMissingNoAccess(-1);
 +                // pur code to increment the stats.
 +                boolean async = resumeReliability(null, null);
 +                if (async) {
 +                  advisorListener.destroyed = true;
 +                }
 +              }
 +            }
 +          }
 +        }
 +        else {
 +          if (!getSystem().isLoner()) {
 +            waitForRequiredRoles(memberTimeout);
 +          }
 +          synchronized (this.advisorListener) {
 +            synchronized (this.missingRequiredRoles) {
 +              if (this.missingRequiredRoles.isEmpty()) {
 +                Assert.assertTrue(!this.isMissingRequiredRoles);
 +                if (logger.isDebugEnabled()) {
 +                  logger.debug("Initialization completed with all required roles present.");
 +                }
 +              }
 +              else {
 +                // starting in state of loss...
 +                this.isMissingRequiredRoles = true;
 +                getCachePerfStats().incReliableRegionsMissing(1);
 +                if (getMembershipAttributes().getLossAction().isAllAccess())
 +                  getCachePerfStats().incReliableRegionsMissingFullAccess(1); // rahul
 +                else if (getMembershipAttributes().getLossAction()
 +                    .isLimitedAccess())
 +                  getCachePerfStats().incReliableRegionsMissingLimitedAccess(1);
 +                else if (getMembershipAttributes().getLossAction().isNoAccess())
 +                  getCachePerfStats().incReliableRegionsMissingNoAccess(1);
 +                
 +                if (logger.isDebugEnabled()) {
 +                  logger.debug("Initialization completed with missing required roles: {}", this.missingRequiredRoles);
 +                }
 +                isInitializingThread = true;
 +                lostReliability(null, null);
 +              }
 +            }
 +          }
 +        }
 +      }
 +      catch (RegionDestroyedException ignore) {
 +        // ignore to fix bug 34639 may be thrown by waitForRequiredRoles
 +      }
 +      catch (CancelException ignore) {
 +        // ignore to fix bug 34639 may be thrown by waitForRequiredRoles
 +        if (isInitializingThread) {
 +          throw ignore;
 +        }
 +      }
 +      catch (Exception e) {
 +        logger.fatal(LocalizedMessage.create(LocalizedStrings.DistributedRegion_UNEXPECTED_EXCEPTION), e);
 +      }
 +
 +    }
 +    // open latch which will allow any threads in lostReliability to proceed
 +    this.initializationLatchAfterMemberTimeout.countDown();
 +  }
 +  private boolean isRecoveryNeeded() {
 +    return getDataPolicy().withPersistence()
 +      && getDiskRegion().isRecreated();
 +  }
 +
 +  // called by InitialImageOperation to clean up destroyed tokens
 +  // release afterGetInitialImageInitializationLatch before unlocking
 +  // cleanUpLock
 +  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UL_UNRELEASED_LOCK")
 +  private void cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus giiStatus)
 +  {
 +    //We need to clean up the disk before we release the after get initial image latch
 +    DiskRegion dskRgn = getDiskRegion();
 +    if (dskRgn != null && dskRgn.isBackup()) {
 +      dskRgn.finishInitializeOwner(this, giiStatus);
 +    }
 +    ImageState is = getImageState();
 +    is.lockGII();
 +    // clear the version tag and left-members sets
 +    is.getVersionTags();
 +    is.getLeftMembers();
 +    // remove DESTROYED tokens
 +    RegionVersionVector rvv = is.getClearRegionVersionVector();
 +    try {
 +      Iterator/*<Object>*/ keysIt = getImageState().getDestroyedEntries();
 +      while (keysIt.hasNext()) {
 +        this.entries.removeIfDestroyed(keysIt.next());
 +      }
 +      if (rvv != null) {
 +        // clear any entries received in the GII that are older than the RVV versions.
 +        // this can happen if entry chunks were received prior to the clear() being
 +        // processed
 +        clearEntries(rvv);
 +      }
 +      //need to do this before we release the afterGetInitialImageLatch
 +      if(persistenceAdvisor != null) {
 +        persistenceAdvisor.setOnline(GIIStatus.didGII(giiStatus), false, getPersistentID());
 +      }
 +    }
 +    finally {
 +      // release after gii lock first so basicDestroy will see isInitialized()
 +      // be true
 +      // when they get the cleanUp lock.
 +        try {
 +          releaseAfterGetInitialImageLatch();
 +        } finally { // make sure unlockGII is done for bug 40001
 +          is.unlockGII();
 +        }
 +    }
 +    
 +    if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER){
 +      CacheObserverHolder.getInstance().afterMarkingGIICompleted();
 +    }
 +    
 +    //"Initializing region {0}" which is not acompanied by a completed message. Users think thread is stuck in some operation. Hence adding this log
 +    logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_COMPLETED_0, this.getName()));
 +  }
 +
 +  /**
 +   * @see LocalRegion#basicDestroy(EntryEventImpl, boolean, Object)
 +   */
 +  @Override
 +  protected
 +  void basicDestroy(EntryEventImpl event,
 +                       boolean cacheWrite,
 +                       Object expectedOldValue)
 +  throws EntryNotFoundException, CacheWriterException, TimeoutException {
 +    //  disallow local destruction for mirrored keysvalues regions
 +    boolean invokeWriter = cacheWrite;
 +    boolean hasSeen = false;
 +    if (hasSeenEvent(event)) {
 +      hasSeen = true;
 +    }
 +    checkIfReplicatedAndLocalDestroy(event);
 +    
 +    try {
 +      if (this.requiresOneHopForMissingEntry(event)) {
 +        // bug #45704: see if a one-hop must be done for this operation
 +        RegionEntry re = getRegionEntry(event.getKey());
 +        if (re == null /*|| re.isTombstone()*/ || !this.generateVersionTag) {
 +          if (this.srp == null) {
 +            // only assert for non-client regions.
 +            Assert.assertTrue(!this.dataPolicy.withReplication() || !this.generateVersionTag);
 +          }
 +          if (!event.isBulkOpInProgress() || this.dataPolicy.withStorage()) {
 +            // removeAll will send a single one-hop for empty regions.  for other missing entries
 +            // we need to get a valid version number before modifying the local cache 
 +          // TODO: deltaGII: verify that delegating to a peer when this region is also a client is acceptable
 +          boolean didDistribute = RemoteDestroyMessage.distribute(event, expectedOldValue, !this.generateVersionTag);
 +
 +          if (!this.generateVersionTag && !didDistribute) {
 +            throw new PersistentReplicatesOfflineException();
 +          }
 +          
 +          if (didDistribute) {
 +            if (logger.isTraceEnabled()) {
 +              logger.trace("Event after remoteDestroy operation: {}", event);
 +            }
 +            invokeWriter = false; // remote cache invoked the writer
 +            if (event.getVersionTag() == null) {
 +              // if the event wasn't applied by the one-hop replicate it will not have a version tag
 +              // and so should not be applied to this cache
 +              return;
 +            }
 +          }
 +          }
 +        }
 +      }
 +      
 +      super.basicDestroy(event, invokeWriter, expectedOldValue);
 +
 +      // if this is a destroy coming in from remote source, free up lock resources
 +      // if this is a local origin destroy, this will happen after lock is
 +      // released
 +      if (this.scope.isGlobal() && event.isOriginRemote()) {
 +        try {
 +          getLockService().freeResources(event.getKey());
 +        }
 +        catch (LockServiceDestroyedException ignore) {
 +        }
 +      }
 +  
 +      return;
 +    } 
 +    finally {
 +      if (hasSeen) {
 +        if (event.isBulkOpInProgress() && !event.isOriginRemote()) {
 +          event.getRemoveAllOperation().addEntry(event, true);
 +        }
-         distributeDestroy(event, expectedOldValue);
-         event.invokeCallbacks(this,true, false);
++        if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++          distributeDestroy(event, expectedOldValue);
++          event.invokeCallbacks(this,true, false);
++        }
 +      }
 +    }
 +  }
 +
 +  @Override
 +  void basicDestroyPart3(RegionEntry re, EntryEventImpl event,
 +      boolean inTokenMode, boolean duringRI, boolean invokeCallbacks, Object expectedOldValue) {
 +  
 +    distributeDestroy(event, expectedOldValue);
 +    super.basicDestroyPart3(re, event, inTokenMode, duringRI, invokeCallbacks, expectedOldValue);
 +  }
 +  
 +  void distributeDestroy(EntryEventImpl event, Object expectedOldValue) {
 +    if (event.isDistributed() && !event.isOriginRemote() && !event.isBulkOpInProgress()) {
 +      boolean distribute = !event.getInhibitDistribution();
 +      if (distribute) {
 +        DestroyOperation op =  new DestroyOperation(event);
 +        op.distribute();
 +      }
 +    }
 +  }
 +  
 +  @Override
 +  boolean evictDestroy(LRUEntry entry) {
 +    boolean evictDestroyWasDone = super.evictDestroy(entry);
 +    if (evictDestroyWasDone) {
 +      if (this.scope.isGlobal()) {
 +        try {
 +          getLockService().freeResources(entry.getKey());
 +        }
 +        catch (LockServiceDestroyedException ignore) {
 +        }
 +      }
 +    }
 +    return evictDestroyWasDone;
 +  }
 +
 +
 +  /**
 +   * @see LocalRegion#basicInvalidateRegion(RegionEventImpl)
 +   */
 +  @Override
 +  void basicInvalidateRegion(RegionEventImpl event)
 +  {
 +    // disallow local invalidation for replicated regions
 +    if (!event.isDistributed() && getScope().isDistributed()
 +        && getDataPolicy().withReplication()) {
 +      throw new IllegalStateException(LocalizedStrings.DistributedRegion_NOT_ALLOWED_TO_DO_A_LOCAL_INVALIDATION_ON_A_REPLICATED_REGION.toLocalizedString());
 +    }
 +    if (shouldDistributeInvalidateRegion(event)) {
 +      distributeInvalidateRegion(event);
 +    }
 +    super.basicInvalidateRegion(event);
 +  }
 +
 +  /**
 +   * decide if InvalidateRegionOperation should be sent to peers. broken out so
 +   * that BucketRegion can override
 +   * @param event
 +   * @return true if {@link InvalidateRegionOperation} should be distributed, false otherwise
 +   */
 +  protected boolean shouldDistributeInvalidateRegion(RegionEventImpl event) {
 +    return event.isDistributed() && !event.isOriginRemote();
 +  }
 +
 +  /**
 +   * Distribute the invalidate of a region given its event.
 +   * This implementation sends the invalidate to peers.
 +   * @since 5.7
 +   */
 +  protected void distributeInvalidateRegion(RegionEventImpl event) {
 +    new InvalidateRegionOperation(event).distribute();
 +  }
 +
 +  /**
 +   * @see LocalRegion#basicDestroyRegion(RegionEventImpl, boolean, boolean,
 +   *      boolean)
 +   */
 +  @Override
 +  void basicDestroyRegion(RegionEventImpl event, boolean cacheWrite,
 +      boolean lock, boolean callbackEvents) throws CacheWriterException,
 +      TimeoutException
 +  {
 +    final String path = getFullPath();
 +    //Keep track of regions that are being destroyed. This helps avoid a race
 +    //when another member concurrently creates this region. See bug 42051.
 +    boolean isClose = event.getOperation().isClose();
 +    if(!isClose) {
 +      cache.beginDestroy(path, this);
 +    }
 +    try {
 +      super.basicDestroyRegion(event, cacheWrite, lock, callbackEvents);
 +      // send destroy region operation even if this is a localDestroyRegion (or
 +      // close)
 +      if (!event.isOriginRemote()) {
 +        distributeDestroyRegion(event, true);
 +      } else {
 +        if(!event.isReinitializing()) {
 +          RegionEventImpl localEvent = new RegionEventImpl(this,
 +              Operation.REGION_LOCAL_DESTROY, event.getCallbackArgument(), false, getMyId(),
 +              generateEventID()/* generate EventID */);
 +          distributeDestroyRegion(localEvent, false/*fixes bug 41111*/);
 +        }
 +      }
 +      notifyBridgeClients(event);
 +    }
 +    catch (CancelException e) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("basicDestroyRegion short-circuited due to cancellation");
 +      }
 +    }
 +    finally {
 +      if(!isClose) {
 +        cache.endDestroy(path, this);
 +      }
 +      RegionLogger.logDestroy(path, getMyId(), getPersistentID(), isClose);
 +    }
 + }
 +
 +
 +  @Override
 +  protected void distributeDestroyRegion(RegionEventImpl event,
 +                                         boolean notifyOfRegionDeparture) {
 +    if(persistenceAdvisor != null) {
 +      persistenceAdvisor.releaseTieLock();
 +    }
 +    new DestroyRegionOperation(event, notifyOfRegionDeparture).distribute();
 +  }
 +
 +  /**
 +   * Return true if invalidation occurred; false if it did not, for example if
 +   * it was already invalidated
 +   * 
 +   * @see LocalRegion#basicInvalidate(EntryEventImpl)
 +   */
 +  @Override
 +  void basicInvalidate(EntryEventImpl event) throws EntryNotFoundException
 +  {
 +    
 +    boolean hasSeen = false;
 +    if (hasSeenEvent(event)) {
 +      hasSeen = true;
 +    }
 +    try {
 +      // disallow local invalidation for replicated regions
 +      if (event.isLocalInvalid() && !event.getOperation().isLocal() && getScope().isDistributed()
 +          && getDataPolicy().withReplication()) {
 +        throw new IllegalStateException(LocalizedStrings.DistributedRegion_NOT_ALLOWED_TO_DO_A_LOCAL_INVALIDATION_ON_A_REPLICATED_REGION.toLocalizedString());
 +      }
 +      if (this.requiresOneHopForMissingEntry(event)) {
 +        // bug #45704: see if a one-hop must be done for this operation
 +        RegionEntry re = getRegionEntry(event.getKey());
 +        if (re == null/* || re.isTombstone()*/ || !this.generateVersionTag) {
 +          if (this.srp == null) {
 +            // only assert for non-client regions.
 +            Assert.assertTrue(!this.dataPolicy.withReplication() || !this.generateVersionTag);
 +          }
 +          // TODO: deltaGII: verify that delegating to a peer when this region is also a client is acceptable
 +          boolean didDistribute = RemoteInvalidateMessage.distribute(event, !this.generateVersionTag);
 +          if (!this.generateVersionTag && !didDistribute) {
 +            throw new PersistentReplicatesOfflineException();
 +          }
 +          if (didDistribute) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Event after remoteInvalidate operation: {}", event);
 +            }
 +            if (event.getVersionTag() == null) {
 +              // if the event wasn't applied by the one-hop replicate it will not have a version tag
 +              // and so should not be applied to this cache
 +              return;
 +            }
 +          }
 +        }
 +      }
 +  
 +      super.basicInvalidate(event);
 +
 +      return;
 +    } finally {
 +      if (hasSeen) {
-         distributeInvalidate(event);
-         event.invokeCallbacks(this,true, false);
++    	if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++          distributeInvalidate(event);
++          event.invokeCallbacks(this,true, false);
++    	}
 +      }
 +    }
 +  }
 +
 +  @Override
 +  void basicInvalidatePart3(RegionEntry re, EntryEventImpl event,
 +      boolean invokeCallbacks) {
 +    distributeInvalidate(event);
 +    super.basicInvalidatePart3(re, event, invokeCallbacks);
 +  }
 +  
 +  void distributeInvalidate(EntryEventImpl event) {
 +    if (!this.regionInvalid && event.isDistributed() && !event.isOriginRemote()
 +        && !isTX() /* only distribute if non-tx */) {
 +      if (event.isDistributed() && !event.isOriginRemote()) {
 +        boolean distribute = !event.getInhibitDistribution();
 +        if (distribute) {
 +          InvalidateOperation op = new InvalidateOperation(event);
 +          op.distribute();
 +        }
 +      }
 +    }
 +  }
 +
 +  
 +  @Override
 +  void basicUpdateEntryVersion(EntryEventImpl event)
 +      throws EntryNotFoundException {
 +
 +    try {
 +      if (!hasSeenEvent(event)) {
 +        super.basicUpdateEntryVersion(event);
 +      }
 +      return;
 +    } finally {
-       distributeUpdateEntryVersion(event);
++      if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++        distributeUpdateEntryVersion(event);
++      }
 +    }
 +  }
 +
 +  private void distributeUpdateEntryVersion(EntryEventImpl event) {
 +    if (!this.regionInvalid && event.isDistributed() && !event.isOriginRemote()
 +        && !isTX() /* only distribute if non-tx */) {
 +      if (event.isDistributed() && !event.isOriginRemote()) {
 +        UpdateEntryVersionOperation op = new UpdateEntryVersionOperation(event);
 +        op.distribute();
 +      }
 +    }
 +  }
 +
 +  @Override
 +  protected void basicClear(RegionEventImpl ev)
 +  {
 +    Lock dlock = this.getRegionDistributedLockIfGlobal();
 +    try {
 +      super.basicClear(ev);
 +    }
 +    finally {
 +      if (dlock != null)
 +        dlock.unlock();
 +    }
 +  }
 +  
 +  @Override
 +  void basicClear(RegionEventImpl regionEvent, boolean cacheWrite)  {
 +    if (this.concurrencyChecksEnabled && !this.dataPolicy.withReplication()) {
 +      boolean retry = false;
 +      do {
 +        // non-replicate regions must defer to a replicate for clear/invalidate of region
 +        Set<InternalDistributedMember> repls = this.distAdvisor.adviseReplicates();
 +        if (repls.size() > 0) {
 +          InternalDistributedMember mbr = repls.iterator().next();
 +          RemoteRegionOperation op = RemoteRegionOperation.clear(mbr, this);
 +          try {
 +            op.distribute();
 +            return;
 +          } catch (CancelException e) {
 +            this.stopper.checkCancelInProgress(e);
 +            retry = true;
 +          } catch (RemoteOperationException e) {
 +            this.stopper.checkCancelInProgress(e);
 +            retry = true;
 +          }
 +        }
 +      } while (retry);
 +    }
 +    // if no version vector or if no replicates are around, use the default mechanism
 +    super.basicClear(regionEvent, cacheWrite);
 +  }
 +  
 +  
 +  @Override
 +  void cmnClearRegion(RegionEventImpl regionEvent, boolean cacheWrite, boolean useRVV) {
 +    boolean enableRVV = useRVV && this.dataPolicy.withReplication() && this.concurrencyChecksEnabled && !getDistributionManager().isLoner(); 
 +    
 +    //Fix for 46338 - apparently multiple threads from the same VM are allowed
 +    //to suspend locking, which is what distributedLockForClear() does. We don't
 +    //want that to happen, so we'll synchronize to make sure only one thread on
 +    //this member performs a clear.
 +    synchronized(clearLock) {
 +      if (enableRVV) {
 +
 +        distributedLockForClear();
 +        try {
 +          Set<InternalDistributedMember> participants = getCacheDistributionAdvisor().adviseInvalidateRegion();
 +          // pause all generation of versions and flush from the other members to this one
 +          try {
 +            obtainWriteLocksForClear(regionEvent, participants);
 +            clearRegionLocally(regionEvent, cacheWrite, null);
 +            if (!regionEvent.isOriginRemote() && regionEvent.isDistributed()) {
 +              DistributedClearOperation.clear(regionEvent, null, participants);
 +            }
 +          } finally {
 +            releaseWriteLocksForClear(regionEvent, participants);
 +          }
 +        }
 +        finally {
 +          distributedUnlockForClear();
 +        }
 +      } else {
 +        Set<InternalDistributedMember> participants = getCacheDistributionAdvisor().adviseInvalidateRegion();
 +        clearRegionLocally(regionEvent, cacheWrite, null);
 +        if (!regionEvent.isOriginRemote() && regionEvent.isDistributed()) {
 +          DistributedClearOperation.clear(regionEvent, null, participants);
 +        }
 +      }
 +    }
 +    
 +    // since clients do not maintain RVVs except for tombstone GC
 +    // we need to ensure that current ops

<TRUNCATED>


[067/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
index 0000000,d4f9e97..feb5de8
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
@@@ -1,0 -1,33 +1,32 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import org.junit.runner.RunWith;
+ import org.junit.runners.Suite;
+ 
+ @Suite.SuiteClasses({
+ 	DataAsAddressJUnitTest.class,
 -	GemFireChunkJUnitTest.class,
 -	ChunkWithHeapFormJUnitTest.class,
 -	GemFireChunkSliceJUnitTest.class,
 -	GemFireChunkFactoryJUnitTest.class
++	ObjectChunkJUnitTest.class,
++	ObjectChunkWithHeapFormJUnitTest.class,
++	ObjectChunkSliceJUnitTest.class,
+ })
+ @RunWith(Suite.class)
+ public class StoredObjectTestSuite {
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
index 0000000,aaa2ec8..3ae6159
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
@@@ -1,0 -1,289 +1,289 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ import static org.mockito.Mockito.*;
+ 
+ import org.junit.After;
+ import org.junit.AfterClass;
+ import org.junit.Before;
+ import org.junit.BeforeClass;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ import org.mockito.listeners.InvocationListener;
+ import org.mockito.listeners.MethodInvocationReport;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class SyncChunkStackJUnitTest {
+   static {
+     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
+   }
+ 
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+   }
+ 
+   @AfterClass
+   public static void tearDownAfterClass() throws Exception {
+   }
+ 
+   @Before
+   public void setUp() throws Exception {
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+   }
+ 
+   @Test
+   public void addressZeroCausesStackToBeEmpty() {
+     SyncChunkStack stack = new SyncChunkStack(0L);
+     assertEquals(true, stack.isEmpty());
+   }
+ 
+   @Test
+   public void defaultStackIsEmpty() {
+     SyncChunkStack stack = new SyncChunkStack();
+     assertEquals(true, stack.isEmpty());
+   }
+ 
+   @Test
+   public void defaultStackReturnsZeroFromTop() {
+     SyncChunkStack stack = new SyncChunkStack();
+     assertEquals(0L, stack.getTopAddress());
+   }
+   
+   @Test
+   public void defaultStackReturnsZeroFromPoll() {
+     SyncChunkStack stack = new SyncChunkStack();
+     assertEquals(0L, stack.poll());
+   }
+   
+   @Test
+   public void defaultStackReturnsZeroFromClear() {
+     SyncChunkStack stack = new SyncChunkStack();
+     assertEquals(0L, stack.clear());
+     assertEquals(true, stack.isEmpty());
+   }
+   
+   @Test
+   public void defaultStackLogsNothing() {
+     SyncChunkStack stack = new SyncChunkStack();
+     LogWriter lw = mock(LogWriter.class, withSettings().invocationListeners(new InvocationListener() {
+       @Override
+       public void reportInvocation(MethodInvocationReport methodInvocationReport) {
+         fail("Unexpected invocation");
+       }
+     }));
+     stack.logSizes(lw, "should not be used");
+   }
+   
+   @Test
+   public void defaultStackComputeSizeIsZero() {
+     SyncChunkStack stack = new SyncChunkStack();
+     assertEquals(0L, stack.computeTotalSize());
+   }
+   
+   @Test
+   public void stackCreatedWithAddressIsNotEmpty() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+ 
+       SyncChunkStack stack = new SyncChunkStack(chunk.getMemoryAddress());
+       assertEquals(false, stack.isEmpty());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+   @Test
+   public void stackWithChunkIsNotEmpty() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+ 
+       SyncChunkStack stack = new SyncChunkStack();
+       stack.offer(chunk.getMemoryAddress());
+       assertEquals(false, stack.isEmpty());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+   @Test
+   public void stackWithChunkTopEqualsAddress() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+ 
+       long addr = chunk.getMemoryAddress();
+       SyncChunkStack stack = new SyncChunkStack();
+       stack.offer(addr);
+       assertEquals(addr, stack.getTopAddress());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+   @Test
+   public void addressZeroOfferCausesFailedAssertion() {
+     SyncChunkStack stack = new SyncChunkStack(0L);
+     try {
+       stack.offer(0);
+       fail("expected AssertionError");
+     } catch (AssertionError expected) {
+     }
+   }
+ 
+ 
+   @Test
+   public void stackWithChunkClearReturnsAddressAndEmptiesStack() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+ 
+       long addr = chunk.getMemoryAddress();
+       SyncChunkStack stack = new SyncChunkStack();
+       stack.offer(addr);
+       long clearAddr = stack.clear();
+       assertEquals(addr, clearAddr);
+       assertEquals(true, stack.isEmpty());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+   @Test
+   public void stackWithChunkPollReturnsAddressAndEmptiesStack() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+ 
+       long addr = chunk.getMemoryAddress();
+       SyncChunkStack stack = new SyncChunkStack();
+       stack.offer(addr);
+       long pollAddr = stack.poll();
+       assertEquals(addr, pollAddr);
+       assertEquals(true, stack.isEmpty());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+   @Test
+   public void stackWithChunkTotalSizeIsChunkSize() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+       int chunkSize = chunk.getSize();
+ 
+       long addr = chunk.getMemoryAddress();
+       SyncChunkStack stack = new SyncChunkStack();
+       stack.offer(addr);
+       assertEquals(chunkSize, stack.computeTotalSize());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+ 
+   @Test
+   public void stackWithChunkLogShowsMsgAndSize() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+       int chunkSize = chunk.getSize();
+ 
+       long addr = chunk.getMemoryAddress();
+       SyncChunkStack stack = new SyncChunkStack();
+       stack.offer(addr);
+       LogWriter lw = mock(LogWriter.class);
+       stack.logSizes(lw, "foo");
+       verify(lw).info("foo"+chunkSize);
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   
+   private class TestableSyncChunkStack extends SyncChunkStack {
+     public boolean doConcurrentMod = true;
+     public int chunk2Size;
+     private SimpleMemoryAllocatorImpl ma;
+     TestableSyncChunkStack(SimpleMemoryAllocatorImpl ma) {
+       this.ma = ma;
+     }
+     @Override
+     protected void testHookDoConcurrentModification() {
+       if (doConcurrentMod) {
+         doConcurrentMod = false;
 -        Chunk chunk2 = (Chunk) ma.allocate(50, null);
++        ObjectChunk chunk2 = (ObjectChunk) ma.allocate(50);
+         this.chunk2Size = chunk2.getSize();
+         this.offer(chunk2.getMemoryAddress());
+       }
+     }
+   }
+   @Test
+   public void stackWithChunkTotalSizeIsChunkSizeWithConcurrentMod() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+       int chunkSize = chunk.getSize();
+ 
+       long addr = chunk.getMemoryAddress();
+       TestableSyncChunkStack stack = new TestableSyncChunkStack(ma);
+       stack.offer(addr);
+       long totalSize = stack.computeTotalSize();
+       assertEquals("chunkSize=" + chunkSize + " chunk2Size=" + stack.chunk2Size, chunkSize + stack.chunk2Size, totalSize);
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+ 
+   @Test
+   public void stackWithChunkLogShowsMsgAndSizeWithConcurrentMod() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      Chunk chunk = (Chunk) ma.allocate(100, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
+       int chunkSize = chunk.getSize();
+ 
+       long addr = chunk.getMemoryAddress();
+       TestableSyncChunkStack stack = new TestableSyncChunkStack(ma);
+       stack.offer(addr);
+       LogWriter lw = mock(LogWriter.class);
+       stack.logSizes(lw, "foo");
+       verify(lw).info("foo"+chunkSize);
+       verify(lw).info("foo"+stack.chunk2Size);
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
index 0000000,a98fa28..d7168a7
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
@@@ -1,0 -1,87 +1,87 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ 
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class UnsafeMemoryChunkJUnitTest extends MemoryChunkJUnitTestBase {
+ 
+   @Override
+   protected MemoryChunk createChunk(int size) {
+     return new UnsafeMemoryChunk(size);
+   }
+ 
+   @Test
+   public void testGetAddress() {
+     MemoryChunk mc = createChunk(1024);
+     try {
 -      UnsafeMemoryChunk umc = (UnsafeMemoryChunk) mc;
++      AddressableMemoryChunk umc = (AddressableMemoryChunk) mc;
+       assertNotEquals(0, umc.getMemoryAddress());
+     } finally {
+       mc.release();
+     }
+   }
+   
+   @Test(expected=AssertionError.class)
+   public void readAbsoluteBytesFailsIfSizeLessThanZero() {
+     UnsafeMemoryChunk.readAbsoluteBytes(0L, null, 0, -1);
+   }
+   @Test
+   public void readAbsoluteBytesDoesNothingIfSizeIsZero() {
+     UnsafeMemoryChunk.readAbsoluteBytes(0L, new byte[0], 0, 0);
+   }
+   @Test(expected=AssertionError.class)
+   public void readAbsoluteBytesFailsIfSizeGreaterThanArrayLength() {
+     UnsafeMemoryChunk.readAbsoluteBytes(0L, new byte[0], 0, 1);
+   }
+   @Test(expected=AssertionError.class)
+   public void readAbsoluteBytesFailsIfByteOffsetNegative() {
+     UnsafeMemoryChunk.readAbsoluteBytes(0L, new byte[0], -1, 0);
+   }
+   @Test(expected=AssertionError.class)
+   public void readAbsoluteBytesFailsIfByteOffsetGreaterThanArrayLength() {
+     UnsafeMemoryChunk.readAbsoluteBytes(0L, new byte[0], 1, 0);
+   }
+   
+   @Test(expected=AssertionError.class)
+   public void writeAbsoluteBytesFailsIfSizeLessThanZero() {
+     UnsafeMemoryChunk.writeAbsoluteBytes(0L, null, 0, -1);
+   }
+   @Test
+   public void writeAbsoluteBytesDoesNothingIfSizeIsZero() {
+     UnsafeMemoryChunk.writeAbsoluteBytes(0L, new byte[0], 0, 0);
+   }
+   @Test(expected=AssertionError.class)
+   public void writeAbsoluteBytesFailsIfSizeGreaterThanArrayLength() {
+     UnsafeMemoryChunk.writeAbsoluteBytes(0L, new byte[0], 0, 1);
+   }
+   @Test(expected=AssertionError.class)
+   public void writeAbsoluteBytesFailsIfByteOffsetNegative() {
+     UnsafeMemoryChunk.writeAbsoluteBytes(0L, new byte[0], -1, 0);
+   }
+   @Test(expected=AssertionError.class)
+   public void writeAbsoluteBytesFailsIfByteOffsetGreaterThanArrayLength() {
+     UnsafeMemoryChunk.writeAbsoluteBytes(0L, new byte[0], 1, 0);
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
index 0000000,c7c7b7b..0f918cb
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
@@@ -1,0 -1,52 +1,52 @@@
+ /*
+  * 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 com.gemstone.gemfire.pdx;
+ 
+ import static org.junit.Assert.fail;
+ 
+ import java.nio.ByteBuffer;
+ 
+ import org.junit.experimental.categories.Category;
+ 
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream.ByteSource;
+ import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream.ByteSourceFactory;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class OffHeapByteBufferByteSourceJUnitTest extends OffHeapByteSourceJUnitTest {
+   
+   @Override
+   protected ByteSource createByteSource(byte[] bytes) {
 -    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false, null);
 -    if (so instanceof Chunk) {
 -      Chunk c = (Chunk) so;
++    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false);
++    if (so instanceof ObjectChunk) {
++      ObjectChunk c = (ObjectChunk) so;
+       ByteBuffer bb = c.createDirectByteBuffer();
+       if (bb == null) {
+         fail("could not create a direct ByteBuffer for an off-heap Chunk");
+       }
+       return ByteSourceFactory.create(bb);
+     } else {
+       // bytes are so small they can be encoded in a long (see DataAsAddress).
+       // So for this test just wrap the original bytes.
+       return ByteSourceFactory.wrap(bytes);
+     }
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
index 0000000,543ef94..6457425
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
@@@ -1,0 -1,65 +1,65 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ package com.gemstone.gemfire.pdx;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.experimental.categories.Category;
+ 
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
+ import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
+ import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream.ByteSource;
+ import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream.ByteSourceFactory;
+ import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream.OffHeapByteSource;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class OffHeapByteSourceJUnitTest extends ByteSourceJUnitTest {
+ 
+   @Before
+   public void setUp() throws Exception {
 -    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+   }
+ 
+   @Override
+   protected boolean isTestOffHeap() {
+     return true;
+   }
+   
+   @Override
+   protected ByteSource createByteSource(byte[] bytes) {
 -    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false, null);
 -    if (so instanceof Chunk) {
++    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false);
++    if (so instanceof ObjectChunk) {
+       // bypass the factory to make sure that OffHeapByteSource is tested
 -      return new OffHeapByteSource((Chunk)so);
++      return new OffHeapByteSource((ObjectChunk)so);
+     } else {
+       // bytes are so small they can be encoded in a long (see DataAsAddress).
+       // So for this test just wrap the original bytes.
+       return ByteSourceFactory.wrap(bytes);
+     }
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
index 0000000,74260ed..dc03990
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientMultiUserAuthzDUnitTest.java
@@@ -1,0 -1,525 +1,523 @@@
+ 
+ package com.gemstone.gemfire.security;
+ 
+ /*
+  * 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.
+  */
+ 
+ 
+ import java.util.Iterator;
+ import java.util.Properties;
+ 
++import com.gemstone.gemfire.test.dunit.VM;
+ import security.AuthzCredentialGenerator;
+ import security.CredentialGenerator;
+ 
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.execute.Function;
+ import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode;
+ import com.gemstone.gemfire.internal.AvailablePort;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.execute.PRClientServerTestBase;
+ import com.gemstone.gemfire.internal.cache.functions.TestFunction;
+ import com.gemstone.gemfire.test.dunit.Host;
+ import com.gemstone.gemfire.test.dunit.LogWriterUtils;
+ 
+ public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestBase {
+ 
+   /** constructor */
+   public ClientMultiUserAuthzDUnitTest(String name) {
+     super(name);
+   }
+ 
+   public void setUp() throws Exception {
+ 
+     super.setUp();
+     final Host host = Host.getHost(0);
+     server1 = host.getVM(0);
+     server2 = host.getVM(1);
+     client1 = host.getVM(2);
+     client2 = host.getVM(3);
+ 
+     server1.invoke(() -> SecurityTestUtil.registerExpectedExceptions( serverExpectedExceptions ));
+     server2.invoke(() -> SecurityTestUtil.registerExpectedExceptions( serverExpectedExceptions ));
+     client2.invoke(() -> SecurityTestUtil.registerExpectedExceptions( clientExpectedExceptions ));
+     SecurityTestUtil.registerExpectedExceptions(clientExpectedExceptions);
+   }
+ 
+   // Tests with one user authorized to do puts/gets/containsKey/destroys and
+   // another not authorized for the same.
+   public void testOps1() throws Exception {
+     Iterator iter = getDummyGeneratorCombos().iterator();
+     while (iter.hasNext()) {
+       AuthzCredentialGenerator gen = (AuthzCredentialGenerator)iter.next();
+       CredentialGenerator cGen = gen.getCredentialGenerator();
+       Properties extraAuthProps = cGen.getSystemProperties();
+       Properties javaProps = cGen.getJavaProperties();
+       Properties extraAuthzProps = gen.getSystemProperties();
+       String authenticator = cGen.getAuthenticator();
+       String authInit = cGen.getAuthInit();
+       String accessor = gen.getAuthorizationCallback();
+ 
+       LogWriterUtils.getLogWriter().info("testOps1: Using authinit: " + authInit);
+       LogWriterUtils.getLogWriter().info(
+           "testOps1: Using authenticator: " + authenticator);
+       LogWriterUtils.getLogWriter().info("testOps1: Using accessor: " + accessor);
+ 
+       // Start servers with all required properties
+       Properties serverProps = buildProperties(authenticator, accessor, false,
+           extraAuthProps, extraAuthzProps);
 -      Integer port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 -      Integer port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 -      createCacheServers(javaProps, serverProps, port1, port2);
++
++      Integer port1 = createCacheServerOnVM(server1, javaProps, serverProps);
++      Integer port2 = createCacheServerOnVM(server2, javaProps, serverProps);
+ 
+       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
 -          OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
 -          OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
++              OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
++              OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
+           port2)) {
+         continue;
+       }
+       verifyPutsGets();
+ 
+       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
 -          OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
 -          OperationCode.DESTROY, OperationCode.DESTROY},
++              OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
++              OperationCode.DESTROY, OperationCode.DESTROY},
+           javaProps, authInit, port1, port2)) {
+         continue;
+       }
+       verifyContainsKeyDestroys();
+ 
+       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
 -          OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
 -          OperationCode.INVALIDATE, OperationCode.INVALIDATE},
++              OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
++              OperationCode.INVALIDATE, OperationCode.INVALIDATE},
+           javaProps, authInit, port1, port2)) {
+         continue;
+       }
+       verifyContainsKeyInvalidates();
+ 
+       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
 -          OperationCode.GET, OperationCode.GET}, new OperationCode[] {
 -          OperationCode.REGION_DESTROY, OperationCode.REGION_DESTROY},
++              OperationCode.GET, OperationCode.GET}, new OperationCode[] {
++              OperationCode.REGION_DESTROY, OperationCode.REGION_DESTROY},
+           javaProps, authInit, port1, port2)) {
+         continue;
+       }
+       verifyGetAllInTX();
+       verifyGetAllRegionDestroys();
+     }
+   }
+ 
+   private boolean prepareClientsForOps(AuthzCredentialGenerator gen,
+       CredentialGenerator cGen, OperationCode[] client1OpCodes,
+       OperationCode[] client2OpCodes, Properties javaProps, String authInit,
+       Integer port1, Integer port2) {
+     return prepareClientsForOps(gen, cGen, client1OpCodes, client2OpCodes,
+         javaProps, authInit, port1, port2, Boolean.TRUE /*
+                                                          * both clients in
+                                                          * multiuser mode
+                                                          */, Boolean.FALSE /* unused */);
+   }
+ 
+   private boolean prepareClientsForOps(AuthzCredentialGenerator gen,
+       CredentialGenerator cGen, OperationCode[] client1OpCodes,
+       OperationCode[] client2OpCodes, Properties javaProps, String authInit,
+       Integer port1, Integer port2, Boolean bothClientsInMultiuserMode,
+       Boolean allowOp) {
+     // Start client1 with valid/invalid client1OpCodes credentials
+     Properties[] client1Credentials = new Properties[] {
+         gen.getAllowedCredentials(client1OpCodes, new String[] {regionName}, 1),
+         gen.getDisallowedCredentials(new OperationCode[] {client1OpCodes[1]},
+             new String[] {regionName}, 1)};
+     if (client1Credentials[0] == null || client1Credentials[0].size() == 0) {
+       LogWriterUtils.getLogWriter().info(
+           "testOps1: Unable to obtain valid credentials with "
+               + client1OpCodes[0].toString()
+               + " permission; skipping this combination.");
+       return false;
+     }
+     if (client1Credentials[1] == null || client1Credentials[1].size() == 0) {
+       LogWriterUtils.getLogWriter().info(
+           "testOps1: Unable to obtain valid credentials with no "
+               + client1OpCodes[0].toString()
+               + " permission; skipping this combination.");
+       return false;
+     }
+     javaProps = cGen.getJavaProperties();
+     LogWriterUtils.getLogWriter().info(
+         "testOps1: For first client credentials: " + client1Credentials[0]
+             + "\n" + client1Credentials[1]);
+     client1.invoke(SecurityTestUtil.class, "createCacheClientForMultiUserMode",
+         new Object[] {Integer.valueOf(2), authInit, client1Credentials,
+             javaProps, new Integer[] {port1, port2}, null, Boolean.FALSE,
+             SecurityTestUtil.NO_EXCEPTION});
+ 
+     // Start client2 with valid/invalid client2OpCodes credentials
+     Properties[] client2Credentials = new Properties[] {
+         gen.getAllowedCredentials(client2OpCodes,
+             new String[] {regionName}, 2),
+         gen.getDisallowedCredentials(client2OpCodes,
+             new String[] {regionName}, 9)};
+     if (client2Credentials[0] == null || client2Credentials[0].size() == 0) {
+       LogWriterUtils.getLogWriter().info(
+           "testOps1: Unable to obtain valid credentials with "
+               + client2OpCodes[0].toString()
+               + " permission; skipping this combination.");
+       return false;
+     }
+     if (client2Credentials[1] == null || client2Credentials[1].size() == 0) {
+       LogWriterUtils.getLogWriter().info(
+           "testOps1: Unable to obtain valid credentials with no "
+               + client2OpCodes[0].toString()
+               + " permission; skipping this combination.");
+       return false;
+     }
+     javaProps = cGen.getJavaProperties();
+     LogWriterUtils.getLogWriter().info(
+         "testOps1: For second client credentials: " + client2Credentials[0]
+             + "\n" + client2Credentials[1]);
+     if (bothClientsInMultiuserMode) {
+       client2.invoke(SecurityTestUtil.class,
+           "createCacheClientForMultiUserMode", new Object[] {
+               Integer.valueOf(2), authInit, client2Credentials, javaProps,
+               new Integer[] {port1, port2}, null, Boolean.FALSE,
+               SecurityTestUtil.NO_EXCEPTION});
+     } else {
+       int credentialsIndex = allowOp ? 0 : 1;
+       client2.invoke(SecurityTestUtil.class, "createCacheClient", new Object[] {
+           authInit, client2Credentials[credentialsIndex], javaProps,
+           new Integer[] {port1, port2}, null, Boolean.FALSE, "false",
+           SecurityTestUtil.NO_EXCEPTION});
+     }
+     return true;
+   }
+ 
+   private void verifyPutsGets() throws Exception {
+     verifyPutsGets(true, false /*unused */);
+   }
+ 
+   private void verifyPutsGets(Boolean isMultiuser, Boolean opAllowed)
+       throws Exception {
+     // Perform some put operations from client1
+     client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
+         Integer.valueOf(2),
+         Integer.valueOf(2),
+         new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+             SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+ 
+     // Verify that the gets succeed/fail
+     if (isMultiuser) {
 -    client2.invoke(SecurityTestUtil.class, "doMultiUserGets", new Object[] {
 -        Integer.valueOf(2),
 -        Integer.valueOf(2),
 -        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
++      client2.invoke(SecurityTestUtil.class, "doMultiUserGets", new Object[] {
++          Integer.valueOf(2),
++          Integer.valueOf(2),
++          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++              SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+     } else {
+       int expectedResult = (opAllowed) ? SecurityTestUtil.NO_EXCEPTION
+           : SecurityTestUtil.NOTAUTHZ_EXCEPTION;
+       client2.invoke(SecurityTestUtil.class, "doMultiUserGets", new Object[] {
+           Integer.valueOf(1), Integer.valueOf(1),
+           new Integer[] {expectedResult}});
+     }
+   }
+ 
+   private void verifyContainsKeyDestroys() throws Exception {
+     verifyContainsKeyDestroys(true, false /* unused */);
+   }
+ 
+   private void verifyContainsKeyDestroys(Boolean isMultiuser, Boolean opAllowed)
+       throws Exception {
+     // Do puts before verifying containsKey
+     client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
+         Integer.valueOf(2),
+         Integer.valueOf(2),
+         new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+             SecurityTestUtil.NO_EXCEPTION}});
+     client1.invoke(SecurityTestUtil.class, "doMultiUserContainsKeys",
+         new Object[] {
+             Integer.valueOf(1),
+             Integer.valueOf(2),
+             new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                 SecurityTestUtil.NOTAUTHZ_EXCEPTION},
+             new Boolean[] {Boolean.TRUE, Boolean.FALSE}});
+ 
+     // Verify that the destroys succeed/fail
+     if (isMultiuser) {
+       client2.invoke(SecurityTestUtil.class, "doMultiUserDestroys",
+           new Object[] {
+               Integer.valueOf(2),
+               Integer.valueOf(2),
+               new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                   SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+     } else {
+       int expectedResult = (opAllowed) ? SecurityTestUtil.NO_EXCEPTION
+           : SecurityTestUtil.NOTAUTHZ_EXCEPTION;
+       client2.invoke(SecurityTestUtil.class, "doMultiUserDestroys",
+           new Object[] {Integer.valueOf(1), Integer.valueOf(1),
+               new Integer[] {expectedResult}});
+     }
+   }
+ 
+   private void verifyContainsKeyInvalidates() throws Exception {
+     verifyContainsKeyInvalidates(true, false /* unused */);
+   }
+ 
+   private void verifyContainsKeyInvalidates(Boolean isMultiuser, Boolean opAllowed)
+       throws Exception {
+     // Do puts before verifying containsKey
+     client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
+         Integer.valueOf(2),
+         Integer.valueOf(2),
+         new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+             SecurityTestUtil.NO_EXCEPTION}});
+     client1.invoke(SecurityTestUtil.class, "doMultiUserContainsKeys",
+         new Object[] {
+             Integer.valueOf(1),
+             Integer.valueOf(2),
+             new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                 SecurityTestUtil.NOTAUTHZ_EXCEPTION},
+             new Boolean[] {Boolean.TRUE, Boolean.FALSE}});
+ 
+     // Verify that the invalidates succeed/fail
+     if (isMultiuser) {
+       client2.invoke(SecurityTestUtil.class, "doMultiUserInvalidates",
+           new Object[] {
+               Integer.valueOf(2),
+               Integer.valueOf(2),
+               new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                   SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+     } else {
+       int expectedResult = (opAllowed) ? SecurityTestUtil.NO_EXCEPTION
+           : SecurityTestUtil.NOTAUTHZ_EXCEPTION;
+       client2.invoke(SecurityTestUtil.class, "doMultiUserInvalidates",
+           new Object[] {Integer.valueOf(1), Integer.valueOf(1),
+               new Integer[] {expectedResult}});
+     }
+   }
+ 
+   private void verifyGetAllInTX() {
+     server1.invoke(() -> ClientMultiUserAuthzDUnitTest.doPuts());
+     client1.invoke(SecurityTestUtil.class, "doMultiUserGetAll", new Object[] {
 -      Integer.valueOf(2),
 -      new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -          SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Boolean.TRUE/*use TX*/});
++        Integer.valueOf(2),
++        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++            SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Boolean.TRUE/*use TX*/});
+   }
+ 
+   private void verifyGetAllRegionDestroys() {
+     server1.invoke(() -> ClientMultiUserAuthzDUnitTest.doPuts());
+     client1.invoke(SecurityTestUtil.class, "doMultiUserGetAll", new Object[] {
 -      Integer.valueOf(2),
 -      new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -          SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
++        Integer.valueOf(2),
++        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+ 
+     // Verify that the region destroys succeed/fail
+     client2.invoke(SecurityTestUtil.class, "doMultiUserRegionDestroys",
+         new Object[] {
+             Integer.valueOf(2),
+             new Integer[] {SecurityTestUtil.NO_EXCEPTION,
+                 SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+   }
 -  
++
+   public static void doPuts() {
+     Region region = GemFireCacheImpl.getInstance().getRegion(SecurityTestUtil.regionName);
+     region.put("key1", "value1");
+     region.put("key2", "value2");
+   }
+ 
+   // Test query/function execute
+   public void testOps2() throws Exception {
 -      AuthzCredentialGenerator gen = getXmlAuthzGenerator();
 -      CredentialGenerator cGen = gen.getCredentialGenerator();
 -      Properties extraAuthProps = cGen.getSystemProperties();
 -      Properties javaProps = cGen.getJavaProperties();
 -      Properties extraAuthzProps = gen.getSystemProperties();
 -      String authenticator = cGen.getAuthenticator();
 -      String authInit = cGen.getAuthInit();
 -      String accessor = gen.getAuthorizationCallback();
++    AuthzCredentialGenerator gen = getXmlAuthzGenerator();
++    CredentialGenerator cGen = gen.getCredentialGenerator();
++    Properties extraAuthProps = cGen.getSystemProperties();
++    Properties javaProps = cGen.getJavaProperties();
++    Properties extraAuthzProps = gen.getSystemProperties();
++    String authenticator = cGen.getAuthenticator();
++    String authInit = cGen.getAuthInit();
++    String accessor = gen.getAuthorizationCallback();
++
++    LogWriterUtils.getLogWriter().info("testOps2: Using authinit: " + authInit);
++    LogWriterUtils.getLogWriter().info("testOps2: Using authenticator: " + authenticator);
++    LogWriterUtils.getLogWriter().info("testOps2: Using accessor: " + accessor);
++
++    // Start servers with all required properties
++    Properties serverProps = buildProperties(authenticator, accessor, false,
++        extraAuthProps, extraAuthzProps);
++    Integer port1 = createCacheServerOnVM(server1, javaProps, serverProps);
++    Integer port2 = createCacheServerOnVM(server2, javaProps, serverProps);
++
++    // Start client1 with valid/invalid QUERY credentials
++    Properties[] client1Credentials = new Properties[] {
++        gen.getAllowedCredentials(
++            new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
++            new String[] {regionName},
++            1),
++        gen.getDisallowedCredentials(
++            new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
++            new String[] {regionName},
++            1)
++    };
+ 
 -      LogWriterUtils.getLogWriter().info("testOps2: Using authinit: " + authInit);
 -      LogWriterUtils.getLogWriter().info("testOps2: Using authenticator: " + authenticator);
 -      LogWriterUtils.getLogWriter().info("testOps2: Using accessor: " + accessor);
++    javaProps = cGen.getJavaProperties();
++    LogWriterUtils.getLogWriter().info(
++        "testOps2: For first client credentials: " + client1Credentials[0]
++            + "\n" + client1Credentials[1]);
++    client1.invoke(SecurityTestUtil.class,
++        "createCacheClientForMultiUserMode", new Object[] {
++            Integer.valueOf(2), authInit, client1Credentials, javaProps,
++            new Integer[] {port1, port2}, null, Boolean.FALSE,
++            SecurityTestUtil.NO_EXCEPTION});
+ 
 -      // Start servers with all required properties
 -      Properties serverProps = buildProperties(authenticator, accessor, false,
 -          extraAuthProps, extraAuthzProps);
 -      Integer port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 -      Integer port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 -      createCacheServers(javaProps, serverProps, port1, port2);
 -
 -      // Start client1 with valid/invalid QUERY credentials
 -      Properties[] client1Credentials = new Properties[] {
 -          gen.getAllowedCredentials(
 -                  new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
 -                  new String[] {regionName},
 -                  1),
 -          gen.getDisallowedCredentials(
 -                  new OperationCode[] {OperationCode.PUT, OperationCode.QUERY},
 -                  new String[] {regionName},
 -                  1)
 -      };
 -
 -      javaProps = cGen.getJavaProperties();
 -      LogWriterUtils.getLogWriter().info(
 -          "testOps2: For first client credentials: " + client1Credentials[0]
 -              + "\n" + client1Credentials[1]);
 -      client1.invoke(SecurityTestUtil.class,
 -          "createCacheClientForMultiUserMode", new Object[] {
 -              Integer.valueOf(2), authInit, client1Credentials, javaProps,
 -              new Integer[] {port1, port2}, null, Boolean.FALSE,
 -              SecurityTestUtil.NO_EXCEPTION});
++    // Start client2 with valid/invalid EXECUTE_FUNCTION credentials
++    Properties[] client2Credentials = new Properties[] {
++        gen.getAllowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
++            new String[] {regionName}, 2),
++        gen.getDisallowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
++            new String[] {regionName}, 9)};
+ 
 -      // Start client2 with valid/invalid EXECUTE_FUNCTION credentials
 -      Properties[] client2Credentials = new Properties[] {
 -          gen.getAllowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
 -              new String[] {regionName}, 2),
 -          gen.getDisallowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION},
 -              new String[] {regionName}, 9)};
++    javaProps = cGen.getJavaProperties();
++    LogWriterUtils.getLogWriter().info(
++        "testOps2: For second client credentials: " + client2Credentials[0]
++            + "\n" + client2Credentials[1]);
++    client2.invoke(SecurityTestUtil.class,
++        "createCacheClientForMultiUserMode", new Object[] {
++            Integer.valueOf(2), authInit, client2Credentials, javaProps,
++            new Integer[] {port1, port2}, null, Boolean.FALSE,
++            SecurityTestUtil.NO_EXCEPTION});
++    Function function = new TestFunction(true,TestFunction.TEST_FUNCTION1);
++    server1.invoke(PRClientServerTestBase.class,
++        "registerFunction", new Object []{function});
+ 
 -      javaProps = cGen.getJavaProperties();
 -      LogWriterUtils.getLogWriter().info(
 -          "testOps2: For second client credentials: " + client2Credentials[0]
 -              + "\n" + client2Credentials[1]);
 -      client2.invoke(SecurityTestUtil.class,
 -          "createCacheClientForMultiUserMode", new Object[] {
 -              Integer.valueOf(2), authInit, client2Credentials, javaProps,
 -              new Integer[] {port1, port2}, null, Boolean.FALSE,
 -              SecurityTestUtil.NO_EXCEPTION});
 -      Function function = new TestFunction(true,TestFunction.TEST_FUNCTION1);
 -      server1.invoke(PRClientServerTestBase.class,
 -          "registerFunction", new Object []{function});
 -      
 -      server2.invoke(PRClientServerTestBase.class,
 -          "registerFunction", new Object []{function});
 -      
 -      // Perform some put operations before verifying queries
 -      client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
 -          Integer.valueOf(4),
 -          Integer.valueOf(2),
 -          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -              SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
 -      client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
 -          new Object[] {
 -              Integer.valueOf(2),
 -              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
 -      client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
 -          new Object[] {
 -              Integer.valueOf(2),
 -              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
++    server2.invoke(PRClientServerTestBase.class,
++        "registerFunction", new Object []{function});
+ 
 -      // Verify that the FE succeeds/fails
 -      client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
 -          Integer.valueOf(2),
 -          function,
 -          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -              SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
 -          Boolean.FALSE});
++    // Perform some put operations before verifying queries
++    client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
++        Integer.valueOf(4),
++        Integer.valueOf(2),
++        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
++    client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
++        new Object[] {
++            Integer.valueOf(2),
++            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
++    client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
++        new Object[] {
++            Integer.valueOf(2),
++            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
+ 
 -      // Failover
 -      server1.invoke(() -> SecurityTestUtil.closeCache());
 -      Thread.sleep(2000);
++    // Verify that the FE succeeds/fails
++    client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
++        Integer.valueOf(2),
++        function,
++        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++            SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
++        Boolean.FALSE});
+ 
 -      client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
 -          Integer.valueOf(4),
 -          Integer.valueOf(2),
 -          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -              SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
++    // Failover
++    server1.invoke(() -> SecurityTestUtil.closeCache());
++    Thread.sleep(2000);
+ 
 -      client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
 -          new Object[] {
 -              Integer.valueOf(2),
 -              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
 -      client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
 -          new Object[] {
 -              Integer.valueOf(2),
 -              new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -                  SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
++    client1.invoke(SecurityTestUtil.class, "doMultiUserPuts", new Object[] {
++        Integer.valueOf(4),
++        Integer.valueOf(2),
++        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++            SecurityTestUtil.NOTAUTHZ_EXCEPTION}});
+ 
 -      // Verify that the FE succeeds/fails
 -      client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
 -          Integer.valueOf(2),
 -          function,
 -          new Integer[] {SecurityTestUtil.NO_EXCEPTION,
 -              SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
 -          Boolean.TRUE});
++    client1.invoke(SecurityTestUtil.class, "doMultiUserQueries",
++        new Object[] {
++            Integer.valueOf(2),
++            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
++    client1.invoke(SecurityTestUtil.class, "doMultiUserQueryExecute",
++        new Object[] {
++            Integer.valueOf(2),
++            new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++                SecurityTestUtil.NOTAUTHZ_EXCEPTION}, Integer.valueOf(4)});
++
++    // Verify that the FE succeeds/fails
++    client2.invoke(SecurityTestUtil.class, "doMultiUserFE", new Object[] {
++        Integer.valueOf(2),
++        function,
++        new Integer[] {SecurityTestUtil.NO_EXCEPTION,
++            SecurityTestUtil.NOTAUTHZ_EXCEPTION}, new Object[] {null, null},
++        Boolean.TRUE});
+ 
+ 
+   }
+ 
 -  protected void createCacheServers(Properties javaProps,
 -      Properties serverProps, Integer port1, Integer port2) {
 -    server1.invoke(() -> ClientAuthorizationTestBase.createCacheServer(SecurityTestUtil.getLocatorPort(), port1, serverProps,
 -            javaProps));
 -    server2.invoke(() -> ClientAuthorizationTestBase.createCacheServer(SecurityTestUtil.getLocatorPort(), port2, serverProps,
 -            javaProps));
++
++  protected Integer createCacheServerOnVM(VM server, Properties javaProps, Properties serverProps) {
++    return (Integer)server.invoke(() -> ClientAuthorizationTestBase.createCacheServer(SecurityTestUtil.getLocatorPort(), serverProps,
++        javaProps));
++
+   }
+ 
+   public void testOpsWithClientsInDifferentModes() throws Exception {
+     Iterator iter = getDummyGeneratorCombos().iterator();
+     while (iter.hasNext()) {
+       AuthzCredentialGenerator gen = (AuthzCredentialGenerator)iter.next();
+       CredentialGenerator cGen = gen.getCredentialGenerator();
+       Properties extraAuthProps = cGen.getSystemProperties();
+       Properties javaProps = cGen.getJavaProperties();
+       Properties extraAuthzProps = gen.getSystemProperties();
+       String authenticator = cGen.getAuthenticator();
+       String authInit = cGen.getAuthInit();
+       String accessor = gen.getAuthorizationCallback();
+ 
+       LogWriterUtils.getLogWriter().info("testOpsWithClientsInDifferentModes: Using authinit: " + authInit);
+       LogWriterUtils.getLogWriter().info(
+           "testOpsWithClientsInDifferentModes: Using authenticator: " + authenticator);
+       LogWriterUtils.getLogWriter().info("testOpsWithClientsInDifferentModes: Using accessor: " + accessor);
+ 
+       // Start servers with all required properties
+       Properties serverProps = buildProperties(authenticator, accessor, false,
+           extraAuthProps, extraAuthzProps);
 -      Integer port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 -      Integer port2 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 -      createCacheServers(javaProps, serverProps, port1, port2);
++      Integer port1 = createCacheServerOnVM(server1, javaProps, serverProps);
++      Integer port2 = createCacheServerOnVM(server2, javaProps, serverProps);
+ 
+       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
 -          OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
 -          OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
++              OperationCode.PUT, OperationCode.PUT}, new OperationCode[] {
++              OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1,
+           port2, Boolean.FALSE, Boolean.TRUE)) {
+         continue;
+       }
+       verifyPutsGets(false, true);
+ 
+       if (!prepareClientsForOps(gen, cGen, new OperationCode[] {
 -          OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
 -          OperationCode.DESTROY, OperationCode.DESTROY},
++              OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] {
++              OperationCode.DESTROY, OperationCode.DESTROY},
+           javaProps, authInit, port1, port2, Boolean.FALSE, Boolean.FALSE)) {
+         continue;
+       }
+       verifyContainsKeyDestroys(false, false);
+     }
+   }
+ 
+   // End Region: Tests
+ 
+   @Override
+   protected final void preTearDown() throws Exception {
+     // close the clients first
+     client1.invoke(() -> SecurityTestUtil.closeCache());
+     client2.invoke(() -> SecurityTestUtil.closeCache());
+     SecurityTestUtil.closeCache();
+     // then close the servers
+     server1.invoke(() -> SecurityTestUtil.closeCache());
+     server2.invoke(() -> SecurityTestUtil.closeCache());
+   }
+ }


[056/100] [abbrv] incubator-geode git commit: GEODE-831: unit test FreeListManager

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkJUnitTest.java
deleted file mode 100644
index 81a59e3..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkJUnitTest.java
+++ /dev/null
@@ -1,921 +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 com.gemstone.gemfire.internal.offheap;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.atLeastOnce;
-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.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.LogWriter;
-import com.gemstone.gemfire.compression.Compressor;
-import com.gemstone.gemfire.internal.DSCODE;
-import com.gemstone.gemfire.internal.HeapDataOutputStream;
-import com.gemstone.gemfire.internal.Version;
-import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
-import com.gemstone.gemfire.internal.cache.CachePerfStats;
-import com.gemstone.gemfire.internal.cache.EntryEventImpl;
-import com.gemstone.gemfire.internal.cache.RegionEntryContext;
-import com.gemstone.gemfire.internal.offheap.MemoryBlock.State;
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class GemFireChunkJUnitTest extends AbstractStoredObjectTestBase {
-
-  private MemoryAllocator ma;
-
-  static {
-    ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
-  }
-
-  @Before
-  public void setUp() {
-    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
-    OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
-    LogWriter lw = mock(LogWriter.class);
-
-    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 3, OffHeapStorage.MIN_SLAB_SIZE * 3, OffHeapStorage.MIN_SLAB_SIZE);
-  }
-
-  @After
-  public void tearDown() {
-    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
-  }
-
-  @Override
-  public Object getValue() {
-    return Long.valueOf(Long.MAX_VALUE);
-  }
-
-  @Override
-  public byte[] getValueAsByteArray() {
-    return convertValueToByteArray(getValue());
-  }
-
-  private byte[] convertValueToByteArray(Object value) {
-    return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong((Long) value).array();
-  }
-
-  @Override
-  public Object convertByteArrayToObject(byte[] valueInByteArray) {
-    return ByteBuffer.wrap(valueInByteArray).getLong();
-  }
-
-  @Override
-  public Object convertSerializedByteArrayToObject(byte[] valueInSerializedByteArray) {
-    return EntryEventImpl.deserialize(valueInSerializedByteArray);
-  }
-
-  @Override
-  public GemFireChunk createValueAsUnserializedStoredObject(Object value) {
-    byte[] valueInByteArray;
-    if (value instanceof Long) {
-      valueInByteArray = convertValueToByteArray(value);
-    } else {
-      valueInByteArray = (byte[]) value;
-    }
-
-    boolean isSerialized = false;
-    boolean isCompressed = false;
-
-    return createChunk(valueInByteArray, isSerialized, isCompressed);
-  }
-
-  @Override
-  public GemFireChunk createValueAsSerializedStoredObject(Object value) {
-    byte[] valueInSerializedByteArray = EntryEventImpl.serialize(value);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    return createChunk(valueInSerializedByteArray, isSerialized, isCompressed);
-  }
-
-  private GemFireChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-    return chunk;
-  }
-
-  @Test
-  public void chunkCanBeCreatedFromAnotherChunk() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    GemFireChunk newChunk = new GemFireChunk(chunk);
-
-    assertNotNull(newChunk);
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-
-    chunk.release();
-  }
-
-  @Test
-  public void chunkCanBeCreatedWithOnlyMemoryAddress() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    GemFireChunk newChunk = new GemFireChunk(chunk.getMemoryAddress());
-
-    assertNotNull(newChunk);
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-
-    chunk.release();
-  }
-
-  @Test
-  public void chunkSliceCanBeCreatedFromAnotherChunk() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    int position = 1;
-    int end = 2;
-
-    GemFireChunk newChunk = (GemFireChunk) chunk.slice(position, end);
-
-    assertNotNull(newChunk);
-    assertThat(newChunk.getClass()).isEqualTo(GemFireChunkSlice.class);
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-
-    chunk.release();
-  }
-
-  @Test
-  public void fillSerializedValueShouldFillWrapperWithSerializedValueIfValueIsSerialized() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    // mock the things
-    BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class);
-
-    byte userBits = 0;
-    byte serializedUserBits = 1;
-    chunk.fillSerializedValue(wrapper, userBits);
-
-    verify(wrapper, times(1)).setChunkData(chunk, serializedUserBits);
-
-    chunk.release();
-  }
-
-  @Test
-  public void fillSerializedValueShouldFillWrapperWithDeserializedValueIfValueIsNotSerialized() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    // mock the things
-    BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class);
-
-    byte userBits = 1;
-    chunk.fillSerializedValue(wrapper, userBits);
-
-    verify(wrapper, times(1)).setChunkData(chunk, userBits);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getShortClassNameShouldReturnShortClassName() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.getShortClassName()).isEqualTo("GemFireChunk");
-
-    chunk.release();
-  }
-
-  @Test
-  public void chunksAreEqualsOnlyByAddress() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    GemFireChunk newChunk = new GemFireChunk(chunk.getMemoryAddress());
-    assertThat(chunk.equals(newChunk)).isTrue();
-
-    GemFireChunk chunkWithSameValue = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.equals(chunkWithSameValue)).isFalse();
-
-    Object someObject = getValue();
-    assertThat(chunk.equals(someObject)).isFalse();
-
-    chunk.release();
-    chunkWithSameValue.release();
-  }
-
-  @Test
-  public void chunksShouldBeComparedBySize() {
-    GemFireChunk chunk1 = createValueAsSerializedStoredObject(getValue());
-
-    GemFireChunk chunk2 = chunk1;
-    assertThat(chunk1.compareTo(chunk2)).isEqualTo(0);
-
-    GemFireChunk chunkWithSameValue = createValueAsSerializedStoredObject(getValue());
-    assertThat(chunk1.compareTo(chunkWithSameValue)).isEqualTo(Long.signum(chunk1.getMemoryAddress() - chunkWithSameValue.getMemoryAddress()));
-
-    GemFireChunk chunk3 = createValueAsSerializedStoredObject(Long.MAX_VALUE);
-    GemFireChunk chunk4 = createValueAsSerializedStoredObject(Long.MAX_VALUE);
-
-    int newSizeForChunk3 = 2;
-    int newSizeForChunk4 = 3;
-
-    assertThat(chunk3.compareTo(chunk4)).isEqualTo(Integer.signum(newSizeForChunk3 - newSizeForChunk4));
-
-    chunk1.release();
-    chunk4.release();
-  }
-
-  @Test
-  public void setSerializedShouldSetTheSerializedBit() {
-    Object regionEntryValue = getValue();
-    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
-
-    boolean isSerialized = false;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    int headerBeforeSerializedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + Chunk.REF_COUNT_OFFSET);
-
-    assertThat(chunk.isSerialized()).isFalse();
-
-    chunk.setSerialized(true); // set to true
-
-    assertThat(chunk.isSerialized()).isTrue();
-
-    int headerAfterSerializedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + Chunk.REF_COUNT_OFFSET);
-
-    assertThat(headerAfterSerializedBitSet).isEqualTo(headerBeforeSerializedBitSet | Chunk.IS_SERIALIZED_BIT);
-
-    chunk.release();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void setSerialziedShouldThrowExceptionIfChunkIsAlreadyReleased() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.release();
-    chunk.setSerialized(true);
-
-    chunk.release();
-  }
-
-  @Test
-  public void setCompressedShouldSetTheCompressedBit() {
-    Object regionEntryValue = getValue();
-    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
-
-    boolean isSerialized = false;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    int headerBeforeCompressedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + Chunk.REF_COUNT_OFFSET);
-
-    assertThat(chunk.isCompressed()).isFalse();
-
-    chunk.setCompressed(true); // set to true
-
-    assertThat(chunk.isCompressed()).isTrue();
-
-    int headerAfterCompressedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + Chunk.REF_COUNT_OFFSET);
-
-    assertThat(headerAfterCompressedBitSet).isEqualTo(headerBeforeCompressedBitSet | Chunk.IS_COMPRESSED_BIT);
-
-    chunk.release();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void setCompressedShouldThrowExceptionIfChunkIsAlreadyReleased() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.release();
-    chunk.setCompressed(true);
-
-    chunk.release();
-  }
-
-  @Test
-  public void setDataSizeShouldSetTheDataSizeBits() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    int beforeSize = chunk.getDataSize();
-
-    chunk.setDataSize(2);
-
-    int afterSize = chunk.getDataSize();
-
-    assertThat(afterSize).isEqualTo(2);
-    assertThat(afterSize).isNotEqualTo(beforeSize);
-
-    chunk.release();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void setDataSizeShouldThrowExceptionIfChunkIsAlreadyReleased() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.release();
-    chunk.setDataSize(1);
-
-    chunk.release();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyRetained() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.retain();
-    chunk.initializeUseCount();
-
-    chunk.release();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyReleased() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.release();
-    chunk.initializeUseCount();
-
-    chunk.release();
-  }
-
-  @Test
-  public void isSerializedPdxInstanceShouldReturnTrueIfItsPDXInstance() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    byte[] serailizedValue = chunk.getSerializedValue();
-    serailizedValue[0] = DSCODE.PDX;
-    chunk.setSerializedValue(serailizedValue);
-
-    assertThat(chunk.isSerializedPdxInstance()).isTrue();
-
-    serailizedValue = chunk.getSerializedValue();
-    serailizedValue[0] = DSCODE.PDX_ENUM;
-    chunk.setSerializedValue(serailizedValue);
-
-    assertThat(chunk.isSerializedPdxInstance()).isTrue();
-
-    serailizedValue = chunk.getSerializedValue();
-    serailizedValue[0] = DSCODE.PDX_INLINE_ENUM;
-    chunk.setSerializedValue(serailizedValue);
-
-    assertThat(chunk.isSerializedPdxInstance()).isTrue();
-
-    chunk.release();
-  }
-
-  @Test
-  public void isSerializedPdxInstanceShouldReturnFalseIfItsNotPDXInstance() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    assertThat(chunk.isSerializedPdxInstance()).isFalse();
-
-    chunk.release();
-  }
-
-  @Test
-  public void checkDataEqualsByChunk() {
-    GemFireChunk chunk1 = createValueAsSerializedStoredObject(getValue());
-    GemFireChunk sameAsChunk1 = chunk1;
-
-    assertThat(chunk1.checkDataEquals(sameAsChunk1)).isTrue();
-
-    GemFireChunk unserializedChunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk1.checkDataEquals(unserializedChunk)).isFalse();
-
-    GemFireChunk chunkDifferBySize = createValueAsSerializedStoredObject(getValue());
-    chunkDifferBySize.setSize(0);
-    assertThat(chunk1.checkDataEquals(chunkDifferBySize)).isFalse();
-
-    GemFireChunk chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1);
-    assertThat(chunk1.checkDataEquals(chunkDifferByValue)).isFalse();
-
-    GemFireChunk newChunk1 = createValueAsSerializedStoredObject(getValue());
-    assertThat(chunk1.checkDataEquals(newChunk1)).isTrue();
-
-    chunk1.release();
-    unserializedChunk.release();
-    chunkDifferBySize.release();
-    chunkDifferByValue.release();
-    newChunk1.release();
-  }
-
-  @Test
-  public void checkDataEqualsBySerializedValue() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    assertThat(chunk.checkDataEquals(new byte[1])).isFalse();
-
-    GemFireChunk chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1);
-    assertThat(chunk.checkDataEquals(chunkDifferByValue.getSerializedValue())).isFalse();
-
-    GemFireChunk newChunk = createValueAsSerializedStoredObject(getValue());
-    assertThat(chunk.checkDataEquals(newChunk.getSerializedValue())).isTrue();
-
-    chunk.release();
-    chunkDifferByValue.release();
-    newChunk.release();
-  }
-
-  @Test
-  public void getDecompressedBytesShouldReturnDecompressedBytesIfCompressed() {
-    Object regionEntryValue = getValue();
-    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
-
-    boolean isSerialized = true;
-    boolean isCompressed = true;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    RegionEntryContext regionContext = mock(RegionEntryContext.class);
-    CachePerfStats cacheStats = mock(CachePerfStats.class);
-    Compressor compressor = mock(Compressor.class);
-
-    long startTime = 10000L;
-
-    // mock required things
-    when(regionContext.getCompressor()).thenReturn(compressor);
-    when(compressor.decompress(regionEntryValueAsBytes)).thenReturn(regionEntryValueAsBytes);
-    when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
-    when(cacheStats.startDecompression()).thenReturn(startTime);
-
-    // invoke the thing
-    byte[] bytes = chunk.getDecompressedBytes(regionContext);
-
-    // verify the thing happened
-    verify(cacheStats, atLeastOnce()).startDecompression();
-    verify(compressor, times(1)).decompress(regionEntryValueAsBytes);
-    verify(cacheStats, atLeastOnce()).endDecompression(startTime);
-
-    assertArrayEquals(regionEntryValueAsBytes, bytes);
-
-    chunk.release();
-  }
-
-  @Test
-  public void incSizeShouldIncrementSize() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    int beforeSize = chunk.getSize();
-
-    chunk.incSize(1);
-    assertThat(chunk.getSize()).isEqualTo(beforeSize + 1);
-
-    chunk.incSize(2);
-    assertThat(chunk.getSize()).isEqualTo(beforeSize + 1 + 2);
-
-    chunk.release();
-  }
-
-  @Test
-  public void readyForFreeShouldResetTheRefCount() {
-    Chunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    int refCountBeforeFreeing = chunk.getRefCount();
-    assertThat(refCountBeforeFreeing).isEqualTo(1);
-
-    chunk.readyForFree();
-
-    int refCountAfterFreeing = chunk.getRefCount();
-    assertThat(refCountAfterFreeing).isEqualTo(0);
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void readyForAllocationShouldThrowExceptionIfAlreadyAllocated() {
-    Chunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    // chunk is already allocated when we created it, so calling readyForAllocation should throw exception.
-    chunk.readyForAllocation(GemFireChunk.TYPE);
-
-    chunk.release();
-  }
-
-  @Test
-  public void checkIsAllocatedShouldReturnIfAllocated() {
-    Chunk chunk = createValueAsSerializedStoredObject(getValue());
-    chunk.checkIsAllocated();
-
-    chunk.release();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void checkIsAllocatedShouldThrowExceptionIfNotAllocated() {
-    Chunk chunk = createValueAsSerializedStoredObject(getValue());
-    chunk.release();
-    chunk.checkIsAllocated();
-
-    chunk.release();
-  }
-
-  @Test
-  public void sendToShouldWriteSerializedValueToDataOutputIfValueIsSerialized() throws IOException {
-    Chunk chunk = createValueAsSerializedStoredObject(getValue());
-    Chunk spyChunk = spy(chunk);
-
-    HeapDataOutputStream dataOutput = mock(HeapDataOutputStream.class);
-    ByteBuffer directByteBuffer = ByteBuffer.allocate(1024);
-
-    doReturn(directByteBuffer).when(spyChunk).createDirectByteBuffer();
-    doNothing().when(dataOutput).write(directByteBuffer);
-
-    spyChunk.sendTo(dataOutput);
-
-    verify(dataOutput, times(1)).write(directByteBuffer);
-
-    chunk.release();
-  }
-
-  @Test
-  public void sendToShouldWriteUnserializedValueToDataOutputIfValueIsUnserialized() throws IOException {
-    byte[] regionEntryValue = getValueAsByteArray();
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
-
-    // writeByte is a final method and cannot be mocked, so creating a real one
-    HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT);
-
-    chunk.sendTo(dataOutput);
-
-    byte[] actual = dataOutput.toByteArray();
-
-    byte[] expected = new byte[regionEntryValue.length + 2];
-    expected[0] = DSCODE.BYTE_ARRAY;
-    expected[1] = (byte) regionEntryValue.length;
-    System.arraycopy(regionEntryValue, 0, expected, 2, regionEntryValue.length);
-
-    assertNotNull(dataOutput);
-    assertThat(actual).isEqualTo(expected);
-
-    chunk.release();
-  }
-
-  @Test
-  public void sendAsByteArrayShouldWriteValueToDataOutput() throws IOException {
-    byte[] regionEntryValue = getValueAsByteArray();
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
-
-    // writeByte is a final method and cannot be mocked, so creating a real one
-    HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT);
-
-    chunk.sendAsByteArray(dataOutput);
-
-    byte[] actual = dataOutput.toByteArray();
-
-    byte[] expected = new byte[regionEntryValue.length + 1];
-    expected[0] = (byte) regionEntryValue.length;
-    System.arraycopy(regionEntryValue, 0, expected, 1, regionEntryValue.length);
-
-    assertNotNull(dataOutput);
-    assertThat(actual).isEqualTo(expected);
-
-    chunk.release();
-  }
-
-  @Test
-  public void createDirectByteBufferShouldCreateAByteBuffer() {
-    byte[] regionEntryValue = getValueAsByteArray();
-
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
-
-    ByteBuffer buffer = chunk.createDirectByteBuffer();
-
-    byte[] actual = new byte[regionEntryValue.length];
-    buffer.get(actual);
-
-    assertArrayEquals(regionEntryValue, actual);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getDirectByteBufferShouldCreateAByteBuffer() {
-    byte[] regionEntryValue = getValueAsByteArray();
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
-
-    ByteBuffer buffer = chunk.createDirectByteBuffer();
-    long bufferAddress = Chunk.getDirectByteBufferAddress(buffer);
-
-    // returned address should be starting of the value (after skipping HEADER_SIZE bytes)
-    assertEquals(chunk.getMemoryAddress() + Chunk.OFF_HEAP_HEADER_SIZE, bufferAddress);
-
-    chunk.release();
-  }
-
-  @Test(expected = AssertionError.class)
-  public void getAddressForReadingShouldFailIfItsOutsideOfChunk() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    chunk.getAddressForReading(0, chunk.getDataSize() + 1);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getAddressForReadingShouldReturnDataAddressFromGivenOffset() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    int offset = 1;
-    long requestedAddress = chunk.getAddressForReading(offset, 1);
-
-    assertThat(requestedAddress).isEqualTo(chunk.getBaseDataAddress() + offset);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getSizeInBytesShouldReturnSize() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    assertThat(chunk.getSizeInBytes()).isEqualTo(chunk.getSize());
-
-    chunk.release();
-  }
-
-  @Test(expected = AssertionError.class)
-  public void getUnsafeAddressShouldFailIfOffsetIsNegative() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    chunk.getUnsafeAddress(-1, 1);
-
-    chunk.release();
-  }
-
-  @Test(expected = AssertionError.class)
-  public void getUnsafeAddressShouldFailIfSizeIsNegative() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    chunk.getUnsafeAddress(1, -1);
-
-    chunk.release();
-  }
-
-  @Test(expected = AssertionError.class)
-  public void getUnsafeAddressShouldFailIfItsOutsideOfChunk() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-    chunk.getUnsafeAddress(0, chunk.getDataSize() + 1);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getUnsafeAddressShouldReturnUnsafeAddress() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    int offset = 1;
-    long unsafeAddress = chunk.getUnsafeAddress(offset, 1);
-
-    assertThat(unsafeAddress).isEqualTo(chunk.getBaseDataAddress() + offset);
-
-    chunk.release();
-  }
-
-  @Test(expected = AssertionError.class)
-  public void readByteAndWriteByteShouldFailIfOffsetIsOutside() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    chunk.readByte(chunk.getDataSize() + 1);
-
-    chunk.writeByte(chunk.getDataSize() + 1, Byte.MAX_VALUE);
-
-    chunk.release();
-  }
-
-  @Test
-  public void writeByteShouldWriteAtCorrectLocation() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    byte valueBeforeWrite = chunk.readByte(2);
-
-    Byte expected = Byte.MAX_VALUE;
-    chunk.writeByte(2, expected);
-
-    Byte actual = chunk.readByte(2);
-
-    assertThat(actual).isNotEqualTo(valueBeforeWrite);
-    assertThat(actual).isEqualTo(expected);
-
-    chunk.release();
-  }
-
-  @Test
-  public void retainShouldIncrementRefCount() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.getRefCount()).isEqualTo(1);
-
-    chunk.retain();
-    assertThat(chunk.getRefCount()).isEqualTo(2);
-
-    chunk.retain();
-    assertThat(chunk.getRefCount()).isEqualTo(3);
-
-    chunk.release();
-    chunk.release();
-    chunk.release();
-    boolean retainAfterRelease = chunk.retain();
-
-    assertThat(retainAfterRelease).isFalse();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void retainShouldThrowExceptionAfterMaxNumberOfTimesRetained() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    // loop though and invoke retain for MAX_REF_COUNT-1 times, as create chunk above counted as one reference
-    for (int i = 0; i < Chunk.MAX_REF_COUNT - 1; i++)
-      chunk.retain();
-
-    // invoke for the one more time should throw exception
-    chunk.retain();
-  }
-
-  @Test
-  public void releaseShouldDecrementRefCount() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.getRefCount()).isEqualTo(1);
-
-    chunk.retain();
-    chunk.retain();
-    assertThat(chunk.getRefCount()).isEqualTo(3);
-
-    chunk.release();
-    assertThat(chunk.getRefCount()).isEqualTo(2);
-
-    chunk.release();
-    assertThat(chunk.getRefCount()).isEqualTo(1);
-
-    chunk.retain();
-    chunk.release();
-    assertThat(chunk.getRefCount()).isEqualTo(1);
-
-    chunk.release();
-    assertThat(chunk.getRefCount()).isEqualTo(0);
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void releaseShouldThrowExceptionIfChunkIsAlreadyReleased() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.release();
-    chunk.release();
-  }
-
-  @Test
-  public void testToStringForOffHeapByteSource() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    String expected = ":<dataSize=" + chunk.getDataSize() + " refCount=" + chunk.getRefCount() + " addr=" + Long.toHexString(chunk.getMemoryAddress()) + ">";
-    assertThat(chunk.toStringForOffHeapByteSource()).endsWith(expected);
-
-    // test toString
-    Chunk spy = spy(chunk);
-    spy.toString();
-    verify(spy, times(1)).toStringForOffHeapByteSource();
-
-    chunk.release();
-  }
-
-  @Test
-  public void getStateShouldReturnAllocatedIfRefCountIsGreaterThanZero() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertEquals(State.ALLOCATED, chunk.getState());
-
-    chunk.release();
-  }
-
-  @Test
-  public void getStateShouldReturnDeallocatedIfRefCountIsZero() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.release();
-    assertEquals(State.DEALLOCATED, chunk.getState());
-  }
-
-  @Test(expected = UnsupportedOperationException.class)
-  public void getNextBlockShouldThrowUnSupportedOperationException() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.getNextBlock();
-
-    chunk.release();
-  }
-
-  @Test
-  public void getBlockSizeShouldBeSameSameGetSize() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertEquals(chunk.getSize(), chunk.getBlockSize());
-
-    chunk.release();
-  }
-
-  @Test(expected = UnsupportedOperationException.class)
-  public void copyBytesShouldThrowUnSupportedOperationException() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.copyBytes(1, 2, 1);
-
-    chunk.release();
-  }
-
-  @Test(expected = UnsupportedOperationException.class)
-  public void getSlabIdShouldThrowUnSupportedOperationException() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    chunk.getSlabId();
-
-    chunk.release();
-  }
-
-  @Test
-  public void getFreeListIdShouldReturnMinusOne() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.getFreeListId()).isEqualTo(-1);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getDataTypeShouldReturnNull() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.getDataType()).isNull();
-
-    chunk.release();
-  }
-
-  @Test
-  public void getDataDataShouldReturnNull() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    assertThat(chunk.getDataValue()).isNull();
-  }
-
-  @Test(expected = UnsupportedOperationException.class)
-  public void getRawBytesShouldThrowExceptionIfValueIsCompressed() {
-    Object regionEntryValue = getValue();
-    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
-
-    boolean isSerialized = true;
-    boolean isCompressed = true;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    chunk.getRawBytes();
-
-    chunk.release();
-  }
-
-  @Test
-  public void getSerializedValueShouldSerializeTheValue() {
-    Object regionEntryValue = getValue();
-    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
-
-    boolean isSerialized = false;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    byte[] serializedValue = chunk.getSerializedValue();
-
-    assertThat(serializedValue).isEqualTo(EntryEventImpl.serialize(regionEntryValueAsBytes));
-
-    chunk.release();
-  }
-
-  @Test
-  public void getSrcTypeOrdinalFromAddressShouldReturnOrdinal() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    assertThat(Chunk.getSrcTypeOrdinal(chunk.getMemoryAddress())).isEqualTo(Chunk.SRC_TYPE_GFE >> Chunk.SRC_TYPE_SHIFT);
-
-    chunk.release();
-  }
-
-  @Test
-  public void getSrcTypeOrdinalFromRawBitsShouldReturnOrdinal() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    int rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + Chunk.REF_COUNT_OFFSET);
-    assertThat(Chunk.getSrcTypeOrdinalFromRawBits(rawBits)).isEqualTo(Chunk.SRC_TYPE_GFE >> Chunk.SRC_TYPE_SHIFT);
-
-    chunk.release();
-  }
-
-  @Test
-  public void fillShouldFillTheChunk() {
-    boolean isSerialized = false;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(new byte[100], isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    // first fill the unused part with FILL_PATTERN
-    Chunk.fill(chunk.getMemoryAddress());
-
-    // Validate that it is filled
-    chunk.validateFill();
-
-    chunk.release();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSliceJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSliceJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSliceJUnitTest.java
deleted file mode 100644
index 39ee620..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkSliceJUnitTest.java
+++ /dev/null
@@ -1,72 +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 com.gemstone.gemfire.internal.offheap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class GemFireChunkSliceJUnitTest extends GemFireChunkJUnitTest {
-
-  @Test
-  public void sliceShouldHaveAValidDataSize() {
-    int position = 1;
-    int end = 2;
-
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    GemFireChunkSlice slice = (GemFireChunkSlice) chunk.slice(position, end);
-
-    assertNotNull(slice);
-    assertEquals(GemFireChunkSlice.class, slice.getClass());
-
-    assertEquals(end - position, slice.getDataSize());
-  }
-
-  @Test
-  public void sliceShouldHaveAValidBaseDataAddress() {
-    int position = 1;
-    int end = 2;
-
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    GemFireChunkSlice slice = (GemFireChunkSlice) chunk.slice(position, end);
-
-    assertNotNull(slice);
-    assertEquals(GemFireChunkSlice.class, slice.getClass());
-
-    assertEquals(chunk.getBaseDataAddress() + position, slice.getBaseDataAddress());
-  }
-
-  @Test
-  public void sliceShouldHaveAValidBaseOffset() {
-    int position = 1;
-    int end = 2;
-
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-    GemFireChunkSlice slice = (GemFireChunkSlice) chunk.slice(position, end);
-
-    assertNotNull(slice);
-    assertEquals(GemFireChunkSlice.class, slice.getClass());
-
-    assertEquals(chunk.getBaseDataOffset() + position, slice.getBaseDataOffset());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
index 5e54b73..97ae486 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
@@ -63,7 +63,7 @@ public class LifecycleListenerJUnitTest {
     LifecycleListener.removeLifecycleListener(this.listener);
 
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
-    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
+    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
         new UnsafeMemoryChunk[] { slab });
 
     Assert.assertEquals(0, this.afterCreateCallbacks.size());
@@ -83,7 +83,7 @@ public class LifecycleListenerJUnitTest {
   public void testCallbacksAreCalledAfterCreate() {
     LifecycleListener.addLifecycleListener(this.listener);
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
-    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
+    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
         new UnsafeMemoryChunk[] { slab });
 
     Assert.assertEquals(1, this.afterCreateCallbacks.size());
@@ -141,7 +141,7 @@ public class LifecycleListenerJUnitTest {
 
   private SimpleMemoryAllocatorImpl createAllocator(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats ohms, UnsafeMemoryChunk[] slab) {
     try {
-       return SimpleMemoryAllocatorImpl.create(ooohml, ohms, slab);
+       return SimpleMemoryAllocatorImpl.createForUnitTest(ooohml, ohms, slab);
     } catch (IllegalStateException e) {
       return null;
     }
@@ -162,7 +162,7 @@ public class LifecycleListenerJUnitTest {
     LifecycleListener.addLifecycleListener(this.listener);
 
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
-    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
+    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
 
     Assert.assertEquals(1, this.afterCreateCallbacks.size());
     Assert.assertEquals(0, this.afterReuseCallbacks.size());
@@ -175,7 +175,7 @@ public class LifecycleListenerJUnitTest {
     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
 
     slab = new UnsafeMemoryChunk(1024); // 1k
-    SimpleMemoryAllocatorImpl ma2 = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
+    SimpleMemoryAllocatorImpl ma2 = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
 
     Assert.assertEquals(2, this.afterCreateCallbacks.size());
     Assert.assertEquals(0, this.afterReuseCallbacks.size());

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java
new file mode 100644
index 0000000..9271b53
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java
@@ -0,0 +1,902 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.atLeastOnce;
+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.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.compression.Compressor;
+import com.gemstone.gemfire.internal.DSCODE;
+import com.gemstone.gemfire.internal.HeapDataOutputStream;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
+import com.gemstone.gemfire.internal.cache.CachePerfStats;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.RegionEntryContext;
+import com.gemstone.gemfire.internal.offheap.MemoryBlock.State;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class ObjectChunkJUnitTest extends AbstractStoredObjectTestBase {
+
+  private MemoryAllocator ma;
+
+  static {
+    ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
+  }
+
+  @Before
+  public void setUp() {
+    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
+    OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
+    LogWriter lw = mock(LogWriter.class);
+
+    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 3, OffHeapStorage.MIN_SLAB_SIZE * 3, OffHeapStorage.MIN_SLAB_SIZE);
+  }
+
+  @After
+  public void tearDown() {
+    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+  }
+
+  @Override
+  public Object getValue() {
+    return Long.valueOf(Long.MAX_VALUE);
+  }
+
+  @Override
+  public byte[] getValueAsByteArray() {
+    return convertValueToByteArray(getValue());
+  }
+
+  private byte[] convertValueToByteArray(Object value) {
+    return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong((Long) value).array();
+  }
+
+  @Override
+  public Object convertByteArrayToObject(byte[] valueInByteArray) {
+    return ByteBuffer.wrap(valueInByteArray).getLong();
+  }
+
+  @Override
+  public Object convertSerializedByteArrayToObject(byte[] valueInSerializedByteArray) {
+    return EntryEventImpl.deserialize(valueInSerializedByteArray);
+  }
+
+  @Override
+  public ObjectChunk createValueAsUnserializedStoredObject(Object value) {
+    byte[] valueInByteArray;
+    if (value instanceof Long) {
+      valueInByteArray = convertValueToByteArray(value);
+    } else {
+      valueInByteArray = (byte[]) value;
+    }
+
+    boolean isSerialized = false;
+    boolean isCompressed = false;
+
+    return createChunk(valueInByteArray, isSerialized, isCompressed);
+  }
+
+  @Override
+  public ObjectChunk createValueAsSerializedStoredObject(Object value) {
+    byte[] valueInSerializedByteArray = EntryEventImpl.serialize(value);
+
+    boolean isSerialized = true;
+    boolean isCompressed = false;
+
+    return createChunk(valueInSerializedByteArray, isSerialized, isCompressed);
+  }
+
+  private ObjectChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed);
+    return chunk;
+  }
+
+  @Test
+  public void chunkCanBeCreatedFromAnotherChunk() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    ObjectChunk newChunk = new ObjectChunk(chunk);
+
+    assertNotNull(newChunk);
+    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
+
+    chunk.release();
+  }
+
+  @Test
+  public void chunkCanBeCreatedWithOnlyMemoryAddress() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    ObjectChunk newChunk = new ObjectChunk(chunk.getMemoryAddress());
+
+    assertNotNull(newChunk);
+    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
+
+    chunk.release();
+  }
+
+  @Test
+  public void chunkSliceCanBeCreatedFromAnotherChunk() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    int position = 1;
+    int end = 2;
+
+    ObjectChunk newChunk = (ObjectChunk) chunk.slice(position, end);
+
+    assertNotNull(newChunk);
+    assertThat(newChunk.getClass()).isEqualTo(ObjectChunkSlice.class);
+    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
+
+    chunk.release();
+  }
+
+  @Test
+  public void fillSerializedValueShouldFillWrapperWithSerializedValueIfValueIsSerialized() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    // mock the things
+    BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class);
+
+    byte userBits = 0;
+    byte serializedUserBits = 1;
+    chunk.fillSerializedValue(wrapper, userBits);
+
+    verify(wrapper, times(1)).setChunkData(chunk, serializedUserBits);
+
+    chunk.release();
+  }
+
+  @Test
+  public void fillSerializedValueShouldFillWrapperWithDeserializedValueIfValueIsNotSerialized() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    // mock the things
+    BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class);
+
+    byte userBits = 1;
+    chunk.fillSerializedValue(wrapper, userBits);
+
+    verify(wrapper, times(1)).setChunkData(chunk, userBits);
+
+    chunk.release();
+  }
+
+  @Test
+  public void getShortClassNameShouldReturnShortClassName() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.getShortClassName()).isEqualTo("ObjectChunk");
+
+    chunk.release();
+  }
+
+  @Test
+  public void chunksAreEqualsOnlyByAddress() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    ObjectChunk newChunk = new ObjectChunk(chunk.getMemoryAddress());
+    assertThat(chunk.equals(newChunk)).isTrue();
+
+    ObjectChunk chunkWithSameValue = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.equals(chunkWithSameValue)).isFalse();
+
+    Object someObject = getValue();
+    assertThat(chunk.equals(someObject)).isFalse();
+
+    chunk.release();
+    chunkWithSameValue.release();
+  }
+
+  @Test
+  public void chunksShouldBeComparedBySize() {
+    ObjectChunk chunk1 = createValueAsSerializedStoredObject(getValue());
+
+    ObjectChunk chunk2 = chunk1;
+    assertThat(chunk1.compareTo(chunk2)).isEqualTo(0);
+
+    ObjectChunk chunkWithSameValue = createValueAsSerializedStoredObject(getValue());
+    assertThat(chunk1.compareTo(chunkWithSameValue)).isEqualTo(Long.signum(chunk1.getMemoryAddress() - chunkWithSameValue.getMemoryAddress()));
+
+    ObjectChunk chunk3 = createValueAsSerializedStoredObject(Long.MAX_VALUE);
+    ObjectChunk chunk4 = createValueAsSerializedStoredObject(Long.MAX_VALUE);
+
+    int newSizeForChunk3 = 2;
+    int newSizeForChunk4 = 3;
+
+    assertThat(chunk3.compareTo(chunk4)).isEqualTo(Integer.signum(newSizeForChunk3 - newSizeForChunk4));
+
+    chunk1.release();
+    chunk4.release();
+  }
+
+  @Test
+  public void setSerializedShouldSetTheSerializedBit() {
+    Object regionEntryValue = getValue();
+    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
+
+    boolean isSerialized = false;
+    boolean isCompressed = false;
+
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
+
+    int headerBeforeSerializedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
+
+    assertThat(chunk.isSerialized()).isFalse();
+
+    chunk.setSerialized(true); // set to true
+
+    assertThat(chunk.isSerialized()).isTrue();
+
+    int headerAfterSerializedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
+
+    assertThat(headerAfterSerializedBitSet).isEqualTo(headerBeforeSerializedBitSet | ObjectChunk.IS_SERIALIZED_BIT);
+
+    chunk.release();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void setSerialziedShouldThrowExceptionIfChunkIsAlreadyReleased() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.release();
+    chunk.setSerialized(true);
+
+    chunk.release();
+  }
+
+  @Test
+  public void setCompressedShouldSetTheCompressedBit() {
+    Object regionEntryValue = getValue();
+    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
+
+    boolean isSerialized = false;
+    boolean isCompressed = false;
+
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
+
+    int headerBeforeCompressedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
+
+    assertThat(chunk.isCompressed()).isFalse();
+
+    chunk.setCompressed(true); // set to true
+
+    assertThat(chunk.isCompressed()).isTrue();
+
+    int headerAfterCompressedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
+
+    assertThat(headerAfterCompressedBitSet).isEqualTo(headerBeforeCompressedBitSet | ObjectChunk.IS_COMPRESSED_BIT);
+
+    chunk.release();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void setCompressedShouldThrowExceptionIfChunkIsAlreadyReleased() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.release();
+    chunk.setCompressed(true);
+
+    chunk.release();
+  }
+
+  @Test
+  public void setDataSizeShouldSetTheDataSizeBits() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    int beforeSize = chunk.getDataSize();
+
+    chunk.setDataSize(2);
+
+    int afterSize = chunk.getDataSize();
+
+    assertThat(afterSize).isEqualTo(2);
+    assertThat(afterSize).isNotEqualTo(beforeSize);
+
+    chunk.release();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void setDataSizeShouldThrowExceptionIfChunkIsAlreadyReleased() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.release();
+    chunk.setDataSize(1);
+
+    chunk.release();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyRetained() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.retain();
+    chunk.initializeUseCount();
+
+    chunk.release();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyReleased() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.release();
+    chunk.initializeUseCount();
+
+    chunk.release();
+  }
+
+  @Test
+  public void isSerializedPdxInstanceShouldReturnTrueIfItsPDXInstance() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    byte[] serailizedValue = chunk.getSerializedValue();
+    serailizedValue[0] = DSCODE.PDX;
+    chunk.setSerializedValue(serailizedValue);
+
+    assertThat(chunk.isSerializedPdxInstance()).isTrue();
+
+    serailizedValue = chunk.getSerializedValue();
+    serailizedValue[0] = DSCODE.PDX_ENUM;
+    chunk.setSerializedValue(serailizedValue);
+
+    assertThat(chunk.isSerializedPdxInstance()).isTrue();
+
+    serailizedValue = chunk.getSerializedValue();
+    serailizedValue[0] = DSCODE.PDX_INLINE_ENUM;
+    chunk.setSerializedValue(serailizedValue);
+
+    assertThat(chunk.isSerializedPdxInstance()).isTrue();
+
+    chunk.release();
+  }
+
+  @Test
+  public void isSerializedPdxInstanceShouldReturnFalseIfItsNotPDXInstance() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    assertThat(chunk.isSerializedPdxInstance()).isFalse();
+
+    chunk.release();
+  }
+
+  @Test
+  public void checkDataEqualsByChunk() {
+    ObjectChunk chunk1 = createValueAsSerializedStoredObject(getValue());
+    ObjectChunk sameAsChunk1 = chunk1;
+
+    assertThat(chunk1.checkDataEquals(sameAsChunk1)).isTrue();
+
+    ObjectChunk unserializedChunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk1.checkDataEquals(unserializedChunk)).isFalse();
+
+    ObjectChunk chunkDifferBySize = createValueAsSerializedStoredObject(getValue());
+    chunkDifferBySize.setSize(0);
+    assertThat(chunk1.checkDataEquals(chunkDifferBySize)).isFalse();
+
+    ObjectChunk chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1);
+    assertThat(chunk1.checkDataEquals(chunkDifferByValue)).isFalse();
+
+    ObjectChunk newChunk1 = createValueAsSerializedStoredObject(getValue());
+    assertThat(chunk1.checkDataEquals(newChunk1)).isTrue();
+
+    chunk1.release();
+    unserializedChunk.release();
+    chunkDifferBySize.release();
+    chunkDifferByValue.release();
+    newChunk1.release();
+  }
+
+  @Test
+  public void checkDataEqualsBySerializedValue() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    assertThat(chunk.checkDataEquals(new byte[1])).isFalse();
+
+    ObjectChunk chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1);
+    assertThat(chunk.checkDataEquals(chunkDifferByValue.getSerializedValue())).isFalse();
+
+    ObjectChunk newChunk = createValueAsSerializedStoredObject(getValue());
+    assertThat(chunk.checkDataEquals(newChunk.getSerializedValue())).isTrue();
+
+    chunk.release();
+    chunkDifferByValue.release();
+    newChunk.release();
+  }
+
+  @Test
+  public void getDecompressedBytesShouldReturnDecompressedBytesIfCompressed() {
+    Object regionEntryValue = getValue();
+    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
+
+    boolean isSerialized = true;
+    boolean isCompressed = true;
+
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
+
+    RegionEntryContext regionContext = mock(RegionEntryContext.class);
+    CachePerfStats cacheStats = mock(CachePerfStats.class);
+    Compressor compressor = mock(Compressor.class);
+
+    long startTime = 10000L;
+
+    // mock required things
+    when(regionContext.getCompressor()).thenReturn(compressor);
+    when(compressor.decompress(regionEntryValueAsBytes)).thenReturn(regionEntryValueAsBytes);
+    when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
+    when(cacheStats.startDecompression()).thenReturn(startTime);
+
+    // invoke the thing
+    byte[] bytes = chunk.getDecompressedBytes(regionContext);
+
+    // verify the thing happened
+    verify(cacheStats, atLeastOnce()).startDecompression();
+    verify(compressor, times(1)).decompress(regionEntryValueAsBytes);
+    verify(cacheStats, atLeastOnce()).endDecompression(startTime);
+
+    assertArrayEquals(regionEntryValueAsBytes, bytes);
+
+    chunk.release();
+  }
+
+  @Test
+  public void incSizeShouldIncrementSize() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    int beforeSize = chunk.getSize();
+
+    chunk.incSize(1);
+    assertThat(chunk.getSize()).isEqualTo(beforeSize + 1);
+
+    chunk.incSize(2);
+    assertThat(chunk.getSize()).isEqualTo(beforeSize + 1 + 2);
+
+    chunk.release();
+  }
+
+  @Test
+  public void readyForFreeShouldResetTheRefCount() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    int refCountBeforeFreeing = chunk.getRefCount();
+    assertThat(refCountBeforeFreeing).isEqualTo(1);
+
+    chunk.readyForFree();
+
+    int refCountAfterFreeing = chunk.getRefCount();
+    assertThat(refCountAfterFreeing).isEqualTo(0);
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void readyForAllocationShouldThrowExceptionIfAlreadyAllocated() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    // chunk is already allocated when we created it, so calling readyForAllocation should throw exception.
+    chunk.readyForAllocation();
+
+    chunk.release();
+  }
+
+  @Test
+  public void checkIsAllocatedShouldReturnIfAllocated() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    chunk.checkIsAllocated();
+
+    chunk.release();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void checkIsAllocatedShouldThrowExceptionIfNotAllocated() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    chunk.release();
+    chunk.checkIsAllocated();
+
+    chunk.release();
+  }
+
+  @Test
+  public void sendToShouldWriteSerializedValueToDataOutputIfValueIsSerialized() throws IOException {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    ObjectChunk spyChunk = spy(chunk);
+
+    HeapDataOutputStream dataOutput = mock(HeapDataOutputStream.class);
+    ByteBuffer directByteBuffer = ByteBuffer.allocate(1024);
+
+    doReturn(directByteBuffer).when(spyChunk).createDirectByteBuffer();
+    doNothing().when(dataOutput).write(directByteBuffer);
+
+    spyChunk.sendTo(dataOutput);
+
+    verify(dataOutput, times(1)).write(directByteBuffer);
+
+    chunk.release();
+  }
+
+  @Test
+  public void sendToShouldWriteUnserializedValueToDataOutputIfValueIsUnserialized() throws IOException {
+    byte[] regionEntryValue = getValueAsByteArray();
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
+
+    // writeByte is a final method and cannot be mocked, so creating a real one
+    HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT);
+
+    chunk.sendTo(dataOutput);
+
+    byte[] actual = dataOutput.toByteArray();
+
+    byte[] expected = new byte[regionEntryValue.length + 2];
+    expected[0] = DSCODE.BYTE_ARRAY;
+    expected[1] = (byte) regionEntryValue.length;
+    System.arraycopy(regionEntryValue, 0, expected, 2, regionEntryValue.length);
+
+    assertNotNull(dataOutput);
+    assertThat(actual).isEqualTo(expected);
+
+    chunk.release();
+  }
+
+  @Test
+  public void sendAsByteArrayShouldWriteValueToDataOutput() throws IOException {
+    byte[] regionEntryValue = getValueAsByteArray();
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
+
+    // writeByte is a final method and cannot be mocked, so creating a real one
+    HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT);
+
+    chunk.sendAsByteArray(dataOutput);
+
+    byte[] actual = dataOutput.toByteArray();
+
+    byte[] expected = new byte[regionEntryValue.length + 1];
+    expected[0] = (byte) regionEntryValue.length;
+    System.arraycopy(regionEntryValue, 0, expected, 1, regionEntryValue.length);
+
+    assertNotNull(dataOutput);
+    assertThat(actual).isEqualTo(expected);
+
+    chunk.release();
+  }
+
+  @Test
+  public void createDirectByteBufferShouldCreateAByteBuffer() {
+    byte[] regionEntryValue = getValueAsByteArray();
+
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
+
+    ByteBuffer buffer = chunk.createDirectByteBuffer();
+
+    byte[] actual = new byte[regionEntryValue.length];
+    buffer.get(actual);
+
+    assertArrayEquals(regionEntryValue, actual);
+
+    chunk.release();
+  }
+
+  @Test
+  public void getDirectByteBufferShouldCreateAByteBuffer() {
+    byte[] regionEntryValue = getValueAsByteArray();
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
+
+    ByteBuffer buffer = chunk.createDirectByteBuffer();
+    long bufferAddress = ObjectChunk.getDirectByteBufferAddress(buffer);
+
+    // returned address should be starting of the value (after skipping HEADER_SIZE bytes)
+    assertEquals(chunk.getMemoryAddress() + ObjectChunk.OFF_HEAP_HEADER_SIZE, bufferAddress);
+
+    chunk.release();
+  }
+
+  @Test(expected = AssertionError.class)
+  public void getAddressForReadingShouldFailIfItsOutsideOfChunk() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    chunk.getAddressForReading(0, chunk.getDataSize() + 1);
+
+    chunk.release();
+  }
+
+  @Test
+  public void getAddressForReadingShouldReturnDataAddressFromGivenOffset() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    int offset = 1;
+    long requestedAddress = chunk.getAddressForReading(offset, 1);
+
+    assertThat(requestedAddress).isEqualTo(chunk.getBaseDataAddress() + offset);
+
+    chunk.release();
+  }
+
+  @Test
+  public void getSizeInBytesShouldReturnSize() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    assertThat(chunk.getSizeInBytes()).isEqualTo(chunk.getSize());
+
+    chunk.release();
+  }
+
+  @Test(expected = AssertionError.class)
+  public void getUnsafeAddressShouldFailIfOffsetIsNegative() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    chunk.getUnsafeAddress(-1, 1);
+
+    chunk.release();
+  }
+
+  @Test(expected = AssertionError.class)
+  public void getUnsafeAddressShouldFailIfSizeIsNegative() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    chunk.getUnsafeAddress(1, -1);
+
+    chunk.release();
+  }
+
+  @Test(expected = AssertionError.class)
+  public void getUnsafeAddressShouldFailIfItsOutsideOfChunk() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+    chunk.getUnsafeAddress(0, chunk.getDataSize() + 1);
+
+    chunk.release();
+  }
+
+  @Test
+  public void getUnsafeAddressShouldReturnUnsafeAddress() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    int offset = 1;
+    long unsafeAddress = chunk.getUnsafeAddress(offset, 1);
+
+    assertThat(unsafeAddress).isEqualTo(chunk.getBaseDataAddress() + offset);
+
+    chunk.release();
+  }
+
+  @Test(expected = AssertionError.class)
+  public void readByteAndWriteByteShouldFailIfOffsetIsOutside() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    chunk.readByte(chunk.getDataSize() + 1);
+
+    chunk.writeByte(chunk.getDataSize() + 1, Byte.MAX_VALUE);
+
+    chunk.release();
+  }
+
+  @Test
+  public void writeByteShouldWriteAtCorrectLocation() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    byte valueBeforeWrite = chunk.readByte(2);
+
+    Byte expected = Byte.MAX_VALUE;
+    chunk.writeByte(2, expected);
+
+    Byte actual = chunk.readByte(2);
+
+    assertThat(actual).isNotEqualTo(valueBeforeWrite);
+    assertThat(actual).isEqualTo(expected);
+
+    chunk.release();
+  }
+
+  @Test
+  public void retainShouldIncrementRefCount() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.getRefCount()).isEqualTo(1);
+
+    chunk.retain();
+    assertThat(chunk.getRefCount()).isEqualTo(2);
+
+    chunk.retain();
+    assertThat(chunk.getRefCount()).isEqualTo(3);
+
+    chunk.release();
+    chunk.release();
+    chunk.release();
+    boolean retainAfterRelease = chunk.retain();
+
+    assertThat(retainAfterRelease).isFalse();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void retainShouldThrowExceptionAfterMaxNumberOfTimesRetained() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    // loop though and invoke retain for MAX_REF_COUNT-1 times, as create chunk above counted as one reference
+    for (int i = 0; i < ObjectChunk.MAX_REF_COUNT - 1; i++)
+      chunk.retain();
+
+    // invoke for the one more time should throw exception
+    chunk.retain();
+  }
+
+  @Test
+  public void releaseShouldDecrementRefCount() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.getRefCount()).isEqualTo(1);
+
+    chunk.retain();
+    chunk.retain();
+    assertThat(chunk.getRefCount()).isEqualTo(3);
+
+    chunk.release();
+    assertThat(chunk.getRefCount()).isEqualTo(2);
+
+    chunk.release();
+    assertThat(chunk.getRefCount()).isEqualTo(1);
+
+    chunk.retain();
+    chunk.release();
+    assertThat(chunk.getRefCount()).isEqualTo(1);
+
+    chunk.release();
+    assertThat(chunk.getRefCount()).isEqualTo(0);
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void releaseShouldThrowExceptionIfChunkIsAlreadyReleased() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.release();
+    chunk.release();
+  }
+
+  @Test
+  public void testToStringForOffHeapByteSource() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    String expected = ":<dataSize=" + chunk.getDataSize() + " refCount=" + chunk.getRefCount() + " addr=" + Long.toHexString(chunk.getMemoryAddress()) + ">";
+    assertThat(chunk.toStringForOffHeapByteSource()).endsWith(expected);
+
+    // test toString
+    ObjectChunk spy = spy(chunk);
+    spy.toString();
+    verify(spy, times(1)).toStringForOffHeapByteSource();
+
+    chunk.release();
+  }
+
+  @Test
+  public void getStateShouldReturnAllocatedIfRefCountIsGreaterThanZero() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertEquals(State.ALLOCATED, chunk.getState());
+
+    chunk.release();
+  }
+
+  @Test
+  public void getStateShouldReturnDeallocatedIfRefCountIsZero() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.release();
+    assertEquals(State.DEALLOCATED, chunk.getState());
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void getNextBlockShouldThrowUnSupportedOperationException() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.getNextBlock();
+
+    chunk.release();
+  }
+
+  @Test
+  public void getBlockSizeShouldBeSameSameGetSize() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertEquals(chunk.getSize(), chunk.getBlockSize());
+
+    chunk.release();
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void copyBytesShouldThrowUnSupportedOperationException() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.copyBytes(1, 2, 1);
+
+    chunk.release();
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void getSlabIdShouldThrowUnSupportedOperationException() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    chunk.getSlabId();
+
+    chunk.release();
+  }
+
+  @Test
+  public void getFreeListIdShouldReturnMinusOne() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.getFreeListId()).isEqualTo(-1);
+
+    chunk.release();
+  }
+
+  @Test
+  public void getDataTypeShouldReturnNull() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.getDataType()).isNull();
+
+    chunk.release();
+  }
+
+  @Test
+  public void getDataDataShouldReturnNull() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    assertThat(chunk.getDataValue()).isNull();
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void getRawBytesShouldThrowExceptionIfValueIsCompressed() {
+    Object regionEntryValue = getValue();
+    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
+
+    boolean isSerialized = true;
+    boolean isCompressed = true;
+
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
+
+    chunk.getRawBytes();
+
+    chunk.release();
+  }
+
+  @Test
+  public void getSerializedValueShouldSerializeTheValue() {
+    Object regionEntryValue = getValue();
+    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
+
+    boolean isSerialized = false;
+    boolean isCompressed = false;
+
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
+
+    byte[] serializedValue = chunk.getSerializedValue();
+
+    assertThat(serializedValue).isEqualTo(EntryEventImpl.serialize(regionEntryValueAsBytes));
+
+    chunk.release();
+  }
+
+  @Test
+  public void fillShouldFillTheChunk() {
+    boolean isSerialized = false;
+    boolean isCompressed = false;
+
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(new byte[100], isSerialized, isCompressed);
+
+    // first fill the unused part with FILL_PATTERN
+    ObjectChunk.fill(chunk.getMemoryAddress());
+
+    // Validate that it is filled
+    chunk.validateFill();
+
+    chunk.release();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java
new file mode 100644
index 0000000..fe55910
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class ObjectChunkSliceJUnitTest extends ObjectChunkJUnitTest {
+
+  @Test
+  public void sliceShouldHaveAValidDataSize() {
+    int position = 1;
+    int end = 2;
+
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    ObjectChunkSlice slice = (ObjectChunkSlice) chunk.slice(position, end);
+
+    assertNotNull(slice);
+    assertEquals(ObjectChunkSlice.class, slice.getClass());
+
+    assertEquals(end - position, slice.getDataSize());
+  }
+
+  @Test
+  public void sliceShouldHaveAValidBaseDataAddress() {
+    int position = 1;
+    int end = 2;
+
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    ObjectChunkSlice slice = (ObjectChunkSlice) chunk.slice(position, end);
+
+    assertNotNull(slice);
+    assertEquals(ObjectChunkSlice.class, slice.getClass());
+
+    assertEquals(chunk.getBaseDataAddress() + position, slice.getBaseDataAddress());
+  }
+
+  @Test
+  public void sliceShouldHaveAValidBaseOffset() {
+    int position = 1;
+    int end = 2;
+
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+    ObjectChunkSlice slice = (ObjectChunkSlice) chunk.slice(position, end);
+
+    assertNotNull(slice);
+    assertEquals(ObjectChunkSlice.class, slice.getClass());
+
+    assertEquals(chunk.getBaseDataOffset() + position, slice.getBaseDataOffset());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.java
new file mode 100644
index 0000000..4486845
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.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 com.gemstone.gemfire.internal.offheap;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class ObjectChunkWithHeapFormJUnitTest extends ObjectChunkJUnitTest {
+
+  @Test
+  public void getRawBytesShouldReturnCachedHeapForm() {
+    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
+
+    byte[] valueInBytes = getValueAsByteArray();
+    ObjectChunkWithHeapForm heapForm = new ObjectChunkWithHeapForm(chunk, valueInBytes);
+
+    assertNotNull(heapForm);
+
+    assertSame(valueInBytes, heapForm.getRawBytes());
+  }
+
+  @Test
+  public void getChunkWithoutHeapFormShouldReturnGemFireChunk() {
+    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
+
+    byte[] valueInBytes = getValueAsByteArray();
+    ObjectChunkWithHeapForm heapForm = new ObjectChunkWithHeapForm(chunk, valueInBytes);
+
+    ObjectChunk chunkWithOutHeapForm = heapForm.getChunkWithoutHeapForm();
+
+    assertNotNull(chunkWithOutHeapForm);
+    assertEquals(ObjectChunk.class, chunkWithOutHeapForm.getClass());
+
+    assertEquals(chunk, heapForm.getChunkWithoutHeapForm());
+
+    assertEquals(chunk.getMemoryAddress(), chunkWithOutHeapForm.getMemoryAddress());
+    assertArrayEquals(chunk.getRawBytes(), chunkWithOutHeapForm.getRawBytes());
+    assertNotSame(valueInBytes, chunkWithOutHeapForm.getRawBytes());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
index fd0eb4f..b1e3af0 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapHelperJUnitTest.java
@@ -128,8 +128,8 @@ public class OffHeapHelperJUnitTest extends AbstractStoredObjectTestBase {
     return createdObject;
   }
 
-  private GemFireChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
+  private ObjectChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed);
     return chunk;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
index b515959..8de0406 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionBase.java
@@ -92,7 +92,7 @@ public abstract class OffHeapRegionBase {
       assertNotNull(ma);
       final long offHeapSize = ma.getFreeMemory();
       assertEquals(0, ma.getUsedMemory());
-      MemoryChunk mc1 = ma.allocate(64, null);
+      MemoryChunk mc1 = ma.allocate(64);
       assertEquals(64+perObjectOverhead(), ma.getUsedMemory());
       assertEquals(offHeapSize-(64+perObjectOverhead()), ma.getFreeMemory());
       mc1.release();
@@ -103,7 +103,7 @@ public abstract class OffHeapRegionBase {
       // (see the todo comment on compact() in SimpleMemoryAllocator).
       // So we request 20m here since that it the total size.
       try {
-        ma.allocate(1024*1024*20, null);
+        ma.allocate(1024*1024*20);
         fail("Expected an out of heap exception");
       } catch (OutOfOffHeapMemoryException expected) {
       }
@@ -123,7 +123,7 @@ public abstract class OffHeapRegionBase {
       assertNotNull(ma);
       final long offHeapSize = ma.getFreeMemory();
       assertEquals(0, ma.getUsedMemory());
-      MemoryChunk mc1 = ma.allocate(64, null);
+      MemoryChunk mc1 = ma.allocate(64);
       assertEquals(64+perObjectOverhead(), ma.getUsedMemory());
       assertEquals(offHeapSize-(64+perObjectOverhead()), ma.getFreeMemory());
       mc1.release();
@@ -131,7 +131,7 @@ public abstract class OffHeapRegionBase {
       assertEquals(0, ma.getUsedMemory());
       // do an allocation larger than the slab size
       try {
-        ma.allocate(1024*1024*10, null);
+        ma.allocate(1024*1024*10);
         fail("Expected an out of heap exception");
       } catch (OutOfOffHeapMemoryException expected) {
         // passed
@@ -163,7 +163,7 @@ public abstract class OffHeapRegionBase {
       final long offHeapSize = ma.getFreeMemory();
       assertEquals(0, ma.getUsedMemory());
       byte[] data = new byte[] {1,2,3,4,5,6,7,8};
-      MemoryChunk mc1 = (MemoryChunk)ma.allocateAndInitialize(data, false, false, null);
+      MemoryChunk mc1 = (MemoryChunk)ma.allocateAndInitialize(data, false, false);
       assertEquals(data.length+perObjectOverhead(), ma.getUsedMemory());
       assertEquals(offHeapSize-(data.length+perObjectOverhead()), ma.getFreeMemory());
       byte[] data2 = new byte[data.length];
@@ -174,7 +174,7 @@ public abstract class OffHeapRegionBase {
       assertEquals(0, ma.getUsedMemory());
       // try some small byte[] that don't need to be stored off heap.
       data = new byte[] {1,2,3,4,5,6,7};
-      StoredObject so1 = ma.allocateAndInitialize(data, false, false, null);
+      StoredObject so1 = ma.allocateAndInitialize(data, false, false);
       assertEquals(0, ma.getUsedMemory());
       assertEquals(offHeapSize, ma.getFreeMemory());
       data2 = new byte[data.length];
@@ -540,11 +540,11 @@ public abstract class OffHeapRegionBase {
     @Released(OffHeapIdentifier.TEST_OFF_HEAP_REGION_BASE_LISTENER)
     @Override
     public void close() {
-      if (this.ohOldValue instanceof Chunk) {
-        ((Chunk)this.ohOldValue).release();
+      if (this.ohOldValue instanceof ObjectChunk) {
+        ((ObjectChunk)this.ohOldValue).release();
       }
-      if (this.ohNewValue instanceof Chunk) {
-        ((Chunk)this.ohNewValue).release();
+      if (this.ohNewValue instanceof ObjectChunk) {
+        ((ObjectChunk)this.ohNewValue).release();
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
index b800977..5d53109 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelperJUnitTest.java
@@ -54,7 +54,7 @@ import com.gemstone.gemfire.test.junit.categories.UnitTest;
 @Category(UnitTest.class)
 @RunWith(PowerMockRunner.class)
 @PowerMockIgnore("*.UnitTest")
-@PrepareForTest({ Chunk.class, OffHeapRegionEntryHelper.class })
+@PrepareForTest({ ObjectChunk.class, OffHeapRegionEntryHelper.class })
 public class OffHeapRegionEntryHelperJUnitTest {
 
   private static final Long VALUE_IS_NOT_ENCODABLE = 0L;
@@ -75,13 +75,13 @@ public class OffHeapRegionEntryHelperJUnitTest {
     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
   }
 
-  private GemFireChunk createChunk(Object value) {
+  private ObjectChunk createChunk(Object value) {
     byte[] v = EntryEventImpl.serialize(value);
 
     boolean isSerialized = true;
     boolean isCompressed = false;
 
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed);
 
     return chunk;
   }
@@ -294,7 +294,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
 
   @Test
   public void isOffHeapShouldReturnTrueIfAddressIsOnOffHeap() {
-    Chunk value = createChunk(Long.MAX_VALUE);
+    ObjectChunk value = createChunk(Long.MAX_VALUE);
     assertThat(OffHeapRegionEntryHelper.isOffHeap(value.getMemoryAddress())).isTrue();
   }
 
@@ -327,7 +327,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
     long oldAddress = 1L;
 
     // testing when the newValue is a chunk
-    Chunk newValue = createChunk(Long.MAX_VALUE);
+    ObjectChunk newValue = createChunk(Long.MAX_VALUE);
     // mock region entry methods required for test
     when(re.getAddress()).thenReturn(oldAddress);
     when(re.setAddress(oldAddress, newValue.getMemoryAddress())).thenReturn(Boolean.TRUE);
@@ -440,13 +440,13 @@ public class OffHeapRegionEntryHelperJUnitTest {
     // mock region entry
     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
 
-    Chunk oldValue = createChunk(Long.MAX_VALUE);
-    Chunk newValue = createChunk(Long.MAX_VALUE - 1);
+    ObjectChunk oldValue = createChunk(Long.MAX_VALUE);
+    ObjectChunk newValue = createChunk(Long.MAX_VALUE - 1);
 
     // mock Chunk static methods - in-order to verify that release is called
-    PowerMockito.spy(Chunk.class);
-    PowerMockito.doNothing().when(Chunk.class);
-    Chunk.release(oldValue.getMemoryAddress(), true);
+    PowerMockito.spy(ObjectChunk.class);
+    PowerMockito.doNothing().when(ObjectChunk.class);
+    ObjectChunk.release(oldValue.getMemoryAddress());
 
     // mock region entry methods required for test
     when(re.getAddress()).thenReturn(oldValue.getMemoryAddress());
@@ -460,7 +460,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
 
     // verify oldAddress is released
     PowerMockito.verifyStatic();
-    Chunk.release(oldValue.getMemoryAddress(), true);
+    ObjectChunk.release(oldValue.getMemoryAddress());
   }
 
   @Test
@@ -475,9 +475,9 @@ public class OffHeapRegionEntryHelperJUnitTest {
     DataAsAddress newAddress = new DataAsAddress(OffHeapRegionEntryHelper.encodeDataAsAddress(newData, false, false));
 
     // mock Chunk static methods - in-order to verify that release is never called
-    PowerMockito.spy(Chunk.class);
-    PowerMockito.doNothing().when(Chunk.class);
-    Chunk.release(oldAddress, true);
+    PowerMockito.spy(ObjectChunk.class);
+    PowerMockito.doNothing().when(ObjectChunk.class);
+    ObjectChunk.release(oldAddress);
 
     // mock region entry methods required for test
     when(re.getAddress()).thenReturn(oldAddress);
@@ -491,7 +491,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
 
     // verify that release is never called as the old address is not on offheap
     PowerMockito.verifyStatic(never());
-    Chunk.release(oldAddress, true);
+    ObjectChunk.release(oldAddress);
   }
 
   @Test
@@ -505,9 +505,9 @@ public class OffHeapRegionEntryHelperJUnitTest {
     long newAddress = OffHeapRegionEntryHelper.REMOVED_PHASE2_ADDRESS;
 
     // mock Chunk static methods - in-order to verify that release is never called
-    PowerMockito.spy(Chunk.class);
-    PowerMockito.doNothing().when(Chunk.class);
-    Chunk.release(oldAddress, true);
+    PowerMockito.spy(ObjectChunk.class);
+    PowerMockito.doNothing().when(ObjectChunk.class);
+    ObjectChunk.release(oldAddress);
 
     // mock region entry methods required for test
     when(re.getAddress()).thenReturn(oldAddress);
@@ -521,7 +521,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
 
     // verify that release is never called as the old address is not on offheap
     PowerMockito.verifyStatic(never());
-    Chunk.release(oldAddress, true);
+    ObjectChunk.release(oldAddress);
   }
 
   @Test(expected = IllegalStateException.class)
@@ -541,7 +541,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
     // mock region entry
     OffHeapRegionEntry re = mock(OffHeapRegionEntry.class);
 
-    Chunk chunk = createChunk(Long.MAX_VALUE);
+    ObjectChunk chunk = createChunk(Long.MAX_VALUE);
 
     // mock region entry methods required for test
     when(re.getAddress()).thenReturn(chunk.getMemoryAddress());
@@ -627,10 +627,10 @@ public class OffHeapRegionEntryHelperJUnitTest {
 
   @Test
   public void addressToObjectShouldReturnValueFromChunk() {
-    Chunk expected = createChunk(Long.MAX_VALUE);
+    ObjectChunk expected = createChunk(Long.MAX_VALUE);
     Object actual = OffHeapRegionEntryHelper.addressToObject(expected.getMemoryAddress(), false, null);
 
-    assertThat(actual).isInstanceOf(Chunk.class);
+    assertThat(actual).isInstanceOf(ObjectChunk.class);
     assertThat(actual).isEqualTo(expected);
   }
 
@@ -640,7 +640,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
     boolean isSerialized = true;
     boolean isCompressed = true;
 
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed, GemFireChunk.TYPE);
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed);
 
     // create the mock context
     RegionEntryContext regionContext = mock(RegionEntryContext.class);
@@ -669,7 +669,7 @@ public class OffHeapRegionEntryHelperJUnitTest {
     boolean isSerialized = false;
     boolean isCompressed = true;
 
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed, GemFireChunk.TYPE);
+    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(data, isSerialized, isCompressed);
 
     // create the mock context
     RegionEntryContext regionContext = mock(RegionEntryContext.class);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
index f0f0461..d5db4e4 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
@@ -245,14 +245,14 @@ public class OffHeapStorageJUnitTest {
 
       OutOfOffHeapMemoryException ex = null;
       try {
-        ma.allocate(1024*1024+1, null);
+        ma.allocate(1024*1024+1);
         fail("expected OutOfOffHeapMemoryException");
       } catch (OutOfOffHeapMemoryException expected) {
         ex = expected;
       }
       verify(ooohml).outOfOffHeapMemory(ex);
       try {
-        ma.allocate(1024*1024+1, null);
+        ma.allocate(1024*1024+1);
         fail("expected OutOfOffHeapMemoryException");
       } catch (OutOfOffHeapMemoryException expected) {
         ex = expected;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
index 2d86296..630ae22 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
@@ -296,8 +296,8 @@ public class OffHeapValidationJUnitTest {
   
   private long getMemoryAddress(Region region, String key) {
     Object entry = ((LocalRegion) region).getRegionEntry(key)._getValue();
-    assertTrue(entry instanceof Chunk);
-    long memoryAddress = ((Chunk)entry).getMemoryAddress();
+    assertTrue(entry instanceof ObjectChunk);
+    long memoryAddress = ((ObjectChunk)entry).getMemoryAddress();
     assertTrue(memoryAddress > 0);
     return memoryAddress;
   }



[043/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/ServerLauncher.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/ServerLauncher.java
index c991cc1,0000000..f13bb73
mode 100644,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/ServerLauncher.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/ServerLauncher.java
@@@ -1,2605 -1,0 +1,2613 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed;
 +
 +import java.io.File;
 +import java.io.FileNotFoundException;
 +import java.io.IOException;
 +import java.lang.management.ManagementFactory;
 +import java.net.InetAddress;
 +import java.net.UnknownHostException;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.TreeMap;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.TimeoutException;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +import java.util.concurrent.atomic.AtomicReference;
 +
 +import javax.management.MalformedObjectNameException;
 +import javax.management.ObjectName;
 +
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.AbstractLauncher.Status;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.GemFireVersion;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.cache.AbstractCacheServer;
 +import com.gemstone.gemfire.internal.cache.CacheConfig;
 +import com.gemstone.gemfire.internal.cache.CacheServerLauncher;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
++import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerHelper;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.lang.ObjectUtils;
 +import com.gemstone.gemfire.internal.lang.StringUtils;
 +import com.gemstone.gemfire.internal.lang.SystemUtils;
 +import com.gemstone.gemfire.internal.process.ClusterConfigurationNotAvailableException;
 +import com.gemstone.gemfire.internal.process.ConnectionFailedException;
 +import com.gemstone.gemfire.internal.process.ControlNotificationHandler;
 +import com.gemstone.gemfire.internal.process.ControllableProcess;
 +import com.gemstone.gemfire.internal.process.FileAlreadyExistsException;
 +import com.gemstone.gemfire.internal.process.MBeanInvocationFailedException;
 +import com.gemstone.gemfire.internal.process.PidUnavailableException;
 +import com.gemstone.gemfire.internal.process.ProcessController;
 +import com.gemstone.gemfire.internal.process.ProcessControllerFactory;
 +import com.gemstone.gemfire.internal.process.ProcessControllerParameters;
 +import com.gemstone.gemfire.internal.process.ProcessLauncherContext;
 +import com.gemstone.gemfire.internal.process.ProcessType;
 +import com.gemstone.gemfire.internal.process.StartupStatusListener;
 +import com.gemstone.gemfire.internal.process.UnableToControlProcessException;
 +import com.gemstone.gemfire.internal.util.CollectionUtils;
 +import com.gemstone.gemfire.internal.util.IOUtils;
 +import com.gemstone.gemfire.lang.AttachAPINotFoundException;
 +import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
 +import com.gemstone.gemfire.management.internal.cli.json.GfJsonArray;
 +import com.gemstone.gemfire.management.internal.cli.json.GfJsonException;
 +import com.gemstone.gemfire.management.internal.cli.json.GfJsonObject;
 +import com.gemstone.gemfire.pdx.PdxSerializer;
 +
 +import joptsimple.OptionException;
 +import joptsimple.OptionParser;
 +import joptsimple.OptionSet;
 +
 +import org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer;
 +
 +/**
 + * The ServerLauncher class is a launcher class with main method to start a GemFire Server (implying a GemFire Cache
 + * Server process).
 + * 
 + * @author John Blum
 + * @author Kirk Lund
 + * @see com.gemstone.gemfire.distributed.AbstractLauncher
 + * @see com.gemstone.gemfire.distributed.LocatorLauncher
 + * @since 7.0
 + */
 +@SuppressWarnings({ "unused" })
 +public final class ServerLauncher extends AbstractLauncher<String> {
 +
 +  /**
 +   * @deprecated This is specific to the internal implementation and may go away in a future release.
 +   */
 +  protected static final Integer DEFAULT_SERVER_PORT = getDefaultServerPort();
 +
 +  private static final Map<String, String> helpMap = new HashMap<>();
 +
 +  static {
 +    helpMap.put("launcher", LocalizedStrings.ServerLauncher_SERVER_LAUNCHER_HELP.toLocalizedString());
 +    helpMap.put(Command.START.getName(), LocalizedStrings.ServerLauncher_START_SERVER_HELP.toLocalizedString(String.valueOf(getDefaultServerPort())));
 +    helpMap.put(Command.STATUS.getName(), LocalizedStrings.ServerLauncher_STATUS_SERVER_HELP.toLocalizedString());
 +    helpMap.put(Command.STOP.getName(), LocalizedStrings.ServerLauncher_STOP_SERVER_HELP.toLocalizedString());
 +    helpMap.put(Command.VERSION.getName(), LocalizedStrings.ServerLauncher_VERSION_SERVER_HELP.toLocalizedString());
 +    helpMap.put("assign-buckets", LocalizedStrings.ServerLauncher_SERVER_ASSIGN_BUCKETS_HELP.toLocalizedString());
 +    helpMap.put("debug", LocalizedStrings.ServerLauncher_SERVER_DEBUG_HELP.toLocalizedString());
 +    helpMap.put("dir", LocalizedStrings.ServerLauncher_SERVER_DIR_HELP.toLocalizedString());
 +    helpMap.put("disable-default-server", LocalizedStrings.ServerLauncher_SERVER_DISABLE_DEFAULT_SERVER_HELP.toLocalizedString());
 +    helpMap.put("force", LocalizedStrings.ServerLauncher_SERVER_FORCE_HELP.toLocalizedString());
 +    helpMap.put("help", LocalizedStrings.SystemAdmin_CAUSES_GEMFIRE_TO_PRINT_OUT_INFORMATION_INSTEAD_OF_PERFORMING_THE_COMMAND_THIS_OPTION_IS_SUPPORTED_BY_ALL_COMMANDS.toLocalizedString());
 +    helpMap.put("member", LocalizedStrings.ServerLauncher_SERVER_MEMBER_HELP.toLocalizedString());
 +    helpMap.put("pid", LocalizedStrings.ServerLauncher_SERVER_PID_HELP.toLocalizedString());
 +    helpMap.put("rebalance", LocalizedStrings.ServerLauncher_SERVER_REBALANCE_HELP.toLocalizedString());
 +    helpMap.put("redirect-output", LocalizedStrings.ServerLauncher_SERVER_REDIRECT_OUTPUT_HELP.toLocalizedString());
 +    helpMap.put("server-bind-address", LocalizedStrings.ServerLauncher_SERVER_BIND_ADDRESS_HELP.toLocalizedString());
 +    helpMap.put("hostname-for-clients", LocalizedStrings.ServerLauncher_SERVER_HOSTNAME_FOR_CLIENT_HELP.toLocalizedString());
 +    helpMap.put("server-port", LocalizedStrings.ServerLauncher_SERVER_PORT_HELP.toLocalizedString(String.valueOf(getDefaultServerPort())));
 +  }
 +
 +  private static final Map<Command, String> usageMap = new TreeMap<>();
 +
 +  static {
 +    usageMap.put(Command.START, "start <member-name> [--assign-buckets] [--disable-default-server] [--rebalance] [--server-bind-address=<IP-address>] [--server-port=<port>] [--force] [--debug] [--help]");
 +    usageMap.put(Command.STATUS, "status [--member=<member-ID/Name>] [--pid=<process-ID>] [--dir=<Server-working-directory>] [--debug] [--help]");
 +    usageMap.put(Command.STOP, "stop [--member=<member-ID/Name>] [--pid=<process-ID>] [--dir=<Server-working-directory>] [--debug] [--help]");
 +    usageMap.put(Command.VERSION, "version");
 +  }
 +
 +  /**
 +   * @deprecated This is specific to the internal implementation and may go away in a future release.
 +   */
 +  public static final String DEFAULT_SERVER_PID_FILE = "vf.gf.server.pid";
 +
 +  private static final String DEFAULT_SERVER_LOG_EXT = ".log";
 +  private static final String DEFAULT_SERVER_LOG_NAME = "gemfire";
 +  private static final String SERVER_SERVICE_NAME = "Server";
 +
 +  private static final AtomicReference<ServerLauncher> INSTANCE = new AtomicReference<>();
 +
 +  private volatile transient boolean debug;
 +
 +  private final transient ControlNotificationHandler controlHandler;
 +  
 +  private final AtomicBoolean starting = new AtomicBoolean(false);
 +
 +  private final boolean assignBuckets;
 +  private final boolean disableDefaultServer;
 +  private final boolean force;
 +  private final boolean help;
 +  private final boolean rebalance;
 +  private final boolean redirectOutput;
 +
 +  private volatile transient Cache cache;
 +
 +  private final transient CacheConfig cacheConfig;
 +
 +  private final Command command;
 +
 +  private final InetAddress serverBindAddress;
 +
 +  private final Integer pid;
 +  private final Integer serverPort;
 +
 +  private final Properties distributedSystemProperties;
 +
 +  private final String memberName;
 +  private final String springXmlLocation;
 +  private final String workingDirectory;
 +
 +  // NOTE in addition to debug, the other shared, mutable state
 +  private volatile transient String statusMessage;
 +  
 +  private final Float criticalHeapPercentage;
 +  private final Float evictionHeapPercentage;
 +  
 +  private final Float criticalOffHeapPercentage;
 +  private final Float evictionOffHeapPercentage;
 +  
 +  private final String hostNameForClients; 
 +  private final Integer maxConnections;
 +  private final Integer maxMessageCount;
 +  private final Integer messageTimeToLive;
 +  private final Integer socketBufferSize;
 +  
 +  private final Integer maxThreads;
 +
 +  private volatile transient ControllableProcess process;
 +
 +  private final transient ServerControllerParameters controllerParameters;
 +  
 +  /**
 +   * Launches a GemFire Server from the command-line configured with the given arguments.
 +   * 
 +   * @param args the command-line arguments used to configure the GemFire Server at runtime.
 +   */
 +  public static void main(final String... args) {
 +    try {
 +      new Builder(args).build().run();
 +    }
 +    catch (AttachAPINotFoundException e) {
 +      System.err.println(e.getMessage());
 +    }
 +  }
 +
 +  private static Integer getDefaultServerPort() {
 +    return Integer.getInteger(AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY, CacheServer.DEFAULT_PORT);
 +  }
 +
 +  /**
 +   * Gets the instance of the ServerLauncher used to launch the GemFire Cache Server, or null if this VM does not
 +   * have an instance of ServerLauncher indicating no GemFire Cache Server is running.
 +   * 
 +   * @return the instance of ServerLauncher used to launcher a GemFire Cache Server in this VM.
 +   */
 +  public static ServerLauncher getInstance() {
 +    return INSTANCE.get();
 +  }
 +
 +  /**
 +   * Gets the ServerState for this process or null if this process was not launched using this VM's
 +   * ServerLauncher reference .
 +   * 
 +   * @return the ServerState for this process or null.
 +   */
 +  public static ServerState getServerState() {
 +    return (getInstance() != null ? getInstance().status() : null);
 +  }
 +
 +  /**
 +   * Private constructor used to properly construct an immutable instance of the ServerLauncher using a Builder.
 +   * The Builder is used to configure a ServerLauncher instance.  The Builder can process user input from the
 +   * command-line or be used programmatically to properly construct an instance of the ServerLauncher using the API.
 +   * 
 +   * @param builder an instance of ServerLauncher.Builder for configuring and constructing an instance of the
 +   * ServerLauncher.
 +   * @see com.gemstone.gemfire.distributed.ServerLauncher.Builder
 +   */
 +  private ServerLauncher(final Builder builder) {
 +    this.cache = builder.getCache(); // testing
 +    this.cacheConfig = builder.getCacheConfig();
 +    this.command = builder.getCommand();
 +    this.assignBuckets = Boolean.TRUE.equals(builder.getAssignBuckets());
 +    setDebug(Boolean.TRUE.equals(builder.getDebug()));
 +    this.disableDefaultServer = Boolean.TRUE.equals(builder.getDisableDefaultServer());
 +    CacheServerLauncher.disableDefaultServer.set(this.disableDefaultServer);
 +    this.distributedSystemProperties = builder.getDistributedSystemProperties();
 +    this.force = Boolean.TRUE.equals(builder.getForce());
 +    this.help = Boolean.TRUE.equals(builder.getHelp());
 +    this.hostNameForClients = builder.getHostNameForClients();
 +    this.memberName = builder.getMemberName();
 +    // TODO:KIRK: set ThreadLocal for LogService with getLogFile or getLogFileName
 +    this.pid = builder.getPid();
 +    this.rebalance = Boolean.TRUE.equals(builder.getRebalance());
 +    this.redirectOutput = Boolean.TRUE.equals(builder.getRedirectOutput());
 +    this.serverBindAddress = builder.getServerBindAddress();
 +    if (builder.isServerBindAddressSetByUser() && this.serverBindAddress != null) {
 +      CacheServerLauncher.serverBindAddress.set(this.serverBindAddress.getHostAddress());
 +    }
 +    this.serverPort = builder.getServerPort();
 +    if (builder.isServerPortSetByUser() && this.serverPort != null) {
 +      CacheServerLauncher.serverPort.set(this.serverPort);
 +    }
 +    this.springXmlLocation = builder.getSpringXmlLocation();
 +    this.workingDirectory = builder.getWorkingDirectory();
 +    this.criticalHeapPercentage = builder.getCriticalHeapPercentage();
 +    this.evictionHeapPercentage = builder.getEvictionHeapPercentage();
 +    this.criticalOffHeapPercentage = builder.getCriticalOffHeapPercentage();
 +    this.evictionOffHeapPercentage = builder.getEvictionOffHeapPercentage();
 +    this.maxConnections = builder.getMaxConnections();
 +    this.maxMessageCount = builder.getMaxMessageCount();
 +    this.maxThreads = builder.getMaxThreads();
 +    this.messageTimeToLive = builder.getMessageTimeToLive();
 +    this.socketBufferSize = builder.getSocketBufferSize();
 +    this.controllerParameters = new ServerControllerParameters();
 +    this.controlHandler = new ControlNotificationHandler() {
 +      @Override
 +      public void handleStop() {
 +        if (isStoppable()) {
 +          stopInProcess();
 +        }
 +      }
 +      @Override
 +      public ServiceState<?> handleStatus() {
 +        return statusInProcess();
 +      }
 +    };
 +  }
 +
 +  /**
 +   * Gets a reference to the Cache that was created when the GemFire Server was started.
 +   * 
 +   * @return a reference to the Cache created by the GemFire Server start operation.
 +   * @see com.gemstone.gemfire.cache.Cache
 +   */
 +  final Cache getCache() {
 +    return this.cache;
 +  }
 +
 +  /**
 +   * Gets the CacheConfig object used to configure additional GemFire Cache components and features (e.g. PDX).
 +   *
 +   * @return a CacheConfig object with additional GemFire Cache configuration meta-data used on startup to configure
 +   * the Cache.
 +   */
 +  final CacheConfig getCacheConfig() {
 +    final CacheConfig copy = new CacheConfig();
 +    copy.setDeclarativeConfig(this.cacheConfig);
 +    return copy;
 +  }
 +
 +  /**
 +   * Gets an identifier that uniquely identifies and represents the Server associated with this launcher.
 +   * 
 +   * @return a String value identifier to uniquely identify the Server and it's launcher.
 +   * @see #getServerBindAddressAsString()
 +   * @see #getServerPortAsString()
 +   */
 +  public final String getId() {
 +    final StringBuilder buffer = new StringBuilder(ServerState.getServerBindAddressAsString(this));
 +    final String serverPort = ServerState.getServerPortAsString(this);
 +
 +    if (!StringUtils.isBlank(serverPort)) {
 +      buffer.append("[").append(serverPort).append("]");
 +    }
 +
 +    return buffer.toString();
 +  }
 +
 +  /**
 +   * Get the Server launcher command used to invoke the Server.
 +   * 
 +   * @return the Server launcher command used to invoke the Server.
 +   * @see com.gemstone.gemfire.distributed.ServerLauncher.Command
 +   */
 +  public Command getCommand() {
 +    return this.command;
 +  }
 +
 +  /**
 +   * Determines whether buckets should be assigned to partitioned regions in the cache upon Server start.
 +   * 
 +   * @return a boolean indicating if buckets should be assigned upon Server start.
 +   */
 +  public boolean isAssignBuckets() {
 +    return this.assignBuckets;
 +  }
 +
 +  /**
 +   * Determines whether a default cache server will be added when the GemFire Server comes online.
 +   * 
 +   * @return a boolean value indicating whether to add a default cache server.
 +   */
 +  public boolean isDisableDefaultServer() {
 +    return this.disableDefaultServer;
 +  }
 +
 +  /**
 +   * Determines whether the PID file is allowed to be overwritten when the Server is started and a PID file
 +   * already exists in the Server's specified working directory.
 +   * 
 +   * @return boolean indicating if force has been enabled.
 +   */
 +  public boolean isForcing() {
 +    return this.force;
 +  }
 +
 +  /**
 +   * Determines whether this launcher will be used to display help information.  If so, then none of the standard
 +   * Server launcher commands will be used to affect the state of the Server.  A launcher is said to be 'helping'
 +   * if the user entered the "--help" option (switch) on the command-line.
 +   * 
 +   * @return a boolean value indicating if this launcher is used for displaying help information.
 +   * @see com.gemstone.gemfire.distributed.ServerLauncher.Command
 +   */
 +  public boolean isHelping() {
 +    return this.help;
 +  }
 +
 +  /**
 +   * Determines whether a rebalance operation on the cache will occur upon starting the GemFire server using this
 +   * launcher.
 +   * 
 +   * @return a boolean indicating if the cache will be rebalance when the GemFire server starts.
 +   */
 +  public boolean isRebalancing() {
 +    return this.rebalance;
 +  }
 +
 +  /**
 +   * Determines whether this launcher will redirect output to system logs when
 +   * starting a new Locator process.
 +   * 
 +   * @return a boolean value indicating if this launcher will redirect output 
 +   * to system logs when starting a new Locator process
 +   */
 +  public boolean isRedirectingOutput() {
 +    return this.redirectOutput;
 +  }
 +
 +  /**
 +   * Gets the name of the log file used to log information about this Server.
 +   * 
 +   * @return a String value indicating the name of this Server's log file.
 +   */
 +  public String getLogFileName() {
 +    return StringUtils.defaultIfBlank(getMemberName(), DEFAULT_SERVER_LOG_NAME).concat(DEFAULT_SERVER_LOG_EXT);
 +  }
 +
 +  /**
 +   * Gets the name of this member (this Server) in the GemFire distributed system as determined by the 'name' GemFire
 +   * property.
 +   * 
 +   * @return a String indicating the name of the member (this Server) in the GemFire distributed system.
 +   * @see AbstractLauncher#getMemberName()
 +   */
 +  public String getMemberName() {
 +    return StringUtils.defaultIfBlank(this.memberName, super.getMemberName());
 +  }
 +
 +  /**
 +   * Gets the user-specified process ID (PID) of the running Server that ServerLauncher uses to issue status and
 +   * stop commands to the Server.
 +   * 
 +   * @return an Integer value indicating the process ID (PID) of the running Server.
 +   */
 +  @Override
 +  public Integer getPid() {
 +    return this.pid;
 +  }
 +
 +  /**
 +   * Gets the GemFire Distributed System (cluster) Properties.
 +   *
 +   * @return a Properties object containing the configuration settings for the GemFire Distributed System (cluster).
 +   * @see java.util.Properties
 +   */
 +  public Properties getProperties() {
 +    return (Properties) this.distributedSystemProperties.clone();
 +  }
 +
 +  /**
 +   * Gets the IP address to which the Server is bound listening for and accepting cache client connections.  This
 +   * property should not be confused with 'bindAddress' ServerLauncher property, which is the port for binding the
 +   * Server's ServerSocket used in distribution and messaging between the peers of the GemFire distributed system.
 +   * 
 +   * @return an InetAddress indicating the IP address that the Server is bound to listening for and accepting cache
 +   * client connections in a client/server topology.
 +   */
 +  public InetAddress getServerBindAddress() {
 +    return this.serverBindAddress;
 +  }
 +
 +  /**
 +   * Gets the host, as either hostname or IP address, on which the Server was bound and running.  An attempt is made
 +   * to get the canonical hostname for IP address to which the Server was bound for accepting client requests.  If
 +   * the server bind address is null or localhost is unknown, then a default String value of "localhost/127.0.0.1"
 +   * is returned.
 +   * 
 +   * Note, this information is purely information and should not be used to re-construct state or for
 +   * other purposes.
 +   * 
 +   * @return the hostname or IP address of the host running the Server, based on the bind-address, or
 +   * 'localhost/127.0.0.1' if the bind address is null and localhost is unknown.
 +   * @see java.net.InetAddress
 +   * @see #getServerBindAddress()
 +   */
 +  public String getServerBindAddressAsString() {
 +    try {
 +      if (getServerBindAddress() != null) {
 +        return getServerBindAddress().getCanonicalHostName();
 +      }
 +
 +      final InetAddress localhost = SocketCreator.getLocalHost();
 +
 +      return localhost.getCanonicalHostName();
 +    }
 +    catch (UnknownHostException ignore) {
 +      // TODO determine a better value for the host on which the Server is running to return here...
 +      // NOTE returning localhost/127.0.0.1 implies the serverBindAddress was null and no IP address for localhost
 +      // could be found
 +      return "localhost/127.0.0.1";
 +    }
 +  }
 +
 +  /**
 +   * Gets the port on which the Server is listening for cache client connections.  This property should not be confused
 +   * with the 'port' ServerLauncher property, which is used by the Server to set the 'tcp-port' distribution config
 +   * property and is used by the ServerSocket for peer distribution and messaging.
 +   * 
 +   * @return an Integer value indicating the port the Server is listening on for cache client connections in the
 +   * client/server topology.
 +   */
 +  public Integer getServerPort() {
 +    return this.serverPort;
 +  }
 +
 +  /**
 +   * Gets the server port on which the Server is listening for client requests represented as a String value.
 +   * 
 +   * @return a String representing the server port on which the Server is listening for client requests.
 +   * @see #getServerPort()
 +   */
 +  public String getServerPortAsString() {
 +    return ObjectUtils.defaultIfNull(getServerPort(), getDefaultServerPort()).toString();
 +  }
 +
 +  /**
 +   * Gets the name for a GemFire Server.
 +   * 
 +   * @return a String indicating the name for a GemFire Server.
 +   */
 +  public String getServiceName() {
 +    return SERVER_SERVICE_NAME;
 +  }
 +
 +  /**
 +   * Gets the location of the Spring XML configuration meta-data file used to bootstrap, configure and initialize
 +   * the GemFire Server on start.
 +   * <p>
 +   * @return a String indicating the location of the Spring XML configuration file.
 +   * @see com.gemstone.gemfire.distributed.ServerLauncher.Builder#getSpringXmlLocation()
 +   */
 +  public String getSpringXmlLocation() {
 +    return this.springXmlLocation;
 +  }
 +
 +  /**
 +   * Determines whether this GemFire Server was configured and initialized with Spring configuration meta-data.
 +   * <p>
 +   * @return a boolean value indicating whether this GemFire Server was configured with Spring configuration meta-data.
 +   */
 +  public boolean isSpringXmlLocationSpecified() {
 +    return !StringUtils.isBlank(this.springXmlLocation);
 +  }
 +
 +  /**
 +   * Gets the working directory pathname in which the Server will be run.
 +   * 
 +   * @return a String value indicating the pathname of the Server's working directory.
 +   */
 +  @Override
 +  public String getWorkingDirectory() {
 +    return this.workingDirectory;
 +  }
 +  
 +  public Float getCriticalHeapPercentage() {
 +    return this.criticalHeapPercentage;
 +  }
 +  
 +  public Float getEvictionHeapPercentage() {
 +    return this.evictionHeapPercentage;
 +  }
 +  
 +  public Float getCriticalOffHeapPercentage() {
 +    return this.criticalOffHeapPercentage;
 +  }
 +  
 +  public Float getEvictionOffHeapPercentage() {
 +    return this.evictionOffHeapPercentage;
 +  }
 +  
 +  public String getHostNameForClients() {
 +    return this.hostNameForClients;
 +  }
 +
 +  public Integer getMaxConnections() {
 +    return this.maxConnections;
 +  }
 +
 +  public Integer getMaxMessageCount() {
 +    return this.maxMessageCount;
 +  }
 +
 +  public Integer getMessageTimeToLive() {
 +    return this.messageTimeToLive;
 +  }
 +
 +  public Integer getMaxThreads() {
 +    return this.maxThreads;
 +  }
 +
 +  public Integer getSocketBufferSize() {
 +    return this.socketBufferSize;
 +  }
 +  
 +  /**
 +   * Displays help for the specified Server launcher command to standard err.  If the Server launcher command
 +   * is unspecified, then usage information is displayed instead.
 +   * 
 +   * @param command the Server launcher command in which to display help information.
 +   * @see #usage()
 +   */
 +  public void help(final Command command) {
 +    if (Command.isUnspecified(command)) {
 +      usage();
 +    }
 +    else {
 +      info(StringUtils.wrap(helpMap.get(command.getName()), 80, ""));
 +      info("\n\nusage: \n\n");
 +      info(StringUtils.wrap("> java ... " + getClass().getName() + " " + usageMap.get(command), 80, "\t\t"));
 +      info("\n\noptions: \n\n");
 +
 +      for (final String option : command.getOptions()) {
 +        info(StringUtils.wrap("--" + option + ": " + helpMap.get(option) + "\n", 80, "\t"));
 +      }
 +
 +      info("\n\n");
 +    }
 +  }
 +
 +  /**
 +   * Displays usage information on the proper invocation of the ServerLauncher from the command-line to standard err.
 +   * 
 +   * @see #help(com.gemstone.gemfire.distributed.ServerLauncher.Command)
 +   */
 +  public void usage() {
 +    info(StringUtils.wrap(helpMap.get("launcher"), 80, "\t"));
 +    info("\n\nSTART\n\n");
 +    help(Command.START);
 +    info("STATUS\n\n");
 +    help(Command.STATUS);
 +    info("STOP\n\n");
 +    help(Command.STOP);
 +  }
 +
 +  /**
 +   * A Runnable method used to invoke the GemFire server (cache server) with the specified command.  From run, a user
 +   * can invoke 'start', 'status', 'stop' and 'version'.  Note, that 'version' is also a command-line option, but can
 +   * be treated as a "command" as well.
 +   * 
 +   * @see java.lang.Runnable
 +   */
 +  @Override
 +  public void run() {
 +    if (!isHelping()) {
 +      switch (getCommand()) {
 +        case START:
 +          info(start());
 +          waitOnServer();
 +          break;
 +        case STATUS:
 +          info(status());
 +          break;
 +        case STOP:
 +          info(stop());
 +          break;
 +        case VERSION:
 +          info(version());
 +          break;
 +        default:
 +          usage();
 +      }
 +    }
 +    else {
 +      help(getCommand());
 +    }
 +  }
 +
 +  /**
 +   * Gets a File reference with the path to the PID file for the Server.
 +   * 
 +   * @return a File reference to the path of the Server's PID file.
 +   */
 +  protected File getServerPidFile() {
 +    return new File(getWorkingDirectory(), ProcessType.SERVER.getPidFileName());
 +  }
 +  
 +  /**
 +   * Determines whether a GemFire Cache Server can be started with this instance of ServerLauncher.
 +   *
 +   * @return a boolean indicating whether a GemFire Cache Server can be started with this instance of ServerLauncher,
 +   * which is true if the ServerLauncher has not already started a Server or a Server is not already running.
 +   * @see #start()
 +   */
 +  private boolean isStartable() {
 +    return (!isRunning() && this.starting.compareAndSet(false, true));
 +  }
 +
 +  /**
 +   * Invokes the 'start' command and operation to startup a GemFire server (a cache server).  Note, this method will
 +   * cause the JVM to block upon server start, providing the calling Thread is a non-daemon Thread.
 +   *
 +   * @see #run()
 +   */
 +  public ServerState start() {
 +    if (isStartable()) {
 +      INSTANCE.compareAndSet(null, this);
 +
 +      try {
 +        process = new ControllableProcess(this.controlHandler, new File(getWorkingDirectory()), ProcessType.SERVER, isForcing());
 +
 +        if (!isDisableDefaultServer()) {
 +          assertPortAvailable(getServerBindAddress(), getServerPort());
 +        }
 +
 +        SystemFailure.setExitOK(true);
 +
 +        ProcessLauncherContext.set(isRedirectingOutput(), getOverriddenDefaults(), new StartupStatusListener() {
 +          @Override
 +          public void setStatus(final String statusMessage) {
 +            debug("Callback setStatus(String) called with message (%1$s)...", statusMessage);
 +            ServerLauncher.this.statusMessage = statusMessage;
 +          }
 +        });
 +
 +        try {
 +          final Properties gemfireProperties = getDistributedSystemProperties(getProperties());
 +          this.cache = (isSpringXmlLocationSpecified() ? startWithSpring() : startWithGemFireApi(gemfireProperties));
 +          
 +          //Set the resource manager options
 +          if (this.criticalHeapPercentage != null) {
 +            this.cache.getResourceManager().setCriticalHeapPercentage(getCriticalHeapPercentage());
 +          } 
 +          if (this.evictionHeapPercentage != null) {
 +            this.cache.getResourceManager().setEvictionHeapPercentage(getEvictionHeapPercentage());
 +          }
 +          if (this.criticalOffHeapPercentage != null) {
 +            this.cache.getResourceManager().setCriticalOffHeapPercentage(getCriticalOffHeapPercentage());
 +          } 
 +          if (this.evictionOffHeapPercentage != null) {
 +            this.cache.getResourceManager().setEvictionOffHeapPercentage(getEvictionOffHeapPercentage());
 +          }
 +          
 +          this.cache.setIsServer(true);
 +          startCacheServer(this.cache);
 +          assignBuckets(this.cache);
 +          rebalance(this.cache);
 +        }
 +        finally {
 +          ProcessLauncherContext.remove();
 +        }
 +        
 +        debug("Running Server on (%1$s) in (%2$s) as (%2$s)...", getId(), getWorkingDirectory(), getMember());
 +        this.running.set(true);
 +
 +        return new ServerState(this, Status.ONLINE);
 +      }
 +      catch (IOException e) {
 +        failOnStart(e);
 +        throw new RuntimeException(LocalizedStrings.Launcher_Command_START_IO_ERROR_MESSAGE.toLocalizedString(
 +          getServiceName(), getWorkingDirectory(), getId(), e.getMessage()), e);
 +      }
 +      catch (FileAlreadyExistsException e) {
 +        failOnStart(e);
 +        throw new RuntimeException(LocalizedStrings.Launcher_Command_START_PID_FILE_ALREADY_EXISTS_ERROR_MESSAGE.
 +           toLocalizedString(getServiceName(), getWorkingDirectory(), getId()), e);
 +      }
 +      catch (PidUnavailableException e) {
 +        failOnStart(e);
 +        throw new RuntimeException(LocalizedStrings.Launcher_Command_START_PID_UNAVAILABLE_ERROR_MESSAGE
 +          .toLocalizedString(getServiceName(), getId(), getWorkingDirectory(), e.getMessage()), e);
 +      }
 +      catch (ClusterConfigurationNotAvailableException e) {
 +        failOnStart(e);
 +        throw e;
 +      }
 +      catch (RuntimeException e) {
 +        failOnStart(e);
 +        throw e;
 +      }
 +      catch (Exception e) {
 +        failOnStart(e);
 +        throw new RuntimeException(e);
 +      }
 +      catch (Error e) {
 +        failOnStart(e);
 +        throw e;
 +      }
 +      finally {
 +        this.starting.set(false);
 +      }
 +    }
 +    else {
 +      throw new IllegalStateException(LocalizedStrings.Launcher_Command_START_SERVICE_ALREADY_RUNNING_ERROR_MESSAGE
 +        .toLocalizedString(getServiceName(), getWorkingDirectory(), getId()));
 +    }
 +  }
 +
 +  private Cache startWithSpring() {
 +    System.setProperty(DistributionConfig.GEMFIRE_PREFIX + DistributionConfig.NAME_NAME, getMemberName());
 +
 +    new SpringContextBootstrappingInitializer().init(CollectionUtils.createProperties(Collections.singletonMap(
 +      SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER, getSpringXmlLocation())));
 +
 +    return SpringContextBootstrappingInitializer.getApplicationContext().getBean(Cache.class);
 +  }
 +
 +  private Cache startWithGemFireApi(final Properties gemfireProperties ) {
 +    final CacheConfig cacheConfig = getCacheConfig();
 +    final CacheFactory cacheFactory = new CacheFactory(gemfireProperties);
 +
 +    if (cacheConfig.pdxPersistentUserSet) {
 +      cacheFactory.setPdxPersistent(cacheConfig.isPdxPersistent());
 +    }
 +
 +    if (cacheConfig.pdxDiskStoreUserSet) {
 +      cacheFactory.setPdxDiskStore(cacheConfig.getPdxDiskStore());
 +    }
 +
 +    if (cacheConfig.pdxIgnoreUnreadFieldsUserSet) {
 +      cacheFactory.setPdxIgnoreUnreadFields(cacheConfig.getPdxIgnoreUnreadFields());
 +    }
 +
 +    if (cacheConfig.pdxReadSerializedUserSet) {
 +      cacheFactory.setPdxReadSerialized(cacheConfig.isPdxReadSerialized());
 +    }
 +
 +    if (cacheConfig.pdxSerializerUserSet) {
 +      cacheFactory.setPdxSerializer(cacheConfig.getPdxSerializer());
 +    }
 +
 +    return cacheFactory.create();
 +  }
 +
 +  /**
 +   * A helper method to ensure the same sequence of actions are taken when the Server fails to start
 +   * caused by some exception.
 +   * 
 +   * @param cause the Throwable thrown during the startup operation on the Server.
 +   */
 +  private void failOnStart(final Throwable cause) {
 +    if (this.cache != null) {
 +      this.cache.close();
 +      this.cache = null;
 +    }
 +    if (this.process != null) {
 +      this.process.stop();
 +      this.process = null;
 +    }
 +
 +    INSTANCE.compareAndSet(this, null);
 +
 +    this.running.set(false);
 +  }
 +
 +  /**
 +   * Determines whether the specified Cache has any CacheServers.
 +   * 
 +   * @param cache the Cache to check for existing CacheServers.
 +   * @return a boolean value indicating if any CacheServers were added to the Cache.
 +   */
 +  protected boolean isServing(final Cache cache) {
 +    return !cache.getCacheServers().isEmpty();
 +  }
 +
 +  /**
 +   * Determines whether to continue waiting and keep the GemFire non-Server data member running.
 +   * 
 +   * @param cache the Cache associated with this GemFire (non-Server) data member.
 +   * @return a boolean value indicating whether the GemFire data member should continue running, as determined
 +   * by the running flag and a connection to the distributed system (GemFire cluster).
 +   */
 +  final boolean isWaiting(final Cache cache) {
 +    //return (isRunning() && !getCache().isClosed());
 +    return (isRunning() && cache.getDistributedSystem().isConnected());
 +  }
 +
 +  /**
 +   * Causes the calling Thread to block until the GemFire Cache Server/Data Member stops.
 +   */
 +  public void waitOnServer() {
 +    assert getCache() != null : "The Cache Server must first be started with a call to start!";
 +
 +    if (!isServing(getCache())) {
 +      Throwable cause = null;
 +      try {
 +        while (isWaiting(getCache())) {
 +          try {
 +            synchronized (this) {
 +              wait(500l);
 +            }
 +          }
 +          catch (InterruptedException ignore) {
 +          }
 +        }
 +      }
 +      catch (RuntimeException e) {
 +        cause = e;
 +        throw e;
 +      }
 +      finally {
 +        failOnStart(cause);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Determines whether a default server (a cache server) should be created on startup as determined by the absence
 +   * of specifying the --disable-default-server command-line option (switch).  In addition, a default cache server
 +   * is started only if no cache servers have been added to the Cache by way of cache.xml.
 +   * 
 +   * @param cache the reference to the Cache to check for any existing cache servers.
 +   * @return a boolean indicating whether a default server should be added to the Cache.
 +   * @see #isDisableDefaultServer()
 +   */
 +  protected boolean isDefaultServerEnabled(final Cache cache) {
 +    return (cache.getCacheServers().isEmpty() && !isDisableDefaultServer());
 +  }
 +
 +  /**
 +   * If the default server (cache server) has not been disabled and no prior cache servers were added to the cache,
 +   * then this method will add a cache server to the Cache and start the server Thread on the specified bind address
 +   * and port.
 +   * 
 +   * @param cache the Cache to which the server will be added.
 +   * @throws IOException if the Cache server fails to start due to IO error.
 +   */
 +  final void startCacheServer(final Cache cache) throws IOException {
 +    if (isDefaultServerEnabled(cache)) {
 +      final String serverBindAddress = (getServerBindAddress() == null ? null : getServerBindAddress().getHostAddress());
 +      final Integer serverPort = getServerPort();
 +      CacheServerLauncher.serverBindAddress.set(serverBindAddress);
 +      CacheServerLauncher.serverPort.set(serverPort);
 +      final CacheServer cacheServer = cache.addCacheServer();
 +      cacheServer.setBindAddress(serverBindAddress);
 +      cacheServer.setPort(serverPort);
 +      
 +      if (getMaxThreads() != null) {
 +        cacheServer.setMaxThreads(getMaxThreads());
 +      }
 +      
 +      if (getMaxConnections() != null) {
 +        cacheServer.setMaxConnections(getMaxConnections());
 +      }
 +      
 +      if (getMaxMessageCount() != null) {
 +        cacheServer.setMaximumMessageCount(getMaxMessageCount());
 +      }
 +      
 +      if (getMessageTimeToLive() != null) {
 +        cacheServer.setMessageTimeToLive(getMessageTimeToLive());
 +      }
 +      
 +      if (getSocketBufferSize() != null) {
 +        cacheServer.setSocketBufferSize(getSocketBufferSize());
 +      }
 +
 +      if (getHostNameForClients() != null) {
 +        cacheServer.setHostnameForClients(getHostNameForClients());
 +      }
++      
++      CacheServerHelper.setIsDefaultServer(cacheServer);
 +
 +      cacheServer.start();
 +    }
 +  }
 +
 +  /**
 +   * Causes a rebalance operation to occur on the given Cache.
 +   * 
 +   * @param cache the reference to the Cache to rebalance.
 +   * @see com.gemstone.gemfire.cache.control.ResourceManager#createRebalanceFactory()
 +   */
 +  private void rebalance(final Cache cache) {
 +    if (isRebalancing()) {
 +      cache.getResourceManager().createRebalanceFactory().start();
 +    }
 +  }
 +
 +  /**
 +   * Determines whether the user indicated that buckets should be assigned on cache server start using the
 +   * --assign-buckets command-line option (switch) at the command-line as well as whether the option is technically
 +   * allowed.  The option is only allowed if the instance of the Cache is the internal GemFireCacheImpl at present.
 +   * @param cache the Cache reference to check for instance type.
 +   * @return a boolean indicating if bucket assignment is both enabled and allowed.
 +   * @see #isAssignBuckets()
 +   */
 +  protected boolean isAssignBucketsAllowed(final Cache cache) {
 +    return (isAssignBuckets() && (cache instanceof GemFireCacheImpl));
 +  }
 +
 +  /**
 +   * Assigns buckets to individual Partitioned Regions of the Cache.
 +   * 
 +   * @param cache the Cache who's Partitioned Regions are accessed to assign buckets to.
 +   * @see PartitionRegionHelper#assignBucketsToPartitions(com.gemstone.gemfire.cache.Region)
 +   */
 +  final void assignBuckets(final Cache cache) {
 +    if (isAssignBucketsAllowed(cache)) {
 +      for (PartitionedRegion region : ((GemFireCacheImpl) cache).getPartitionedRegions()) {
 +        PartitionRegionHelper.assignBucketsToPartitions(region);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Determines whether the Server is the process of starting or is already running.
 +   * 
 +   * @return a boolean indicating if the Server is starting or is already running.
 +   */
 +  protected boolean isStartingOrRunning() {
 +    return (this.starting.get() || isRunning());
 +  }
 +
 +  /**
 +   * Invokes the 'status' command and operation to check the status of a GemFire server (a cache server).
 +   */
 +  public ServerState status() {
 +    final ServerLauncher launcher = getInstance();
 +    // if this instance is running then return local status
 +    if (isStartingOrRunning()) {
 +      debug("Getting status from the ServerLauncher instance that actually launched the GemFire Cache Server.%n");
 +      return new ServerState(this, (isRunning() ? Status.ONLINE : Status.STARTING));
 +    }
 +    else if (isPidInProcess() && launcher != null) {
 +      return launcher.statusInProcess();
 +    }
 +    else if (getPid() != null) {
 +      debug("Getting Server status using process ID (%1$s)%n", getPid());
 +      return statusWithPid();
 +    }
 +    // attempt to get status using workingDirectory
 +    else if (getWorkingDirectory() != null) {
 +      debug("Getting Server status using working directory (%1$s)%n", getWorkingDirectory());
 +      return statusWithWorkingDirectory();
 +    }
 +
 +    debug("This ServerLauncher was not the instance used to launch the GemFire Cache Server, and neither PID "
 +      .concat("nor working directory were specified; the Server's state is unknown.%n"));
 +
 +    return new ServerState(this, Status.NOT_RESPONDING);
 +  }
 +  
 +  private ServerState statusInProcess() {
 +    if (isStartingOrRunning()) {
 +      debug("Getting status from the ServerLauncher instance that actually launched the GemFire Cache Server.%n");
 +      return new ServerState(this, (isRunning() ? Status.ONLINE : Status.STARTING));
 +    } else {
 +      return new ServerState(this, Status.NOT_RESPONDING);
 +    }
 +  }
 +  
 +  private ServerState statusWithPid() {
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, getPid());
 +      controller.checkPidSupport();
 +      final String statusJson = controller.status();
 +      return ServerState.fromJson(statusJson);
 +    }
 +//    catch (NoClassDefFoundError error) {
 +//      if (isAttachAPINotFound(error)) {
 +//        throw new AttachAPINotFoundException(LocalizedStrings.Launcher_ATTACH_API_NOT_FOUND_ERROR_MESSAGE
 +//          .toLocalizedString(), error);
 +//      }
 +//
 +//      throw error;
 +//    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to server JVM
 +      return createNoResponseState(e, "Failed to connect to server with process id " + getPid());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    } 
 +//    catch (MalformedObjectNameException e) { // impossible
 +//      // JMX object name is bad
 +//      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +//    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    } 
 +//    catch (PidUnavailableException e) {
 +//      // couldn't determine pid from within server JVM
 +//      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +//    } 
 +    catch (UnableToControlProcessException e) {
 +      // TODO comment me
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    } 
 +    catch (InterruptedException e) {
 +      // TODO comment me
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    } 
 +    catch (TimeoutException e) {
 +      // TODO comment me
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    }
 +  }
 +
 +  private ServerState statusWithWorkingDirectory() {
 +    int parsedPid = 0;
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, new File(getWorkingDirectory()), ProcessType.SERVER.getPidFileName(), READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
 +      parsedPid = controller.getProcessId();
 +      
 +      // note: in-process request will go infinite loop unless we do the following
 +      if (parsedPid == identifyPid()) {
 +        final ServerLauncher runningLauncher = getInstance();
 +        if (runningLauncher != null) {
 +          return runningLauncher.statusInProcess();
 +        }
 +      }
 +
 +      final String statusJson = controller.status();
 +      return ServerState.fromJson(statusJson);
 +    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to server JVM
 +      return createNoResponseState(e, "Failed to connect to server with process id " + parsedPid);
 +    } 
 +    catch (FileNotFoundException e) {
 +      // could not find pid file
 +      return createNoResponseState(e, "Failed to find process file " + ProcessType.SERVER.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      return createNoResponseState(e, "Interrupted while trying to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (PidUnavailableException e) {
 +      // couldn't determine pid from within server JVM
 +      return createNoResponseState(e, "Failed to find usable process id within file " + ProcessType.SERVER.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (UnableToControlProcessException e) {
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (TimeoutException e) {
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    }
 +  }
 +
 +  /**
 +   * Determines whether the Server can be stopped in-process, such as when a Server is embedded in an application
 +   * and the ServerLauncher API is being used.
 +   * 
 +   * @return a boolean indicating whether the Server can be stopped in-process (the application's process with
 +   * an embedded Server).
 +   */
 +  private boolean isStoppable() {
 +    return (isRunning() && getCache() != null);
 +  }
 +
 +  /**
 +   * Invokes the 'stop' command and operation to stop a GemFire server (a cache server).
 +   */
 +  public ServerState stop() {
 +    final ServerLauncher launcher = getInstance();
 +    // if this instance is running then stop it
 +    if (isStoppable()) {
 +      return stopInProcess();
 +    }
 +    // if in-process but difference instance of ServerLauncher
 +    else if (isPidInProcess() && launcher != null) {
 +      return launcher.stopInProcess();
 +    }
 +    // attempt to stop using pid if provided
 +    else if (getPid() != null) {
 +      return stopWithPid();
 +    }
 +    // attempt to stop using workingDirectory
 +    else if (getWorkingDirectory() != null) {
 +      return stopWithWorkingDirectory();
 +    }
 +
 +    // TODO give user detailed error message?
 +    return new ServerState(this, Status.NOT_RESPONDING);
 +  }
 +  
 +  private ServerState stopInProcess() {
 +    if (isStoppable()) {
 +      this.cache.close();
 +      this.cache = null;
 +      this.process.stop();
 +      this.process = null;
 +      INSTANCE.compareAndSet(this, null); // note: other thread may return Status.NOT_RESPONDING now
 +      this.running.set(false);
 +      return new ServerState(this, Status.STOPPED);
 +    } else {
 +      return new ServerState(this, Status.NOT_RESPONDING);
 +    }
 +  }
 +
 +  private ServerState stopWithPid() {
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, getPid());
 +      controller.checkPidSupport();
 +      controller.stop();
 +      return new ServerState(this, Status.STOPPED);
 +    }
 +//    catch (NoClassDefFoundError error) {
 +//      if (isAttachAPINotFound(error)) {
 +//        throw new AttachAPINotFoundException(LocalizedStrings.Launcher_ATTACH_API_NOT_FOUND_ERROR_MESSAGE
 +//          .toLocalizedString(), error);
 +//      }
 +//
 +//      throw error;
 +//    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to server JVM
 +      return createNoResponseState(e, "Failed to connect to server with process id " + getPid());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    } 
 +//    catch (MalformedObjectNameException e) { // impossible
 +//      // JMX object name is bad
 +//      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +//    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    } 
 +//    catch (PidUnavailableException e) {
 +//      // couldn't determine pid from within server JVM
 +//      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +//    } 
 +    catch (UnableToControlProcessException e) {
 +      // TODO comment me
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + getPid());
 +    }
 +  }
 +
 +  private ServerState stopWithWorkingDirectory() {
 +    int parsedPid = 0;
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, new File(getWorkingDirectory()), ProcessType.SERVER.getPidFileName(), READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
 +      parsedPid = controller.getProcessId();
 +      
 +      // NOTE in-process request will go infinite loop unless we do the following
 +      if (parsedPid == identifyPid()) {
 +        final ServerLauncher runningLauncher = getInstance();
 +        if (runningLauncher != null) {
 +          return runningLauncher.stopInProcess();
 +        }
 +      }
 +      
 +      controller.stop();
 +      return new ServerState(this, Status.STOPPED);
 +    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to server JVM
 +      return createNoResponseState(e, "Failed to connect to server with process id " + parsedPid);
 +    } 
 +    catch (FileNotFoundException e) {
 +      // could not find pid file
 +      return createNoResponseState(e, "Failed to find process file " + ProcessType.SERVER.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      return createNoResponseState(e, "Interrupted while trying to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    } 
 +    catch (PidUnavailableException e) {
 +      // couldn't determine pid from within server JVM
 +      return createNoResponseState(e, "Failed to find usable process id within file " + ProcessType.SERVER.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (TimeoutException e) {
 +      return createNoResponseState(e, "Timed out trying to find usable process id within file " + ProcessType.SERVER.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (UnableToControlProcessException e) {
 +      return createNoResponseState(e, "Failed to communicate with server with process id " + parsedPid);
 +    }
 +  }
 +
 +  private ServerState createNoResponseState(final Exception cause, final String errorMessage) {
 +    debug(cause);
 +    return new ServerState(this, Status.NOT_RESPONDING, errorMessage);
 +  }
 +
 +  private Properties getOverriddenDefaults() {
 +    final Properties overriddenDefaults = new Properties();
 +    
 +    overriddenDefaults.put(
 +      ProcessLauncherContext.OVERRIDDEN_DEFAULTS_PREFIX.concat(DistributionConfig.LOG_FILE_NAME), 
 +      getLogFileName());
 +
 +    for (String key : System.getProperties().stringPropertyNames()) {
 +      if (key.startsWith(ProcessLauncherContext.OVERRIDDEN_DEFAULTS_PREFIX)) {
 +        overriddenDefaults.put(key, System.getProperty(key));
 +      }
 +    }
 +
 +    return overriddenDefaults;
 +  }
 +
 +  private class ServerControllerParameters implements ProcessControllerParameters {
 +    @Override
 +    public File getPidFile() {
 +      return getServerPidFile();
 +    }
 +  
 +    @Override
 +    public File getWorkingDirectory() {
 +      return new File(ServerLauncher.this.getWorkingDirectory());
 +    }
 +  
 +    @Override
 +    public int getProcessId() {
 +      return getPid();
 +    }
 +  
 +    @Override
 +    public ProcessType getProcessType() {
 +      return ProcessType.SERVER;
 +    }
 +  
 +    @Override
 +    public ObjectName getNamePattern() {
 +      try {
 +        return ObjectName.getInstance("GemFire:type=Member,*");
 +      } catch (MalformedObjectNameException e) {
 +        return null;
 +      } catch (NullPointerException e) {
 +        return null;
 +      }
 +    }
 +  
 +    @Override
 +    public String getPidAttribute() {
 +      return "ProcessId";
 +    }
 +  
 +    @Override
 +    public String getStopMethod() {
 +      return "shutDownMember";
 +    }
 +    
 +    @Override
 +    public String getStatusMethod() {
 +      return "status";
 +    }
 +  
 +    @Override
 +    public String[] getAttributes() {
 +      return new String[] {"Server"};
 +    }
 +  
 +    @Override
 +    public Object[] getValues() {
 +      return new Object[] {Boolean.TRUE};
 +    }
 +  }
 +
 +  /**
 +   * The Builder class, modeled after the Builder creational design pattern, is used to construct a properly configured
 +   * and initialized instance of the ServerLauncher to control and run GemFire servers (in particular, cache servers).
 +   */
 +  public static class Builder {
 +
 +    protected static final Command DEFAULT_COMMAND = Command.UNSPECIFIED;
 +
 +    private boolean serverBindAddressSetByUser;
 +    private boolean serverPortSetByUser;
 +
 +    private Boolean assignBuckets;
 +    private Boolean debug;
 +    private Boolean disableDefaultServer;
 +    private Boolean force;
 +    private Boolean help;
 +    private Boolean rebalance;
 +    private Boolean redirectOutput;
 +
 +    private Cache cache;
 +
 +    private final CacheConfig cacheConfig = new CacheConfig();
 +
 +    private Command command;
 +
 +    private InetAddress serverBindAddress;
 +
 +    private Integer pid;
 +    private Integer serverPort;
 +
 +    private final Properties distributedSystemProperties = new Properties();
 +
 +    private String memberName;
 +    private String springXmlLocation;
 +    private String workingDirectory;
 +    
 +    private Float criticalHeapPercentage;
 +    private Float evictionHeapPercentage;
 +    
 +    private Float criticalOffHeapPercentage;
 +    private Float evictionOffHeapPercentage;
 +    
 +    private String hostNameForClients; 
 +    private Integer loadPollInterval;
 +    private Integer maxConnections;
 +    private Integer maxMessageCount;
 +    private Integer messageTimeToLive;
 +    private Integer socketBufferSize;
 +    private Integer maxThreads;
 +
 +    /**
 +     * Default constructor used to create an instance of the Builder class for programmatical access.
 +     */
 +    public Builder() {
 +    }
 +
 +    /**
 +     * Constructor used to create and configure an instance of the Builder class with the specified arguments, passed in
 +     * from the command-line when launching an instance of this class from the command-line using the Java launcher.
 +     * 
 +     * @param args the array of arguments used to configure the Builder.
 +     * @see #parseArguments(String...)
 +     */
 +    public Builder(final String... args) {
 +      parseArguments(args != null ? args : new String[0]);
 +    }
 +
 +    /**
 +     * Gets an instance of the JOptSimple OptionParser to parse the command-line arguments for Server.
 +     * 
 +     * @return an instance of the JOptSimple OptionParser configured with the command-line options used by the Server.
 +     */
 +    private OptionParser getParser() {
 +      OptionParser parser = new OptionParser(true);
 +
 +      parser.accepts("assign-buckets");
 +      parser.accepts("debug");
 +      parser.accepts("dir").withRequiredArg().ofType(String.class);
 +      parser.accepts("disable-default-server");
 +      parser.accepts("force");
 +      parser.accepts("help");
 +      parser.accepts("member").withRequiredArg().ofType(String.class);
 +      parser.accepts("pid").withRequiredArg().ofType(Integer.class);
 +      parser.accepts("rebalance");
 +      parser.accepts("redirect-output");
 +      parser.accepts("server-bind-address").withRequiredArg().ofType(String.class);
 +      parser.accepts("server-port").withRequiredArg().ofType(Integer.class);
 +      parser.accepts("spring-xml-location").withRequiredArg().ofType(String.class);
 +      parser.accepts("version");
 +      parser.accepts(CliStrings.START_SERVER__CRITICAL__HEAP__PERCENTAGE).withRequiredArg().ofType(Float.class);
 +      parser.accepts(CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE).withRequiredArg().ofType(Float.class);
 +      parser.accepts(CliStrings.START_SERVER__CRITICAL_OFF_HEAP_PERCENTAGE).withRequiredArg().ofType(Float.class);
 +      parser.accepts(CliStrings.START_SERVER__EVICTION_OFF_HEAP_PERCENTAGE).withRequiredArg().ofType(Float.class);
 +      parser.accepts(CliStrings.START_SERVER__MAX__CONNECTIONS).withRequiredArg().ofType(Integer.class);
 +      parser.accepts(CliStrings.START_SERVER__MAX__MESSAGE__COUNT).withRequiredArg().ofType(Integer.class);
 +      parser.accepts(CliStrings.START_SERVER__MAX__THREADS).withRequiredArg().ofType(Integer.class);
 +      parser.accepts(CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE).withRequiredArg().ofType(Integer.class);
 +      parser.accepts(CliStrings.START_SERVER__SOCKET__BUFFER__SIZE).withRequiredArg().ofType(Integer.class);
 +      parser.accepts(CliStrings.START_SERVER__HOSTNAME__FOR__CLIENTS).withRequiredArg().ofType(String.class);
 +
 +      return parser;
 +    }
 +
 +    /**
 +     * Parses the list of arguments to configure this Builder with the intent of constructing a Server launcher to
 +     * invoke a Cache Server.  This method is called to parse the arguments specified by the user on the command-line.
 +     * 
 +     * @param args the array of arguments used to configure this Builder and create an instance of ServerLauncher.
 +     */
 +    protected void parseArguments(final String... args) {
 +      try {
 +        OptionSet options = getParser().parse(args);
 +
 +        parseCommand(args);
 +        parseMemberName(args); // TODO:KIRK: need to get the name to LogService for log file name
 +
 +        setAssignBuckets(options.has("assign-buckets"));
 +        setDebug(options.has("debug"));
 +        setDisableDefaultServer(options.has("disable-default-server"));
 +        setForce(options.has("force"));
 +        setHelp(options.has("help"));
 +        setRebalance(options.has("rebalance"));
 +        setRedirectOutput(options.has("redirect-output"));
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__CRITICAL__HEAP__PERCENTAGE)) {
 +          setCriticalHeapPercentage(Float.parseFloat(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__CRITICAL__HEAP__PERCENTAGE))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE)) {
 +          setEvictionHeapPercentage(Float.parseFloat(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__CRITICAL_OFF_HEAP_PERCENTAGE)) {
 +          setCriticalOffHeapPercentage(Float.parseFloat(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__CRITICAL_OFF_HEAP_PERCENTAGE))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__EVICTION_OFF_HEAP_PERCENTAGE)) {
 +          setEvictionOffHeapPercentage(Float.parseFloat(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__EVICTION_OFF_HEAP_PERCENTAGE))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__MAX__CONNECTIONS)) {
 +          setMaxConnections(Integer.parseInt(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__MAX__CONNECTIONS))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__MAX__MESSAGE__COUNT)) {
 +          setMaxConnections(Integer.parseInt(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__MAX__MESSAGE__COUNT))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE)) {
 +          setMaxConnections(Integer.parseInt(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__SOCKET__BUFFER__SIZE)) {
 +          setMaxConnections(Integer.parseInt(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__SOCKET__BUFFER__SIZE))));
 +        } 
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__MAX__THREADS)) {
 +          setMaxThreads(Integer.parseInt(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__MAX__THREADS))));
 +        }
 +        
 +        if (!isHelping()) {
 +          if (options.has("dir")) {
 +            setWorkingDirectory(ObjectUtils.toString(options.valueOf("dir")));
 +          }
 +
 +          if (options.has("pid")) {
 +            setPid((Integer) options.valueOf("pid"));
 +          }
 +
 +          if (options.has("server-bind-address")) {
 +            setServerBindAddress(ObjectUtils.toString(options.valueOf("server-bind-address")));
 +          }
 +
 +          if (options.has("server-port")) {
 +            setServerPort((Integer) options.valueOf("server-port"));
 +          }
 +
 +          if (options.has("spring-xml-location")) {
 +            setSpringXmlLocation(ObjectUtils.toString(options.valueOf("spring-xml-location")));
 +          }
 +
 +          if (options.has("version")) {
 +            setCommand(Command.VERSION);
 +          }
 +        }
 +
 +        // TODO why are these option not inside the 'if (!isHelping())' conditional block!?
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__CRITICAL__HEAP__PERCENTAGE)) {
 +          setCriticalHeapPercentage(Float.parseFloat(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__CRITICAL__HEAP__PERCENTAGE))));
 +        }
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE)) {
 +          setEvictionHeapPercentage(Float.parseFloat(ObjectUtils.toString(options.valueOf(
 +            CliStrings.START_SERVER__EVICTION__HEAP__PERCENTAGE))));
 +        }
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__MAX__CONNECTIONS)) {
 +          setMaxConnections(Integer.parseInt(ObjectUtils.toString(options.valueOf(
 +            CliStrings.START_SERVER__MAX__CONNECTIONS))));
 +        }
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__MAX__MESSAGE__COUNT)) {
 +          setMaxMessageCount(Integer.parseInt(ObjectUtils.toString(options.valueOf(
 +            CliStrings.START_SERVER__MAX__MESSAGE__COUNT))));
 +        }
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__MAX__THREADS)) {
 +          setMaxThreads(Integer.parseInt(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__MAX__THREADS))));
 +        }
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE)) {
 +          setMessageTimeToLive(Integer.parseInt(ObjectUtils.toString(options.valueOf(
 +            CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE))));
 +        }
 +        
 +        if (options.hasArgument(CliStrings.START_SERVER__SOCKET__BUFFER__SIZE)) {
 +          setSocketBufferSize(Integer.parseInt(ObjectUtils.toString(options.valueOf(
 +            CliStrings.START_SERVER__SOCKET__BUFFER__SIZE))));
 +        }
 +
 +        if (options.hasArgument(CliStrings.START_SERVER__HOSTNAME__FOR__CLIENTS)) {
 +          setHostNameForClients(ObjectUtils.toString(options.valueOf(CliStrings.START_SERVER__HOSTNAME__FOR__CLIENTS)));
 +        }
 +
 +      }
 +      catch (OptionException e) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_PARSE_COMMAND_LINE_ARGUMENT_ERROR_MESSAGE
 +          .toLocalizedString("Server", e.getMessage()), e);
 +      }
 +      catch (Exception e) {
 +        throw new RuntimeException(e.getMessage(), e);
 +      }
 +    }
 +
 +    /**
 +     * Iterates the list of arguments in search of the target Server launcher command.
 +     * 
 +     * @param args an array of arguments from which to search for the Server launcher command.
 +     * @see com.gemstone.gemfire.distributed.ServerLauncher.Command#valueOfName(String)
 +     * @see #parseArguments(String...)
 +     */
 +    protected void parseCommand(final String... args) {
 +      if (args != null) {
 +        for (String arg : args) {
 +          Command command = Command.valueOfName(arg);
 +          if (command != null) {
 +            setCommand(command);
 +            break;
 +          }
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Iterates the list of arguments in search of the Server's GemFire member name.  If the argument does not
 +     * start with '-' or is not the name of a Server launcher command, then the value is presumed to be the member name
 +     * for the Server in GemFire.
 +     * 
 +     * @param args the array of arguments from which to search for the Server's member name in GemFire.
 +     * @see com.gemstone.gemfire.distributed.ServerLauncher.Command#isCommand(String)
 +     * @see #parseArguments(String...)
 +     */
 +    protected void parseMemberName(final String... args) {
 +      if (args != null) {
 +        for (String arg : args) {
 +          if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) {
 +            setMemberName(arg);
 +            break;
 +          }
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Gets the CacheConfig object used to configure PDX on the GemFire Cache by the Builder.
 +     *
 +     * @return the CacheConfig object used to configure PDX on the GemFire Cache by the Builder.
 +     */
 +    CacheConfig getCacheConfig() {
 +      return this.cacheConfig;
 +    }
 +
 +    /**
 +     * Gets the Server launcher command used during the invocation of the ServerLauncher.
 +     * 
 +     * @return the Server launcher command used to invoke (run) the ServerLauncher class.
 +     * @see #setCommand(com.gemstone.gemfire.distributed.ServerLauncher.Command)
 +     * @see com.gemstone.gemfire.distributed.ServerLauncher.Command
 +     */
 +    public Command getCommand() {
 +      return ObjectUtils.defaultIfNull(this.command, DEFAULT_COMMAND);
 +    }
 +
 +    /**
 +     * Sets the Sever launcher command used during the invocation of the ServerLauncher
 +     * 
 +     * @param command the targeted Server launcher command used during the invocation (run) of ServerLauncher.
 +     * @return this Builder instance.
 +     * @see #getCommand()
 +     * @see com.gemstone.gemfire.distributed.ServerLauncher.Command
 +     */
 +    public Builder setCommand(final Command command) {
 +      this.command = command;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether buckets should be assigned to partitioned regions in the cache upon Server start.
 +     * 
 +     * @return a boolean indicating if buckets should be assigned upon Server start.
 +     * @see #setAssignBuckets(Boolean)
 +     */
 +    public Boolean getAssignBuckets() {
 +      return this.assignBuckets;
 +    }
 +
 +    /**
 +     * Sets whether buckets should be assigned to partitioned regions in the cache upon Server start.
 +     * 
 +     * @param assignBuckets a boolean indicating if buckets should be assigned upon Server start.
 +     * @return this Builder instance.
 +     * @see #getAssignBuckets()
 +     */
 +    public Builder setAssignBuckets(final Boolean assignBuckets) {
 +      this.assignBuckets = assignBuckets;
 +      return this;
 +    }
 +
 +    // For testing purposes only!
 +    Cache getCache() {
 +      return this.cache;
 +    }
 +
 +    // For testing purposes only!
 +    Builder setCache(final Cache cache) {
 +      this.cache = cache;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether the new instance of the ServerLauncher will be set to debug mode.
 +     * 
 +     * @return a boolean value indicating whether debug mode is enabled or disabled.
 +     * @see #setDebug(Boolean)
 +     */
 +    public Boolean getDebug() {
 +      return this.debug;
 +    }
 +
 +    /**
 +     * Sets whether the new instance of the ServerLauncher will be set to debug mode.
 +     * 
 +     * @param debug a boolean value indicating whether debug mode is to be enabled or disabled.
 +     * @return this Builder instance.
 +     * @see #getDebug()
 +     */
 +    public Builder setDebug(final Boolean debug) {
 +      this.debug = debug;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether a default cache server will be added when the GemFire Server comes online.
 +     * 
 +     * @return a boolean value indicating whether to add a default cache server.
 +     * @see #setDisableDefaultServer(Boolean)
 +     */
 +    public Boolean getDisableDefaultServer() {
 +      return this.disableDefaultServer;
 +    }
 +
 +    /**
 +     * Sets a boolean value indicating whether to add a default cache when the GemFire Server comes online.
 +     * 
 +     * @param disableDefaultServer a boolean value indicating whether to add a default cache server.
 +     * @return this Builder instance.
 +     * @see #getDisableDefaultServer()
 +     */
 +    public Builder setDisableDefaultServer(final Boolean disableDefaultServer) {
 +      this.disableDefaultServer = disableDefaultServer;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the GemFire Distributed System (cluster) Properties configuration.
 +     *
 +     * @return a Properties object containing configuration settings for the GemFire Distributed System (cluster).
 +     * @see java.util.Properties
 +     */
 +    public Properties getDistributedSystemProperties() {
 +      return this.distributedSystemProperties;
 +    }
 +
 +    /**
 +     * Gets the boolean value used by the Server to determine if it should overwrite the PID file if it already exists.
 +     * 
 +     * @return the boolean value specifying whether or not to overwrite the PID file if it already exists.
 +     * @see com.gemstone.gemfire.internal.process.LocalProcessLauncher
 +     * @see #setForce(Boolean)
 +     */
 +    public Boolean getForce() {
 +      return ObjectUtils.defaultIfNull(this.force, DEFAULT_FORCE);
 +    }
 +
 +    /**
 +     * Sets the boolean value used by the Server to determine if it should overwrite the PID file if it already exists.
 +     * 
 +     * @param force a boolean value indicating whether to overwrite the PID file when it already exists.
 +     * @return this Builder instance.
 +     * @see com.gemstone.gemfire.internal.process.LocalProcessLauncher
 +     * @see #getForce()
 +     */
 +    public Builder setForce(final Boolean force) {
 +      this.force = force;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether the new instance of the ServerLauncher will be used to output help information for either
 +     * a specific command, or for using ServerLauncher in general.
 +     * 
 +     * @return a boolean value indicating whether help will be output during the invocation of the ServerLauncher.
 +     * @see #setHelp(Boolean)
 +     */
 +    public Boolean getHelp() {
 +      return this.help;
 +    }
 +
 +    /**
 +     * Determines whether help has been enabled.
 +     * 
 +     * @return a boolean indicating if help was enabled.
 +     */
 +    protected final boolean isHelping() {
 +      return Boolean.TRUE.equals(getHelp());
 +    }
 +
 +    /**
 +     * Sets whether the new instance of ServerLauncher will be used to output help information for either a specific
 +     * command, or for using ServerLauncher in general.
 +     * 
 +     * @param help a boolean indicating whether help information is to be displayed during invocation of ServerLauncher.
 +     * @return this Builder instance.
 +     * @see #getHelp()
 +     */
 +    public Builder setHelp(final Boolean help) {
 +      this.help = help;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether a rebalance operation on the cache will occur upon starting the GemFire server.
 +     * 
 +     * @return a boolean indicating if the cache will be rebalance when the GemFire server starts.
 +     * @see #setRebalance(Boolean)
 +     */
 +    public Boolean getRebalance() {
 +      return this.rebalance;
 +    }
 +
 +    /**
 +     * Set a boolean value indicating whether a rebalance operation on the cache should occur upon starting
 +     * the GemFire server.
 +     * 
 +     * @param rebalance a boolean indicating if the cache will be rebalanced when the GemFire server starts.
 +     * @return this Builder instance.
 +     * @see #getRebalance()
 +     */
 +    public Builder setRebalance(final Boolean rebalance) {
 +      this.rebalance = rebalance;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the member name of this Server in GemFire.
 +     * 
 +     * @return a String indicating the member name of this Server in GemFire.
 +     * @see #setMemberName(String)
 +     */
 +    public String getMemberName() {
 +      return this.memberName;
 +    }
 +
 +    /**
 +     * Sets the member name of the Server in GemFire.
 +     * 
 +     * @param memberName a String indicating the member name of this Server in GemFire.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the member name is invalid.
 +     * @see #getMemberName()
 +     */
 +    public Builder setMemberName(final String memberName) {
 +      if (StringUtils.isEmpty(StringUtils.trim(memberName))) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_MEMBER_NAME_ERROR_MESSAGE
 +          .toLocalizedString("Server"));
 +      }
 +      this.memberName = memberName;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the process ID (PID) of the running Server indicated by the user as an argument to the ServerLauncher.
 +     * This PID is used by the Server launcher to determine the Server's status, or invoke shutdown on the Server.
 +     * 
 +     * @return a user specified Integer value indicating the process ID of the running Server.
 +     * @see #setPid(Integer)
 +     */
 +    public Integer getPid() {
 +      return this.pid;
 +    }
 +
 +    /**
 +     * Sets the process ID (PID) of the running Server indicated by the user as an argument to the ServerLauncher.
 +     * This PID will be used by the Server launcher to determine the Server's status, or invoke shutdown on the Server.
 +     * 
 +     * @param pid a user specified Integer value indicating the process ID of the running Server.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the process ID (PID) is not valid (greater than zero if not null).
 +     * @see #getPid()
 +     */
 +    public Builder setPid(final Integer pid) {
 +      if (pid != null && pid < 0) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_PID_ERROR_MESSAGE.toLocalizedString());
 +      }
 +      this.pid = pid;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether the new instance of LocatorLauncher will redirect
 +     * output to system logs when starting a Locator.
 +     * 
 +     * @return a boolean value indicating if output will be redirected to system 
 +     * logs when starting a Locator
 +     * 
 +     * @see #setRedirectOutput(Boolean)
 +     */
 +    public Boolean getRedirectOutput() {
 +      return this.redirectOutput;
 +    }
 +
 +    /**
 +     * Determines whether redirecting of output has been enabled.
 +     * 
 +     * @return a boolean indicating if redirecting of output was enabled.
 +     */
 +    private boolean isRedirectingOutput() {
 +      return Boolean.TRUE.equals(getRedirectOutput());
 +    }
 +
 +    /**
 +     * Sets whether the new instance of LocatorLauncher will redirect output to system logs when starting a Locator.
 +     * 
 +     * @param redirectOutput a boolean value indicating if output will be redirected to system logs when starting
 +     * a Locator.
 +     * @return this Builder instance.
 +     * @see #getRedirectOutput()
 +     */
 +    public Builder setRedirectOutput(final Boolean redirectOutput) {
 +      this.redirectOutput = redirectOutput;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the IP address to which the Server will be bound listening for and accepting cache client connections in
 +     * a client/server topology.
 +     * 
 +     * @return an InetAddress indicating the IP address that the Server is bound to listening for and accepting cache
 +     * client connections in a client/server topology.
 +     * @see #setServerBindAddress(String)
 +     */
 +    public InetAddress getServerBindAddress() {
 +      return this.serverBindAddress;
 +    }
 +    
 +    boolean isServerBindAddressSetByUser() {
 +      return this.serverBindAddressSetByUser;
 +    }
 +
 +    /**
 +     * Sets the IP address to which the Server will be bound listening for and accepting cache client connections in
 +     * a client/server topology.
 +     * 
 +     * @param serverBindAddress a String specifying the IP address or hostname that the Server will be bound to listen
 +     * for and accept cache client connections in a client/server topology.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException wrapping the UnknownHostException if the IP address or hostname for the
 +     * server bind address is unknown.
 +     * @see #getServerBindAddress()
 +     */
 +    public Builder setServerBindAddress(final String serverBindAddress) {
 +      if (StringUtils.isBlank(serverBindAddress)) {
 +        this.serverBindAddress = null;
 +        return this;
 +      }
 +      // NOTE only set the 'bind address' if the user specified a value
 +      else {
 +        try {
 +          this.serverBindAddress = InetAddress.getByName(serverBindAddress);
-           this.serverBindAddressSetByUser = true;
-           return this;
++          if (SocketCreator.isLocalHost(this.serverBindAddress)) {
++            this.serverBindAddressSetByUser = true;
++            return this;
++          }
++          else {
++            throw new IllegalArgumentException(serverBindAddress + " is not an address for this machine.");
++          }
 +        }
 +        catch (UnknownHostException e) {
 +          throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE
 +            .toLocalizedString("Server"), e);
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Gets the port on which the Server will listen for and accept cache client connections in a client/server topology.
 +     * 
 +     * @return an Integer value specifying the port the Server will listen on and accept cache client connections in
 +     * a client/server topology.
 +     * @see #setServerPort(Integer)
 +     */
 +    public Integer getServerPort() {
 +      return ObjectUtils.defaultIfNull(this.serverPort, getDefaultServerPort());
 +    }
 +    
 +    boolean isServerPortSetByUser() {
 +      return this.serverPortSetByUser;
 +    }
 +
 +    /**
 +     * Sets the port on which the Server will listen for and accept cache client connections in a client/server topology.
 +     * 
 +     * @param serverPort an Integer value specifying the port the Server will listen on and accept cache client
 +     * connections in a client/server topology.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the port number is not valid.
 +     * @see #getServerPort()
 +     */
 +    public Builder setServerPort(final Integer serverPort) {
 +      if (serverPort != null && (serverPort < 0 || serverPort > 65535)) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_INVALID_PORT_ERROR_MESSAGE
 +          .toLocalizedString("Server"));
 +      }
 +      this.serverPort = serverPort;
 +      this.serverPortSetByUser = true;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the location of the Spring XML configuration meta-data file used to bootstrap, configure and initialize
 +     * the GemFire Server on start.
 +     * <p>
 +     * @return a String indicating the location of the Spring XML configuration file.
 +     * @see #setSpringXmlLocation(String)
 +     */
 +    public String getSpringXmlLocation() {
 +      return this.springXmlLocation;
 +    }
 +
 +    /**
 +     * Sets the location of the Spring XML configuration meta-data file used to bootstrap, configure and initialize
 +     * the GemFire Server on start.
 +     * <p>
 +     * @param springXmlLocation a String indicating the location of the Spring XML configuration file.
 +     * @return this Builder instance.
 +     * @see #getSpringXmlLocation()
 +     */
 +    public Builder setSpringXmlLocation(final String springXmlLocation) {
 +      this.springXmlLocation = springXmlLocation;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the working directory pathname in which the Server will be ran.  If the directory is unspecified,
 +     * then working directory defaults to the current directory.
 +     * 
 +     * @return a String indicating the working directory pathname.
 +     * @see #setWorkingDirectory(String)
 +     */
 +    public String getWorkingDirectory() {
 +      return IOUtils.tryGetCanonicalPathElseGetAbsolutePath(
 +        new File(StringUtils.defaultIfBlank(this.workingDirectory, DEFAULT_WORKING_DIRECTORY)));
 +    }
 +
 +    /**
 +     * Sets the working directory in which the Server will be ran.  This also the directory in which all Server files
 +     * (such as log and license files) will be written.  If the directory is unspecified, then the working directory
 +     * defaults to the current directory.
 +     * 
 +     * @param workingDirectory a String indicating the pathname of the directory in which the Server will be ran.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException wrapping a FileNotFoundException if the working directory pathname cannot be
 +     * found.
 +     * @see #getWorkingDirectory()
 +     * @see java.io.FileNotFoundException
 +     */
 +    public Builder setWorkingDirectory(final String workingDirectory) {
 +      if (!(new File(StringUtils.defaultIfBlank(workingDirectory, DEFAULT_WORKING_DIRECTORY)).isDirectory())) {
 +        throw new IllegalArgumentException(
 +          LocalizedStrings.Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE.toLocalizedString("Server"),
 +            new FileNotFoundException(workingDirectory));
 +      }
 +      this.workingDirectory = workingDirectory;
 +      return this;
 +    }
 +    
 +    public Float getCriticalHeapPercentage() {
 +      return this.criticalHeapPercentage;
 +    }
 +
 +    public Builder setCriticalHeapPercentage(final Float criticalHeapPercentage) {
 +      if (criticalHeapPercentage != null) {
 +        if (criticalHeapPercentage < 0 || criticalHeapPercentage > 100.0f) {
 +          throw new IllegalArgumentException(String.format("Critical heap percentage (%1$s) must be between 0 and 100!",
 +            criticalHeapPercentage));
 +        }
 +      }
 +      this.criticalHeapPercentage = criticalHeapPercentage;
 +      return this;
 +    }
 +
 +    public Float getCriticalOffHeapPercentage() {
 +      return this.criticalOffHeapPercentage;
 +    }
 +    
 +    public Builder setCriticalOffHeapPercentage(final Float criticalOffHeapPercentage) {
 +      if (criticalOffHeapPercentage != null) {
 +        if (criticalOffHeapPercentage < 0 || criticalOffHeapPercentage > 100.0f) {
 +          throw new IllegalArgumentException(String.format("Critical off-heap percentage (%1$s) must be between 0 and 100!", criticalOffHeapPercentage));
 +        }
 +      }
 +     this.criticalOffHeapPercentage = criticalOffHeapPercentage;
 +     return this;
 +    }
 +    
 +    public Float getEvictionHeapPercentage() {
 +      return this.evictionHeapPercentage;
 +    }
 +
 +    public Builder setEvictionHeapPercentage(final Float evictionHeapPercentage) {
 +      if (evictionHeapPercentage != null) {
 +        if (evictionHeapPercentage < 0 || evictionHeapPercentage > 100.0f) {
 +          throw new IllegalArgumentException(String.format("Eviction heap percentage (%1$s) must be between 0 and 100!",
 +            evictionHeapPercentage));
 +        }
 +      }
 +      this.evictionHeapPercentage = evictionHeapPercentage;
 +      return this;
 +    }
 +    
 +    public Float getEvictionOffHeapPercentage() {
 +      return this.evictionOffHeapPercentage;
 +    }
 +    
 +    public Builder setEvictionOffHeapPercentage(final Float evictionOffHeapPercentage) {
 +      if (evictionOffHeapPercentage != null) {
 +        if (evictionOffHeapPercentage < 0 || evictionOffHeapPercentage > 100.0f) {
 +          throw new IllegalArgumentException(String.format("Eviction off-heap percentage (%1$s) must be between 0 and 100", evictionOffHeapPercentage));
 +        }
 +      }
 +      this.evictionOffHeapPercentage = evictionOffHeapPercentage;
 +      return this;
 +    }
 +    
 +    public String getHostNameForClients() {
 +      return this.hostNameForClients;
 +    }
 +
 +    public Builder setHostNameForClients(String hostNameForClients) {
 +      this.hostNameForClients = hostNameForClients;
 +      return this;
 +    }
 +
 +    public Integer getMaxConnections() {
 +      return this.maxConnections;
 +    }
 +
 +    public Builder setMaxConnections(Integer maxConnections) {
 +      if (maxConnections != null && maxConnections < 1) {
 +        throw new IllegalArgumentException(String.format("Max Connections (%1$s) must be greater than 0!",
 +          maxConnections));
 +      }
 +      this.maxConnections = maxConnections;
 +      return this;
 +    }
 +
 +    public Integer getMaxMessageCount() {
 +      return this.maxMessageCount;
 +    }
 +
 +    public Builder setMaxMessageCount(Integer maxMessageCount) {
 +      if (maxMessageCount != null && maxMessageCount < 1) {
 +        throw new IllegalArgumentException(String.format("Max Message Count (%1$s) must be greater than 0!",
 +          maxMessageCount));
 +      }
 +      this.maxMessageCount = maxMessageCount;
 +      return this;
 +    }
 +


<TRUNCATED>


[051/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
Merge remote-tracking branch 'origin/develop' into feature/GEODE-917


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/5beaaedc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/5beaaedc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/5beaaedc

Branch: refs/heads/feature/GEODE-870
Commit: 5beaaedcebdd08f17a9a4cc169178b9c4af5f567
Parents: 8780b5c 110a5b4
Author: Dan Smith <up...@apache.org>
Authored: Fri Feb 19 11:31:08 2016 -0800
Committer: Dan Smith <up...@apache.org>
Committed: Fri Feb 19 11:39:33 2016 -0800

----------------------------------------------------------------------
 LICENSE                                         |    6 +
 NOTICE                                          |   10 +
 geode-assembly/build.gradle                     |    7 +-
 geode-assembly/src/main/dist/LICENSE            |    5 +
 geode-assembly/src/src/dist/gradlew             |  221 ++
 .../management/internal/AgentUtilJUnitTest.java |   52 +-
 .../cache/FailedSynchronizationException.java   |   10 +-
 .../cache/client/internal/AbstractOp.java       |    2 +-
 .../cache/client/internal/AddPDXEnumOp.java     |    2 +-
 .../cache/client/internal/AddPDXTypeOp.java     |    4 +-
 .../client/internal/AuthenticateUserOp.java     |    4 +-
 .../client/internal/CloseConnectionOp.java      |    2 +-
 .../gemfire/cache/client/internal/CommitOp.java |    2 +-
 .../client/internal/GetClientPRMetaDataOp.java  |    2 +-
 .../GetClientPartitionAttributesOp.java         |    2 +-
 .../cache/client/internal/GetEventValueOp.java  |    2 +-
 .../client/internal/GetFunctionAttributeOp.java |    2 +-
 .../cache/client/internal/GetPDXEnumByIdOp.java |    4 +-
 .../cache/client/internal/GetPDXEnumsOp.java    |    2 +-
 .../client/internal/GetPDXIdForEnumOp.java      |    4 +-
 .../client/internal/GetPDXIdForTypeOp.java      |    4 +-
 .../cache/client/internal/GetPDXTypeByIdOp.java |    4 +-
 .../cache/client/internal/GetPDXTypesOp.java    |    2 +-
 .../cache/client/internal/MakePrimaryOp.java    |    2 +-
 .../gemfire/cache/client/internal/PingOp.java   |    2 +-
 .../cache/client/internal/PrimaryAckOp.java     |    2 +-
 .../client/internal/ProxyCacheCloseOp.java      |    2 +-
 .../cache/client/internal/ReadyForEventsOp.java |    2 +-
 .../internal/RegisterDataSerializersOp.java     |    2 +-
 .../internal/RegisterInstantiatorsOp.java       |    2 +-
 .../cache/client/internal/RollbackOp.java       |    2 +-
 .../gemfire/cache/client/internal/SizeOp.java   |    2 +-
 .../cache/client/internal/TXFailoverOp.java     |    2 +-
 .../client/internal/TXSynchronizationOp.java    |    2 +-
 .../cache/hdfs/internal/cardinality/Bits.java   |   54 -
 .../cardinality/CardinalityMergeException.java  |   42 -
 .../hdfs/internal/cardinality/HyperLogLog.java  |  313 ---
 .../hdfs/internal/cardinality/IBuilder.java     |   41 -
 .../hdfs/internal/cardinality/ICardinality.java |   87 -
 .../hdfs/internal/cardinality/MurmurHash.java   |  261 ---
 .../hdfs/internal/cardinality/RegisterSet.java  |  136 --
 .../hdfs/internal/hoplog/AbstractHoplog.java    |    2 +-
 .../hdfs/internal/hoplog/HFileSortedOplog.java  |    4 +-
 .../hoplog/HdfsSortedOplogOrganizer.java        |    8 +-
 .../cache/hdfs/internal/hoplog/Hoplog.java      |    3 +-
 .../internal/hoplog/SequenceFileHoplog.java     |    2 +-
 .../query/internal/index/IndexElemArray.java    |   94 +-
 .../query/internal/index/IndexManager.java      |    5 +-
 .../index/PrimaryKeyIndexCreationHelper.java    |   25 +-
 .../gemfire/distributed/LocatorLauncher.java    |    7 +-
 .../gemfire/distributed/ServerLauncher.java     |   12 +-
 .../gemfire/distributed/internal/DMStats.java   |    3 +
 .../distributed/internal/DistributionStats.java |   14 +
 .../internal/InternalDistributedSystem.java     |   53 +-
 .../internal/LonerDistributionManager.java      |    4 +
 .../membership/InternalDistributedMember.java   |    2 +-
 .../gms/messenger/JGroupsMessenger.java         |  105 +-
 .../gms/mgr/GMSMembershipManager.java           |    9 +-
 .../gemfire/internal/cache/BucketAdvisor.java   |    2 +-
 .../gemfire/internal/cache/BucketRegion.java    |   26 +-
 .../gemfire/internal/cache/CacheServerImpl.java |   11 +
 .../internal/cache/CacheServerLauncher.java     |    4 +-
 .../internal/cache/DistributedRegion.java       |   22 +-
 .../gemfire/internal/cache/EntryEventImpl.java  |    7 +
 .../gemfire/internal/cache/EventTracker.java    |   11 +-
 .../internal/cache/GemFireCacheImpl.java        |    0
 .../gemfire/internal/cache/TXManagerImpl.java   |    2 +-
 .../cache/tier/sockets/BaseCommand.java         |    2 +-
 .../cache/tier/sockets/CacheClientProxy.java    |    2 +
 .../cache/tier/sockets/CacheServerHelper.java   |   46 +-
 .../internal/cache/tier/sockets/Message.java    |  236 +-
 .../internal/cache/tier/sockets/Part.java       |    9 +-
 .../command/ExecuteRegionFunction66.java        |    9 +-
 .../cache/xmlcache/AsyncEventQueueCreation.java |    1 +
 .../internal/cache/xmlcache/CacheCreation.java  |    9 +-
 .../cache/xmlcache/CacheXmlGenerator.java       |   37 +-
 .../com/gemstone/gemfire/internal/hll/Bits.java |   48 +
 .../internal/hll/CardinalityMergeException.java |   26 +
 .../gemfire/internal/hll/HyperLogLog.java       |  345 +++
 .../gemfire/internal/hll/HyperLogLogPlus.java   | 1053 +++++++++
 .../gemstone/gemfire/internal/hll/IBuilder.java |   24 +
 .../gemfire/internal/hll/ICardinality.java      |   72 +
 .../gemfire/internal/hll/MurmurHash.java        |  245 ++
 .../gemfire/internal/hll/RegisterSet.java       |  110 +
 .../gemfire/internal/redis/RegionProvider.java  |    2 +-
 .../internal/redis/executor/hll/Bits.java       |   65 -
 .../executor/hll/CardinalityMergeException.java |   42 -
 .../redis/executor/hll/HyperLogLog.java         |  360 ---
 .../redis/executor/hll/HyperLogLogPlus.java     | 1068 ---------
 .../internal/redis/executor/hll/IBuilder.java   |   41 -
 .../redis/executor/hll/ICardinality.java        |   89 -
 .../internal/redis/executor/hll/MurmurHash.java |  234 --
 .../redis/executor/hll/PFAddExecutor.java       |    1 +
 .../redis/executor/hll/PFCountExecutor.java     |    2 +
 .../redis/executor/hll/PFMergeExecutor.java     |    2 +
 .../redis/executor/hll/RegisterSet.java         |  126 -
 .../gemfire/internal/tcp/Connection.java        |    5 +-
 .../gemfire/redis/GemFireRedisServer.java       |    2 +-
 .../cache/CacheRegionClearStatsDUnitTest.java   |   38 +-
 .../cache/ClientServerTimeSyncDUnitTest.java    |    4 +-
 .../internal/AutoConnectionSourceDUnitTest.java |    2 +-
 .../CacheServerSSLConnectionDUnitTest.java      |   44 +-
 .../internal/LocatorLoadBalancingDUnitTest.java |   15 +-
 .../cache/client/internal/LocatorTestBase.java  |    6 +-
 .../internal/SSLNoClientAuthDUnitTest.java      |   14 +-
 .../management/MemoryThresholdsDUnitTest.java   |   10 +-
 .../MemoryThresholdsOffHeapDUnitTest.java       |   10 +-
 .../query/dunit/PdxStringQueryDUnitTest.java    |   42 +-
 .../dunit/QueryDataInconsistencyDUnitTest.java  |   12 +-
 .../QueryUsingFunctionContextDUnitTest.java     |   41 +-
 .../query/dunit/QueryUsingPoolDUnitTest.java    |   32 +-
 .../cache/query/dunit/RemoteQueryDUnitTest.java |   18 +-
 ...ueryFromClauseCanonicalizationJUnitTest.java |    7 -
 .../query/internal/ResultsBagJUnitTest.java     |    7 -
 ...rrentIndexInitOnOverflowRegionDUnitTest.java |    3 +-
 .../query/internal/index/IndexUseJUnitTest.java |  452 +---
 .../index/PutAllWithIndexPerfDUnitTest.java     |    2 +-
 .../gemfire/cache30/Bug34387DUnitTest.java      |    2 +-
 .../gemfire/cache30/CacheMapTxnDUnitTest.java   |   20 +-
 .../cache30/CachedAllEventsDUnitTest.java       |    2 +-
 .../gemfire/cache30/CallbackArgDUnitTest.java   |    2 +-
 .../cache30/ClearMultiVmCallBkDUnitTest.java    |   18 +-
 .../gemfire/cache30/ClearMultiVmDUnitTest.java  |   22 +-
 .../cache30/ClientMembershipDUnitTest.java      |   30 +-
 .../ClientRegisterInterestDUnitTest.java        |    9 +-
 .../cache30/DistAckMapMethodsDUnitTest.java     |   52 +-
 .../DistributedNoAckRegionCCEDUnitTest.java     |   28 +-
 .../gemfire/cache30/MultiVMRegionTestCase.java  |   68 +-
 .../cache30/PartitionedRegionDUnitTest.java     |    2 +-
 .../gemfire/cache30/ProxyDUnitTest.java         |    2 +-
 .../cache30/PutAllCallBkRemoteVMDUnitTest.java  |    8 +-
 .../cache30/PutAllCallBkSingleVMDUnitTest.java  |   10 +-
 .../gemfire/cache30/PutAllMultiVmDUnitTest.java |    8 +-
 .../gemfire/cache30/ReconnectDUnitTest.java     |    6 +-
 .../ReconnectedCacheServerDUnitTest.java        |   27 +
 .../RegionMembershipListenerDUnitTest.java      |    2 +-
 .../cache30/RegionReliabilityTestCase.java      |   21 +-
 .../cache30/RemoveAllMultiVmDUnitTest.java      |    8 +-
 .../cache30/RolePerformanceDUnitTest.java       |    3 +-
 .../gemfire/cache30/SearchAndLoadDUnitTest.java |    4 +-
 .../gemfire/cache30/TXDistributedDUnitTest.java |   12 +-
 .../gemfire/cache30/TXOrderDUnitTest.java       |    2 +-
 .../gemfire/distributed/LocatorDUnitTest.java   |   59 +-
 .../distributed/LocatorLauncherJUnitTest.java   |   27 +-
 .../LocatorLauncherLocalJUnitTest.java          |    4 +-
 .../LocatorLauncherRemoteJUnitTest.java         |    2 +-
 .../distributed/ServerLauncherJUnitTest.java    |   26 +-
 .../ServerLauncherLocalJUnitTest.java           |    4 +-
 .../ServerLauncherRemoteJUnitTest.java          |    2 +-
 .../ConsoleDistributionManagerDUnitTest.java    |    7 +-
 .../messenger/JGroupsMessengerJUnitTest.java    |   86 +-
 .../gemfire/disttx/CacheMapDistTXDUnitTest.java |    8 +-
 .../gemfire/disttx/DistTXDebugDUnitTest.java    |   20 +-
 .../disttx/DistributedTransactionDUnitTest.java |    3 +-
 .../internal/cache/BucketRegionJUnitTest.java   |  208 ++
 .../internal/cache/Bug33359DUnitTest.java       |    8 +-
 .../internal/cache/Bug33726DUnitTest.java       |   10 +-
 .../internal/cache/Bug37241DUnitTest.java       |   26 +-
 .../internal/cache/Bug39079DUnitTest.java       |   21 +-
 .../internal/cache/Bug41733DUnitTest.java       |    2 +-
 .../internal/cache/ClearDAckDUnitTest.java      |   26 +-
 .../internal/cache/ClearGlobalDUnitTest.java    |    6 +-
 .../cache/DeltaPropagationDUnitTest.java        |  324 ++-
 .../cache/DeltaPropagationStatsDUnitTest.java   |  120 +-
 .../cache/DiskRegByteArrayDUnitTest.java        |   14 +-
 .../cache/DistributedCacheTestCase.java         |    5 +-
 .../internal/cache/EventTrackerDUnitTest.java   |    6 +-
 .../internal/cache/EvictionStatsDUnitTest.java  |   12 +-
 .../internal/cache/EvictionTestBase.java        |    9 +-
 .../cache/FixedPRSinglehopDUnitTest.java        |  140 +-
 .../internal/cache/GIIDeltaDUnitTest.java       |   84 +-
 .../internal/cache/HABug36773DUnitTest.java     |  370 ---
 .../HAOverflowMemObjectSizerDUnitTest.java      |   54 +-
 .../internal/cache/MapClearGIIDUnitTest.java    |   17 +-
 .../cache/P2PDeltaPropagationDUnitTest.java     |  105 +-
 .../PartitionedRegionCreationDUnitTest.java     |    2 +-
 .../PartitionedRegionSingleHopDUnitTest.java    |  460 ++--
 ...RegionSingleHopWithServerGroupDUnitTest.java |  243 +-
 .../internal/cache/PutAllDAckDUnitTest.java     |   12 +-
 .../internal/cache/PutAllGlobalDUnitTest.java   |   12 +-
 .../internal/cache/RemoveAllDAckDUnitTest.java  |   12 +-
 .../internal/cache/RemoveDAckDUnitTest.java     |   10 +-
 .../internal/cache/RemoveGlobalDUnitTest.java   |   12 +-
 .../internal/cache/SingleHopStatsDUnitTest.java |   60 +-
 .../internal/cache/SystemFailureDUnitTest.java  |    4 +-
 .../control/RebalanceOperationDUnitTest.java    |    6 +-
 .../cache/execute/Bug51193DUnitTest.java        |   18 +-
 .../ClientServerFunctionExecutionDUnitTest.java |  148 +-
 .../execute/ColocationFailoverDUnitTest.java    |   43 +-
 ...ributedRegionFunctionExecutionDUnitTest.java |  875 +++----
 .../cache/execute/LocalDataSetDUnitTest.java    |   26 +-
 .../LocalFunctionExecutionDUnitTest.java        |   16 +-
 .../MemberFunctionExecutionDUnitTest.java       |   59 +-
 .../MultiRegionFunctionExecutionDUnitTest.java  |    8 +-
 ...ntServerFunctionExecutionNoAckDUnitTest.java |   20 +-
 ...tServerRegionFunctionExecutionDUnitTest.java |  102 +-
 ...egionFunctionExecutionFailoverDUnitTest.java |  236 +-
 ...onFunctionExecutionNoSingleHopDUnitTest.java |  176 +-
 ...onExecutionSelectorNoSingleHopDUnitTest.java |  164 +-
 ...gionFunctionExecutionSingleHopDUnitTest.java |  132 +-
 .../cache/execute/PRClientServerTestBase.java   |  155 +-
 .../cache/execute/PRColocationDUnitTest.java    |  219 +-
 .../execute/PRCustomPartitioningDUnitTest.java  |    8 +-
 .../execute/PRFunctionExecutionDUnitTest.java   |    8 +-
 .../execute/PRPerformanceTestDUnitTest.java     |    8 +-
 .../cache/execute/PRTransactionDUnitTest.java   |   50 +-
 .../execute/SingleHopGetAllPutAllDUnitTest.java |    6 +-
 .../cache/ha/Bug36853EventsExpiryDUnitTest.java |   17 +-
 .../internal/cache/ha/Bug48571DUnitTest.java    |   22 +-
 .../internal/cache/ha/Bug48879DUnitTest.java    |   20 +-
 .../cache/ha/EventIdOptimizationDUnitTest.java  |   44 +-
 .../internal/cache/ha/FailoverDUnitTest.java    |   18 +-
 .../internal/cache/ha/HABugInPutDUnitTest.java  |   28 +-
 .../internal/cache/ha/HAClearDUnitTest.java     |   41 +-
 .../cache/ha/HAConflationDUnitTest.java         |   18 +-
 .../internal/cache/ha/HADuplicateDUnitTest.java |   30 +-
 .../cache/ha/HAEventIdPropagationDUnitTest.java |  107 +-
 .../internal/cache/ha/HAExpiryDUnitTest.java    |   56 +-
 .../internal/cache/ha/HAGIIBugDUnitTest.java    |   12 +-
 .../internal/cache/ha/HAGIIDUnitTest.java       |   37 +-
 .../cache/ha/HARQueueNewImplDUnitTest.java      |  440 ++--
 .../internal/cache/ha/HARegionDUnitTest.java    |   68 +-
 .../cache/ha/HARegionQueueDUnitTest.java        |   83 +-
 .../cache/ha/HASlowReceiverDUnitTest.java       |   32 +-
 .../ha/OperationsPropagationDUnitTest.java      |   36 +-
 .../internal/cache/ha/PutAllDUnitTest.java      |   59 +-
 .../internal/cache/ha/StatsBugDUnitTest.java    |   28 +-
 .../cache/locks/TXLockServiceDUnitTest.java     |   28 +-
 .../cache/partitioned/Bug43684DUnitTest.java    |   38 +-
 .../cache/partitioned/Bug47388DUnitTest.java    |   29 +-
 .../cache/partitioned/Bug51400DUnitTest.java    |   23 +-
 .../PartitionedRegionLoaderWriterDUnitTest.java |   54 +-
 .../fixed/FixedPartitioningDUnitTest.java       | 1251 +++++-----
 .../fixed/FixedPartitioningTestBase.java        |   10 +-
 ...ngWithColocationAndPersistenceDUnitTest.java | 1368 +++++------
 .../internal/cache/tier/Bug40396DUnitTest.java  |   21 +-
 ...mpatibilityHigherVersionClientDUnitTest.java |   31 +-
 .../cache/tier/sockets/Bug36269DUnitTest.java   |   14 +-
 .../cache/tier/sockets/Bug36457DUnitTest.java   |   31 +-
 .../cache/tier/sockets/Bug36805DUnitTest.java   |   34 +-
 .../cache/tier/sockets/Bug36829DUnitTest.java   |   23 +-
 .../cache/tier/sockets/Bug36995DUnitTest.java   |   35 +-
 .../cache/tier/sockets/Bug37210DUnitTest.java   |   22 +-
 .../cache/tier/sockets/Bug37805DUnitTest.java   |   16 +-
 .../CacheServerTransactionsDUnitTest.java       |  222 +-
 .../tier/sockets/ClearPropagationDUnitTest.java |   48 +-
 .../tier/sockets/ClientConflationDUnitTest.java |   30 +-
 .../sockets/ClientInterestNotifyDUnitTest.java  |   88 +-
 .../tier/sockets/ClientServerMiscDUnitTest.java |   35 +-
 .../cache/tier/sockets/ConflationDUnitTest.java |  106 +-
 .../DataSerializerPropogationDUnitTest.java     |  337 ++-
 .../DestroyEntryPropagationDUnitTest.java       |   96 +-
 .../DurableClientQueueSizeDUnitTest.java        |  106 +-
 .../DurableClientReconnectDUnitTest.java        |   40 +-
 .../sockets/DurableClientStatsDUnitTest.java    |   72 +-
 .../sockets/DurableRegistrationDUnitTest.java   |  335 +--
 .../sockets/DurableResponseMatrixDUnitTest.java |   86 +-
 .../sockets/EventIDVerificationDUnitTest.java   |   71 +-
 .../EventIDVerificationInP2PDUnitTest.java      |   51 +-
 .../cache/tier/sockets/HABug36738DUnitTest.java |   18 +-
 .../tier/sockets/HAInterestPart1DUnitTest.java  |  100 +-
 .../tier/sockets/HAInterestPart2DUnitTest.java  |  114 +-
 .../cache/tier/sockets/HAInterestTestCase.java  |   32 +-
 .../sockets/HAStartupAndFailoverDUnitTest.java  |  108 +-
 .../InstantiatorPropagationDUnitTest.java       |  236 +-
 .../tier/sockets/InterestListDUnitTest.java     |  300 +--
 .../sockets/InterestListEndpointDUnitTest.java  |   66 +-
 .../sockets/InterestListFailoverDUnitTest.java  |   50 +-
 .../sockets/InterestListRecoveryDUnitTest.java  |   26 +-
 .../sockets/InterestRegrListenerDUnitTest.java  |   82 +-
 .../sockets/InterestResultPolicyDUnitTest.java  |   35 +-
 .../cache/tier/sockets/MessageJUnitTest.java    |   75 +
 .../sockets/NewRegionAttributesDUnitTest.java   |   28 +-
 .../sockets/RedundancyLevelPart1DUnitTest.java  |   36 +-
 .../sockets/RedundancyLevelPart2DUnitTest.java  |   67 +-
 .../sockets/RedundancyLevelPart3DUnitTest.java  |  100 +-
 .../tier/sockets/RedundancyLevelTestBase.java   |   20 +-
 .../tier/sockets/RegionCloseDUnitTest.java      |   20 +-
 ...erInterestBeforeRegionCreationDUnitTest.java |   20 +-
 .../sockets/RegisterInterestKeysDUnitTest.java  |   32 +-
 .../sockets/ReliableMessagingDUnitTest.java     |   22 +-
 .../sockets/UnregisterInterestDUnitTest.java    |   62 +-
 .../sockets/UpdatePropagationDUnitTest.java     |   91 +-
 .../sockets/UpdatePropagationPRDUnitTest.java   |    3 -
 .../VerifyEventIDGenerationInP2PDUnitTest.java  |   13 +-
 ...UpdatesFromNonInterestEndPointDUnitTest.java |   29 +-
 .../cache/wan/AsyncEventQueueTestBase.java      |  233 +-
 .../asyncqueue/AsyncEventListenerDUnitTest.java | 2185 +++++++-----------
 .../AsyncEventQueueStatsDUnitTest.java          |  321 ++-
 .../ConcurrentAsyncEventQueueDUnitTest.java     |  354 ++-
 .../CommonParallelAsyncEventQueueDUnitTest.java |   15 +-
 .../internal/jta/dunit/ExceptionsDUnitTest.java |   10 +-
 .../jta/dunit/IdleTimeOutDUnitTest.java         |    7 +-
 .../jta/dunit/LoginTimeOutDUnitTest.java        |    8 +-
 .../jta/dunit/MaxPoolSizeDUnitTest.java         |    5 +-
 .../jta/dunit/TransactionTimeOutDUnitTest.java  |   24 +-
 .../dunit/TxnManagerMultiThreadDUnitTest.java   |   14 +-
 .../internal/jta/dunit/TxnTimeOutDUnitTest.java |    9 +-
 .../internal/offheap/FragmentJUnitTest.java     |  280 +++
 .../statistics/StatisticsDUnitTest.java         |   11 +-
 .../management/CacheManagementDUnitTest.java    |   16 +-
 .../management/ClientHealthStatsDUnitTest.java  |   58 +-
 .../gemfire/management/QueryDataDUnitTest.java  |   20 +-
 ...ersalMembershipListenerAdapterDUnitTest.java |   54 +-
 .../cli/commands/FunctionCommandsDUnitTest.java |    4 +-
 .../commands/GemfireDataCommandsDUnitTest.java  |    4 +-
 ...WithCacheLoaderDuringCacheMissDUnitTest.java |    8 +-
 ...stAndDescribeDiskStoreCommandsDUnitTest.java |    4 +-
 .../cli/commands/ListIndexCommandDUnitTest.java |    8 +-
 .../MiscellaneousCommandsDUnitTest.java         |    6 +-
 ...laneousCommandsExportLogsPart3DUnitTest.java |    2 +-
 .../internal/pulse/TestFunctionsDUnitTest.java  |    3 +-
 .../internal/pulse/TestHeapDUnitTest.java       |    5 +-
 .../internal/pulse/TestLocatorsDUnitTest.java   |    3 +-
 .../web/controllers/RestAPITestBase.java        |    8 +-
 .../security/ClientAuthenticationDUnitTest.java |  502 ++--
 .../security/ClientAuthorizationDUnitTest.java  |  272 ++-
 .../security/ClientAuthorizationTestBase.java   |   23 +-
 .../security/ClientMultiUserAuthzDUnitTest.java |   52 +-
 .../DeltaClientAuthorizationDUnitTest.java      |   69 +-
 .../DeltaClientPostAuthorizationDUnitTest.java  |   40 +-
 .../security/P2PAuthenticationDUnitTest.java    |  127 +-
 .../gemfire/test/dunit/AsyncInvocation.java     |    4 +-
 .../gemfire/test/dunit/IgnoredException.java    |   12 +-
 .../gemfire/test/dunit/RMIException.java        |    2 +-
 .../test/dunit/SerializableRunnableIF.java      |    3 +-
 .../com/gemstone/gemfire/test/dunit/VM.java     |  927 +-------
 .../gemfire/test/dunit/rules/RemoteInvoker.java |    6 +-
 .../test/dunit/tests/BasicDUnitTest.java        |   12 +-
 .../gemfire/test/dunit/tests/VMDUnitTest.java   |   51 +-
 .../gemfire/codeAnalysis/excludedClasses.txt    |    3 +
 .../codeAnalysis/sanctionedSerializables.txt    |   23 +-
 .../cache/query/cq/dunit/CqDataDUnitTest.java   |   33 +-
 .../cq/dunit/CqDataUsingPoolDUnitTest.java      |   91 +-
 .../cache/query/cq/dunit/CqPerfDUnitTest.java   |   19 +-
 .../cq/dunit/CqPerfUsingPoolDUnitTest.java      |   17 +-
 .../cache/query/cq/dunit/CqQueryDUnitTest.java  |   94 +-
 .../dunit/CqQueryOptimizedExecuteDUnitTest.java |   12 +-
 .../cq/dunit/CqQueryUsingPoolDUnitTest.java     |   49 +-
 .../cq/dunit/CqResultSetUsingPoolDUnitTest.java |   34 +-
 ...ltSetUsingPoolOptimizedExecuteDUnitTest.java |    4 +-
 .../cache/query/cq/dunit/CqStatsDUnitTest.java  |    4 +-
 .../cq/dunit/CqStatsUsingPoolDUnitTest.java     |    4 +-
 .../PartitionedRegionCqQueryDUnitTest.java      |   34 +-
 ...dRegionCqQueryOptimizedExecuteDUnitTest.java |    6 +-
 .../query/cq/dunit/PrCqUsingPoolDUnitTest.java  |   28 +-
 .../cache/query/dunit/PdxQueryCQDUnitTest.java  |   14 +-
 .../cache/query/dunit/PdxQueryCQTestBase.java   |    2 +-
 .../dunit/QueryIndexUpdateRIDUnitTest.java      |   24 +-
 .../query/dunit/QueryMonitorDUnitTest.java      |    7 +-
 .../cache/PRDeltaPropagationDUnitTest.java      |  192 +-
 .../internal/cache/ha/CQListGIIDUnitTest.java   |  138 +-
 .../cache/ha/HADispatcherDUnitTest.java         |   50 +-
 .../sockets/ClientToServerDeltaDUnitTest.java   |  282 +--
 .../DeltaPropagationWithCQDUnitTest.java        |   41 +-
 ...ToRegionRelationCQRegistrationDUnitTest.java |  144 +-
 .../sockets/DurableClientCrashDUnitTest.java    |    4 +-
 .../sockets/DurableClientNetDownDUnitTest.java  |   10 +-
 .../sockets/DurableClientSimpleDUnitTest.java   |  442 ++--
 .../tier/sockets/DurableClientTestCase.java     |  206 +-
 .../CacheServerManagementDUnitTest.java         |    3 +-
 .../cli/commands/ClientCommandsDUnitTest.java   |    8 +-
 .../DurableClientCommandsDUnitTest.java         |    6 +-
 .../internal/pulse/TestCQDUnitTest.java         |    6 +-
 .../internal/pulse/TestClientsDUnitTest.java    |    6 +-
 .../internal/pulse/TestServerDUnitTest.java     |    3 +-
 .../ClientAuthorizationTwoDUnitTest.java        |   20 +-
 .../security/ClientAuthzObjectModDUnitTest.java |   23 +-
 .../ClientCQPostAuthorizationDUnitTest.java     |   62 +-
 .../ClientPostAuthorizationDUnitTest.java       |   49 +-
 .../gemfire/security/MultiuserAPIDUnitTest.java |   41 +-
 .../MultiuserDurableCQAuthzDUnitTest.java       |   52 +-
 geode-pulse/build.gradle                        |    8 +-
 .../src/main/resources/gemfire.properties       |    4 +-
 geode-pulse/src/main/webapp/DataBrowser.html    |   52 +-
 geode-pulse/src/main/webapp/Login.html          |   46 +-
 geode-pulse/src/main/webapp/MemberDetails.html  |   35 +-
 .../src/main/webapp/QueryStatistics.html        |   31 +-
 geode-pulse/src/main/webapp/clusterDetail.html  |   36 +-
 .../src/main/webapp/css/grips/horizontal.png    |  Bin 0 -> 2753 bytes
 .../src/main/webapp/css/grips/vertical.png      |  Bin 0 -> 91 bytes
 geode-pulse/src/main/webapp/css/style.css       |   44 +-
 .../src/main/webapp/images/about-geode.png      |  Bin 0 -> 7640 bytes
 .../main/webapp/images/apache_geode_logo.png    |  Bin 0 -> 23616 bytes
 .../src/main/webapp/images/pivotal-logo.png     |  Bin 4302 -> 3500 bytes
 .../main/webapp/properties/gemfire.properties   |    4 +-
 .../webapp/properties/gemfire_en.properties     |    4 +-
 .../main/webapp/properties/gemfirexd.properties |    2 +-
 .../webapp/properties/gemfirexd_en.properties   |    2 +-
 geode-pulse/src/main/webapp/regionDetail.html   |   33 +-
 .../src/main/webapp/scripts/lib/split.js        |  375 +++
 .../scripts/pulsescript/pages/DataBrowser.js    |   13 +-
 .../client/internal/GatewaySenderBatchOp.java   |    2 +-
 .../cache/CacheXml80GatewayDUnitTest.java       |   72 +-
 .../internal/cache/UpdateVersionDUnitTest.java  |   88 +-
 .../gemfire/internal/cache/wan/WANTestBase.java |   33 +-
 ...oncurrentParallelGatewaySenderDUnitTest.java | 1164 +++++-----
 ...allelGatewaySenderOperation_1_DUnitTest.java | 1063 +++++----
 ...allelGatewaySenderOperation_2_DUnitTest.java |   63 +-
 .../ConcurrentWANPropogation_1_DUnitTest.java   |  644 +++---
 .../ConcurrentWANPropogation_2_DUnitTest.java   |  699 +++---
 .../cache/wan/disttx/DistTXWANDUnitTest.java    |  258 +--
 .../CommonParallelGatewaySenderDUnitTest.java   |  459 ++--
 ...wWANConcurrencyCheckForDestroyDUnitTest.java |  168 +-
 .../cache/wan/misc/PDXNewWanDUnitTest.java      |  744 +++---
 ...dRegion_ParallelWANPersistenceDUnitTest.java |  767 +++---
 ...dRegion_ParallelWANPropogationDUnitTest.java | 1014 ++++----
 .../SenderWithTransportFilterDUnitTest.java     |   66 +-
 ...downAllPersistentGatewaySenderDUnitTest.java |   48 +-
 .../wan/misc/WANLocatorServerDUnitTest.java     |   40 +-
 .../cache/wan/misc/WANSSLDUnitTest.java         |   98 +-
 .../wan/misc/WanAutoDiscoveryDUnitTest.java     |  284 +--
 .../cache/wan/misc/WanValidationsDUnitTest.java | 1594 ++++++-------
 ...arallelGatewaySenderOperationsDUnitTest.java |  273 ++-
 ...llelGatewaySenderQueueOverflowDUnitTest.java |  476 ++--
 ...ersistenceEnabledGatewaySenderDUnitTest.java | 1851 +++++++--------
 ...llelWANPropagationClientServerDUnitTest.java |   94 +-
 ...lelWANPropagationConcurrentOpsDUnitTest.java |  264 ++-
 .../ParallelWANPropagationDUnitTest.java        | 2015 ++++++++--------
 ...ParallelWANPropagationLoopBackDUnitTest.java |  438 ++--
 .../wan/parallel/ParallelWANStatsDUnitTest.java |  366 ++-
 ...tewaySenderDistributedDeadlockDUnitTest.java |  171 +-
 ...rialGatewaySenderEventListenerDUnitTest.java |  312 ++-
 .../SerialGatewaySenderOperationsDUnitTest.java |   26 +-
 .../SerialGatewaySenderQueueDUnitTest.java      |  224 +-
 ...ersistenceEnabledGatewaySenderDUnitTest.java |  707 +++---
 .../SerialWANPropagationLoopBackDUnitTest.java  |  547 ++---
 .../serial/SerialWANPropogationDUnitTest.java   | 1674 +++++++-------
 ...NPropogation_PartitionedRegionDUnitTest.java |  693 +++---
 .../SerialWANPropogationsFeatureDUnitTest.java  |  562 +++--
 .../wan/serial/SerialWANStatsDUnitTest.java     |  733 +++---
 .../wan/wancommand/WANCommandTestBase.java      |   16 +-
 ...anCommandCreateGatewayReceiverDUnitTest.java |  274 +--
 .../WanCommandCreateGatewaySenderDUnitTest.java |  302 +--
 ...WanCommandGatewayReceiverStartDUnitTest.java |  171 +-
 .../WanCommandGatewayReceiverStopDUnitTest.java |  175 +-
 .../WanCommandGatewaySenderStartDUnitTest.java  |  289 ++-
 .../WanCommandGatewaySenderStopDUnitTest.java   |  273 +--
 .../wan/wancommand/WanCommandListDUnitTest.java |  172 +-
 .../WanCommandPauseResumeDUnitTest.java         |  630 +++--
 .../wancommand/WanCommandStatusDUnitTest.java   |  234 +-
 .../management/WANManagementDUnitTest.java      |  108 +-
 .../pulse/TestRemoteClusterDUnitTest.java       |   46 +-
 443 files changed, 23025 insertions(+), 29264 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-assembly/build.gradle
----------------------------------------------------------------------
diff --cc geode-assembly/build.gradle
index 2c7e365,0000000..2a46147
mode 100755,000000..100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@@ -1,340 -1,0 +1,345 @@@
 +/*
 + * 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.
 + */
 +import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact;
 +
 +apply plugin: 'distribution'
 +
 +// disable artifact generation for this project
 +jar.enabled = false
 +extraArchive {
 +  sources = false
 +  javadoc = false
 +  tests = false
 +}
 +
 +disableMavenPublishing()
 +
 +// Gradle doesn't automatically remove the jar artifact even though we disabled it
 +// this causes publishing to fail.  So we nuke all the disabled artifacts from all configurations.
 +configurations.all {
 +  artifacts.removeAll artifacts.findAll { it instanceof ArchivePublishArtifact && !it.archiveTask.enabled }
 +}
 +
 +gradle.taskGraph.whenReady( { graph ->
 +  tasks.withType(Tar).each { tar ->
 +    tar.compression = Compression.GZIP
 +    tar.extension = 'tar.gz'
 +  }
 +})
 +
 +dependencies {
 +  provided project(':geode-core')
 +  
 +  archives project(':geode-common')  
 +  archives project(':geode-json')  
 +  archives project(':geode-joptsimple')  
 +  archives project(':geode-core')  
 +  archives project(':geode-lucene')
 +  archives project(':geode-web')
 +  archives project(':geode-web-api')
 +  archives project(':geode-pulse')
 +  archives project(':geode-wan')
 +  archives project(':geode-cq')
 +
 +  testCompile project(':geode-junit')
 +  testCompile project(path: ':geode-core', configuration: 'testOutput')
 +
 +  testRuntime files("${System.getProperty('java.home')}/../lib/tools.jar")
 +}
 +
 +sourceSets {
 +  // need to remove this since we use the dependencies jar out of the install dir
 +  //test.runtimeClasspath -= configurations.provided
 +}
 +
 +test {
 +  // test from the actual classpath not the gradle classpath
 +  dependsOn installDist
 +  // @TODO: this doesn't seem to be working need to get basename first.
 +  classpath += files "$buildDir/install/apache-geode/lib/geode-dependencies.jar"
 +}
 +
 +tasks.withType(Test){
 +  environment 'GEMFIRE', "$buildDir/install/${distributions.main.baseName}/lib"
 +}
 +
 +task defaultDistributionConfig(type: JavaExec, dependsOn: classes) {
 +  outputs.file file("$buildDir/gemfire.properties")
 +  main 'com.gemstone.gemfire.distributed.internal.DistributionConfigImpl'
 +  classpath project(':geode-core').sourceSets.main.runtimeClasspath
 +  workingDir buildDir
 +  
 +  doFirst {
 +    buildDir.mkdirs()
 +  }
 +}
 +
 +task defaultCacheConfig(type: JavaExec, dependsOn: classes) {
 +  outputs.file file("$buildDir/cache.xml")
 +  main 'com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator'
 +  classpath project(':geode-core').sourceSets.main.runtimeClasspath
 +  workingDir buildDir
 +
 +  doFirst {
 +    buildDir.mkdirs()
 +  }
 +}
 +
 +// This closure sets the gemfire classpath.  If we add another jar to the classpath it must
 +// be included in the filter logic below.
 +def cp = {
 +  // first add all the dependent project jars
 +  def jars = configurations.archives.dependencies.collect { it.dependencyProject }
 +    .findAll { !it.name.contains('web') }
 +    .collect { it.jar.archiveName }
 +    .join(' ')
 +
 +  // then add all the dependencies of the dependent jars
 +  jars += ' ' + configurations.archives.dependencies.collect { 
 +    it.dependencyProject.configurations.runtime.collect { it.getName() }.findAll {
 +      // depedencies from geode-core
 +      it.contains('antlr') ||
 +      it.contains('commons-io') ||
 +      it.contains('commons-lang') ||
 +      it.contains('commons-logging') ||
 +      it.contains('fastutil') ||
 +      it.contains('jackson-annotations') ||
 +      it.contains('jackson-core') ||
 +      it.contains('jackson-databind') ||
 +      it.contains('jansi') ||
 +      it.contains('javax.resource-api') ||
 +      it.contains('javax.servlet-api') ||
 +      it.contains('javax.transaction-api') ||
 +      it.contains('jetty-http') ||
 +      it.contains('jetty-io') ||
 +      it.contains('jetty-security') ||
 +      it.contains('jetty-server') ||
 +      it.contains('jetty-servlet') ||
 +      it.contains('jetty-webapp') ||
 +      it.contains('jetty-util') ||
 +      it.contains('jetty-xml') ||
 +      it.contains('jline') ||
 +      it.contains('jna') ||
 +      it.contains('log4j-api') ||
 +      it.contains('log4j-core') ||
 +      it.contains('log4j-jcl') ||
 +      it.contains('log4j-jul') ||
 +      it.contains('log4j-slf4j-impl') ||
 +      it.contains('slf4j-api') ||
 +      it.contains('spring-core') ||
 +      it.contains('spring-shell') ||
 +      it.contains('snappy-java') ||
 +      it.contains('hbase') ||
 +      it.contains('jgroups') ||
 +      it.contains('netty') ||
 +      
 +      // dependencies from geode-lucene
 +      it.contains('lucene-analyzers-common') ||
 +      it.contains('lucene-core') ||
 +      it.contains('lucene-queries') ||
 +      it.contains('lucene-queryparser')
 +    }
 +  }.flatten().unique().join(' ')
 +
 +  return jars
 +}
 +
 +// Note: this dependency doesn't work if you change a library version from
 +// a dependent project.  Please fix me.
 +task depsJar (type: Jar, dependsOn: ':geode-core:classes') {
 +  description 'Assembles the jar archive that defines the gemfire classpath.'
 +  archiveName 'geode-dependencies.jar'
 +  doFirst {
 +    manifest { 
 +      attributes("Class-Path": cp())
 +    }
 +  }
 +}
 +
 +// Note: this dependency doesn't work if you change a library version from
 +// a dependent project.  Please fix me.
 +task gfshDepsJar (type: Jar, dependsOn: ':geode-core:classes') {
 +  description 'Assembles the jar archive that defines the gfsh classpath.'
 +  def springWeb = configurations.runtime.collect { it.getName() }.find { it.contains('spring-web') }
 +  archiveName 'gfsh-dependencies.jar'
 +  doFirst {
 +    manifest {
 +      attributes("Class-Path": cp() + 
 +        ' ' + project(':geode-core').webJar.archiveName +
 +        ' ' + springWeb
 +      )
 +    }
 +  }
 +}
 +
 +
 +def docsDir = file("$buildDir/javadocs")
 +task docs(type: Javadoc) {
 +    options.addStringOption('Xdoclint:none', '-quiet')
 +    options.encoding='UTF-8'
 +    source parent.subprojects*.javadoc*.source
 +    classpath = files(parent.subprojects*.javadoc*.classpath)
 +    title = "Apache Geode ${project.version}"
 +    include 'com/gemstone/gemfire/**/'
 +    exclude 'com/gemstone/gemfire/internal/**/'
 +    exclude 'com/gemstone/gemfire/**/internal/**/'
 +    exclude 'com/gemstone/gemfire/**/xml/**/'
 +    exclude 'com/gemstone/gemfire/distributed/**/util/**/'
 +    exclude 'com/gemstone/gemfire/test/**/'
 +    destinationDir = docsDir
 +}
 +
 +gradle.taskGraph.whenReady( { graph ->
 +  tasks.withType(AbstractArchiveTask).findAll {
 +    it.name.toLowerCase().contains("dist")
 +  }.each { archive ->
 +    archive.doLast {
 +      ant.checksum file:"${archive.archivePath}", algorithm:"md5"
 +      ant.checksum file:"${archive.archivePath}", algorithm:"sha-256"
 +    }
 +  }
 +})
 +
 +distributions {
 +  src {
 +    baseName = 'apache-geode-src'
 +    contents {
 +      from (rootDir) {
 +        exclude 'KEYS'
 +        exclude 'gradlew'
 +        exclude 'gradlew.bat'
 +        exclude 'gradle/wrapper/gradle-wrapper.jar'
-         exclude 'gradle/wrapper/gradle-wrapper.properties'
 +        exclude '.gradle'
 +        exclude '**/build/**'
 +        exclude '**/.project'
 +        exclude '**/.classpath'
 +        exclude '**/.settings/**'
 +        exclude '**/build-eclipse/**'
 +        exclude '.idea/**'
 +        exclude '**/*.iml'
 +        exclude '**/*.ipr'
 +        exclude '**/*.iws'
 +        exclude '**/tags'
++
++        //These directories are generated on the jenkins server by gradle
++        exclude 'caches'
++        exclude 'daemon'
++        exclude 'native'
++        exclude 'wrapper'
 +      }
 +    }
 +  }
 +
 +  main {
 +    baseName = 'apache-geode' //TODO rootProject.name
 +    contents {
 +      duplicatesStrategy 'exclude'
 +      exclude '*.asc'
 +      
 +      exclude '*.asc'
 +      exclude '*-sources.jar'
 +      exclude '*-javadoc.jar'
 +
 +      into ('config') {
 +        from defaultCacheConfig
 +        from defaultDistributionConfig
 +        from (project(':geode-core').sourceSets.main.resources.files.find {
 +          it.name == 'log4j2.xml' 
 +        })
 +      }
 +      
 +      into ('lib') {
 +        from project(":geode-common").configurations.runtime
 +        from project(":geode-common").configurations.archives.allArtifacts.files
 +
 +        from project(":geode-json").configurations.runtime
 +        from project(":geode-json").configurations.archives.allArtifacts.files
 +
 +        from project(":geode-joptsimple").configurations.runtime
 +        from project(":geode-joptsimple").configurations.archives.allArtifacts.files
 +
 +        from project(":geode-wan").configurations.runtime
 +        from project(":geode-wan").configurations.archives.allArtifacts.files
 +
 +        from project(":geode-cq").configurations.runtime
 +        from project(":geode-cq").configurations.archives.allArtifacts.files
 +
 +        from project(":geode-core").configurations.runtime
 +        // Copying from provided configuration is only for supporting Spring Data GemFire.
 +        // If there are more dependencies added to provided configuration, this will need
 +        // to change
 +        from (project(":geode-core").configurations.provided) {
 +          include 'spring-data-gemfire-*'
 +        }
 +        from project(":geode-core").configurations.archives.allArtifacts.files
 +        from project(":geode-core").webJar
 +        from project(":geode-core").raJar
 +        from project(":geode-core").jcaJar
 +        
 +        from project(":geode-lucene").configurations.runtime
 +        from project(":geode-lucene").configurations.archives.allArtifacts.files
 +
 +        // include this jar        
 +        from project(":geode-web-api").jar
 +        
 +        // dependency jars
 +        from depsJar
 +        from gfshDepsJar
 +      }
 +
 +      into ('tools/Extensions') {
 +        from (project(":geode-web").configurations.archives.allArtifacts.files) {
 +          exclude '*.jar'
 +        }
 +        from (project(":geode-web-api").configurations.archives.allArtifacts.files) {
 +          exclude '*.jar'
 +        }
 +      }
 +
 +      into ('javadoc') {
 +        from docs
 +      }
 +
 +      into ('tools/Pulse') {
 +        from (project(":geode-pulse").configurations.archives.allArtifacts.files) {
 +          exclude '*.jar'
 +        }
 +      }
 +
 +      into ('tools/Modules') {
 +        from (project(':extensions/geode-modules-assembly').configurations.moduleDistOutputs.files)
 +      }
 +    }
 +  }
 +}
 +
 +// Create a configuration closure to configure test targets with the install directory
 +def dependOnInstalledProduct = {
 +  dependsOn installDist
 +  def install = file("$buildDir/install/${distributions.main.baseName}")
 +  environment ('GEMFIRE', install)
 +}
 +
 +// Add the configuration closure to the test targets so they depend on the install directory
 +test dependOnInstalledProduct
 +distributedTest dependOnInstalledProduct
 +integrationTest dependOnInstalledProduct
 +
 +// Make build final task to generate all test and product resources
 +build.dependsOn installDist
 +
 +installDist.dependsOn ':extensions/geode-modules-assembly:dist'

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-assembly/src/main/dist/LICENSE
----------------------------------------------------------------------
diff --cc geode-assembly/src/main/dist/LICENSE
index 12ffb42,0000000..2f1374b
mode 100644,000000..100644
--- a/geode-assembly/src/main/dist/LICENSE
+++ b/geode-assembly/src/main/dist/LICENSE
@@@ -1,429 -1,0 +1,434 @@@
 +                                 Apache License
 +                           Version 2.0, January 2004
 +                        http://www.apache.org/licenses/
 +
 +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 +
 +   1. Definitions.
 +
 +      "License" shall mean the terms and conditions for use, reproduction,
 +      and distribution as defined by Sections 1 through 9 of this document.
 +
 +      "Licensor" shall mean the copyright owner or entity authorized by
 +      the copyright owner that is granting the License.
 +
 +      "Legal Entity" shall mean the union of the acting entity and all
 +      other entities that control, are controlled by, or are under common
 +      control with that entity. For the purposes of this definition,
 +      "control" means (i) the power, direct or indirect, to cause the
 +      direction or management of such entity, whether by contract or
 +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 +      outstanding shares, or (iii) beneficial ownership of such entity.
 +
 +      "You" (or "Your") shall mean an individual or Legal Entity
 +      exercising permissions granted by this License.
 +
 +      "Source" form shall mean the preferred form for making modifications,
 +      including but not limited to software source code, documentation
 +      source, and configuration files.
 +
 +      "Object" form shall mean any form resulting from mechanical
 +      transformation or translation of a Source form, including but
 +      not limited to compiled object code, generated documentation,
 +      and conversions to other media types.
 +
 +      "Work" shall mean the work of authorship, whether in Source or
 +      Object form, made available under the License, as indicated by a
 +      copyright notice that is included in or attached to the work
 +      (an example is provided in the Appendix below).
 +
 +      "Derivative Works" shall mean any work, whether in Source or Object
 +      form, that is based on (or derived from) the Work and for which the
 +      editorial revisions, annotations, elaborations, or other modifications
 +      represent, as a whole, an original work of authorship. For the purposes
 +      of this License, Derivative Works shall not include works that remain
 +      separable from, or merely link (or bind by name) to the interfaces of,
 +      the Work and Derivative Works thereof.
 +
 +      "Contribution" shall mean any work of authorship, including
 +      the original version of the Work and any modifications or additions
 +      to that Work or Derivative Works thereof, that is intentionally
 +      submitted to Licensor for inclusion in the Work by the copyright owner
 +      or by an individual or Legal Entity authorized to submit on behalf of
 +      the copyright owner. For the purposes of this definition, "submitted"
 +      means any form of electronic, verbal, or written communication sent
 +      to the Licensor or its representatives, including but not limited to
 +      communication on electronic mailing lists, source code control systems,
 +      and issue tracking systems that are managed by, or on behalf of, the
 +      Licensor for the purpose of discussing and improving the Work, but
 +      excluding communication that is conspicuously marked or otherwise
 +      designated in writing by the copyright owner as "Not a Contribution."
 +
 +      "Contributor" shall mean Licensor and any individual or Legal Entity
 +      on behalf of whom a Contribution has been received by Licensor and
 +      subsequently incorporated within the Work.
 +
 +   2. Grant of Copyright License. Subject to the terms and conditions of
 +      this License, each Contributor hereby grants to You a perpetual,
 +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 +      copyright license to reproduce, prepare Derivative Works of,
 +      publicly display, publicly perform, sublicense, and distribute the
 +      Work and such Derivative Works in Source or Object form.
 +
 +   3. Grant of Patent License. Subject to the terms and conditions of
 +      this License, each Contributor hereby grants to You a perpetual,
 +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 +      (except as stated in this section) patent license to make, have made,
 +      use, offer to sell, sell, import, and otherwise transfer the Work,
 +      where such license applies only to those patent claims licensable
 +      by such Contributor that are necessarily infringed by their
 +      Contribution(s) alone or by combination of their Contribution(s)
 +      with the Work to which such Contribution(s) was submitted. If You
 +      institute patent litigation against any entity (including a
 +      cross-claim or counterclaim in a lawsuit) alleging that the Work
 +      or a Contribution incorporated within the Work constitutes direct
 +      or contributory patent infringement, then any patent licenses
 +      granted to You under this License for that Work shall terminate
 +      as of the date such litigation is filed.
 +
 +   4. Redistribution. You may reproduce and distribute copies of the
 +      Work or Derivative Works thereof in any medium, with or without
 +      modifications, and in Source or Object form, provided that You
 +      meet the following conditions:
 +
 +      (a) You must give any other recipients of the Work or
 +          Derivative Works a copy of this License; and
 +
 +      (b) You must cause any modified files to carry prominent notices
 +          stating that You changed the files; and
 +
 +      (c) You must retain, in the Source form of any Derivative Works
 +          that You distribute, all copyright, patent, trademark, and
 +          attribution notices from the Source form of the Work,
 +          excluding those notices that do not pertain to any part of
 +          the Derivative Works; and
 +
 +      (d) If the Work includes a "NOTICE" text file as part of its
 +          distribution, then any Derivative Works that You distribute must
 +          include a readable copy of the attribution notices contained
 +          within such NOTICE file, excluding those notices that do not
 +          pertain to any part of the Derivative Works, in at least one
 +          of the following places: within a NOTICE text file distributed
 +          as part of the Derivative Works; within the Source form or
 +          documentation, if provided along with the Derivative Works; or,
 +          within a display generated by the Derivative Works, if and
 +          wherever such third-party notices normally appear. The contents
 +          of the NOTICE file are for informational purposes only and
 +          do not modify the License. You may add Your own attribution
 +          notices within Derivative Works that You distribute, alongside
 +          or as an addendum to the NOTICE text from the Work, provided
 +          that such additional attribution notices cannot be construed
 +          as modifying the License.
 +
 +      You may add Your own copyright statement to Your modifications and
 +      may provide additional or different license terms and conditions
 +      for use, reproduction, or distribution of Your modifications, or
 +      for any such Derivative Works as a whole, provided Your use,
 +      reproduction, and distribution of the Work otherwise complies with
 +      the conditions stated in this License.
 +
 +   5. Submission of Contributions. Unless You explicitly state otherwise,
 +      any Contribution intentionally submitted for inclusion in the Work
 +      by You to the Licensor shall be under the terms and conditions of
 +      this License, without any additional terms or conditions.
 +      Notwithstanding the above, nothing herein shall supersede or modify
 +      the terms of any separate license agreement you may have executed
 +      with Licensor regarding such Contributions.
 +
 +   6. Trademarks. This License does not grant permission to use the trade
 +      names, trademarks, service marks, or product names of the Licensor,
 +      except as required for reasonable and customary use in describing the
 +      origin of the Work and reproducing the content of the NOTICE file.
 +
 +   7. Disclaimer of Warranty. Unless required by applicable law or
 +      agreed to in writing, Licensor provides the Work (and each
 +      Contributor provides its Contributions) on an "AS IS" BASIS,
 +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 +      implied, including, without limitation, any warranties or conditions
 +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 +      PARTICULAR PURPOSE. You are solely responsible for determining the
 +      appropriateness of using or redistributing the Work and assume any
 +      risks associated with Your exercise of permissions under this License.
 +
 +   8. Limitation of Liability. In no event and under no legal theory,
 +      whether in tort (including negligence), contract, or otherwise,
 +      unless required by applicable law (such as deliberate and grossly
 +      negligent acts) or agreed to in writing, shall any Contributor be
 +      liable to You for damages, including any direct, indirect, special,
 +      incidental, or consequential damages of any character arising as a
 +      result of this License or out of the use or inability to use the
 +      Work (including but not limited to damages for loss of goodwill,
 +      work stoppage, computer failure or malfunction, or any and all
 +      other commercial damages or losses), even if such Contributor
 +      has been advised of the possibility of such damages.
 +
 +   9. Accepting Warranty or Additional Liability. While redistributing
 +      the Work or Derivative Works thereof, You may choose to offer,
 +      and charge a fee for, acceptance of support, warranty, indemnity,
 +      or other liability obligations and/or rights consistent with this
 +      License. However, in accepting such obligations, You may act only
 +      on Your own behalf and on Your sole responsibility, not on behalf
 +      of any other Contributor, and only if You agree to indemnify,
 +      defend, and hold each Contributor harmless for any liability
 +      incurred by, or claims asserted against, such Contributor by reason
 +      of your accepting any such warranty or additional liability.
 +
 +   END OF TERMS AND CONDITIONS
 +
 +   APPENDIX: How to apply the Apache License to your work.
 +
 +      To apply the Apache License to your work, attach the following
 +      boilerplate notice, with the fields enclosed by brackets "[]"
 +      replaced with your own identifying information. (Don't include
 +      the brackets!)  The text should be enclosed in the appropriate
 +      comment syntax for the file format. We also recommend that a
 +      file or class name and description of purpose be included on the
 +      same "printed page" as the copyright notice for easier
 +      identification within third-party archives.
 +
 +   Copyright [yyyy] [name of copyright owner]
 +
 +   Licensed under the Apache License, Version 2.0 (the "License");
 +   you may not use this file except in compliance with the License.
 +   You may obtain a copy of the License at
 +
 +       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.
 +
 +===========================================================================
 +
 +Apache Geode includes a number of components and libraries with separate 
 +copyright notices and license terms. Your use of those components are 
 +subject to the terms and conditions of the following licenses. 
 +
 +
 +---------------------------------------------------------------------------
 +Antlr (http://www.antlr.org/) antlr:antlr:2.7.7
 +---------------------------------------------------------------------------
 +This product bundles Antlr which is available under a BSD license.  
 +For details see http://www.antlr.org/license.html.
 +
 +---------------------------------------------------------------------------
 +Backbone (http://backbonejs.org)
 +---------------------------------------------------------------------------
 +This product bundles Backbone which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +CompactConcurrentHashSet2 (http://gee.cs.oswego.edu/dl/concurrency-interest)
 +---------------------------------------------------------------------------
 +This product bundles CompactConcurrentHashSet2 derived from JSR-166 
 +ConcurrentHashMap v1.43 which is available in the public domain.  
 +
 +---------------------------------------------------------------------------
 +Handlebars (http://handlebarsjs.com)
 +---------------------------------------------------------------------------
 +This product bundles Handlebars which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +highlight.js (https://highlightjs.org)
 +---------------------------------------------------------------------------
 +This product bundles highlight.js which is available under a BSD 3 clauses license.  
 +For details see http://opensource.org/licenses/BSD-3-Clause.
 +
 +---------------------------------------------------------------------------
 +javax.activation (http://java.sun.com/javase/technologies/desktop/javabeans/jaf/index.jsp) javax.activation:activation:1.1.1
 +---------------------------------------------------------------------------
 +This product bundles javax.activation which is available under a CDDL license.  
 +For details see https://glassfish.dev.java.net/public/CDDLv1.0.html.
 +
 +---------------------------------------------------------------------------
 +javax.mail (http://www.oracle.com/) javax.mail:javax.mail-api:1.4.5
 +---------------------------------------------------------------------------
 +This product bundles javax.mail which is available under a CDDL or GPLv2+CE license.  
 +For details see http://www.sun.com/cddl or https://glassfish.dev.java.net/public/CDDL+GPL.html.
 +
 +---------------------------------------------------------------------------
 +javax.resource (https://glassfish.java.net/) javax.resource:javax.resource-api:1.7
 +---------------------------------------------------------------------------
 +This product bundles javax.resource which is available under a CDDL or GPLv2+CE license.  
 +For details see https://glassfish.dev.java.net/public/CDDL+GPL.html.
 +
 +---------------------------------------------------------------------------
 +javax.servlet (https://glassfish.java.net/) javax.servlet:javax.servlet-api:3.1.0
 +---------------------------------------------------------------------------
 +This product bundles javax.servlet which is available under a CDDL or GPLv2+CE license.  
 +For details see https://glassfish.dev.java.net/public/CDDL+GPL.html.
 +
 +---------------------------------------------------------------------------
 +javax.transaction (https://glassfish.java.net/) javax.transaction:javax.transaction-api:1.2
 +---------------------------------------------------------------------------
 +This product bundles javax.transaction which is available under a CDDL or GPLv2+CE license.  
 +For details see https://glassfish.dev.java.net/public/CDDL+GPL.html.
 +
 +---------------------------------------------------------------------------
 +JLine (http://jline.sourceforge.net) jline:jline:2.12
 +---------------------------------------------------------------------------
 +This product bundles JLine which is available under a BSD license.  
 +For details see http://www.opensource.org/licenses/bsd-license.php.
 +
 +---------------------------------------------------------------------------
 +JOpt Simple (http://pholser.github.io/jopt-simple/)
 +---------------------------------------------------------------------------
 +This product bundles JOpt Simple which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jQuery (https://jquery.com)
 +---------------------------------------------------------------------------
 +This product bundles jQuery which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jQuery BBQ (http://benalman.com/projects/jquery-bbq-plugin/)
 +---------------------------------------------------------------------------
 +This product bundles jQuery BBQ which is available under an MIT and GPL dual license.  
 +For details see http://benalman.com/about/license.
 +
 +---------------------------------------------------------------------------
 +jQuery-slideto (https://github.com/Sleavely/jQuery-slideto)
 +---------------------------------------------------------------------------
 +This product bundles jQuery-slideto which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jQuery Wiggle (https://github.com/wilhelm-murdoch/jQuery-Wiggle)
 +---------------------------------------------------------------------------
 +This product bundles jQuery Wiggle which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +JSON (http://json.org)
 +---------------------------------------------------------------------------
 +This product bundles JSON which is available under a BSD-like license.  
 +For details see http://json.org/license.html.
 +
 +---------------------------------------------------------------------------
 +Paranamer (https://github.com/paul-hammant/paranamer) com.thoughtworks.paranamer:paranamer:2.3
 +---------------------------------------------------------------------------
 +This product bundles Paranamer which is available under a BSD license.  
 +For details see http://www.opensource.org/licenses/bsd-license.php.
 +
 +---------------------------------------------------------------------------
 +reset.css (http://meyerweb.com/eric/tools/css/reset/)
 +---------------------------------------------------------------------------
 +This product bundles reset.css which is available in the public domain.
 +
 +---------------------------------------------------------------------------
 +tooltip.js (http://flowplayer.org/tools/tooltip/)
 +---------------------------------------------------------------------------
 +This product bundles tooltip.css which is available in the public domain.
 +
 +---------------------------------------------------------------------------
 +scala-reflect (http://www.scala-lang.org/) org.scala-lang:scala-reflect:2.10.0
 +---------------------------------------------------------------------------
 +This product bundles scala-reflect which is available under a BSD-like license.  
 +For details see http://www.scala-lang.org/downloads/license.html.
 +
 +---------------------------------------------------------------------------
 +scala-library (http://www.scala-lang.org/) org.scala-lang:scala-library:2.10.0
 +---------------------------------------------------------------------------
 +This product bundles scala-library which is available under a BSD-like license.  
 +For details see http://www.scala-lang.org/downloads/license.html.
 +
 +---------------------------------------------------------------------------
 +shred (https://github.com/pandastrike/shred)
 +---------------------------------------------------------------------------
 +This product bundles shred which is available under an MIT or ISC license.  
 +For details see https://github.com/pandastrike/shred/blob/master/LICENSE.
 +
 +---------------------------------------------------------------------------
 +SLF4J API (http://www.slf4j.org) org.slf4j:slf4j-api:jar:1.7.7
 +---------------------------------------------------------------------------
 +This product bundles SLF4J API which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +underscore (http://underscorejs.org)
 +---------------------------------------------------------------------------
 +This product bundles underscore which is available under an MIT license.  
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery jqGrid (https://plugins.jquery.com/jqGrid/)
 +---------------------------------------------------------------------------
 +This product bundles jqGrid which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +html5.js (https://github.com/aFarkas/html5shiv)
 +---------------------------------------------------------------------------
 +This product bundles html5 which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.i18n.properties (https://github.com/jquery-i18n-properties/jquery-i18n-properties)
 +---------------------------------------------------------------------------
 +This product bundles jQuery i18n which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.jscrollpane (http://jscrollpane.kelvinluck.com/)
 +---------------------------------------------------------------------------
 +This product bundles jquery.jscrollpane which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.mousewheel (http://brandonaaron.net)
 +---------------------------------------------------------------------------
 +This product bundles jquery.mousewheel which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.placeholder (http://webcloud.se)
 +---------------------------------------------------------------------------
 +This product bundles jquery.placeholder which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.tablednd (https://github.com/isocra/TableDnD)
 +---------------------------------------------------------------------------
 +This product bundles jquery.tablednd which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.timeago (http://timeago.yarp.com/)
 +---------------------------------------------------------------------------
 +This product bundles jquery.timeago which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.ztree (http://zTree.me/)
 +---------------------------------------------------------------------------
 +This product bundles jquery.ztree which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.multiselect (http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/)
 +---------------------------------------------------------------------------
 +This product bundles jQuery.multiselect which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.ui (http://jqueryui.com/about)
 +---------------------------------------------------------------------------
 +This product bundles jquery UI which is available under an MIT license.
 +For details see http://www.opensource.org/licenses/mit-license.php.
 +
 +---------------------------------------------------------------------------
 +jquery.sparkline.js (http://omnipotent.net/jquery.sparkline/)
 +---------------------------------------------------------------------------
 +This product bundles jquery.sparkline which is available under a BSD-like license.
 +For details see http://opensource.org/licenses/BSD-3-Clause.
 +
++---------------------------------------------------------------------------
++split.js (https://github.com/nathancahill/Split.js)
++---------------------------------------------------------------------------
++This product bundles split.js which is available under an MIT license.
++For details see http://www.opensource.org/licenses/mit-license.php.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-assembly/src/src/dist/gradlew
----------------------------------------------------------------------
diff --cc geode-assembly/src/src/dist/gradlew
index 0000000,0000000..de155c6
new file mode 100755
--- /dev/null
+++ b/geode-assembly/src/src/dist/gradlew
@@@ -1,0 -1,0 +1,221 @@@
++#!/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.
++
++##
++## Tries to recreate Gradle's gradlew command in pure bash.
++## This way you don't have to worry about binaries in your build.
++##
++## Depdencies
++## unzip
++##
++
++set -e
++set -o pipefail
++
++APP_NAME="Gradle"
++APP_BASE_NAME=`basename "$0"`
++
++# Use the maximum available, or set MAX_FD != -1 to use that value.
++    MAX_FD="maximum"
++
++# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
++DEFAULT_JVM_OPTS="-Dorg.gradle.appname=$APP_BASE_NAME"
++
++bin=`dirname "$0"`
++bin=`cd "$bin">/dev/null; pwd`
++
++if [ -e "$bin/gradle/wrapper/gradle-wrapper.properties" ]; then
++  . "$bin/gradle/wrapper/gradle-wrapper.properties"
++else
++  # the location that the wrapper is at doesn't have a properties
++  # check PWD, gradlew may be shared
++  if [ -e "$PWD/gradle/wrapper/gradle-wrapper.properties" ]; then
++    . "$PWD/gradle/wrapper/gradle-wrapper.properties"
++  else
++    echo "Unable to locate gradle-wrapper.properties.  Not at $PWD/gradle/wrapper/gradle-wrapper.properties or $bin/gradle/wrapper/gradle-wrapper.properties" 1>&2
++    exit 1
++  fi
++fi
++
++warn ( ) {
++    echo "$*"
++}
++
++die ( ) {
++    echo
++    echo "$*"
++    echo
++    exit 1
++}
++
++# OS specific support (must be 'true' or 'false').
++darwin=false
++case "`uname`" in
++  Darwin* )
++    darwin=true
++    ;;
++esac
++
++# Attempt to set APP_HOME
++# Resolve links: $0 may be a link
++PRG="$0"
++# Need this for relative symlinks.
++while [ -h "$PRG" ] ; do
++    ls=`ls -ld "$PRG"`
++    link=`expr "$ls" : '.*-> \(.*\)$'`
++    if expr "$link" : '/.*' > /dev/null; then
++        PRG="$link"
++    else
++        PRG=`dirname "$PRG"`"/$link"
++    fi
++done
++SAVED="`pwd`"
++cd "`dirname \"$PRG\"`/" >&-
++APP_HOME="`pwd -P`"
++cd "$SAVED" >&-
++
++CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
++
++# Determine the Java command to use to start the JVM.
++if [ -n "$JAVA_HOME" ] ; then
++    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
++        # IBM's JDK on AIX uses strange locations for the executables
++        JAVACMD="$JAVA_HOME/jre/sh/java"
++    else
++        JAVACMD="$JAVA_HOME/bin/java"
++    fi
++    if [ ! -x "$JAVACMD" ] ; then
++        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
++
++Please set the JAVA_HOME variable in your environment to match the
++location of your Java installation."
++    fi
++else
++    JAVACMD="java"
++    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
++
++Please set the JAVA_HOME variable in your environment to match the
++location of your Java installation."
++fi
++
++# Increase the maximum file descriptors if we can.
++if [ "$darwin" = "false" ] ; then
++    MAX_FD_LIMIT=`ulimit -H -n`
++    if [ $? -eq 0 ] ; then
++        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
++            MAX_FD="$MAX_FD_LIMIT"
++        fi
++        ulimit -n $MAX_FD
++        if [ $? -ne 0 ] ; then
++            warn "Could not set maximum file descriptor limit: $MAX_FD"
++        fi
++    else
++        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
++    fi
++fi
++
++# For Darwin, add options to specify how the application appears in the dock
++if $darwin; then
++    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
++fi
++
++# does not match gradle's hash
++# waiting for http://stackoverflow.com/questions/26642077/java-biginteger-in-bash-rewrite-gradlew
++hash() {
++  local input="$1"
++  if $darwin; then
++    md5 -q -s "$1"
++  else
++    echo -n "$1" | md5sum  | cut -d" " -f1
++  fi
++}
++
++dist_path() {
++  local dir=$(basename $distributionUrl | sed 's;.zip;;g')
++  local id=$(hash "$distributionUrl")
++
++  echo "$HOME/.gradle/${distributionPath:-wrapper/dists}/$dir/$id"
++}
++
++zip_path() {
++  local dir=$(basename $distributionUrl | sed 's;.zip;;g')
++  local id=$(hash "$distributionUrl")
++
++  echo "$HOME/.gradle/${zipStorePath:-wrapper/dists}/$dir/$id"
++}
++
++download() {
++  local base_path=$(dist_path)
++  local file_name=$(basename $distributionUrl)
++  local dir_name=$(echo "$file_name" | sed 's;-bin.zip;;g' | sed 's;-src.zip;;g' |sed 's;-all.zip;;g')
++
++  if [ ! -d "$base_path" ]; then
++    mkdir -p "$base_path"
++  else
++    # if data already exists, it means we failed to do this before
++    # so cleanup last run and try again
++    rm -rf $base_path/*
++  fi
++
++  # download dist. curl on mac doesn't like the cert provided...
++  local zip_path=$(zip_path)
++  curl --insecure -L -o "$zip_path/$file_name" "$distributionUrl"
++
++  pushd "$base_path"
++    touch "$file_name.lck"
++    unzip "$zip_path/$file_name" 1> /dev/null
++    touch "$file_name.ok"
++  popd
++}
++
++is_cached() {
++  local file_name=$(basename $distributionUrl)
++
++  [ -e "$(dist_path)/$file_name.ok" ]
++}
++
++lib_path() {
++  local base_path=$(dist_path)
++  local file_name=$(basename $distributionUrl | sed 's;-bin.zip;;g' | sed 's;-src.zip;;g' |sed 's;-all.zip;;g')
++
++  echo "$base_path/$file_name/lib"
++}
++
++classpath() {
++  local dir=$(lib_path)
++  local cp=$(ls -1 $dir/*.jar | tr '\n' ':')
++  echo "$dir:$cp"
++}
++
++# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
++function splitJvmOpts() {
++    JVM_OPTS=("$@")
++}
++
++main() {
++  if ! is_cached; then
++    download
++  fi
++
++  eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
++  JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
++
++  $JAVACMD "${JVM_OPTS[@]}" -cp $(classpath) org.gradle.launcher.GradleMain "$@"
++}
++
++main "$@"
++

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/AgentUtilJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/AgentUtilJUnitTest.java
index 9a446cc,0000000..59da3cf
mode 100644,000000..100644
--- a/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/AgentUtilJUnitTest.java
+++ b/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/AgentUtilJUnitTest.java
@@@ -1,98 -1,0 +1,50 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package com.gemstone.gemfire.management.internal;
 +
++import com.gemstone.gemfire.internal.GemFireVersion;
 +import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
 +import org.junit.Before;
 +import org.junit.Test;
 +import org.junit.experimental.categories.Category;
 +
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Properties;
- 
 +import static org.junit.Assert.assertNotNull;
 +
 +@Category(IntegrationTest.class)
 +public class AgentUtilJUnitTest {
 +
 +  private AgentUtil agentUtil;
 +  private String version;
 +
 +  @Before
 +  public void setUp() {
-     version = getGemfireVersion();
++    version = GemFireVersion.getGemFireVersion();
 +    agentUtil = new AgentUtil(version);
 +  }
 +
 +  @Test
 +  public void testRESTApiExists() {
 +    String gemFireWarLocation = agentUtil.findWarLocation("geode-web-api");
 +    assertNotNull("GemFire REST API WAR File was not found", gemFireWarLocation);
 +  }
 +
 +  @Test
 +  public void testPulseWarExists() {
 +    String gemFireWarLocation = agentUtil.findWarLocation("geode-pulse");
 +    assertNotNull("Pulse WAR File was not found", gemFireWarLocation);
 +  }
- 
-   private String getGemfireVersion() {
-     String version = null;
- 
-     Properties prop = new Properties();
-     InputStream inputStream = null;
-     String pathPrefix = null;
-     try {
-       pathPrefix = calculatePathPrefixToProjectRoot("geode-assembly/");
-       inputStream = new FileInputStream(pathPrefix + "gradle.properties");
-     } catch (FileNotFoundException e1) {
-       try {
-         pathPrefix = calculatePathPrefixToProjectRoot("geode-core/");
-         inputStream = new FileInputStream(pathPrefix + "gradle.properties");
-       } catch (FileNotFoundException e) {
-       }
-     }
- 
-     if (inputStream != null) {
-       try {
-         prop.load(inputStream);
-         version = prop.getProperty("versionNumber") + prop.getProperty("releaseType");
-       } catch (FileNotFoundException e) {
-       } catch (IOException e) {
-       }
-     }
-     return version;
-   }
- 
-   private String calculatePathPrefixToProjectRoot(String subDirectory) {
-     String pathPrefix = "";
- 
-     String currentDirectoryPath = new File(".").getAbsolutePath();
-     int gemfireCoreLocationIx = currentDirectoryPath.indexOf(subDirectory);
-     if (gemfireCoreLocationIx < 0) {
-       return pathPrefix;
-     }
- 
-     return currentDirectoryPath.substring(0, gemfireCoreLocationIx);
-   }
- 
- 
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
index d7fd2fc,0000000..4842324
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
@@@ -1,55 -1,0 +1,59 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache;
 +
++import javax.transaction.Status;
++import javax.transaction.Transaction;
++import javax.transaction.UserTransaction;
++
 +/** Thrown when a cache transaction fails to register with the
 + * <code>UserTransaction</code> (aka JTA transaction), most likely the
 + * cause of the <code>UserTransaction</code>'s
 + * <code>javax.transaction.Status#STATUS_MARKED_ROLLBACK</code>
 + * status.
 + *
 + * @author Mitch Thomas
 + *
-  * @see javax.transaction.UserTransaction#setRollbackOnly
-  * @see javax.transaction.Transaction#registerSynchronization
-  * @see javax.transaction.Status
++ * @see UserTransaction#setRollbackOnly
++ * @see Transaction#registerSynchronization
++ * @see Status
 + * @since 4.0
 + */
 +public class FailedSynchronizationException extends CacheRuntimeException {
 +private static final long serialVersionUID = -6225053492344591496L;
 +  /**
 +   * Constructs an instance of
 +   * <code>FailedSynchronizationException</code> with the
 +   * specified detail message.
 +   * @param msg the detail message
 +   */
 +  public FailedSynchronizationException(String msg) {
 +    super(msg);
 +  }
 +  
 +  /**
 +   * Constructs an instance of
 +   * <code>FailedSynchronizationException</code> with the
 +   * specified detail message and cause.
 +   * @param msg the detail message
 +   * @param cause the causal Throwable
 +   */
 +  public FailedSynchronizationException(String msg, Throwable cause) {
 +    super(msg, cause);
 +  }
 +}


[061/100] [abbrv] incubator-geode git commit: Moving a couple of classes to the correct package

Posted by ud...@apache.org.
Moving a couple of classes to the correct package

This appear to have been placed in the wrong package as part of the
rename.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/87586d04
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/87586d04
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/87586d04

Branch: refs/heads/feature/GEODE-870
Commit: 87586d04526974e2f5e8a4b93841ebef1f167284
Parents: 9eb7a05
Author: Dan Smith <up...@apache.org>
Authored: Fri Feb 19 17:25:28 2016 -0800
Committer: Dan Smith <up...@apache.org>
Committed: Fri Feb 19 17:25:28 2016 -0800

----------------------------------------------------------------------
 .../tests/GetDefaultDiskStoreNameDUnitTest.java | 67 ++++++++++++++++++++
 .../dunit/tests/GetTestMethodNameDUnitTest.java | 54 ++++++++++++++++
 .../tests/GetDefaultDiskStoreNameDUnitTest.java | 67 --------------------
 .../tests/tests/GetTestMethodNameDUnitTest.java | 54 ----------------
 4 files changed, 121 insertions(+), 121 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/87586d04/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java
new file mode 100755
index 0000000..99dcc29
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.test.dunit.tests;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+@SuppressWarnings("serial")
+@Category(DistributedTest.class)
+public class GetDefaultDiskStoreNameDUnitTest extends DistributedTestCase {
+
+  public GetDefaultDiskStoreNameDUnitTest(final String name) {
+    super(name);
+  }
+
+  public void testGetTestMethodName() {
+    String expected = createDefaultDiskStoreName(0, -1, "testGetTestMethodName");
+    assertGetDefaultDiskStoreName(expected);
+  }
+  
+  public void testGetTestMethodNameChanges() {
+    String expected = createDefaultDiskStoreName(0, -1, "testGetTestMethodNameChanges");
+    assertGetDefaultDiskStoreName(expected);
+  }
+  
+  public void testGetTestMethodNameInAllVMs() {
+    String expected = createDefaultDiskStoreName(0, -1, "testGetTestMethodNameInAllVMs");
+    assertGetDefaultDiskStoreName(expected);
+    
+    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
+      String expectedInVM = createDefaultDiskStoreName(0, vmIndex, "testGetTestMethodNameInAllVMs");
+      Host.getHost(0).getVM(vmIndex).invoke(()->assertGetDefaultDiskStoreName(expectedInVM));
+    }
+  }
+  
+  private void assertGetDefaultDiskStoreName(final String expected) {
+    assertThat(getDefaultDiskStoreName()).isEqualTo(expected);
+  }
+  
+  private String createDefaultDiskStoreName(final int hostIndex, final int vmIndex, final String methodName) {
+    return "DiskStore-" + hostIndex + "-" + vmIndex + "-" + getClass().getCanonicalName() + "." + methodName;
+  }
+  
+  private String getDefaultDiskStoreName() {
+    return GemFireCacheImpl.DEFAULT_DS_NAME; // TODO: not thread safe
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/87586d04/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetTestMethodNameDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetTestMethodNameDUnitTest.java
new file mode 100755
index 0000000..9bad472
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/GetTestMethodNameDUnitTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.test.dunit.tests;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+@SuppressWarnings("serial")
+@Category(DistributedTest.class)
+public class GetTestMethodNameDUnitTest extends DistributedTestCase {
+
+  public GetTestMethodNameDUnitTest(final String name) {
+    super(name);
+  }
+
+  public void testGetTestMethodName() {
+    assertGetTestMethodName("testGetTestMethodName");
+  }
+  
+  public void testGetTestMethodNameChanges() {
+    assertGetTestMethodName("testGetTestMethodNameChanges");
+  }
+  
+  public void testGetTestMethodNameInAllVMs() {
+    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
+    
+    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
+      Host.getHost(0).getVM(vmIndex).invoke(()->assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
+    }
+  }
+  
+  private void assertGetTestMethodName(final String expected) {
+    assertThat(getTestMethodName()).isEqualTo(expected);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/87586d04/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetDefaultDiskStoreNameDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetDefaultDiskStoreNameDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetDefaultDiskStoreNameDUnitTest.java
deleted file mode 100755
index 99dcc29..0000000
--- a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetDefaultDiskStoreNameDUnitTest.java
+++ /dev/null
@@ -1,67 +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 com.gemstone.gemfire.test.dunit.tests;
-
-import static org.assertj.core.api.Assertions.*;
-
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
-import com.gemstone.gemfire.test.dunit.DistributedTestCase;
-import com.gemstone.gemfire.test.dunit.Host;
-import com.gemstone.gemfire.test.junit.categories.DistributedTest;
-
-@SuppressWarnings("serial")
-@Category(DistributedTest.class)
-public class GetDefaultDiskStoreNameDUnitTest extends DistributedTestCase {
-
-  public GetDefaultDiskStoreNameDUnitTest(final String name) {
-    super(name);
-  }
-
-  public void testGetTestMethodName() {
-    String expected = createDefaultDiskStoreName(0, -1, "testGetTestMethodName");
-    assertGetDefaultDiskStoreName(expected);
-  }
-  
-  public void testGetTestMethodNameChanges() {
-    String expected = createDefaultDiskStoreName(0, -1, "testGetTestMethodNameChanges");
-    assertGetDefaultDiskStoreName(expected);
-  }
-  
-  public void testGetTestMethodNameInAllVMs() {
-    String expected = createDefaultDiskStoreName(0, -1, "testGetTestMethodNameInAllVMs");
-    assertGetDefaultDiskStoreName(expected);
-    
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      String expectedInVM = createDefaultDiskStoreName(0, vmIndex, "testGetTestMethodNameInAllVMs");
-      Host.getHost(0).getVM(vmIndex).invoke(()->assertGetDefaultDiskStoreName(expectedInVM));
-    }
-  }
-  
-  private void assertGetDefaultDiskStoreName(final String expected) {
-    assertThat(getDefaultDiskStoreName()).isEqualTo(expected);
-  }
-  
-  private String createDefaultDiskStoreName(final int hostIndex, final int vmIndex, final String methodName) {
-    return "DiskStore-" + hostIndex + "-" + vmIndex + "-" + getClass().getCanonicalName() + "." + methodName;
-  }
-  
-  private String getDefaultDiskStoreName() {
-    return GemFireCacheImpl.DEFAULT_DS_NAME; // TODO: not thread safe
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/87586d04/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetTestMethodNameDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetTestMethodNameDUnitTest.java
deleted file mode 100755
index 9bad472..0000000
--- a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/tests/GetTestMethodNameDUnitTest.java
+++ /dev/null
@@ -1,54 +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 com.gemstone.gemfire.test.dunit.tests;
-
-import static org.assertj.core.api.Assertions.*;
-
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.test.dunit.DistributedTestCase;
-import com.gemstone.gemfire.test.dunit.Host;
-import com.gemstone.gemfire.test.junit.categories.DistributedTest;
-
-@SuppressWarnings("serial")
-@Category(DistributedTest.class)
-public class GetTestMethodNameDUnitTest extends DistributedTestCase {
-
-  public GetTestMethodNameDUnitTest(final String name) {
-    super(name);
-  }
-
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
-  }
-  
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
-  }
-  
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
-    
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex).invoke(()->assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
-    }
-  }
-  
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
-  }
-}


[035/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketRegion.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketRegion.java
index fae381f,0000000..69f61c4
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketRegion.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketRegion.java
@@@ -1,2614 -1,0 +1,2622 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.DataOutput;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.atomic.AtomicLong;
 +import java.util.concurrent.atomic.AtomicReference;
 +import java.util.concurrent.locks.Lock;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.CopyHelper;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.DeltaSerializationException;
 +import com.gemstone.gemfire.GemFireIOException;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.InvalidDeltaException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.CustomEvictionAttributes;
 +import com.gemstone.gemfire.cache.DiskAccessException;
 +import com.gemstone.gemfire.cache.EntryNotFoundException;
 +import com.gemstone.gemfire.cache.EvictionAction;
 +import com.gemstone.gemfire.cache.EvictionAlgorithm;
 +import com.gemstone.gemfire.cache.EvictionAttributes;
 +import com.gemstone.gemfire.cache.EvictionCriteria;
 +import com.gemstone.gemfire.cache.ExpirationAction;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.cache.hdfs.HDFSIOException;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HoplogOrganizer;
 +import com.gemstone.gemfire.cache.partition.PartitionListener;
 +import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.AtomicLongWithTerminalState;
 +import com.gemstone.gemfire.distributed.internal.DirectReplyProcessor;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
 +import com.gemstone.gemfire.distributed.internal.DistributionStats;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.BucketAdvisor.BucketProfile;
 +import com.gemstone.gemfire.internal.cache.FilterRoutingInfo.FilterInfo;
 +import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
 +import com.gemstone.gemfire.internal.cache.delta.Delta;
 +import com.gemstone.gemfire.internal.cache.partitioned.Bucket;
 +import com.gemstone.gemfire.internal.cache.partitioned.DestroyMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.InvalidateMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.LockObject;
 +import com.gemstone.gemfire.internal.cache.partitioned.PRTombstoneMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.PartitionMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.PutAllPRMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.PutMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.RemoveAllPRMessage;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientNotifier;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientTombstoneMessage;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientUpdateMessage;
 +import com.gemstone.gemfire.internal.cache.versions.VersionSource;
 +import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventImpl;
 +import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewaySenderQueue;
 +import com.gemstone.gemfire.internal.concurrent.Atomics;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +import com.gemstone.gemfire.internal.offheap.StoredObject;
 +import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 +import com.gemstone.gemfire.internal.concurrent.AtomicLong5;
 +
 +
 +/**
 + * The storage used for a Partitioned Region.
 + * This class asserts distributed scope as well as a replicate data policy
 + * It does not support transactions
 + * 
 + * Primary election for a BucketRegion can be found in the 
 + * {@link com.gemstone.gemfire.internal.cache.BucketAdvisor} class
 + * 
 + * @author Mitch Thomas
 + * @since 5.1
 + *
 + */
 +public class BucketRegion extends DistributedRegion
 +implements Bucket
 +{
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  public static final RawValue NULLVALUE = new RawValue(null);
 +  public static final RawValue REQUIRES_ENTRY_LOCK = new RawValue(null);
 +  /**
 +   * A special value for the bucket size indicating that this bucket
 +   * has been destroyed.
 +   */
 +  private static final long BUCKET_DESTROYED = Long.MIN_VALUE;
 +  private AtomicLong counter = new AtomicLong();
 +  private AtomicLong limit;
 +  private final AtomicLong numOverflowOnDisk = new AtomicLong();
 +  private final AtomicLong numOverflowBytesOnDisk = new AtomicLong();
 +  private final AtomicLong numEntriesInVM = new AtomicLong();
 +  private final AtomicLong evictions = new AtomicLong();
 +  
 +  /**
 +   * Contains size in bytes of the values stored
 +   * in theRealMap. Sizes are tallied during put and remove operations.
 +   */
 +  private final AtomicLongWithTerminalState bytesInMemory = new AtomicLongWithTerminalState();
 +  
 +  public static final class RawValue {
 +    private final Object rawValue;
 +    public RawValue(Object rawVal) {
 +      this.rawValue = rawVal;
 +    }
 +
 +    public final boolean isValueByteArray() {
 +      return this.rawValue instanceof byte[];
 +    }
 +    
 +    public Object getRawValue() {
 +      return this.rawValue;
 +    }
 +
 +    public void writeAsByteArray(DataOutput out) throws IOException {
 +      if (isValueByteArray()) {
 +        DataSerializer.writeByteArray((byte[]) this.rawValue, out);
 +      } else if (this.rawValue instanceof CachedDeserializable) {
 +        ((CachedDeserializable)this.rawValue).writeValueAsByteArray(out);
 +      } else if (Token.isInvalid(this.rawValue)) {
 +        DataSerializer.writeByteArray(null, out);
 +      } else if (this.rawValue == Token.TOMBSTONE) { 
 +        DataSerializer.writeByteArray(null, out);
 +      } else {
 +        DataSerializer.writeObjectAsByteArray(this.rawValue, out);
 +      }
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      return "RawValue("+this.rawValue+")";
 +    }
 +
 +    /**
 +     * Return the de-serialized value without changing the stored form
 +     * in the heap.  This causes local access to create a de-serialized copy (extra work)
 +     * in favor of keeping values in serialized form which is important because
 +     * it makes remote access more efficient.  This assumption is that remote
 +     * access is much more frequent.
 +     * TODO Unused, but keeping for potential performance boost when local Bucket 
 +     * access de-serializes the entry (which could hurt perf.)
 +     * 
 +     * @return the de-serialized value
 +     */
 +    public Object getDeserialized(boolean copyOnRead) {
 +      if (isValueByteArray()) {
 +        if (copyOnRead) {
 +          // TODO move this code to CopyHelper.copy?
 +          byte[] src = (byte[])this.rawValue;
 +          byte[] dest = new byte[src.length];
 +          System.arraycopy(this.rawValue, 0, dest, 0, dest.length);
 +          return dest;
 +        } else {
 +          return this.rawValue;
 +        }
 +      } else if (this.rawValue instanceof CachedDeserializable) {
 +        if (copyOnRead) {
 +          return ((CachedDeserializable)this.rawValue).getDeserializedWritableCopy(null, null);
 +        } else {
 +          return ((CachedDeserializable)this.rawValue).getDeserializedForReading();
 +        }
 +      } else if (Token.isInvalid(this.rawValue)) {
 +        return null;
 +      } else {
 +        if (copyOnRead) {
 +          return CopyHelper.copy(this.rawValue);
 +        } else {
 +          return this.rawValue;
 +        }
 +      }
 +    }
 +  }
 +
 +  private static final long serialVersionUID = 1L;
 +
 +  private final int redundancy;
 +  
 +  /** the partitioned region to which this bucket belongs */
 +  private final PartitionedRegion partitionedRegion;
 +  private final Map<Object, ExpiryTask> pendingSecondaryExpires = new HashMap<Object, ExpiryTask>(); 
 + 
 +  /* one map per bucket region */
 +  public HashMap allKeysMap = new HashMap();
 +
 +  static final boolean FORCE_LOCAL_LISTENERS_INVOCATION = 
 +    Boolean.getBoolean("gemfire.BucketRegion.alwaysFireLocalListeners");
 +  // gemfire.BucktRegion.alwaysFireLocalListeners=true
 +  
 +  private volatile AtomicLong5 eventSeqNum = null;
 +  
 +  public AtomicLong5 getEventSeqNum() {
 +    return eventSeqNum;
 +  }
 +
 +  protected final AtomicReference<HoplogOrganizer> hoplog = new AtomicReference<HoplogOrganizer>();
 +  
 +  public BucketRegion(String regionName, RegionAttributes attrs,
 +      LocalRegion parentRegion, GemFireCacheImpl cache,
 +      InternalRegionArguments internalRegionArgs) {
 +    super(regionName, attrs, parentRegion, cache, internalRegionArgs);
 +    if(PartitionedRegion.DISABLE_SECONDARY_BUCKET_ACK) {
 +      Assert.assertTrue(attrs.getScope().isDistributedNoAck());
 +    } 
 +    else {
 +      Assert.assertTrue(attrs.getScope().isDistributedAck());
 +    }
 +    Assert.assertTrue(attrs.getDataPolicy().withReplication());
 +    Assert.assertTrue( ! attrs.getEarlyAck());
 +    Assert.assertTrue(isUsedForPartitionedRegionBucket());
 +    Assert.assertTrue( ! isUsedForPartitionedRegionAdmin());
 +    Assert.assertTrue(internalRegionArgs.getBucketAdvisor() != null);
 +    Assert.assertTrue(internalRegionArgs.getPartitionedRegion() != null);
 +    this.redundancy = internalRegionArgs.getPartitionedRegionBucketRedundancy();
 +    this.partitionedRegion = internalRegionArgs.getPartitionedRegion();
 +  }
 +  
 +  // Attempt to direct the GII process to the primary first
 +  @Override
 +  protected void initialize(InputStream snapshotInputStream,
 +      InternalDistributedMember imageTarget,
 +      InternalRegionArguments internalRegionArgs) 
 +    throws TimeoutException, IOException, ClassNotFoundException
 +  {
 +    // Set this region in the ProxyBucketRegion early so that profile exchange will
 +    // perform the correct fillInProfile method
 +    getBucketAdvisor().getProxyBucketRegion().setBucketRegion(this);
 +    boolean success = false;
 +    try {
 +      if (this.partitionedRegion.isShadowPR()
 +          && this.partitionedRegion.getColocatedWith() != null) {
 +        PartitionedRegion parentPR = ColocationHelper
 +            .getLeaderRegion(this.partitionedRegion);
 +        BucketRegion parentBucket = parentPR.getDataStore().getLocalBucketById(
 +            getId());
 +        // needs to be set only once.
 +        if (parentBucket.eventSeqNum == null) {
 +          parentBucket.eventSeqNum = new AtomicLong5(getId());
 +        }
 +      }
 +      if (this.partitionedRegion.getColocatedWith() == null) {
 +        this.eventSeqNum = new AtomicLong5(getId());
 +      } else {
 +        PartitionedRegion parentPR = ColocationHelper
 +            .getLeaderRegion(this.partitionedRegion);
 +        BucketRegion parentBucket = parentPR.getDataStore().getLocalBucketById(
 +            getId());
 +        if (parentBucket == null && logger.isDebugEnabled()) {
 +          logger.debug("The parentBucket of region {} bucketId {} is NULL", this.partitionedRegion.getFullPath(), getId());
 +        }
 +        Assert.assertTrue(parentBucket != null);
 +        this.eventSeqNum = parentBucket.eventSeqNum;
 +      }
 +      
 +      final InternalDistributedMember primaryHolder = 
 +        getBucketAdvisor().basicGetPrimaryMember();
 +      if (primaryHolder != null && ! primaryHolder.equals(getMyId())) {
 +        // Ignore the provided image target, use an existing primary (if any)
 +        super.initialize(snapshotInputStream, primaryHolder, internalRegionArgs);
 +      } else {
 +        super.initialize(snapshotInputStream, imageTarget, internalRegionArgs);
 +      }
 +      
 +      success = true;
 +    } finally {
 +      if(!success) {
 +        removeFromPeersAdvisors(false);
 +        getBucketAdvisor().getProxyBucketRegion().clearBucketRegion(this);
 +      }
 +    }
 +  }
 +  
 +  
 +
 +  @Override
 +  public void initialized() {
 +    //announce that the bucket is ready
 +    //setHosting performs a profile exchange, so there
 +    //is no need to call super.initialized() here.
 +  }
 +  
 +  @Override
 +  protected DiskStoreImpl findDiskStore(RegionAttributes ra, InternalRegionArguments internalRegionArgs) {
 +    return internalRegionArgs.getPartitionedRegion().getDiskStore();
 +  }
 +
 +  @Override
 +  public void createEventTracker() {
 +    this.eventTracker = new EventTracker(this);
 +    this.eventTracker.start();
 +  }
 +  
 +  @Override
 +  protected CacheDistributionAdvisor createDistributionAdvisor(
 +      InternalRegionArguments internalRegionArgs){
 +    return internalRegionArgs.getBucketAdvisor();
 +  }
 +  
 +  public BucketAdvisor getBucketAdvisor() {
 +    return (BucketAdvisor) getDistributionAdvisor();
 +  }
 +  
 +  public boolean isHosting() {
 +    return getBucketAdvisor().isHosting();
 +  }
 +  
 +  @Override
 +  protected EventID distributeTombstoneGC(Set<Object> keysRemoved) {
 +    EventID eventId = super.distributeTombstoneGC(keysRemoved);
 +    if (keysRemoved != null && keysRemoved.size() > 0 && getFilterProfile() != null) {
 +      // send the GC to members that don't have the bucket but have the PR so they
 +      // can forward the event to clients
 +      PRTombstoneMessage.send(this, keysRemoved, eventId);
 +    }
 +    return eventId;
 +  }
 +
 +  @Override
 +  protected void notifyClientsOfTombstoneGC(Map<VersionSource, Long> regionGCVersions, Set<Object>removedKeys, EventID eventID, FilterInfo routing) {
 +    if (CacheClientNotifier.getInstance() != null) {
 +      // Only route the event to clients interested in the partitioned region.
 +      // We do this by constructing a region-level event and then use it to
 +      // have the filter profile ferret out all of the clients that have interest
 +      // in this region
 +      FilterProfile fp = getFilterProfile();
 +      if ((removedKeys != null && removedKeys.size() > 0) // bug #51877 - NPE in clients
 +          && (routing != null || fp != null)) { // fix for bug #46309 - don't send null/empty key set to clients
 +        RegionEventImpl regionEvent = new RegionEventImpl(getPartitionedRegion(), Operation.REGION_DESTROY, null, true, getMyId()); 
 +        FilterInfo clientRouting = routing;
 +        if (clientRouting == null) {
 +          clientRouting = fp.getLocalFilterRouting(regionEvent);
 +        }
 +        regionEvent.setLocalFilterInfo(clientRouting); 
 +          
 +        ClientUpdateMessage clientMessage = ClientTombstoneMessage.gc(getPartitionedRegion(), removedKeys,
 +            eventID);
 +        CacheClientNotifier.notifyClients(regionEvent, clientMessage);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Search the CM for keys. If found any, return the first found one
 +   * Otherwise, save the keys into the CM, and return null
 +   * The thread will acquire the lock before searching.
 +   * 
 +   * @param keys
 +   * @return first key found in CM
 +   *         null means not found
 +   */
 +  private LockObject searchAndLock(Object keys[]) {
 +    final boolean isDebugEnabled = logger.isDebugEnabled();
 +    
 +    LockObject foundLock = null;
 +    
 +    synchronized(allKeysMap) {
 +      // check if there's any key in map
 +      for (int i=0; i<keys.length; i++) {
 +        if (allKeysMap.containsKey(keys[i])) {
 +          foundLock = (LockObject)allKeysMap.get(keys[i]);
 +          if (isDebugEnabled) {
 +            logger.debug("LockKeys: found key: {}:{}", keys[i], foundLock.lockedTimeStamp);
 +          }
 +          break;
 +        }
 +      }
 +      
 +      // save the keys when still locked
 +      if (foundLock == null) {
 +        for (int i=0; i<keys.length; i++) {
 +          LockObject lockValue = new LockObject(keys[i], isDebugEnabled?System.currentTimeMillis():0);
 +          allKeysMap.put(keys[i], lockValue);
 +          if (isDebugEnabled) {
 +            logger.debug("LockKeys: add key: {}:{}", keys[i], lockValue.lockedTimeStamp);
 +          }
 +        }
 +      }
 +    } 
 +    
 +    return foundLock;
 +  }
 +
 +  /**
 +   * After processed the keys, this method will remove them from CM. 
 +   * And notifyAll for each key. 
 +   * The thread needs to acquire lock of CM first.
 +   * 
 +   * @param keys
 +   */
 +  public void removeAndNotifyKeys(Object keys[]) {
 +    final boolean isTraceEnabled = logger.isTraceEnabled();
 +    
 +    synchronized(allKeysMap) {
 +      for (int i=0; i<keys.length; i++) {
 +        LockObject lockValue = (LockObject)allKeysMap.remove(keys[i]);
 +        if (lockValue != null) {
 +          // let current thread become the monitor of the key object
 +          synchronized (lockValue) {
 +            lockValue.setRemoved();
 +            if (isTraceEnabled) {
 +              long waitTime = System.currentTimeMillis()-lockValue.lockedTimeStamp;
 +              logger.trace("LockKeys: remove key {}, notifyAll for {}. It waited", keys[i], lockValue, waitTime);
 +            }
 +            lockValue.notifyAll();
 +          }
 +        }
 +      } // for
 +    } 
 +  }
 +  
 +  /**
 +   * Keep checking if CM has contained any key in keys. If yes, wait for notify,
 +   * then retry again. This method will block current thread for long time. 
 +   * It only exits when current thread successfully save its keys into CM. 
 +   * 
 +   * @param keys
 +   */
 +  public void waitUntilLocked(Object keys[]) {
 +    final boolean isDebugEnabled = logger.isDebugEnabled();
 +    
 +    final String title = "BucketRegion.waitUntilLocked:";
 +    while (true) {
 +      LockObject foundLock = searchAndLock(keys);
 +
 +      if (foundLock != null) {
 +        synchronized(foundLock) {
 +          try {
 +            while (!foundLock.isRemoved()) {
 +              this.partitionedRegion.checkReadiness();
 +              foundLock.wait(1000);
 +              // primary could be changed by prRebalancing while waiting here
 +              checkForPrimary();
 +            }
 +          }
 +          catch (InterruptedException e) {
 +            // TODO this isn't a localizable string and it's being logged at info level
 +            if (isDebugEnabled) {
 +              logger.debug("{} interrupted while waiting for {}", title, foundLock, e.getMessage());
 +            }
 +          }
 +          if (isDebugEnabled) {
 +            long waitTime = System.currentTimeMillis()-foundLock.lockedTimeStamp;
 +            logger.debug("{} waited {} ms to lock", title, waitTime, foundLock);
 +          }
 +        }
 +      } else {
 +        // now the keys have been locked by this thread
 +        break;
 +      } // to lock and process
 +    } // while
 +  }
 +  
 +  // Entry (Put/Create) rules
 +  // If this is a primary for the bucket
 +  //  1) apply op locally, aka update or create entry
 +  //  2) distribute op to bucket secondaries and bridge servers with synchrony on local entry
 +  //  3) cache listener with synchrony on entry
 +  // Else not a primary
 +  //  1) apply op locally
 +  //  2) update local bs, gateway
 +  @Override
 +  protected
 +  boolean virtualPut(EntryEventImpl event,
 +                     boolean ifNew,
 +                     boolean ifOld,
 +                     Object expectedOldValue,
 +                     boolean requireOldValue,
 +                     long lastModified,
 +                     boolean overwriteDestroyed)
 + throws TimeoutException,
 +      CacheWriterException {
 +    beginLocalWrite(event);
 +    
 +    try {
 +      if (this.partitionedRegion.isParallelWanEnabled()) {
 +        handleWANEvent(event);
 +      }
 +      if (!hasSeenEvent(event)) {
 +        forceSerialized(event);
 +        RegionEntry oldEntry = this.entries
 +            .basicPut(event, lastModified, ifNew, ifOld, expectedOldValue,
 +                requireOldValue, overwriteDestroyed);
 +        return oldEntry != null;
 +      }
 +      if (event.getDeltaBytes() != null && event.getRawNewValue() == null) {
 +        // This means that this event has delta bytes but no full value.
 +        // Request the full value of this event.
 +        // The value in this vm may not be same as this event's value.
 +        throw new InvalidDeltaException(
 +            "Cache encountered replay of event containing delta bytes for key "
 +                + event.getKey());
 +      }
 +      // Forward the operation and event messages
 +      // to members with bucket copies that may not have seen the event. Their
 +      // EventTrackers will keep them from applying the event a second time if
 +      // they've already seen it.
 +      if (logger.isTraceEnabled(LogMarker.DM)) {
 +        logger.trace(LogMarker.DM, "BR.virtualPut: this cache has already seen this event {}", event);
 +      }
-       distributeUpdateOperation(event, lastModified);
++      if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++        distributeUpdateOperation(event, lastModified);
++      }
 +      return true;
 +    } finally {
 +      endLocalWrite(event);
 +    }
 +  }
 +
 +  
 +  public long generateTailKey() {
 +    long key = this.eventSeqNum.addAndGet(this.partitionedRegion
 +        .getTotalNumberOfBuckets());
 +    if (key < 0
 +        || key % getPartitionedRegion().getTotalNumberOfBuckets() != getId()) {
 +      logger
 +          .error(LocalizedMessage
 +              .create(
 +                  LocalizedStrings.GatewaySender_SEQUENCENUMBER_GENERATED_FOR_EVENT_IS_INVALID,
 +                  new Object[] { key, getId() }));
 +    }
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("WAN: On primary bucket {}, setting the seq number as {}",
 +          getId(), this.eventSeqNum.get());
 +    }
 +    return eventSeqNum.get();
 +  }
 +  
 +  public void handleWANEvent(EntryEventImpl event) {
 +    if (this.eventSeqNum == null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("The bucket corresponding to this user bucket is not created yet. This event will not go to remote wan site. Event: {}", event);
 +      }
 +    }
 +    
 +    if (!(this instanceof AbstractBucketRegionQueue)) {
 +      if (getBucketAdvisor().isPrimary()) {
 +        long key = this.eventSeqNum.addAndGet(this.partitionedRegion.getTotalNumberOfBuckets());
 +        if (key < 0
 +            || key % getPartitionedRegion().getTotalNumberOfBuckets() != getId()) {
 +          logger.error(LocalizedMessage.create(LocalizedStrings.GatewaySender_SEQUENCENUMBER_GENERATED_FOR_EVENT_IS_INVALID,
 +                  new Object[] { key, getId() }));
 +        }
 +        event.setTailKey(key);
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("WAN: On primary bucket {}, setting the seq number as {}", getId(), this.eventSeqNum.get());
 +        }
 +      } else {
 +        // Can there be a race here? Like one thread has done put in primary but
 +        // its update comes later
 +        // in that case its possible that a tail key is missed.
 +        // we can handle that by only incrementing the tailKey and never
 +        // setting it less than the current value.
 +        Atomics.setIfGreater(this.eventSeqNum, event.getTailKey());
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("WAN: On secondary bucket {}, setting the seq number as {}", getId(), event.getTailKey());
 +        }
 +      }
 +    }
 +  }
 +  /**
 +   * Fix for Bug#45917
 +   * We are updating the seqNumber so that new seqNumbers are 
 +   * generated starting from the latest in the system.
 +   * @param l
 +   */
 +
 +  public void updateEventSeqNum(long l) {
 +    Atomics.setIfGreater(this.eventSeqNum, l);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("WAN: On bucket {}, setting the seq number as {} before GII", getId(), l);
 +    }
 +  }
 +  
 +  protected void distributeUpdateOperation(EntryEventImpl event, long lastModified) {
 +    if (!event.isOriginRemote()
 +        && !event.isNetSearch()
 +        && getBucketAdvisor().isPrimary()) {
 +      if (event.isBulkOpInProgress()) {
 +        // consolidate the UpdateOperation for each entry into a PutAllMessage
 +        // since we did not call basicPutPart3(), so we have to explicitly addEntry here
 +        event.getPutAllOperation().addEntry(event, this.getId());
 +      } else {
 +        new UpdateOperation(event, lastModified).distribute();
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("sent update operation : for region  : {}: with event: {}", this.getName(), event);
 +        }
 +      }
 +    }
 +    if (!event.getOperation().isPutAll()) {  // putAll will invoke listeners later
 +      event.invokeCallbacks(this, true, true);
 +    }
 +  }
 +  
 +  /**
 +   * distribute the operation in basicPutPart2 so the region entry lock is
 +   * held
 +   */
 +  @Override
 +  protected long basicPutPart2(EntryEventImpl event, RegionEntry entry, boolean isInitialized, 
 +      long lastModified, boolean clearConflict)  {
 +    // Assumed this is called with entry synchrony
 +
 +    // Typically UpdateOperation is called with the
 +    // timestamp returned from basicPutPart2, but as a bucket we want to do
 +    // distribution *before* we do basicPutPart2.
 +    final long modifiedTime = event.getEventTime(lastModified);
 +    // Update the get stats if necessary. 
 +    if (this.partitionedRegion.getDataStore().hasClientInterest(event)) {
 +      updateStatsForGet(entry, true);
 +    }
 +    if (!event.isOriginRemote()) {
 +      if (event.getVersionTag() == null || event.getVersionTag().isGatewayTag()) {
 +        boolean eventHasDelta = event.getDeltaBytes() != null;
 +        VersionTag v = entry.generateVersionTag(null, eventHasDelta, this, event);
 +        if (v != null) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("generated version tag {} in region {}", v, this.getName());
 +          }
 +        }
 +      }
 +
 +      // This code assumes it is safe ignore token mode (GII in progress) 
 +      // because it assumes when the origin of the event is local,
 +      // the GII has completed and the region is initialized and open for local
 +      // ops
 +      if (!event.isBulkOpInProgress()) {
 +        long start = this.partitionedRegion.getPrStats().startSendReplication();
 +        try {
 +          UpdateOperation op = new UpdateOperation(event, modifiedTime);
 +          op.distribute();
 +        } finally {
 +          this.partitionedRegion.getPrStats().endSendReplication(start);
 +        }
 +      } else {
 +        // consolidate the UpdateOperation for each entry into a PutAllMessage
 +        // basicPutPart3 takes care of this
 +      }
 +    }
 +
 +    return super.basicPutPart2(event, entry, isInitialized, lastModified, clearConflict);
 +  }
 +
 +  protected void notifyGatewaySender(EnumListenerEvent operation,
 +      EntryEventImpl event) {
 +    // We don't need to clone the event for new Gateway Senders.
 +    // Preserve the bucket reference for resetting it later.
 +    LocalRegion bucketRegion = event.getRegion();
 +    try {
 +      event.setRegion(this.partitionedRegion);
 +      this.partitionedRegion.notifyGatewaySender(operation, event);
 +    }
 +    finally {
 +      // reset the event region back to bucket region.
 +      // This should work as gateway queue create GatewaySenderEvent for
 +      // queueing.
 +      event.setRegion(bucketRegion);
 +    }
 +  }
 +
 +  public void checkForPrimary() {
 +    final boolean isp = getBucketAdvisor().isPrimary();
 +    if (! isp){
 +      this.partitionedRegion.checkReadiness();
 +      checkReadiness();
 +      InternalDistributedMember primaryHolder = getBucketAdvisor().basicGetPrimaryMember();    
 +      throw new PrimaryBucketException("Bucket " + getName()
 +          + " is not primary. Current primary holder is "+primaryHolder);
 +    }
 +  }
 +  
 +  /**
 +   * Checks to make sure that this node is primary, and locks the bucket
 +   * to make sure the bucket stays the primary bucket while the write
 +   * is in progress. Any call to this method must be followed with a call
 +   * to endLocalWrite().
 +   * @param event
 +   */
 +  private boolean beginLocalWrite(EntryEventImpl event) {
 +    if(!needWriteLock(event)) {
 +      return false;
 +    }
 +
 +    if (cache.isCacheAtShutdownAll()) {
 +      throw new CacheClosedException("Cache is shutting down");
 +    }
 +
 +    Object keys[] = new Object[1];
 +    keys[0] = event.getKey();
 +    waitUntilLocked(keys); // it might wait for long time
 +
 +    boolean lockedForPrimary = false;
 +    try {
 +      doLockForPrimary(false);
 +      return lockedForPrimary = true;
 +    } finally {
 +      if (!lockedForPrimary) {
 +        removeAndNotifyKeys(keys);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * lock this bucket and, if present, its colocated "parent"
 +   * @param tryLock - whether to use tryLock (true) or a blocking lock (false)
 +   * @return true if locks were obtained and are still held
 +   */
 +  public boolean doLockForPrimary(boolean tryLock) {
 +    boolean locked = lockPrimaryStateReadLock(tryLock);
 +    if(!locked) {
 +      return false;
 +    }
 +    
 +    boolean isPrimary = false;
 +    try {
 +      // Throw a PrimaryBucketException if this VM is assumed to be the
 +      // primary but isn't, preventing update and distribution
 +      checkForPrimary();
 +
 +      if (cache.isCacheAtShutdownAll()) {
 +        throw new CacheClosedException("Cache is shutting down");
 +      }
 +
 +      isPrimary = true;
 +    } finally {
 +      if(!isPrimary) {
 +        doUnlockForPrimary();
 +      }
 +    }
 +    
 +    return true;
 +  }
 +
 +  private boolean lockPrimaryStateReadLock(boolean tryLock) {
 +    Lock activeWriteLock = this.getBucketAdvisor().getActiveWriteLock();
 +    Lock parentLock = this.getBucketAdvisor().getParentActiveWriteLock();
 +    for (;;) {
 +      boolean interrupted = Thread.interrupted();
 +      try {
 +        //Get the lock. If we have to wait here, it's because
 +        //this VM is actively becoming "not primary". We don't want
 +        //to throw an exception until this VM is actually no longer
 +        //primary, so we wait here for not primary to complete. See bug #39963
 +        if (parentLock != null) {
 +          if (tryLock) {
 +            boolean locked = parentLock.tryLock();
 +            if (!locked) {
 +              return false;
 +            }
 +          } else {
 +            parentLock.lockInterruptibly();
 +          }
 +          if (tryLock) {
 +            boolean locked = activeWriteLock.tryLock();
 +            if (!locked) {
 +              parentLock.unlock();
 +              return false;
 +            }
 +          } else {
 +            activeWriteLock.lockInterruptibly();
 +          }
 +        }
 +        else {
 +          if (tryLock) {
 +            boolean locked = activeWriteLock.tryLock();
 +            if (!locked) {
 +              return false;
 +            }
 +          } else {
 +            activeWriteLock.lockInterruptibly();
 +          }
 +        }
 +        break; // success
 +      } catch (InterruptedException e) {
 +        interrupted = true;
 +        cache.getCancelCriterion().checkCancelInProgress(null);
 +        // don't throw InternalGemFireError to fix bug 40102
 +      } finally {
 +        if (interrupted) {
 +          Thread.currentThread().interrupt();
 +        }
 +      }
 +    }
 +    
 +    return true;
 +  }
 +
 +  public void doUnlockForPrimary() {
 +    Lock activeWriteLock = this.getBucketAdvisor().getActiveWriteLock();
 +    activeWriteLock.unlock();
 +    Lock parentLock = this.getBucketAdvisor().getParentActiveWriteLock();
 +    if(parentLock!= null){
 +      parentLock.unlock();
 +    }
 +  }
 +
 +  /**
 +   * Release the lock on the bucket that makes the bucket
 +   * stay the primary during a write.
 +   */
 +  private void endLocalWrite(EntryEventImpl event) {
 +    if(!needWriteLock(event)) {
 +      return;
 +    }
 +    
 +    
 +    doUnlockForPrimary();
 +
 +    Object keys[] = new Object[1];
 +    keys[0] = event.getKey();
 +    removeAndNotifyKeys(keys);
 +  }
 +
 +  protected boolean needWriteLock(EntryEventImpl event) {
 +    return !(event.isOriginRemote()
 +        || event.isNetSearch()
 +        || event.getOperation().isLocal() 
 +        || event.getOperation().isPutAll()
 +        || event.getOperation().isRemoveAll()
 +        || (event.isExpiration() && isEntryEvictDestroyEnabled() 
 +            || event.isPendingSecondaryExpireDestroy()));
 +  }
 +
 +  // this is stubbed out because distribution is done in basicPutPart2 while
 +  // the region entry is still locked
 +  @Override
 +  protected void distributeUpdate(EntryEventImpl event, long lastModified, boolean ifNew, boolean ifOld, Object expectedOldValue, boolean requireOldValue) {
 +  }
 +
 +  // Entry Invalidation rules
 +  // If this is a primary for the bucket
 +  //  1) apply op locally, aka update entry
 +  //  2) distribute op to bucket secondaries and bridge servers with synchrony on local entry
 +  //  3) cache listener with synchrony on entry
 +  //  4) update local bs, gateway
 +  // Else not a primary
 +  //  1) apply op locally
 +  //  2) update local bs, gateway
 +  @Override
 +  void basicInvalidate(EntryEventImpl event) throws EntryNotFoundException
 +  {
 +    basicInvalidate(event, isInitialized(), false);
 +  }
 +  
 +  @Override
 +  void basicInvalidate(final EntryEventImpl event, boolean invokeCallbacks,
 +      boolean forceNewEntry)
 +      throws EntryNotFoundException {
 +    // disallow local invalidation
 +    Assert.assertTrue(! event.isLocalInvalid());
 +    Assert.assertTrue(!isTX());
 +    Assert.assertTrue(event.getOperation().isDistributed());
 +
 +    beginLocalWrite(event);
 +    try {
 +      // increment the tailKey so that invalidate operations are written to HDFS
 +      if (this.partitionedRegion.hdfsStoreName != null) {
 +        /* MergeGemXDHDFSToGFE Disabled this while porting. Is this required? */
 +        //assert this.partitionedRegion.isLocalParallelWanEnabled();
 +        handleWANEvent(event);
 +      }
 +      // which performs the local op.
 +      // The ARM then calls basicInvalidatePart2 with the entry synchronized.
 +      if ( !hasSeenEvent(event) ) {
 +        if (event.getOperation().isExpiration()) { // bug 39905 - invoke listeners for expiration
 +          DistributedSystem sys =   cache.getDistributedSystem(); 
 +          EventID newID = new EventID(sys); 
 +          event.setEventId(newID);
 +          event.setInvokePRCallbacks(getBucketAdvisor().isPrimary());
 +        }
 +        boolean forceCallbacks = isEntryEvictDestroyEnabled(); 
 +        boolean done = this.entries.invalidate(event, invokeCallbacks, forceNewEntry, forceCallbacks); 
 +        ExpirationAction expirationAction = getEntryExpirationAction();
 +        if (done && !getBucketAdvisor().isPrimary() && expirationAction != null
 +            && expirationAction.isInvalidate()) {
 +          synchronized(pendingSecondaryExpires) {
 +            pendingSecondaryExpires.remove(event.getKey());
 +          }
 +        }
 +        return;
 +      }
 +      else {
 +        if (logger.isTraceEnabled(LogMarker.DM)) {
 +          logger.trace(LogMarker.DM, "LR.basicInvalidate: this cache has already seen this event {}", event);
 +        }
-         if (!event.isOriginRemote()
-             && getBucketAdvisor().isPrimary()) {
-           // This cache has processed the event, forward operation
-           // and event messages to backup buckets
-           new InvalidateOperation(event).distribute();
++        if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++          if (!event.isOriginRemote()
++              && getBucketAdvisor().isPrimary()) {
++            // This cache has processed the event, forward operation
++            // and event messages to backup buckets
++            new InvalidateOperation(event).distribute();
++          }
++          event.invokeCallbacks(this,true, false);
 +        }
-         event.invokeCallbacks(this,true, false);
 +        return;
 +      }
 +    } finally {
 +      endLocalWrite(event);
 +    }
 +  }
 +  @Override
 +  void basicInvalidatePart2(final RegionEntry re, final EntryEventImpl event,
 +      boolean clearConflict, boolean invokeCallbacks)
 +  {
 +    // Assumed this is called with the entry synchronized
 +    if (!event.isOriginRemote()) {
 +      if (event.getVersionTag() == null || event.getVersionTag().isGatewayTag()) {
 +        VersionTag v = re.generateVersionTag(null, false, this, event);
 +        if (logger.isDebugEnabled() && v != null) {
 +          logger.debug("generated version tag {} in region {}", v, this.getName());
 +        }
 +        event.setVersionTag(v);
 +      }
 +
 +      // This code assumes it is safe ignore token mode (GII in progress) 
 +      // because it assumes when the origin of the event is local,
 +      // the GII has completed and the region is initialized and open for local
 +      // ops
 +      
 +      // This code assumes that this bucket is primary
 +      // distribute op to bucket secondaries and event to other listeners
 +      InvalidateOperation op = new InvalidateOperation(event);
 +      op.distribute();
 +    }
 +    super.basicInvalidatePart2(re, event, clearConflict /*Clear conflict occurred */, invokeCallbacks);
 +  }
 +
 +  @Override
 +  void distributeInvalidate(EntryEventImpl event) {
 +  }
 +
 +  @Override
 +  protected void distributeInvalidateRegion(RegionEventImpl event) {
 +    // switch region in event so that we can have distributed region
 +    // send InvalidateRegion message.
 +    event.region = this;
 +    super.distributeInvalidateRegion(event);
 +    event.region = this.partitionedRegion;
 +  }
 +
 +  @Override
 +  protected boolean shouldDistributeInvalidateRegion(RegionEventImpl event) {
 +    return getBucketAdvisor().isPrimary();
 +  }
 +  
 +  @Override
 +  protected boolean shouldGenerateVersionTag(RegionEntry entry, EntryEventImpl event) {
 +    if (event.getOperation().isLocal()) { // bug #45402 - localDestroy generated a version tag
 +      return false;
 +    }
 +    return this.concurrencyChecksEnabled && ((event.getVersionTag() == null) || event.getVersionTag().isGatewayTag());
 +  }
 +  
 +  @Override
 +  void expireDestroy(EntryEventImpl event, boolean cacheWrite) {
 +    
 +    /* Early out before we throw a PrimaryBucketException because we're not primary */
 +    if(needWriteLock(event) && !getBucketAdvisor().isPrimary()) {
 +      return;
 +    }
 +    try {
 +      super.expireDestroy(event, cacheWrite);
 +      return;
 +    } catch(PrimaryBucketException e) {
 +      //must have concurrently removed the primary
 +      return;
 +    }
 +  }
 +  
 +  @Override
 +  void expireInvalidate(EntryEventImpl event) {
 +    if(!getBucketAdvisor().isPrimary()) {
 +      return;
 +    }
 +    try {
 +      super.expireInvalidate(event);
 +    } catch (PrimaryBucketException e) {
 +      //must have concurrently removed the primary
 +    }
 +  }
 +
 +  @Override
 +  final void performExpiryTimeout(ExpiryTask p_task) throws CacheException
 +  {
 +    ExpiryTask task = p_task;
 +    boolean isEvictDestroy = isEntryEvictDestroyEnabled();
 +    //Fix for bug 43805 - get the primary lock before
 +    //synchronizing on pendingSecondaryExpires, to match the lock
 +    //ordering in other place (like acquiredPrimaryLock)
 +    lockPrimaryStateReadLock(false);
 +    try {
 +      // Why do we care if evict destroy is configured?
 +      // See bug 41096 for the answer.
 +      if(!getBucketAdvisor().isPrimary() && !isEvictDestroy) {
 +        synchronized (this.pendingSecondaryExpires) {
 +          if (task.isPending()) {
 +            Object key = task.getKey();
 +            if (key != null) {
 +              this.pendingSecondaryExpires.put(key, task);
 +            }
 +          }
 +        }
 +      } else {
 +        super.performExpiryTimeout(task);
 +      }
 +    } finally {
 +      doUnlockForPrimary();
 +    }
 +  }
 +
 +  protected boolean isEntryEvictDestroyEnabled() {
 +    return getEvictionAttributes() != null && EvictionAction.LOCAL_DESTROY.equals(getEvictionAttributes().getAction());
 +  }
 +  
 +  protected final void processPendingSecondaryExpires()
 +  {
 +    ExpiryTask[] tasks;
 +    while (true) {
 +      // note we just keep looping until no more pendingExpires exist
 +      synchronized (this.pendingSecondaryExpires) {
 +        if (this.pendingSecondaryExpires.isEmpty()) {
 +          return;
 +        }
 +        tasks = new ExpiryTask[this.pendingSecondaryExpires.size()];
 +        tasks = this.pendingSecondaryExpires.values().toArray(tasks);
 +        this.pendingSecondaryExpires.clear();
 +      }
 +      try {
 +        if (isCacheClosing() || isClosed() || this.isDestroyed) {
 +          return;
 +        }
 +        final boolean isDebugEnabled = logger.isDebugEnabled();
 +        for (int i = 0; i < tasks.length; i++) {
 +          try {
 +            if (isDebugEnabled) {
 +              logger.debug("{} fired at {}", tasks[i], System.currentTimeMillis());
 +            }
 +            tasks[i].basicPerformTimeout(true);
 +            if (isCacheClosing() || isClosed() || isDestroyed()) {
 +              return;
 +            }
 +          }
 +          catch (EntryNotFoundException ignore) {
 +            // ignore and try the next expiry task
 +          }
 +        }
 +      }
 +      catch (RegionDestroyedException re) {
 +        // Ignore - our job is done
 +      }
 +      catch (CancelException ex) {
 +        // ignore
 +      }
 +      catch (VirtualMachineError err) {
 +        SystemFailure.initiateFailure(err);
 +        // If this ever returns, rethrow the error.  We're poisoned
 +        // now, so don't let this thread continue.
 +        throw err;
 +      }
 +      catch (Throwable ex) {
 +        // Whenever you catch Error or Throwable, you must also
 +        // catch VirtualMachineError (see above).  However, there is
 +        // _still_ a possibility that you are dealing with a cascading
 +        // error condition, so you also need to check to see if the JVM
 +        // is still usable:
 +        SystemFailure.checkFailure();
 +        logger.fatal(LocalizedMessage.create(LocalizedStrings.LocalRegion_EXCEPTION_IN_EXPIRATION_TASK), ex);
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Creates an event for the EVICT_DESTROY operation so that events will fire
 +   * for Partitioned Regions.
 +   * @param key - the key that this event is related to
 +   * @return an event for EVICT_DESTROY
 +   */
 +  @Override
 +  protected EntryEventImpl generateEvictDestroyEvent(Object key) {
 +    EntryEventImpl event = super.generateEvictDestroyEvent(key);
 +    event.setInvokePRCallbacks(true);   //see bug 40797
 +    return event;
 +  }
 +    
 +  // Entry Destruction rules
 +  // If this is a primary for the bucket
 +  //  1) apply op locally, aka destroy entry (REMOVED token)
 +  //  2) distribute op to bucket secondaries and bridge servers with synchrony on local entry
 +  //  3) cache listener with synchrony on local entry
 +  //  4) update local bs, gateway
 +  // Else not a primary
 +  //  1) apply op locally
 +  //  2) update local bs, gateway
 +  @Override
 +  protected
 +  void basicDestroy(final EntryEventImpl event,
 +                       final boolean cacheWrite,
 +                       Object expectedOldValue)
 +  throws EntryNotFoundException, CacheWriterException, TimeoutException {
 +
 +    Assert.assertTrue(!isTX());
 +    Assert.assertTrue(event.getOperation().isDistributed());
 +
 +    beginLocalWrite(event);
 +    try {
 +      // increment the tailKey for the destroy event
 +      if (this.partitionedRegion.isParallelWanEnabled()) {
 +        handleWANEvent(event);
 +      }
 +      // In GemFire EVICT_DESTROY is not distributed, so in order to remove the entry
 +      // from memory, allow the destroy to proceed. fixes #49784
 +      if (event.isLoadedFromHDFS() && !getBucketAdvisor().isPrimary()) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Put the destory event in HDFS queue on secondary "
 +              + "and return as event is HDFS loaded " + event);
 +        }
 +        notifyGatewaySender(EnumListenerEvent.AFTER_DESTROY, event);
 +        return;
 +      }else{
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Going ahead with the destroy on GemFire system");
 +        }
 +      }
 +      // This call should invoke AbstractRegionMap (aka ARM) destroy method
 +      // which calls the CacheWriter, then performs the local op.
 +      // The ARM then calls basicDestroyPart2 with the entry synchronized.
 +      if ( !hasSeenEvent(event) ) {
 +        if (event.getOperation().isExpiration()) { // bug 39905 - invoke listeners for expiration
 +          DistributedSystem sys =   cache.getDistributedSystem(); 
 +          if (event.getEventId() == null) { // Fix for #47388
 +            EventID newID = new EventID(sys);
 +            event.setEventId(newID);
 +          }
 +          event.setInvokePRCallbacks(getBucketAdvisor().isPrimary());
 +        }
 +        boolean done = mapDestroy(event,
 +                          cacheWrite,
 +                          false, // isEviction //merge44610: In cheetah instead of false event.getOperation().isEviction() is used. We kept the cedar change as it is.
 +                          expectedOldValue);
 +        if(done && !getBucketAdvisor().isPrimary() && isEntryExpiryPossible()) {
 +          synchronized(pendingSecondaryExpires) {
 +            pendingSecondaryExpires.remove(event.getKey());
 +          }
 +        }
 +        return;
 +      }
 +      else {
-         distributeDestroyOperation(event);
++    	if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++          distributeDestroyOperation(event);
++    	}
 +        return;
 +      }
 +    } finally {
 +      endLocalWrite(event);
 +    }
 +  }
 +  
 +  protected void distributeDestroyOperation (EntryEventImpl event) {
 +    if (logger.isTraceEnabled(LogMarker.DM)) {
 +      logger.trace(LogMarker.DM, "BR.basicDestroy: this cache has already seen this event {}", event);
 +    }
 +    if (!event.isOriginRemote()
 +        && getBucketAdvisor().isPrimary()) {
 +      if (event.isBulkOpInProgress()) {
 +        // consolidate the DestroyOperation for each entry into a RemoveAllMessage
 +        event.getRemoveAllOperation().addEntry(event, this.getId());
 +      } else {
 +        // This cache has processed the event, forward operation
 +        // and event messages to backup buckets
 +        event.setOldValueFromRegion();
 +        new DestroyOperation(event).distribute();
 +      }
 +    }
 +
 +    if (!event.getOperation().isRemoveAll()) {  // removeAll will invoke listeners later
 +      event.invokeCallbacks(this,true, false);    
 +    }
 +  }
 +
 +  @Override
 +  protected void basicDestroyBeforeRemoval(RegionEntry entry, EntryEventImpl event) {
 +    // Assumed this is called with entry synchrony
 +    if (!event.isOriginRemote()
 +        && !event.isBulkOpInProgress()
 +        && !event.getOperation().isLocal()
 +        && !Operation.EVICT_DESTROY.equals(event.getOperation())
 +        && !(event.isExpiration() && isEntryEvictDestroyEnabled())) {
 +
 +      if (event.getVersionTag() == null || event.getVersionTag().isGatewayTag()) {
 +        VersionTag v = entry.generateVersionTag(null, false, this, event);
 +        if (logger.isDebugEnabled() && v != null) {
 +          logger.debug("generated version tag {} in region {}", v, this.getName());
 +        }
 +      }
 +
 +      // This code assumes it is safe ignore token mode (GII in progress)
 +      // because it assume when the origin of the event is local,
 +      // then GII has completed (the region has been completely initialized)
 +
 +      // This code assumes that this bucket is primary
 +      new DestroyOperation(event).distribute();
 +    }
 +    super.basicDestroyBeforeRemoval(entry, event);
 +  }
 +
 +  @Override
 +  void distributeDestroy(EntryEventImpl event, Object expectedOldValue) {
 +  }
 +  
 +  
 +// impl removed - not needed for listener invocation alterations
 +//  void basicDestroyPart2(RegionEntry re, EntryEventImpl event, boolean inTokenMode, boolean invokeCallbacks)
 +
 +  @Override
 +  protected void validateArguments(Object key, Object value, Object aCallbackArgument)
 +  {
 +    Assert.assertTrue(!isTX());
 +    super.validateArguments(key, value, aCallbackArgument);
 +  }
 +
 +  public void forceSerialized(EntryEventImpl event) {
 +    event.makeSerializedNewValue();
 +//    Object obj = event.getRawNewValue();
 +//    if (obj instanceof byte[]
 +//                            || obj == null
 +//                            || obj instanceof CachedDeserializable
 +//                            || obj == NotAvailable.NOT_AVAILABLE
 +//                            || Token.isInvalidOrRemoved(obj)) {
 +//                          // already serialized
 +//                          return;
 +//                        }
 +//    throw new InternalGemFireError("event did not force serialized: " + event);
 +  }
 +  
 +  /**
 +   * This method is called when a miss from a get ends up
 +   * finding an object through a cache loader or from a server.
 +   * In that case we want to make sure that we don't move
 +   * this bucket while putting the value in the ache.
 +   * @see LocalRegion#basicPutEntry(EntryEventImpl, long) 
 +   */
 +  @Override
 +  protected RegionEntry basicPutEntry(final EntryEventImpl event,
 +      final long lastModified) throws TimeoutException,
 +      CacheWriterException {
 +    beginLocalWrite(event);
 +    try {
 +      event.setInvokePRCallbacks(true);
 +      forceSerialized(event);
 +      return super.basicPutEntry(event, lastModified);
 +    } finally {
 +      endLocalWrite(event);
 +    }
 +  }
 +
 +  @Override
 +  void basicUpdateEntryVersion(EntryEventImpl event)
 +      throws EntryNotFoundException {
 +    
 +    Assert.assertTrue(!isTX());
 +    Assert.assertTrue(event.getOperation().isDistributed());
 +
 +    beginLocalWrite(event);
 +    try {
 +      
 +      if (!hasSeenEvent(event)) {
 +        this.entries.updateEntryVersion(event);
 +      } else {
 +        if (logger.isTraceEnabled(LogMarker.DM)) {
 +          logger.trace(LogMarker.DM, "BR.basicUpdateEntryVersion: this cache has already seen this event {}", event);
 +        }
 +      }
 +      if (!event.isOriginRemote() && getBucketAdvisor().isPrimary()) {
 +        // This cache has processed the event, forward operation
 +        // and event messages to backup buckets
-         new UpdateEntryVersionOperation(event).distribute();
++    	if (!getConcurrencyChecksEnabled() || event.hasValidVersionTag()) {
++          new UpdateEntryVersionOperation(event).distribute();
++    	}
 +      }
 +      return;
 +    } finally {
 +      endLocalWrite(event);
 +    }
 +  }
 +
 +  public int getRedundancyLevel()
 +  {
 +    return this.redundancy;
 +  }
 +
 +  public boolean isPrimary() {
 +    throw new UnsupportedOperationException(LocalizedStrings.BucketRegion_THIS_SHOULD_NEVER_BE_CALLED_ON_0.toLocalizedString(getClass()));
 +  }
 +  
 +  @Override
 +  public boolean isDestroyed() {
 +    //TODO prpersist - Added this if null check for the partitioned region
 +    // because we create the disk store for a bucket *before* in the constructor
 +    // for local region, which is before this final field is assigned. This is why
 +    // we shouldn't do some much work in the constructors! This is a temporary
 +    // hack until I move must of the constructor code to region.initialize.
 +    return isBucketDestroyed()
 +        || (this.partitionedRegion != null
 +            && this.partitionedRegion.isLocallyDestroyed && !isInDestroyingThread()); 
 +  }
 +
 +  /**
 +   * Return true if this bucket has been destroyed.
 +   * Don't bother checking to see if the PR that owns this bucket was destroyed;
 +   * that has already been checked.
 +   * @since 6.0
 +   */
 +  public boolean isBucketDestroyed() {
 +    return super.isDestroyed();
 +  }
 +
 +  @Override
 +  public boolean isHDFSRegion() {
 +    return this.partitionedRegion.isHDFSRegion();
 +  }
 +
 +  @Override
 +  public boolean isHDFSReadWriteRegion() {
 +    return this.partitionedRegion.isHDFSReadWriteRegion();
 +  }
 +
 +  @Override
 +  protected boolean isHDFSWriteOnly() {
 +    return this.partitionedRegion.isHDFSWriteOnly();
 +  }
 +
 +  @Override
 +  public int sizeEstimate() {
 +    if (isHDFSReadWriteRegion()) {
 +      try {
 +        checkForPrimary();
 +        ConcurrentParallelGatewaySenderQueue q = getHDFSQueue();
 +        if (q == null) return 0;
 +        int hdfsBucketRegionSize = q.getBucketRegionQueue(
 +            partitionedRegion, getId()).size();
 +        int hoplogEstimate = (int) getHoplogOrganizer().sizeEstimate();
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("for bucket " + getName() + " estimateSize returning "
 +                  + (hdfsBucketRegionSize + hoplogEstimate));
 +        }
 +        return hdfsBucketRegionSize + hoplogEstimate;
 +      } catch (ForceReattemptException e) {
 +        throw new PrimaryBucketException(e.getLocalizedMessage(), e);
 +      }
 +    }
 +    return size();
 +  }
 +
 +  @Override
 +  public void checkReadiness()
 +  {
 +    super.checkReadiness();
 +    if (isDestroyed()) {
 +      throw new RegionDestroyedException(toString(), getFullPath());
 +    }
 +  }
 +
 +  @Override
 +  public PartitionedRegion getPartitionedRegion(){
 +    return this.partitionedRegion;
 +  }
 +  
 +  /**
 +   * is the current thread involved in destroying the PR that
 +   * owns this region?
 +   */
 +  private final boolean isInDestroyingThread() {
 +    return this.partitionedRegion.locallyDestroyingThread
 +      == Thread.currentThread();
 +  }
 +//  public int getSerialNumber() {
 +//    String s = "This should never be called on " + getClass();
 +//    throw new UnsupportedOperationException(s);
 +//  }
 +
 +  @Override
 +  public void fillInProfile(Profile profile) {
 +    super.fillInProfile(profile);
 +    BucketProfile bp = (BucketProfile) profile;
 +    bp.isInitializing = this.initializationLatchAfterGetInitialImage.getCount() > 0;
 +  }
 +  
 +  /** check to see if the partitioned region is locally destroyed or closed */
 +  public boolean isPartitionedRegionOpen() {
 +    return !this.partitionedRegion.isLocallyDestroyed &&
 +      !this.partitionedRegion.isClosed && !this.partitionedRegion.isDestroyed();
 +  }
 +  
 +  /**
 +   * Horribly plagiarized from the similar method in LocalRegion
 +   * 
 +   * @param key
 +   * @param updateStats
 +   * @param clientEvent holder for client version tag
 +   * @param returnTombstones whether Token.TOMBSTONE should be returned for destroyed entries
 +   * @return serialized form if present, null if the entry is not in the cache,
 +   *         or INVALID or LOCAL_INVALID re is a miss (invalid)
 +   * @throws IOException
 +   *                 if there is a serialization problem
 +   * see LocalRegion#getDeserializedValue(RegionEntry, KeyInfo, boolean, boolean,  boolean, EntryEventImpl, boolean, boolean, boolean)
 +   */
 +  private RawValue getSerialized(Object key, boolean updateStats, boolean doNotLockEntry, EntryEventImpl clientEvent, boolean returnTombstones, boolean allowReadFromHDFS) 
 +      throws EntryNotFoundException, IOException {
 +    RegionEntry re = null;
 +    if (allowReadFromHDFS) {
 +      re = this.entries.getEntry(key);
 +    } else {
 +      re = this.entries.getOperationalEntryInVM(key);
 +    }
 +    if (re == null) {
 +      return NULLVALUE;
 +    }
 +    if (re.isTombstone() && !returnTombstones) {
 +      return NULLVALUE;
 +    }
 +    Object v = null;
 +    
 +    try {
 +      v =re.getValue(this);  // TODO OFFHEAP: todo v ends up in a RawValue. For now this can be a copy of the offheap onto the heap. But it might be easy to track lifetime of RawValue
 +      if(doNotLockEntry) {
 +        if(v == Token.NOT_AVAILABLE || v == null) {
 +          return REQUIRES_ENTRY_LOCK;
 +        }
 +      }
 +      if (clientEvent != null) {
 +        VersionStamp stamp = re.getVersionStamp();
 +        if (stamp != null) {
 +          clientEvent.setVersionTag(stamp.asVersionTag());
 +        }
 +      }
 +    }catch(DiskAccessException dae) {
 +      this.handleDiskAccessException(dae);     
 +      throw dae;
 +    }
 +    
 +    if (v == null) {
 +      return NULLVALUE;
 +    } else { 
 +      if (updateStats) {
 +        updateStatsForGet(re, true);
 +      }
 +      return new RawValue(v);
 +    }
 +  }
 +
 +  /**
 +   * Return serialized form of an entry
 +   * <p>
 +   * Horribly plagiarized from the similar method in LocalRegion
 +   * 
 +   * @param keyInfo
 +   * @param generateCallbacks
 +   * @param clientEvent holder for the entry's version information 
 +   * @param returnTombstones TODO
 +   * @return serialized (byte) form
 +   * @throws IOException if the result is not serializable
 +   * @see LocalRegion#get(Object, Object, boolean, EntryEventImpl)
 +   */
 +  public RawValue getSerialized(KeyInfo keyInfo, boolean generateCallbacks, boolean doNotLockEntry, ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones, boolean allowReadFromHDFS) throws IOException {
 +    checkReadiness();
 +    checkForNoAccess();
 +    CachePerfStats stats = getCachePerfStats();
 +    long start = stats.startGet();
 +    
 +    boolean miss = true;
 +    try {
 +      RawValue valueBytes = NULLVALUE;
 +      boolean isCreate = false;
 +      RawValue result = getSerialized(keyInfo.getKey(), true, doNotLockEntry, clientEvent, returnTombstones, allowReadFromHDFS);
 +      isCreate = result == NULLVALUE || (result.getRawValue() == Token.TOMBSTONE && !returnTombstones);
 +      miss = (result == NULLVALUE || Token.isInvalid(result.getRawValue()));
 +      if (miss) {
 +        // if scope is local and there is no loader, then
 +        // don't go further to try and get value
 +        if (hasServerProxy() || 
 +            basicGetLoader() != null) {
 +          if(doNotLockEntry) {
 +            return REQUIRES_ENTRY_LOCK;
 +          }
 +          // TODO OFFHEAP: optimze
 +          Object value = nonTxnFindObject(keyInfo, isCreate,
 +              generateCallbacks, result.getRawValue(), true, true, requestingClient, clientEvent, false, allowReadFromHDFS);
 +          if (value != null) {
 +            result = new RawValue(value);
 +          }
 +        }
 +        else { // local scope with no loader, still might need to update stats
 +          if (isCreate) {
 +            recordMiss(null, keyInfo.getKey());
 +          }
 +        }
 +      }
 +      return result;  // changed in 7.0 to return RawValue(Token.INVALID) if the entry is invalid
 +    }
 +    finally {
 +      stats.endGet(start, miss);
 +    }
 +    
 +  } // getSerialized
 +
 +  @Override
 +  public String toString()
 +  {
 +    return new StringBuilder()
 +    .append("BucketRegion")
 +    .append("[path='").append(getFullPath())
 +    .append(";serial=").append(getSerialNumber())
 +    .append(";primary=").append(getBucketAdvisor().getProxyBucketRegion().isPrimary())
 +    .append(";indexUpdater=").append(getIndexUpdater())
 +    .append("]")
 +    .toString();
 +  }
 +
 +  @Override
 +  protected void distributedRegionCleanup(RegionEventImpl event)
 +  {
 +    // No need to close advisor, assume its already closed 
 +    // However we need to remove our listener from the advisor (see bug 43950).
 +    this.distAdvisor.removeMembershipListener(this.advisorListener);
 +  }
 +  
 +  /**
 +   * Tell the peers that this VM has destroyed the region.
 +   * 
 +   * Also marks the local disk files as to be deleted before 
 +   * sending the message to peers.
 +   * 
 +   * 
 +   * @param rebalance true if this is due to a rebalance removing the bucket
 +   */
 +  public void removeFromPeersAdvisors(boolean rebalance) {
 +    if(getPersistenceAdvisor() != null) {
 +      getPersistenceAdvisor().releaseTieLock();
 +    }
 +    
 +    DiskRegion diskRegion = getDiskRegion();
 +    
 +    //Tell our peers whether we are destroying this region
 +    //or just closing it.
 +    boolean shouldDestroy = rebalance || diskRegion == null
 +        || !diskRegion.isRecreated();
 +    Operation op = shouldDestroy ? Operation.REGION_LOCAL_DESTROY
 +        : Operation.REGION_CLOSE;
 +    
 +    RegionEventImpl event = new RegionEventImpl(this, op, null, false,
 +        getMyId(), generateEventID()/* generate EventID */);
 +    // When destroying the whole partitioned region, there's no need to
 +    // distribute the region closure/destruction, the PR RegionAdvisor.close() 
 +    // has taken care of it
 +    if (isPartitionedRegionOpen()) {
 +      
 +      
 +      //Only delete the files on the local disk if
 +      //this is a rebalance, or we are creating the bucket
 +      //for the first time
 +      if (diskRegion != null && shouldDestroy) { 
 +        diskRegion.beginDestroyDataStorage();
 +      }
 +      
 +      //Send out the destroy op to peers
 +      new DestroyRegionOperation(event, true).distribute();
 +    }
 +  }
 +
 +  @Override
 +  protected void distributeDestroyRegion(RegionEventImpl event,
 +                                         boolean notifyOfRegionDeparture) {
 +    //No need to do this when we actually destroy the region,
 +    //we already distributed this info.
 +  }
 +  
 +  EntryEventImpl createEventForPR(EntryEventImpl sourceEvent) {
 +    EntryEventImpl e2 = new EntryEventImpl(sourceEvent);
 +    boolean returned = false;
 +    try {
 +    e2.setRegion(this.partitionedRegion);
 +    if (FORCE_LOCAL_LISTENERS_INVOCATION) {
 +      e2.setInvokePRCallbacks(true);
 +    }
 +    else {
 +      e2.setInvokePRCallbacks(sourceEvent.getInvokePRCallbacks());
 +    }
 +    DistributedMember dm = this.getDistributionManager().getDistributionManagerId();
 +    e2.setOriginRemote(!e2.getDistributedMember().equals(dm));
 +    returned = true;
 +    return e2;
 +    } finally {
 +      if (!returned) {
 +        e2.release();
 +      }
 +    }
 +  }
 +
 +  
 +  
 +  @Override
 +  public void invokeTXCallbacks(
 +      final EnumListenerEvent eventType, final EntryEventImpl event,
 +      final boolean callDispatchListenerEvent)
 +  {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("BR.invokeTXCallbacks for event {}", event);
 +    }
 +    // bucket events may make it to this point even though the bucket is still
 +    // initializing.  We can't block while initializing or a GII state flush
 +    // may hang, so we avoid notifying the bucket
 +    if (this.isInitialized()) {
 +      boolean callThem = callDispatchListenerEvent;
 +      if (event.isPossibleDuplicate()
 +          && this.eventTracker.isInitialImageProvider(event.getDistributedMember())) {
 +        callThem = false;
 +      }
 +      super.invokeTXCallbacks(eventType, event, callThem);
 +    }
 +    final EntryEventImpl prevent = createEventForPR(event);
 +    try {
 +      this.partitionedRegion.invokeTXCallbacks(eventType, prevent, this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false);
 +    } finally {
 +      prevent.release();
 +    }
 +  }
 +  
 +  
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.internal.cache.LocalRegion#invokeDestroyCallbacks(com.gemstone.gemfire.internal.cache.EnumListenerEvent, com.gemstone.gemfire.internal.cache.EntryEventImpl, boolean)
 +   */
 +  @Override
 +  public void invokeDestroyCallbacks(
 +      final EnumListenerEvent eventType, final EntryEventImpl event,
 +      final boolean callDispatchListenerEvent, boolean notifyGateways)
 +  {
 +    // bucket events may make it to this point even though the bucket is still
 +    // initializing.  We can't block while initializing or a GII state flush
 +    // may hang, so we avoid notifying the bucket
 +    if (this.isInitialized()) {
 +      boolean callThem = callDispatchListenerEvent;
 +      if (event.isPossibleDuplicate()
 +          && this.eventTracker.isInitialImageProvider(event.getDistributedMember())) {
 +        callThem = false;
 +      }
 +      super.invokeDestroyCallbacks(eventType, event, callThem, notifyGateways);
 +    }
 +    final EntryEventImpl prevent = createEventForPR(event);
 +    try {
 +      this.partitionedRegion.invokeDestroyCallbacks(eventType, prevent, this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false, false);
 +    } finally {
 +      prevent.release();
 +    }
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.internal.cache.LocalRegion#invokeInvalidateCallbacks(com.gemstone.gemfire.internal.cache.EnumListenerEvent, com.gemstone.gemfire.internal.cache.EntryEventImpl, boolean)
 +   */
 +  @Override
 +  public void invokeInvalidateCallbacks(
 +      final EnumListenerEvent eventType, final EntryEventImpl event,
 +      final boolean callDispatchListenerEvent)
 +  {
 +    // bucket events may make it to this point even though the bucket is still
 +    // initializing.  We can't block while initializing or a GII state flush
 +    // may hang, so we avoid notifying the bucket
 +    if (this.isInitialized()) {
 +      boolean callThem = callDispatchListenerEvent;
 +      if (event.isPossibleDuplicate()
 +          && this.eventTracker.isInitialImageProvider(event.getDistributedMember())) {
 +        callThem = false;
 +      }
 +      super.invokeInvalidateCallbacks(eventType, event, callThem);
 +    }
 +    final EntryEventImpl prevent = createEventForPR(event);
 +    try {
 +      this.partitionedRegion.invokeInvalidateCallbacks(eventType, prevent, this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false);
 +    } finally {
 +      prevent.release();
 +    }
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.internal.cache.LocalRegion#invokePutCallbacks(com.gemstone.gemfire.internal.cache.EnumListenerEvent, com.gemstone.gemfire.internal.cache.EntryEventImpl, boolean)
 +   */
 +  @Override
 +  public void invokePutCallbacks(
 +      final EnumListenerEvent eventType, final EntryEventImpl event,
 +      final boolean callDispatchListenerEvent, boolean notifyGateways)
 +  {
 +    if (logger.isTraceEnabled()) {
 +      logger.trace("invoking put callbacks on bucket for event {}", event);
 +    }
 +    // bucket events may make it to this point even though the bucket is still
 +    // initializing.  We can't block while initializing or a GII state flush
 +    // may hang, so we avoid notifying the bucket
 +    if (this.isInitialized()) {
 +      boolean callThem = callDispatchListenerEvent;
 +      if (callThem && event.isPossibleDuplicate()
 +          && this.eventTracker.isInitialImageProvider(event.getDistributedMember())) {
 +        callThem = false;
 +      }
 +      super.invokePutCallbacks(eventType, event, callThem, notifyGateways);
 +    }
 +
 +    final EntryEventImpl prevent = createEventForPR(event);
 +    try {
 +      this.partitionedRegion.invokePutCallbacks(eventType, prevent,
 +              this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false, false);
 +    } finally {
 +      prevent.release();
 +    }
 +  }
 +  
 +  /**
 +   * perform adjunct messaging for the given operation and return a set of
 +   * members that should be attached to the operation's reply processor (if any)
 +   * @param event the event causing this messaging
 +   * @param cacheOpRecipients set of receiver which got cacheUpdateOperation.
 +   * @param adjunctRecipients recipients that must unconditionally get the event
 +   * @param filterRoutingInfo routing information for all members having the region
 +   * @param processor the reply processor, or null if there isn't one
 +   * @return the set of failed recipients
 +   */
 +  protected Set performAdjunctMessaging(EntryEventImpl event,
 +      Set cacheOpRecipients, Set adjunctRecipients,
 +      FilterRoutingInfo filterRoutingInfo,
 +      DirectReplyProcessor processor,
 +      boolean calculateDelta,
 +      boolean sendDeltaWithFullValue) {
 +    
 +    Set failures = Collections.EMPTY_SET;
 +    PartitionMessage msg = event.getPartitionMessage();
 +    if (calculateDelta) {
 +      setDeltaIfNeeded(event);
 +    }
 +    if (msg != null) {
 +      // The primary bucket member which is being modified remotely by a GemFire
 +      // thread via a received PartitionedMessage
 +      //Asif: Some of the adjunct recepients include those members which 
 +      // are sqlFabricHub & would need old value along with news
 +      msg = msg.getMessageForRelayToListeners(event, adjunctRecipients);
 +      msg.setSender(this.partitionedRegion.getDistributionManager()
 +          .getDistributionManagerId());
 +      msg.setSendDeltaWithFullValue(sendDeltaWithFullValue);
 +      
 +      failures = msg.relayToListeners(cacheOpRecipients, adjunctRecipients,
 +          filterRoutingInfo, event, this.partitionedRegion, processor);
 +    }
 +    else {
 +      // The primary bucket is being modified locally by an application thread locally 
 +      Operation op = event.getOperation();
 +      if (op.isCreate() || op.isUpdate()) {
 +        // note that at this point ifNew/ifOld have been used to update the
 +        // local store, and the event operation should be correct
 +        failures = PutMessage.notifyListeners(cacheOpRecipients,
 +            adjunctRecipients, filterRoutingInfo, this.partitionedRegion, 
 +            event, op.isCreate(), !op.isCreate(), processor,
 +            sendDeltaWithFullValue);
 +      }
 +      else if (op.isDestroy()) {
 +        failures = DestroyMessage.notifyListeners(cacheOpRecipients,
 +            adjunctRecipients, filterRoutingInfo,
 +            this.partitionedRegion, event, processor);
 +      }
 +      else if (op.isInvalidate()) {
 +        failures = InvalidateMessage.notifyListeners(cacheOpRecipients,
 +            adjunctRecipients, filterRoutingInfo, 
 +            this.partitionedRegion, event, processor);
 +      }
 +      else {
 +        failures = adjunctRecipients;
 +      }
 +    }
 +    return failures;
 +  }
 +
 +  private void setDeltaIfNeeded(EntryEventImpl event) {
 +    if (this.partitionedRegion.getSystem().getConfig().getDeltaPropagation()
 +        && event.getOperation().isUpdate() && event.getDeltaBytes() == null) {
 +      @Unretained Object rawNewValue = event.getRawNewValue();
 +      if (!(rawNewValue instanceof CachedDeserializable)) {
 +        return;
 +      }
 +      if (rawNewValue instanceof StoredObject && !((StoredObject) rawNewValue).isSerialized()) {
 +        // it is a byte[]; not a Delta
 +        return;
 +      }
 +      Object instance = ((CachedDeserializable)rawNewValue).getValue();
 +      if (instance instanceof com.gemstone.gemfire.Delta
 +          && ((com.gemstone.gemfire.Delta)instance).hasDelta()) {
 +        try {
 +          HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
 +          long start = DistributionStats.getStatTime();
 +          ((com.gemstone.gemfire.Delta)instance).toDelta(hdos);
 +          event.setDeltaBytes(hdos.toByteArray());
 +          this.partitionedRegion.getCachePerfStats().endDeltaPrepared(start);
 +        }
 +        catch (RuntimeException re) {
 +          throw re;
 +        }
 +        catch (Exception e) {
 +          throw new DeltaSerializationException(
 +              LocalizedStrings.DistributionManager_CAUGHT_EXCEPTION_WHILE_SENDING_DELTA
 +                  .toLocalizedString(), e);
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * create a PutAllPRMessage for notify-only and send it to all adjunct nodes. 
 +   * return a set of members that should be attached to the operation's reply processor (if any)
 +   * @param dpao DistributedPutAllOperation object for PutAllMessage
 +   * @param cacheOpRecipients set of receiver which got cacheUpdateOperation.
 +   * @param adjunctRecipients recipients that must unconditionally get the event
 +   * @param filterRoutingInfo routing information for all members having the region
 +   * @param processor the reply processor, or null if there isn't one
 +   * @return the set of failed recipients
 +   */
 +  public Set performPutAllAdjunctMessaging(DistributedPutAllOperation dpao,
 +      Set cacheOpRecipients, Set adjunctRecipients, FilterRoutingInfo filterRoutingInfo,
 +      DirectReplyProcessor processor) {
 +    // create a PutAllPRMessage out of PutAllMessage to send to adjunct nodes
 +    PutAllPRMessage prMsg = dpao.createPRMessagesNotifyOnly(getId());
 +    prMsg.initMessage(this.partitionedRegion, adjunctRecipients, true, processor);
 +    prMsg.setSender(this.partitionedRegion.getDistributionManager()
 +        .getDistributionManagerId());
 +    
 +    // find members who have clients subscribed to this event and add them
 +    // to the recipients list.  Also determine if there are any FilterInfo
 +    // routing tables for any of the receivers
 +//    boolean anyWithRouting = false;
 +    Set recipients = null;
 +    Set membersWithRouting = filterRoutingInfo.getMembers();
 +    for (Iterator it=membersWithRouting.iterator(); it.hasNext(); ) {
 +      Object mbr = it.next();
 +      if (!cacheOpRecipients.contains(mbr)) {
 +//        anyWithRouting = true;
 +        if (!adjunctRecipients.contains(mbr)) {
 +          if (recipients == null) {
 +            recipients = new HashSet();
 +            recipients.add(mbr);
 +          }
 +        }
 +      }
 +    }
 +    if (recipients == null) {
 +      recipients = adjunctRecipients;
 +    } else {
 +      recipients.addAll(adjunctRecipients);
 +    }
 +
 +//    Set failures = Collections.EMPTY_SET;
 +
 +//    if (!anyWithRouting) {
 +      Set failures = this.partitionedRegion.getDistributionManager().putOutgoing(prMsg);
 +
 +//  } else {
 +//      // Send message to each member.  We set a FilterRoutingInfo serialization
 +//      // target so that serialization of the PutAllData objects held in the
 +//      // message will only serialize the routing entry for the message recipient
 +//      Iterator rIter = recipients.iterator();
 +//      failures = new HashSet();
 +//      while (rIter.hasNext()){
 +//        InternalDistributedMember member = (InternalDistributedMember)rIter.next();
 +//        FilterRoutingInfo.setSerializationTarget(member);
 +//        try {
 +//          prMsg.resetRecipients();
 +//          prMsg.setRecipient(member);
 +//          Set fs = this.partitionedRegion.getDistributionManager().putOutgoing(prMsg);
 +//          if (fs != null && !fs.isEmpty()) {
 +//            failures.addAll(fs);
 +//          }
 +//        } finally {
 +//          FilterRoutingInfo.clearSerializationTarget();
 +//        }
 +//      }
 +//    }
 +
 +    return failures;
 +  }
 +
 +  /**
 +   * create a RemoveAllPRMessage for notify-only and send it to all adjunct nodes. 
 +   * return a set of members that should be attached to the operation's reply processor (if any)
 +   * @param op DistributedRemoveAllOperation object for RemoveAllMessage
 +   * @param cacheOpRecipients set of receiver which got cacheUpdateOperation.
 +   * @param adjunctRecipients recipients that must unconditionally get the event
 +   * @param filterRoutingInfo routing information for all members having the region
 +   * @param processor the reply processor, or null if there isn't one
 +   * @return the set of failed recipients
 +   */
 +  public Set performRemoveAllAdjunctMessaging(DistributedRemoveAllOperation op,
 +      Set cacheOpRecipients, Set adjunctRecipients, FilterRoutingInfo filterRoutingInfo,
 +      DirectReplyProcessor processor) {
 +    // create a RemoveAllPRMessage out of RemoveAllMessage to send to adjunct nodes
 +    RemoveAllPRMessage prMsg = op.createPRMessagesNotifyOnly(getId());
 +    prMsg.initMessage(this.partitionedRegion, adjunctRecipients, true, processor);
 +    prMsg.setSender(this.partitionedRegion.getDistributionManager()
 +        .getDistributionManagerId());
 +    
 +    // find members who have clients subscribed to this event and add them
 +    // to the recipients list.  Also determine if there are any FilterInfo
 +    // routing tables for any of the receivers
 +    Set recipients = null;
 +    Set membersWithRouting = filterRoutingInfo.getMembers();
 +    for (Iterator it=membersWithRouting.iterator(); it.hasNext(); ) {
 +      Object mbr = it.next();
 +      if (!cacheOpRecipients.contains(mbr)) {
 +//        anyWithRouting = true;
 +        if (!adjunctRecipients.contains(mbr)) {
 +          if (recipients == null) {
 +            recipients = new HashSet();
 +            recipients.add(mbr);
 +          }
 +        }
 +      }
 +    }
 +    if (recipients == null) {
 +      recipients = adjunctRecipients;
 +    } else {
 +      recipients.addAll(adjunctRecipients);
 +    }
 +
 +    Set failures = this.partitionedRegion.getDistributionManager().putOutgoing(prMsg);
 +    return failures;
 +  }
 +
 +  /**
 +   * return the set of recipients for adjunct operations
 +   */
 +  protected Set getAdjunctReceivers(EntryEventImpl event, Set cacheOpReceivers,
 +      Set twoMessages, FilterRoutingInfo routing) {
 +    Operation op = event.getOperation();
 +    if (op.isUpdate() || op.isCreate() || op.isDestroy() || op.isInvalidate()) {
 +      // this method can safely assume that the operation is being distributed from
 +      // the primary bucket holder to other nodes
 +      Set r = this.partitionedRegion.getRegionAdvisor()
 +        .adviseRequiresNotification(event);
 +            
 +      if (r.size() > 0) {
 +        r.removeAll(cacheOpReceivers);
 +      }
 +      
 +      // buckets that are initializing may transition out of token mode during
 +      // message transmission and need both cache-op and adjunct messages to
 +      // ensure that listeners are invoked
 +      if (twoMessages.size() > 0) {
 +        if (r.size() == 0) { // can't add to Collections.EMPTY_SET
 +          r = twoMessages;
 +        }
 +        else {
 +          r.addAll(twoMessages);
 +        }  
 +      }      
 +      if (routing != null) {
 +        // add adjunct messages to members with client routings
 +        for (InternalDistributedMember id: routing.getMembers()) {
 +          if (!cacheOpReceivers.contains(id)) {
 +            if (r.isEmpty()) {
 +              r = new HashSet();
 +            }
 +            r.add(id);
 +          }
 +        }
 +      }
 +      return r;
 +    } 
 +    else {
 +      return Collections.EMPTY_SET;
 +    }
 +  }
 +
 +  public int getId() {
 +    return getBucketAdvisor().getProxyBucketRegion().getId();
 +  }
 +
 +  @Override
 +  protected void cacheWriteBeforePut(EntryEventImpl event, Set netWriteRecipients,
 +      CacheWriter localWriter,
 +      boolean requireOldValue, Object expectedOldValue)
 +  throws CacheWriterException, TimeoutException {
 +    
 +    boolean origRemoteState = false;
 +    try {
 +      if (event.getPartitionMessage() != null || event.hasClientOrigin()) {
 +        origRemoteState=event.isOriginRemote();
 +        event.setOriginRemote(true);
 +      }
 +      event.setRegion(this.partitionedRegion);
 +      this.partitionedRegion.cacheWriteBeforePut(event, netWriteRecipients,
 +          localWriter, requireOldValue, expectedOldValue);
 +    } finally {
 +      if (event.getPartitionMessage() != null || event.hasClientOrigin()) {
 +        event.setOriginRemote(origRemoteState);
 +      }
 +      event.setRegion(this);
 +    }
 +  }
 +
 +  @Override
 +  boolean cacheWriteBeforeDestroy(EntryEventImpl event, Object expectedOldValue)
 +  throws CacheWriterException, EntryNotFoundException, TimeoutException {
 +    
 +    boolean origRemoteState = false;
 +    boolean ret = false;
 +    try {
 +      if (event.getPartitionMessage() != null || event.hasClientOrigin()) {
 +        origRemoteState=event.isOriginRemote();
 +        event.setOriginRemote(true);
 +      }
 +      event.setRegion(this.partitionedRegion);
 +      ret = this.partitionedRegion.cacheWriteBeforeDestroy(event, expectedOldValue);
 +    } finally {
 +      if (event.getPartitionMessage() != null || event.hasClientOrigin()) {
 +        event.setOriginRemote(origRemoteState);
 +      }
 +      event.setRegion(this);
 +    }
 +    return ret;
 +    //  return super.cacheWriteBeforeDestroy(event);
 +  }
 +
 +  @Override
 +  public CacheWriter basicGetWriter() {
 +    return this.partitionedRegion.basicGetWriter();
 +  }
 +   @Override
 +  void cleanUpOnIncompleteOp(EntryEventImpl event,   RegionEntry re, 
 +      boolean eventRecorded, boolean updateStats, boolean isReplace) {
 +     
 +    
 +    if(!eventRecorded || isReplace) {
 +      //No indexes updated so safe to remove.
 +      this.entries.removeEntry(event.getKey(), re, updateStats) ;      
 +    }/*else {
 +      //if event recorded is true, that means as per event tracker entry is in
 +      //system. As per sqlfabric, indexes have been updated. What is not done
 +      // is basicPutPart2( distribution etc). So we do nothing as PR's re-attempt
 +      // will do the required basicPutPart2. If we remove the entry here, than 
 +      //event tracker will not allow re insertion. So either we do nothing or
 +      //if we remove ,than we have to update sqlfindexes as well as undo recording
 +      // of event.
 +       //TODO:OQL indexes? : Hope they get updated during retry. The issue is that oql indexes
 +       // get updated after distribute , so it is entirely possible that oql index are 
 +        // not updated. what if retry fails?
 +       
 +    }*/
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.internal.cache.partitioned.Bucket#getBucketOwners()
 +   * @since gemfire59poc
 +   */
 +  public Set getBucketOwners() {
 +    return getBucketAdvisor().getProxyBucketRegion().getBucketOwners();    
 +  }
 +
 +  public long getCounter() {
 +    return counter.get();
 +  }
 +
 +  public void setCounter(AtomicLong counter) {
 +    this.counter = counter;
 +  }
 +
 +  public void updateCounter(long delta) {
 +    if (delta != 0) {
 +      this.counter.getAndAdd(delta);
 +    }
 +  }
 +
 +  public void resetCounter() {
 +    if (this.counter.get() != 0) {
 +      this.counter.set(0);
 +    }
 +  }
 +
 +  public long getLimit() {
 +    if (this.limit == null) {
 +	  return 0;
 +	}
 +	return limit.get();
 +  }
 +
 +  public void setLimit(long limit) {
 +	// This method can be called before object of this class is created
 +	if (this.limit == null) {
 +	  this.limit = new AtomicLong();
 +	}
 +	this.limit.set(limit);
 +  }
 +
 +  static int calcMemSize(Object value) {
 +    if (value != null && (value instanceof GatewaySenderEventImpl)) {
 +      return ((GatewaySenderEventImpl)value).getSerializedValueSize();
 +    } 
 +    if (value == null || value instanceof Token) {
 +      return 0;
 +    }
 +    if (!(value instanceof byte[]) && !(value instanceof CachedDeserializable)
 +        && !(value instanceof com.gemstone.gemfire.Delta) && !(value instanceof Delta)) {
 +    // ezoerner:20090401 it's possible this value is a Delta
 +      throw new InternalGemFireError("DEBUG: calcMemSize: weird value (class " 
 +          + value.getClass() + "): " + value);
 +    }
 +    
 +    try {
 +      return CachedDeserializableFactory.calcMemSize(value);
 +    } catch (IllegalArgumentException e) {
 +      return 0;
 +    }
 +  }
 +
 +  boolean isDestroyingDiskRegion;
 +
 +  @Override
 +  protected void updateSizeOnClearRegion(int sizeBeforeClear) {
 +    // This method is only called when the bucket is destroyed. If we
 +    // start supporting clear of partitioned regions, this logic needs to change
 +    // we can't just set these counters to zero, because there could be
 +    // concurrent operations that are also updating these stats. For example,
 +    //a destroy could have already been applied to the map, and then updates
 +    //the stat after we reset it, making the state negative.
 +    
 +    final PartitionedRegionDataStore prDs = this.partitionedRegion.getDataStore();
 +    long oldMemValue;
 +
 +    if(this.isDestroyed || this.isDestroyingDiskRegion) {
 +      //If this region is destroyed, mark the stat as destroyed.
 +      oldMemValue = this.bytesInMemory.getAndSet(BUCKET_DESTROYED);
 +            
 +    } else if(!this.isInitialized()) {
 +      //This case is rather special. We clear the region if the GII failed.
 +      //In the case of bucket regions, we know that there will be no concurrent operations
 +      //if GII has failed, because there is not primary. So it's safe to set these
 +      //counters to 0.
 +      oldMemValue = this.bytesInMemory.getAndSet(0);
 +    }
 +    // Gemfire PRs don't support clear. allowing it via a hack for tests
 +    else if (LocalRegion.simulateClearForTests) {
 +      oldMemValue = this.bytesInMemory.getAndSet(0);
 +    }
 +    else {
 +      throw new InternalGemFireError("Trying to clear a bucket region that was not destroyed or in initialization.");
 +    }
 +    if(oldMemValue != BUCKET_DESTROYED) {
 +      this.partitionedRegion.getPrStats().incDataStoreEntryCount(-sizeBeforeClear);
 +      prDs.updateMemoryStats(-oldMemValue);
 +    }
 +  }
 +
 +  @Override
 +  public int calculateValueSize(Object val) {
 +    // Only needed by BucketRegion
 +    return calcMemSize(val);
 +  }
 +  @Override
 +  public int calculateRegionEntryValueSize(RegionEntry re) {
 +    return calcMemSize(re._getValue()); // OFFHEAP _getValue ok
 +  }
 +
 +  @Override
 +  void updateSizeOnPut(Object key, int oldSize, int newSize) {
 +    updateBucket2Size(oldSize, newSize, SizeOp.UPDATE);
 +  }
 +  
 +  @Override
 +  void updateSizeOnCreate(Object key, int newSize) {
 +    this.partitionedRegion.getPrStats().incDataStoreEntryCount(1);
 +    updateBucket2Size(0, newSize, SizeOp.CREATE);
 +  }
 +
 +  @Override
 +  void updateSizeOnRemove(Object key, int oldSize) {
 +    this.partitionedRegion.getPrStats().incDataStoreEntryCount(-1);
 +    updateBucket2Size(oldSize, 0, SizeOp.DESTROY);
 +  }
 +
 +  @Override
 +  int updateSizeOnEvict(Object key, int oldSize) {
 +    int newDiskSize = oldSize;
 +    updateBucket2Size(oldSize, newDiskSize, SizeOp.EVICT);
 +    return newDiskSize;
 +  }
 +
 +  @Override
 +  public void updateSizeOnFaultIn(Object key, int newMemSize, int oldDiskSize) {
 +    updateBucket2Size(oldDiskSize, newMemSize, SizeOp.FAULT_IN);
 +  }
 +  
 +  @Override
 +  public void initializeStats(long numEntriesInVM, long

<TRUNCATED>


[002/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/TXDistributedDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/TXDistributedDUnitTest.java
index 7a306f0,0000000..720da56
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/TXDistributedDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/TXDistributedDUnitTest.java
@@@ -1,1527 -1,0 +1,1527 @@@
 +/*
 + * 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.
 + */
 +
 +/** 
 + * Test various distributed aspects of transactions,
 + * e.g. locking/reservation symantics that do not need multiple Region
 + * configurations. For those tests see
 + * <code>MultiVMRegionTestCase</code>.
 + * 
 + *
 + * @author Mitch Thomas
 + * @since 4.0
 + * @see MultiVMRegionTestCase
 + *
 + */
 +
 +package com.gemstone.gemfire.cache30;
 +
 +
 +//import com.gemstone.gemfire.*;
 +import java.io.IOException;
 +import java.io.Serializable;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Properties;
 +import java.util.concurrent.CountDownLatch;
 +
 +import junit.framework.AssertionFailedError;
 +
 +import org.junit.Ignore;
 +
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.CommitConflictException;
 +import com.gemstone.gemfire.cache.CommitIncompleteException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.DiskAccessException;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.MirrorType;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.distributed.internal.ResourceEvent;
 +import com.gemstone.gemfire.distributed.internal.ResourceEventsListener;
 +import com.gemstone.gemfire.distributed.internal.locks.DLockBatch;
 +import com.gemstone.gemfire.distributed.internal.locks.DLockService;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
 +import com.gemstone.gemfire.internal.cache.CommitReplyException;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.InternalRegionArguments;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.RegionEntry;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.TXState;
 +import com.gemstone.gemfire.internal.cache.TXStateInterface;
 +import com.gemstone.gemfire.internal.cache.TXStateProxyImpl;
 +//import com.gemstone.gemfire.internal.cache.locks.TXLockId;
 +import com.gemstone.gemfire.internal.cache.locks.TXLockBatch;
 +import com.gemstone.gemfire.internal.cache.locks.TXLockService;
 +import com.gemstone.gemfire.internal.cache.locks.TXLockServiceImpl;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +public class TXDistributedDUnitTest extends CacheTestCase {
 +  public TXDistributedDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  protected RegionAttributes getRegionAttributes() {
 +    return this.getRegionAttributes(Scope.DISTRIBUTED_ACK);
 +  }
 +
 +  protected RegionAttributes getRegionAttributes(Scope scope) {
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(scope);
 +    if (scope.isDistributedAck()) {
 +      factory.setEarlyAck(false);
 +    }
 +    return factory.create();
 +  }
 +
 +  /**
 +   * Test a remote grantor
 +   */
 +  public void testRemoteGrantor() throws Exception {
 +    IgnoredException.addIgnoredException("killing members ds");
 +    final CacheTransactionManager txMgr = this.getCache().getCacheTransactionManager();
 +    final String rgnName = getUniqueName();
 +    Region rgn = getCache().createRegion(rgnName, getRegionAttributes());
 +    rgn.create("key", null);
 +
 +    Invoke.invokeInEveryVM(new SerializableRunnable("testRemoteGrantor: initial configuration") {
 +        public void run() {
 +          try {
 +            Region rgn1 = getCache().createRegion(rgnName, getRegionAttributes());
 +            rgn1.put("key", "val0");
 +          } catch (CacheException e) {
 +            Assert.fail("While creating region", e);
 +          }
 +        }
 +      });
 +    
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +//    VM vm1 = host.getVM(1);
 +//    VM vm2 = host.getVM(2);
 +
 +    vm0.invoke(new SerializableRunnable("testRemoteGrantor: remote grantor init") {
 +        public void run() {
 +          try {
 +            Region rgn1 = getCache().getRegion(rgnName);
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            txMgr2.begin();
 +            rgn1.put("key", "val1");
 +            txMgr2.commit();
 +            assertNotNull(TXLockService.getDTLS());
 +            assertTrue(TXLockService.getDTLS().isLockGrantor());
 +          } catch (CacheException e) {
 +            fail("While performing first transaction");
 +          }
 +        }
 +      });
 +
 +    // fix for bug 38843 causes the DTLS to be created in every TX participant
 +    assertNotNull(TXLockService.getDTLS());
 +    assertFalse(TXLockService.getDTLS().isLockGrantor());
 +    assertEquals("val1", rgn.getEntry("key").getValue());
 +
 +    vm0.invoke(new SerializableRunnable("Disconnect from DS, remote grantor death") {
 +        public void run() {
 +            try {
 +              MembershipManagerHelper.crashDistributedSystem(getSystem());
 +            } finally {
 +                // Allow getCache() to re-establish a ds connection
 +                closeCache();
 +            }
 +        }
 +      });
 +
 +    // Make this VM the remote Grantor
 +    txMgr.begin();
 +    rgn.put("key", "val2");
 +    txMgr.commit();
 +    assertNotNull(TXLockService.getDTLS());
 +    assertTrue(TXLockService.getDTLS().isLockGrantor());
 +
 +    SerializableRunnable remoteComm = 
 +      new SerializableRunnable("testRemoteGrantor: remote grantor commit") {
 +        public void run() {
 +          try {
 +            Cache c = getCache();
 +            CacheTransactionManager txMgr2 = c.getCacheTransactionManager();
 +            Region rgn1 = c.getRegion(rgnName);
 +            if (rgn1 == null) {
 +                // This block should only execute on VM0
 +                rgn1 = c.createRegion(rgnName, getRegionAttributes());
 +            }
 +
 +            txMgr2.begin();
 +            rgn1.put("key", "val3");
 +            txMgr2.commit();
 +
 +            if (TXLockService.getDTLS() != null) {
 +              assertTrue(!TXLockService.getDTLS().isLockGrantor());
 +            }
 +          } catch (CacheException e) {
 +            Assert.fail("While creating region", e);
 +          }
 +        }
 +      };
 +    Invoke.invokeInEveryVM(remoteComm);
 +    // vm1.invoke(remoteComm);
 +    // vm2.invoke(remoteComm);
 +
 +    assertNotNull(TXLockService.getDTLS());
 +    assertTrue(TXLockService.getDTLS().isLockGrantor());
 +    assertEquals("val3", rgn.getEntry("key").getValue());
 +    rgn.destroyRegion();
 +  }
 +
 +  /**
 +   * Test the internal callbacks used for what else... testing
 +   */
 +  public void testInternalCallbacks() throws Exception {
 +    final CacheTransactionManager txMgr = this.getCache().getCacheTransactionManager();
 +    final String rgnName1 = getUniqueName() + "_1";
 +    final String rgnName2 = getUniqueName() + "_2";
 +    final String rgnName3 = getUniqueName() + "_3";
 +    Region rgn1 = getCache().createRegion(rgnName1, getRegionAttributes());
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    SerializableRunnable createRgn = 
 +      new SerializableRunnable("testInternalCallbacks: initial configuration") {
 +        public void run() {
 +          try {
 +            Region rgn1a = getCache().createRegion(rgnName1, getRegionAttributes());
 +            Region rgn2 = getCache().createRegion(rgnName2, getRegionAttributes());
 +            Region rgn3 = getCache().createRegion(rgnName3, getRegionAttributes(Scope.DISTRIBUTED_NO_ACK));
 +            rgn1a.create("key", null);
 +            rgn2.create("key", null);
 +            rgn3.create("key", null);
 +          } catch (CacheException e) {
 +            Assert.fail("While creating region", e);
 +          }
 +        }
 +      };
 +    vm0.invoke(createRgn);
 +    vm1.invoke(createRgn);
 +   
 +    // Standard commit check
 +    txMgr.begin();
 +    rgn1.put("key", "value0");
 +    txMgr.commit();
 +    SerializableRunnable checkRgn1 = 
 +      new SerializableRunnable("testInternalCallbacks: check rgn1 valus") {
 +        public void run() {
 +          Region rgn1a = getCache().getRegion(rgnName1);
 +          assertNotNull(rgn1a);
 +          assertEquals("value0", rgn1a.getEntry("key").getValue());
 +        }
 +      };
 +    vm0.invoke(checkRgn1);
 +    vm1.invoke(checkRgn1);
 +
 +    {
 +      final byte cbSensors[] = {0,0,0,0,0,0,0,0,0};
 +      txMgr.begin();
 +      ((TXStateProxyImpl)((TXManagerImpl)txMgr).getTXState()).forceLocalBootstrap();
 +      setInternalCallbacks(((TXManagerImpl)txMgr).getTXState(), cbSensors);
 +      rgn1.put("key", "value1");
 +      txMgr.commit();
 +      for(int i=cbSensors.length-3; i>=0; --i) {
 +        assertEquals("Internal callback " + i + " was not called the expected number of times!", 
 +                     (byte) 1, cbSensors[i]);
 +      }
 +      for(int i=cbSensors.length-1; i>cbSensors.length-3; --i) {
 +        assertEquals("Internal \"during\" callback " + i + " invoked an unexpected number of times!", 
 +                     (byte) 2, cbSensors[i]);
 +      }
 +    }
 +    SerializableRunnable checkRgn1Again = 
 +      new SerializableRunnable("testInternalCallbacks: validate remote values") {
 +        public void run() {
 +          Region rgn1a = getCache().getRegion(rgnName1);
 +          assertNotNull(rgn1a);
 +          assertEquals("value1", rgn1a.getEntry("key").getValue());
 +        }
 +      };
 +    vm0.invoke(checkRgn1Again);
 +    vm1.invoke(checkRgn1Again);
 +    
 +    // Try 2 regions
 +    Region rgn2 = getCache().createRegion(rgnName2, getRegionAttributes());
 +    txMgr.begin();
 +    rgn1.put("key", "value2");
 +    rgn2.put("key", "value2");
 +    txMgr.commit();
 +    SerializableRunnable checkRgn12 = 
 +      new SerializableRunnable("testInternalCallbacks: check rgn1 valus") {
 +        public void run() {
 +          Region rgn1a = getCache().getRegion(rgnName1);
 +          assertNotNull(rgn1a);
 +          assertEquals("value2", rgn1a.getEntry("key").getValue());
 +          Region rgn2a = getCache().getRegion(rgnName2);
 +          assertNotNull(rgn2a);
 +          assertEquals("value2", rgn2a.getEntry("key").getValue());
 +        }
 +      };
 +    vm0.invoke(checkRgn12);
 +    vm1.invoke(checkRgn12);
 +
 +    {
 +      final byte cbSensors[] = {0,0,0,0,0,0,0,0,0};
 +      txMgr.begin();
 +      ((TXStateProxyImpl)((TXManagerImpl)txMgr).getTXState()).forceLocalBootstrap();
 +      setInternalCallbacks(((TXManagerImpl)txMgr).getTXState(), cbSensors);
 +      rgn1.put("key", "value3");
 +      rgn2.put("key", "value3");
 +      txMgr.commit();
 +      
 +      for(int i=cbSensors.length-3; i>=0; i--) {
 +        assertEquals("Internal callback " + i + " was not called the expected number of times!", 
 +                     (byte) 1, cbSensors[i]);
 +      }
 +      for(int i=cbSensors.length-1; i> cbSensors.length-3; --i) {
 +        assertEquals("Internal \"during\" callback " + i + " invoked an unexpected number of times!", 
 +                     (byte) 2, cbSensors[i]);
 +      }
 +    }
 +    SerializableRunnable checkRgn12Again = 
 +      new SerializableRunnable("testInternalCallbacks: validate both regions remote values") {
 +        public void run() {
 +          Region rgn1a = getCache().getRegion(rgnName1);
 +          assertNotNull(rgn1a);
 +          assertEquals("value3", rgn1a.getEntry("key").getValue());
 +          Region rgn2a = getCache().getRegion(rgnName2);
 +          assertNotNull(rgn2a);
 +          assertEquals("value3", rgn2a.getEntry("key").getValue());
 +        }
 +      };
 +    vm0.invoke(checkRgn12Again);
 +    vm1.invoke(checkRgn12Again);
 +
 +    // Try a third region (D_NO_ACK)
 +    Region rgn3 = getCache().createRegion(rgnName3, getRegionAttributes(Scope.DISTRIBUTED_NO_ACK));
 +    txMgr.begin();
 +    rgn1.put("key", "value4");
 +    rgn2.put("key", "value4");
 +    rgn3.put("key", "value4");
 +    txMgr.commit();
 +    SerializableRunnable checkRgn123 = 
 +      new SerializableRunnable("testInternalCallbacks: check rgn1 valus") {
 +        public void run() {
 +          Region rgn1a = getCache().getRegion(rgnName1);
 +          assertNotNull(rgn1a);
 +          assertEquals("value4", rgn1a.getEntry("key").getValue());
 +          Region rgn2a = getCache().getRegion(rgnName2);
 +          assertNotNull(rgn2a);
 +          assertEquals("value4", rgn2a.getEntry("key").getValue());
 +          Region rgn3a = getCache().getRegion(rgnName3);
 +          assertNotNull(rgn3a);
 +          assertEquals("value4", rgn3a.getEntry("key").getValue());
 +        }
 +      };
 +    vm0.invoke(checkRgn123);
 +    vm1.invoke(checkRgn123);
 +
 +    {
 +      final byte cbSensors[] = {0,0,0,0,0,0,0,0,0};
 +      txMgr.begin();
 +      ((TXStateProxyImpl)((TXManagerImpl)txMgr).getTXState()).forceLocalBootstrap();
 +      setInternalCallbacks(((TXManagerImpl)txMgr).getTXState(), cbSensors);
 +
 +      rgn1.put("key", "value5");
 +      rgn2.put("key", "value5");
 +      rgn3.put("key", "value5");
 +      txMgr.commit();
 +      
 +      for(int i=cbSensors.length-3; i>=0; i--) {
 +        assertEquals("Internal callback " + i + " was not called the expected number of times!", 
 +                     (byte) 1, cbSensors[i]);
 +      }
 +      for(int i=cbSensors.length-1; i> cbSensors.length-3; --i) {
 +        assertEquals("Internal \"during\" callback " + i + " invoked an unexpected number of times!", 
 +                     (byte) 2, cbSensors[i]);
 +      }
 +    }
 +    SerializableRunnable checkRgn123Again = 
 +      new SerializableRunnable("testInternalCallbacks: validate both regions remote values") {
 +        public void run() {
 +          Region rgn1a = getCache().getRegion(rgnName1);
 +          assertNotNull(rgn1a);
 +          assertEquals("value5", rgn1a.getEntry("key").getValue());
 +          Region rgn2a = getCache().getRegion(rgnName2);
 +          assertNotNull(rgn2a);
 +          assertEquals("value5", rgn2a.getEntry("key").getValue());
 +          Region rgn3a = getCache().getRegion(rgnName3);
 +          assertNotNull(rgn3a);
 +          assertEquals("value5", rgn3a.getEntry("key").getValue());
 +        }
 +      };
 +    vm0.invoke(checkRgn123Again);
 +    vm1.invoke(checkRgn123Again);
 +    
 +    rgn1.destroyRegion();
 +    rgn2.destroyRegion();
 +  }
 +  static final void setInternalCallbacks(TXStateInterface txp, final byte[] cbSensors) {
 +    ((TXStateProxyImpl)txp).forceLocalBootstrap();
 +    TXState tx = (TXState)((TXStateProxyImpl)txp).getRealDeal(null,null);
 +    assertEquals(9, cbSensors.length);
 +    tx.setAfterReservation(new Runnable() {
 +        public void run() {
 +          cbSensors[0]++;
 +        }
 +      });
 +    tx.setAfterConflictCheck(new Runnable() {
 +        public void run() {
 +          cbSensors[1]++;
 +        }
 +      });
 +    tx.setAfterApplyChanges(new Runnable() {
 +        public void run() {
 +          cbSensors[2]++;            
 +        }
 +      });
 +    tx.setAfterReleaseLocalLocks(new Runnable() {
 +        public void run() {
 +          cbSensors[3]++;            
 +        }
 +      });
 +    tx.setAfterIndividualSend(new Runnable() {
 +        public void run() {
 +          cbSensors[4]++;
 +        }
 +      });
 +    tx.setAfterIndividualCommitProcess(new Runnable() {
 +        public void run() {
 +          cbSensors[5]++;
 +        }
 +      });
 +    tx.setAfterSend(new Runnable() {
 +        public void run() {
 +          cbSensors[6]++;
 +        }
 +      });
 +    tx.setDuringIndividualSend(new Runnable() {
 +        public void run() {
 +          cbSensors[7]++;            
 +        }
 +      });
 +    tx.setDuringIndividualCommitProcess(new Runnable() {
 +        public void run() {
 +          cbSensors[8]++;
 +        }
 +      });
 +  }
 +
 +  /** 
 +   * Test distributed ack transactions that consist only of 
 +   * data from loaded values
 +   */
 +  public void testDACKLoadedMessage() throws Exception {
 +    final CacheTransactionManager txMgr = this.getCache().getCacheTransactionManager();
 +    final String rgnName = getUniqueName();
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setEarlyAck(false);
 +    factory.setCacheLoader(new CacheLoader() {
 +        public Object load(LoaderHelper helper) {
 +          return "val" + helper.getArgument();
 +        }
 +        public void close() {}
 +      });
 +    Region rgn = getCache().createRegion(rgnName, factory.create());
 +    
 +    Invoke.invokeInEveryVM(new SerializableRunnable("testDACKLoadedMessage: intial configuration") {
 +        public void run() {
 +          try {
 +            AttributesFactory factory2 = new AttributesFactory();
 +            factory2.setScope(Scope.DISTRIBUTED_ACK);
 +            factory2.setEarlyAck(false);
 +            // factory.setDataPolicy(DataPolicy.REPLICATE);
 +            factory2.setMirrorType(MirrorType.KEYS);
 +            getCache().createRegion(rgnName, factory2.create());
 +          } catch (CacheException e) {
 +            Assert.fail("While creating region", e);
 +          }
 +        }
 +      });
 +
 +    // Confirm the standard case
 +    txMgr.begin();
 +    rgn.put("key1", "val1");
 +    txMgr.commit();
 +    assertEquals("val1", rgn.getEntry("key1").getValue());
 +
 +    Invoke.invokeInEveryVM(new SerializableRunnable("testDACKLoadedMessage: confirm standard case") {
 +        public void run() {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          assertEquals("val1", rgn1.getEntry("key1").getValue());
 +        }
 +      });
 +
 +    // Confirm loaded value case
 +    txMgr.begin();
 +    rgn.get("key2", new Integer(2));
 +    txMgr.commit();
 +    assertEquals("val2", rgn.getEntry("key2").getValue());
 +    
 +    Invoke.invokeInEveryVM(new SerializableRunnable("testDACKLoadedMessage: confirm standard case") {
 +        public void run() {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          assertEquals("val2", rgn1.getEntry("key2").getValue());
 +        }
 +      });
 +
 +    // This should use the ack w/ the lockid
 +    txMgr.begin();
 +    rgn.put("key3", "val3");
 +    rgn.get("key4", new Integer(4));
 +    txMgr.commit();
 +
 +    Invoke.invokeInEveryVM(new SerializableRunnable("testDACKLoadedMessage: confirm standard case") {
 +        public void run() {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          assertEquals("val3", rgn1.getEntry("key3").getValue());
 +          assertEquals("val4", rgn1.getEntry("key4").getValue());
 +        }
 +      });
 +
 +  }
 +  
 +  @Override
 +  public Properties getDistributedSystemProperties() {
 +    Properties p = super.getDistributedSystemProperties();
 +    p.put("log-level", LogWriterUtils.getDUnitLogLevel());
 +    return p;
 +  }
 +
 +  public void testHighAvailabilityFeatures() throws Exception {
 +    IgnoredException.addIgnoredException("DistributedSystemDisconnectedException");
 +//    final CacheTransactionManager txMgr = this.getCache().getCacheTransactionManager();
 +//    final TXManagerImpl txMgrImpl = (TXManagerImpl) txMgr;
 +    final String rgnName = getUniqueName();
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setEarlyAck(false);
 +    Region rgn = getCache().createRegion(rgnName, factory.create());
 +    Invoke.invokeInEveryVM(new SerializableRunnable("testHighAvailabilityFeatures: intial region configuration") {
 +        public void run() {
 +          try {
 +            AttributesFactory factory2 = new AttributesFactory();
 +            factory2.setScope(Scope.DISTRIBUTED_ACK);
 +            factory2.setEarlyAck(false);
 +            factory2.setDataPolicy(DataPolicy.REPLICATE);
 +            getCache().createRegion(rgnName, factory2.create());
 +          } catch (CacheException e) {
 +            Assert.fail("While creating region", e);
 +          }
 +        }
 +      });
 +
 +    // create entries
 +    rgn.put("key0", "val0_0");
 +    rgn.put("key1", "val1_0");
 +
 +    Host host = Host.getHost(0);
 +    // This test assumes that there are at least three VMs; the origin and two recipients
 +    assertTrue(host.getVMCount() >= 3);
 +    final VM originVM = host.getVM(0);
 +
 +    // Test that there is no commit after a partial commit message
 +    // send (only sent to a minority of the recipients)
 +    originVM.invoke(new SerializableRunnable("Flakey DuringIndividualSend Transaction") {
 +        public void run() {
 +          final Region rgn1 = getCache().getRegion(rgnName);
 +          assertNotNull(rgn1);
 +          try {
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            final CacheTransactionManager txMgrImpl = txMgr2;
 +            
 +            txMgr2.begin();
 +            // 1. setup an internal callback on originVM that will call
 +            // disconnectFromDS() on the 2nd duringIndividualSend
 +            // call.
 +            ((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).forceLocalBootstrap();
 +            TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).getRealDeal(null,null);
 +            txState.setDuringIndividualSend(new Runnable() {
 +                private int numCalled = 0;
 +                public synchronized void run() {
 +                  ++numCalled;
 +                  rgn1.getCache().getLogger().info("setDuringIndividualSend Runnable called " + numCalled + " times");
 +                  if (numCalled > 1) {
 +                    MembershipManagerHelper.crashDistributedSystem(getSystem());
 +                  }
 +                }
 +              });
 +            rgn1.put("key0", "val0_1");
 +            rgn1.put("key1", "val1_1");
 +            // 2. commit a transaction in originVM, it will disconnect from the DS
 +            txMgr2.commit();
 +          } 
 +          catch (VirtualMachineError e) {
 +            SystemFailure.initiateFailure(e);
 +            throw e;
 +          }
 +          catch (Throwable e) {
 +            rgn1.getCache().getLogger().warning("Ignoring Exception", e);
 +          } 
 +          finally {
 +            // Allow this VM to re-connect to the DS upon getCache() call
 +            closeCache();
 +          }
 +        }
 +      });
 +    // 3. verify on all VMs that the transaction was not committed
 +    final SerializableRunnable noChangeValidator = 
 +      new SerializableRunnable("testHighAvailabilityFeatures: validate no change in Region") {
 +        public void run() {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          if (rgn1 == null) {
 +            // Expect a null region from originVM
 +            try {
 +              AttributesFactory factory2 = new AttributesFactory();
 +              factory2.setScope(Scope.DISTRIBUTED_ACK);
 +              factory2.setEarlyAck(false);
 +              factory2.setDataPolicy(DataPolicy.REPLICATE);
 +              rgn1 = getCache().createRegion(rgnName, factory2.create());
 +            } catch (CacheException e) {
 +              Assert.fail("While creating region", e);
 +            }
 +          }
 +          Region.Entry re = rgn1.getEntry("key0");
 +          assertNotNull(re);
 +          assertEquals("val0_0", re.getValue());
 +          re = rgn1.getEntry("key1");
 +          assertNotNull(re);
 +          assertEquals("val1_0", re.getValue());
 +        }
 +      };
 +    Invoke.invokeInEveryVM(noChangeValidator);
 +
 +    // Test that there is no commit after sending to all recipients
 +    // but prior to sending the "commit process" message
 +    originVM.invoke(new SerializableRunnable("Flakey AfterIndividualSend Transaction") {
 +        public void run() {
 +          final Region rgn1 = getCache().getRegion(rgnName);
 +          assertNotNull(rgn1);
 +          try {
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            final CacheTransactionManager txMgrImpl = txMgr2;
 +            
 +            txMgr2.begin();
 +            // 1. setup an internal callback on originVM that will call
 +            // disconnectFromDS() on AfterIndividualSend
 +            ((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).forceLocalBootstrap();
 +            TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).getRealDeal(null,null);
 +            txState.setAfterIndividualSend(new Runnable() {
 +                public synchronized void run() {
 +                  MembershipManagerHelper.crashDistributedSystem(getSystem());
 +                }
 +              });
 +            rgn1.put("key0", "val0_2");
 +            rgn1.put("key1", "val1_2");
 +            // 2. commit a transaction in originVM, it will disconnect from the DS
 +            txMgr2.commit();
 +          } 
 +          catch (VirtualMachineError e) {
 +            SystemFailure.initiateFailure(e);
 +            throw e;
 +          }
 +          catch (Throwable e) {
 +            rgn1.getCache().getLogger().warning("Ignoring Exception", e);
 +          } 
 +          finally {
 +            // Allow this VM to re-connect to the DS upon getCache() call
 +            closeCache();
 +          }
 +        }
 +      });
 +    // 3. verify on all VMs, including the origin, that the transaction was not committed
 +    Invoke.invokeInEveryVM(noChangeValidator);
 +
 +    // Test commit success upon a single commit process message received.
 +    originVM.invoke(new SerializableRunnable("Flakey DuringIndividualCommitProcess Transaction") {
 +        public void run() {
 +          final Region rgn1 = getCache().getRegion(rgnName);
 +          assertNotNull(rgn1);
 +          try {
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            final CacheTransactionManager txMgrImpl = txMgr2;
 +            
 +            txMgr2.begin();
 +
 +            ((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).forceLocalBootstrap();
 +            TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).getRealDeal(null,null);
 +            // 1. setup an internal callback on originVM that will call
 +            // disconnectFromDS() on the 2nd internalDuringIndividualCommitProcess
 +            // call.
 +            txState.setDuringIndividualCommitProcess(new Runnable() {
 +                private int numCalled = 0;
 +                public synchronized void run() {
 +                  ++numCalled;
 +                  rgn1.getCache().getLogger().info("setDuringIndividualCommitProcess Runnable called " + numCalled + " times");
 +                  if (numCalled > 1) {
 +                    MembershipManagerHelper.crashDistributedSystem(getSystem());
 +                  }
 +                }
 +              });
 +            rgn1.put("key0", "val0_3");
 +            rgn1.put("key1", "val1_3");
 +            // 2. commit a transaction in originVM, it will disconnect from the DS
 +            txMgr2.commit();
 +          } 
 +          catch (VirtualMachineError e) {
 +            SystemFailure.initiateFailure(e);
 +            throw e;
 +          }
 +          catch (Throwable e) {
 +            rgn1.getCache().getLogger().warning("Ignoring Exception", e);
 +          } 
 +          finally {
 +            // Allow this VM to re-connect to the DS upon getCache() call
 +            closeCache();
 +          }
 +        }
 +      });
 +    // 3. verify on all VMs that the transaction was committed (including the orgin, due to GII)
 +    SerializableRunnable nonSoloChangeValidator1 = 
 +      new SerializableRunnable("testHighAvailabilityFeatures: validate v1 non-solo Region changes") {
 +        public void run() {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          if (rgn1 == null) {
 +            // Expect a null region from originVM
 +            try {
 +              AttributesFactory factory2 = new AttributesFactory();
 +              factory2.setScope(Scope.DISTRIBUTED_ACK);
 +              factory2.setEarlyAck(false);
 +              factory2.setDataPolicy(DataPolicy.REPLICATE);
 +              rgn1 = getCache().createRegion(rgnName, factory2.create());
 +            } catch (CacheException e) {
 +              Assert.fail("While creating region", e);
 +            }
 +          }
 +          long giveUp = System.currentTimeMillis() + 10000;
 +          while (giveUp > System.currentTimeMillis()) {
 +            try {
 +              Region.Entry re = rgn1.getEntry("key0");
 +              assertNotNull(re);
 +              assertEquals("val0_3", re.getValue());
 +              re = rgn1.getEntry("key1");
 +              assertNotNull(re);
 +              assertEquals("val1_3", re.getValue());
 +              break;
 +            } catch (AssertionFailedError e) {
 +              if (giveUp > System.currentTimeMillis()) {
 +                throw e;
 +              }
 +            }
 +          }
 +        }
 +      };
 +    Invoke.invokeInEveryVM(nonSoloChangeValidator1);
 +
 +    // Verify successful solo region commit after duringIndividualSend
 +    // (same as afterIndividualSend).
 +    // Create a region that only exists on the origin and another VM
 +    final String soloRegionName = getUniqueName() + "_solo";
 +    SerializableRunnable createSoloRegion = 
 +      new SerializableRunnable("testHighAvailabilityFeatures: solo region configuration") {
 +        public void run() {
 +          try {
 +            AttributesFactory factory2 = new AttributesFactory();
 +            factory2.setScope(Scope.DISTRIBUTED_ACK);
 +            factory2.setEarlyAck(false);
 +            factory2.setDataPolicy(DataPolicy.REPLICATE);
 +            Region rgn1 = getCache().createRegion(soloRegionName, factory2.create());
 +            rgn1.put("soloKey0", "soloVal0_0");
 +            rgn1.put("soloKey1", "soloVal1_0");
 +          } catch (CacheException e) {
 +            Assert.fail("While creating region", e);
 +          }
 +        }
 +      };
 +    final VM soloRegionVM = host.getVM(1);
 +    originVM.invoke(createSoloRegion);
 +    soloRegionVM.invoke(createSoloRegion);
 +    originVM.invoke(new SerializableRunnable("Flakey solo region DuringIndividualSend Transaction") {
 +        public void run() {
 +          final Region soloRgn = getCache().getRegion(soloRegionName);
 +          assertNotNull(soloRgn);
 +          try {
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            final CacheTransactionManager txMgrImpl = txMgr2;
 +            
 +            txMgr2.begin();
 +            // 1. setup an internal callback on originVM that will call
 +            // disconnectFromDS() on the 2nd duringIndividualSend
 +            // call.
 +            ((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).forceLocalBootstrap();
 +            TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).getRealDeal(null,null);
 +            txState.setDuringIndividualSend(new Runnable() {
 +                private int numCalled = 0;
 +                public synchronized void run() {
 +                  ++numCalled;
 +                  soloRgn.getCache().getLogger().info("setDuringIndividualSend Runnable called " + numCalled + " times");
 +                  if (numCalled > 1) {
 +                    MembershipManagerHelper.crashDistributedSystem(getSystem());
 +                  }
 +                }
 +              });
 +            soloRgn.put("soloKey0", "soloVal0_1");
 +            soloRgn.put("soloKey1", "soloVal1_1");
 +            // 2. commit a transaction in originVM, it will disconnect from the DS
 +            txMgr2.commit();
 +          } 
 +          catch (VirtualMachineError e) {
 +            SystemFailure.initiateFailure(e);
 +            throw e;
 +          }
 +          catch (Throwable e) {
 +            soloRgn.getCache().getLogger().warning("Ignoring Exception", e);
 +          } 
 +          finally {
 +            // Allow this VM to re-connect to the DS upon getCache() call
 +            closeCache();
 +          }
 +        }
 +      });
 +    // 3. verify on the soloRegionVM that the transaction was committed
 +    final SerializableRunnable soloRegionCommitValidator1 = 
 +      new SerializableRunnable("testHighAvailabilityFeatures: validate successful v1 commit in solo Region") {
 +        public void run() {
 +          Region soloRgn = getCache().getRegion(soloRegionName);
 +          if (soloRgn == null) {
 +            // Expect a null region from originVM
 +            try {
 +              AttributesFactory factory2 = new AttributesFactory();         
 +              factory2.setScope(Scope.DISTRIBUTED_ACK);
 +              factory2.setEarlyAck(false);
 +              factory2.setDataPolicy(DataPolicy.REPLICATE);
 +              soloRgn = getCache().createRegion(soloRegionName, factory2.create());
 +            } catch (CacheException e) {
 +              Assert.fail("While creating region ", e);
 +            }
 +          }
 +          Region.Entry re = soloRgn.getEntry("soloKey0");
 +          assertNotNull(re);
 +          assertEquals("soloVal0_1", re.getValue());
 +          re = soloRgn.getEntry("soloKey1");
 +          assertNotNull(re);
 +          assertEquals("soloVal1_1", re.getValue());
 +        }
 +      };
 +    originVM.invoke(soloRegionCommitValidator1);
 +    soloRegionVM.invoke(soloRegionCommitValidator1);
 +    // verify no change in nonSolo region, re-establish region in originVM
 +    Invoke.invokeInEveryVM(nonSoloChangeValidator1);
 +
 +    // Verify no commit for failed send (afterIndividualSend) for solo
 +    // Region combined with non-solo Region
 +    originVM.invoke(new SerializableRunnable("Flakey mixed (solo+non-solo) region DuringIndividualSend Transaction") {
 +        public void run() {
 +          final Region rgn1 = getCache().getRegion(rgnName);
 +          assertNotNull(rgn1);
 +          final Region soloRgn = getCache().getRegion(soloRegionName);
 +          assertNotNull(soloRgn);
 +          try {
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            final CacheTransactionManager txMgrImpl = txMgr2;
 +            
 +            txMgr2.begin();
 +            // 1. setup an internal callback on originVM that will call
 +            // disconnectFromDS() on the afterIndividualSend
 +            // call.
 +            ((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).forceLocalBootstrap();
 +            TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).getRealDeal(null,null);
 +            txState.setAfterIndividualSend(new Runnable() {
 +                public synchronized void run() {
 +                  MembershipManagerHelper.crashDistributedSystem(getSystem());
 +                }
 +              });
 +
 +            rgn1.put("key0", "val0_4");
 +            rgn1.put("key1", "val1_4");
 +            soloRgn.put("soloKey0", "soloVal0_2");
 +            soloRgn.put("soloKey1", "soloVal1_2");
 +
 +            // 2. commit a transaction in originVM, it will disconnect from the DS
 +            txMgr2.commit();
 +          } 
 +          catch (VirtualMachineError e) {
 +            SystemFailure.initiateFailure(e);
 +            throw e;
 +          }
 +          catch (Throwable e) {
 +            rgn1.getCache().getLogger().warning("Ignoring Exception", e);
 +          } 
 +          finally {
 +            // Allow this VM to re-connect to the DS upon getCache() call
 +            closeCache();
 +          }
 +        }
 +      });
 +    // Origin and Solo Region VM should be the same as last validation
 +    originVM.invoke(soloRegionCommitValidator1);
 +    soloRegionVM.invoke(soloRegionCommitValidator1);
 +    Invoke.invokeInEveryVM(nonSoloChangeValidator1);
 +
 +    // Verify commit after sending a single
 +    // (duringIndividualCommitProcess) commit process for solo Region
 +    // combined with non-solo Region
 +    originVM.invoke(new SerializableRunnable("Flakey mixed (solo+non-solo) region DuringIndividualCommitProcess Transaction") {
 +        public void run() {
 +          final Region rgn1 = getCache().getRegion(rgnName);
 +          assertNotNull(rgn1);
 +          final Region soloRgn = getCache().getRegion(soloRegionName);
 +          assertNotNull(soloRgn);
 +          try {
 +            final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +            final CacheTransactionManager txMgrImpl = txMgr2;
 +            
 +            txMgr2.begin();
 +            // 1. setup an internal callback on originVM that will call
 +            // disconnectFromDS() on the afterIndividualSend
 +            // call.
 +            ((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).forceLocalBootstrap();
 +            TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgrImpl).getTXState()).getRealDeal(null,null);
 +            txState.setAfterIndividualSend(new Runnable() {
 +                private int numCalled = 0;
 +                public synchronized void run() {
 +                  ++numCalled;
 +                  rgn1.getCache().getLogger().info("setDuringIndividualCommitProcess Runnable called " + numCalled + " times");
 +                  if (numCalled > 1) {
 +                    MembershipManagerHelper.crashDistributedSystem(getSystem());
 +                  }
 +                }
 +              });
 +
 +            rgn1.put("key0", "val0_5");
 +            rgn1.put("key1", "val1_5");
 +            soloRgn.put("soloKey0", "soloVal0_3");
 +            soloRgn.put("soloKey1", "soloVal1_3");
 +
 +            // 2. commit a transaction in originVM, it will disconnect from the DS
 +            txMgr2.commit();
 +          } 
 +          catch (VirtualMachineError e) {
 +            SystemFailure.initiateFailure(e);
 +            throw e;
 +          }
 +          catch (Throwable e) {
 +            rgn1.getCache().getLogger().warning("Ignoring Exception", e);
 +          } 
 +          finally {
 +            // Allow this VM to re-connect to the DS upon getCache() call
 +            closeCache();
 +          }
 +        }
 +      });
 +    final SerializableRunnable soloRegionCommitValidator2 = 
 +      new SerializableRunnable("testHighAvailabilityFeatures: validate successful v2 commit in solo Region") {
 +        public void run() {
 +          Region soloRgn = getCache().getRegion(soloRegionName);
 +          if (soloRgn == null) {
 +            // Expect a null region from originVM
 +            try {
 +              AttributesFactory factory2 = new AttributesFactory();         
 +              factory2.setScope(Scope.DISTRIBUTED_ACK);
 +              factory2.setEarlyAck(false);
 +              factory2.setDataPolicy(DataPolicy.REPLICATE);
 +              soloRgn = getCache().createRegion(soloRegionName, factory2.create());
 +            } catch (CacheException e) {
 +              Assert.fail("While creating region ", e);
 +            }
 +          }
 +          Region.Entry re = soloRgn.getEntry("soloKey0");
 +          assertNotNull(re);
 +          assertEquals("soloVal0_3", re.getValue());
 +          re = soloRgn.getEntry("soloKey1");
 +          assertNotNull(re);
 +          assertEquals("soloVal1_3", re.getValue());
 +        }
 +      };
 +    originVM.invoke(soloRegionCommitValidator2);
 +    soloRegionVM.invoke(soloRegionCommitValidator2);
 +    SerializableRunnable nonSoloChangeValidator2 = 
 +      new SerializableRunnable("testHighAvailabilityFeatures: validate v2 non-solo Region changes") {
 +        public void run() {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          if (rgn1 == null) {
 +            // Expect a null region from originVM
 +            try {
 +              AttributesFactory factory2 = new AttributesFactory();
 +              factory2.setScope(Scope.DISTRIBUTED_ACK);
 +              factory2.setEarlyAck(false);
 +              factory2.setDataPolicy(DataPolicy.REPLICATE);
 +              rgn1 = getCache().createRegion(rgnName, factory2.create());
 +            } catch (CacheException e) {
 +              Assert.fail("While creating region", e);
 +            }
 +          }
 +          Region.Entry re = rgn1.getEntry("key0");
 +          assertNotNull(re);
 +          assertEquals("val0_5", re.getValue());
 +          re = rgn1.getEntry("key1");
 +          assertNotNull(re);
 +          assertEquals("val1_5", re.getValue());
 +        }
 +      };
 +    Invoke.invokeInEveryVM(nonSoloChangeValidator2);
 +  }
 +  
 +  /** 
 +   * A class used in testLockBatchParticipantsUpdate to pause a transaction in the
 +   * afterResrvation and afterSend states.
 +   */
 +  static public class PausibleTX implements Runnable {
 +    public boolean isRunning = false;
 +    public String rgnName = null;
 +    public Cache myCache = null;
 +    public Object key = null;
 +    public Object value = null;
 +
 +    public boolean getIsRunning() {
 +      return this.isRunning;
 +    }
 +
 +    public void run() {
 +      Region rgn = this.myCache.getRegion(this.rgnName);
 +      final CacheTransactionManager txMgr = this.myCache.getCacheTransactionManager();
 +      txMgr.begin();
 +      ((TXStateProxyImpl)((TXManagerImpl)txMgr).getTXState()).forceLocalBootstrap();
 +      TXState txState = (TXState)((TXStateProxyImpl)((TXManagerImpl)txMgr).getTXState()).getRealDeal(null,null);
 +      txState.setAfterReservation(new Runnable() {
 +        public void run() {
 +          try {
 +            synchronized (PausibleTX.class) {
 +              PausibleTX.this.isRunning = true;
 +              // Notify the thread that created this, that we are ready
 +              PausibleTX.class.notifyAll();
 +              // Wait for the controller to start a GII and let us proceed
 +              PausibleTX.class.wait();
 +            }
 +          }
 +          catch (InterruptedException ie) {
 +//            PausibleTX.this.myCache.getLogger().info("Why was I interrupted? " + ie);
 +            fail("interrupted");
 +          }
 +        }
 +      });
 +      txState.setAfterSend(new Runnable() {
 +        public void run() {
 +          try {
 +            synchronized (PausibleTX.class) {
 +              // Notify the controller that we have sent the TX data (and the
 +              // update)
 +              PausibleTX.class.notifyAll();
 +              // Wait until the controller has determined in fact the update
 +              // took place
 +              PausibleTX.class.wait();
 +            }
 +          }
 +          catch (InterruptedException ie) {
 +//            PausibleTX.this.myCache.getLogger().info("Why was I interrupted? " + ie);
 +            fail("interrupted");
 +          }
 +        }
 +      });
 +      try { 
 +        rgn.put(key, value);
 +        txMgr.commit();
 +      } catch (CommitConflictException cce) {
 +        fail("Did not expect commit conflict exception when sending updates to new members in PausibleTX" + cce);
 +//      } catch (CacheException ce) {
 +//        fail("Did not expect cache exception when sending updates to new members in PausibleTX" + ce);
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Returns the GemFire system ID of the VM on which this method is run
 +   */
 +  public static Serializable getSystemId() {
 +    Serializable ret = null;
 +    if (DistributedTestCase.system != null) {
 +      ret = DistributedTestCase.system.getDistributionManager().getId();
 +    }
 +    return ret;
 +  }
 +  static HashSet preTXSystemIds;
 +  public static void setPreTXSystemIds(HashSet ids) {
 +    TXDistributedDUnitTest.preTXSystemIds = ids;
 +  }
 +  static HashSet postTXSystemIds;
 +  public static void setPostTXSystemIds(HashSet ids) {
 +    TXDistributedDUnitTest.postTXSystemIds = ids;
 +  }
 +  static Serializable txHostId;
 +  public static void setTXHostSystemId(Serializable id) {
 +    TXDistributedDUnitTest.txHostId = id;
 +  }
 +  /**
 +   * Test update of lock batch participants (needed when new members are
 +   * discovered between a commit's locking phase and the applicatoin of the
 +   * Region's data. See bug 32999
 +   */
 +  public void testLockBatchParticipantsUpdate() throws Exception {
 +//    final CacheTransactionManager txMgr = this.getCache().getCacheTransactionManager();
 +    final String rgnName = getUniqueName();
 +    Region rgn = getCache().createRegion(rgnName, getRegionAttributes());
 +    rgn.create("key", null);
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    SerializableRunnable initRegions = 
 +      new SerializableRunnable("testLockBatchParticipantsUpdate: initial configuration") {
 +      public void run() {
 +        try {
 +          Region rgn1 = getCache().createRegion(rgnName, getRegionAttributes());
 +          rgn1.create("key", null);
 +        } catch (CacheException e) {
 +          Assert.fail("While creating region", e);
 +        }
 +      }
 +    };
 +    vm0.invoke(initRegions);
 +    vm1.invoke(initRegions);
 +    rgn.put("key", "val1");
 +
 +    // Connect vm2 also since it may have been shutdown when logPerTest
 +    // is turned on
 +    vm2.invoke(new SerializableRunnable("connect vm2 if not connected") {
 +      public void run() {
 +        getCache();
 +      }
 +    });
 +
 +    // Make VM0 the Grantor 
 +    vm0.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: remote grantor init") {
 +      public void run() {
 +        try {
 +          Region rgn1 = getCache().getRegion(rgnName);
 +          final CacheTransactionManager txMgr2 = getCache().getCacheTransactionManager();
 +          assertEquals("val1", rgn1.getEntry("key").getValue());
 +          txMgr2.begin();
 +          rgn1.put("key", "val2");
 +          txMgr2.commit();
 +          assertNotNull(TXLockService.getDTLS());
 +          assertTrue(TXLockService.getDTLS().isLockGrantor());
 +        } catch (CacheException e) {
 +          fail("While performing first transaction");
 +        }
 +      }
 +    });
 +    
 +    // fix for bug 38843 causes the DTLS to be created in every TX participant
 +    assertNotNull(TXLockService.getDTLS());
 +    assertFalse(TXLockService.getDTLS().isLockGrantor());
 +    assertEquals("val2", rgn.getEntry("key").getValue());
 +
 +    // Build sets of System Ids and set them up on VM0 for future batch member checks
 +    HashSet txMembers = new HashSet(4);
 +    txMembers.add(getSystemId());
-     txMembers.add(vm0.invoke(TXDistributedDUnitTest.class, "getSystemId"));
-     vm0.invoke(TXDistributedDUnitTest.class, "setPreTXSystemIds", new Object[] {txMembers});
-     txMembers.add(vm2.invoke(TXDistributedDUnitTest.class, "getSystemId"));
-     vm0.invoke(TXDistributedDUnitTest.class, "setPostTXSystemIds", new Object[] {txMembers});
++    txMembers.add(vm0.invoke(() -> TXDistributedDUnitTest.getSystemId()));
++    vm0.invoke(() -> TXDistributedDUnitTest.setPreTXSystemIds(txMembers));
++    txMembers.add(vm2.invoke(() -> TXDistributedDUnitTest.getSystemId()));
++    vm0.invoke(() -> TXDistributedDUnitTest.setPostTXSystemIds(txMembers));
 +
 +    // Don't include the tx host in the batch member set(s)
-     Serializable vm1HostId = (Serializable) vm1.invoke(TXDistributedDUnitTest.class, "getSystemId");
-     vm0.invoke(TXDistributedDUnitTest.class, "setTXHostSystemId", new Object[] {vm1HostId});
++    Serializable vm1HostId = (Serializable) vm1.invoke(() -> TXDistributedDUnitTest.getSystemId());
++    vm0.invoke(() -> TXDistributedDUnitTest.setTXHostSystemId(vm1HostId));
 +
 +    // Create a TX on VM1 (such that it will ask for locks on VM0) that uses the callbacks
 +    // to pause and give us time to start a GII process on another VM
 +    vm1.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: slow tx (one that detects new member)") {
 +      public void run() {
 +        // fix for bug 38843 causes the DTLS to be created in every TX participant
 +        assertNotNull(TXLockService.getDTLS());
 +        assertFalse(TXLockService.getDTLS().isLockGrantor());
 +        
 +        PausibleTX pauseTXRunnable = new PausibleTX();
 +        pauseTXRunnable.rgnName = rgnName;
 +        pauseTXRunnable.myCache = getCache();
 +        pauseTXRunnable.key = "key";
 +        pauseTXRunnable.value = "val3";
 +        new Thread(pauseTXRunnable, "PausibleTX Thread").start();
 +        synchronized(PausibleTX.class) {
 +          while(!pauseTXRunnable.getIsRunning()) {
 +            try {
 +              PausibleTX.class.wait();
 +            }
 +            catch (InterruptedException ie) {
 +              fail("Did not expect " + ie);
 +            }
 +          }
 +        }
 +      }
 +    });
 +
 +    // Verify that the lock batch exists VM0 and has the size we expect
 +    vm0.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: Verify lock batch exists on VM0 with expected size") {
 +      public void run() {
 +        getCache().getRegion(rgnName);
 +        TXLockServiceImpl dtls = (TXLockServiceImpl) TXLockService.getDTLS();
 +        assertNotNull(dtls);
 +        assertTrue(dtls.isLockGrantor());
 +        DLockService dLockSvc = dtls.getInternalDistributedLockService();
 +        assertNotNull(TXDistributedDUnitTest.txHostId);
 +        DLockBatch[] batches = dLockSvc.getGrantor().getLockBatches((InternalDistributedMember)TXDistributedDUnitTest.txHostId);
 +        assertEquals(batches.length, 1);
 +        TXLockBatch txLockBatch = (TXLockBatch) batches[0];
 +        assertNotNull(txLockBatch);
 +        assertNotNull(TXDistributedDUnitTest.preTXSystemIds);
 +        assertTrue("Members in lock batch " + txLockBatch.getParticipants() + " not the same as " + TXDistributedDUnitTest.preTXSystemIds, 
 +                   txLockBatch.getParticipants().equals(TXDistributedDUnitTest.preTXSystemIds));
 +      }
 +    });
 +    
 +    // Start a GII process on VM2
 +    vm2.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: start GII") {
 +      public void run() {
 +        try {
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setEarlyAck(false);
 +          factory.setDataPolicy(DataPolicy.REPLICATE);
 +          getCache().createRegion(rgnName, factory.create());
 +        } catch (CacheException e) {
 +          Assert.fail("While creating region", e);
 +        }
 +      }
 +    });
 +
 +    // Notify TX on VM1 so that it can continue
 +    vm1.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: Notfiy VM1 TX to continue") {
 +      public void run() {
 +        synchronized(PausibleTX.class) {
 +          // Notify VM1 that it should proceed to the TX send
 +          PausibleTX.class.notifyAll();
 +          // Wait until VM1 has sent the TX
 +          try {
 +            PausibleTX.class.wait();
 +          }
 +          catch (InterruptedException ie) {
 +            fail("Did not expect " + ie);
 +          }
 +        }
 +      }
 +    });
 +    
 +    // Verify that the batch on VM0 has added VM2 into the set
 +    vm0.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: Verify lock batch contains VM2") {
 +      public void run() {
 +        getCache().getRegion(rgnName);
 +        TXLockServiceImpl dtls = (TXLockServiceImpl) TXLockService.getDTLS();
 +        assertNotNull(dtls);
 +        assertTrue(dtls.isLockGrantor());
 +        DLockService dLockSvc = dtls.getInternalDistributedLockService();
 +        assertNotNull(TXDistributedDUnitTest.txHostId);
 +        DLockBatch[] batches = dLockSvc.getGrantor().getLockBatches((InternalDistributedMember)TXDistributedDUnitTest.txHostId);
 +        assertEquals(batches.length, 1);
 +        TXLockBatch txLockBatch = (TXLockBatch) batches[0];
 +        assertNotNull(txLockBatch);
 +        assertNotNull(TXDistributedDUnitTest.preTXSystemIds);
 +        assertTrue("Members in lock batch " + txLockBatch.getParticipants() + " not the same as " + TXDistributedDUnitTest.postTXSystemIds, 
 +                   txLockBatch.getParticipants().equals(TXDistributedDUnitTest.postTXSystemIds));
 +      }
 +    });
 +    // fix for bug 38843 causes the DTLS to be created in every TX participant
 +    assertNotNull(TXLockService.getDTLS());
 +    assertFalse(TXLockService.getDTLS().isLockGrantor());
 +    assertEquals("val3", rgn.getEntry("key").getValue());
 +    
 +    
 +    // Notify TX on VM1 that it can go ahead and complete the TX
 +    vm1.invoke(new SerializableRunnable("testLockBatchParticipantsUpdate: Notfiy VM1 TX to finish") {
 +      public void run() {
 +        synchronized(PausibleTX.class) {
 +          // Notify VM1 that it should finish the TX
 +          PausibleTX.class.notifyAll();
 +        }
 +      }
 +    });
 +    
 +    
 +    rgn.destroyRegion();
 +  }
 +
 +  /**
 +   * Hitachi bug 38809:  Applying an exception to a remote VM fails due to
 +   * an IOException on a Region configured for LRU Overflow
 +   */
 +  public static final String TROUBLE_KEY = "GoBoom";
 +  public static class TXTroubleMaker implements LocalRegion.TestCallable {
 +    // private final Region r;
 +    public void call(LocalRegion r, Operation op, RegionEntry re) {
 +      if (TROUBLE_KEY.equals(re.getKey())) {
 +        throw new DiskAccessException(TROUBLE_KEY, r);
 +      }
 +    }
 +  }
 +
 +  public static class ShutdownListener implements ResourceEventsListener {
 +    CountDownLatch latch = new CountDownLatch(1);
 +    @Override
 +    public void handleEvent(ResourceEvent event, Object resource) {
 +      if (event.equals(ResourceEvent.CACHE_REMOVE)) {
 +        try {
 +          latch.await();
 +        } catch (InterruptedException e) {
 +          e.printStackTrace();
 +        }
 +      }
 +    }
 +    public void unblockShutdown() {
 +      this.latch.countDown();
 +    }
 +  }
 +  
 +  @Ignore("Disabled for 51260")
 +  public void DISABLED_testRemoteCommitFailure() {
 +    try {
 +    disconnectAllFromDS();
 +    final String rgnName1= getUniqueName()  + "_1";
 +    final String rgnName2 = getUniqueName() + "_2";
 +    final String diskStoreName = getUniqueName() + "_store";
 +    Host host = Host.getHost(0);
 +    VM origin = host.getVM(0);
 +    VM trouble1 = host.getVM(1);
 +    VM trouble2 = host.getVM(2);
 +    VM noTrouble = host.getVM(3);
 +    CacheSerializableRunnable initRegions =
 +      new CacheSerializableRunnable("Initialize no trouble regions") {
 +      @Override
 +      public void run2() {
 +        getCache().createDiskStoreFactory().setDiskDirs(getDiskDirs()).create(diskStoreName);
 +        TXManagerImpl.ALLOW_PERSISTENT_TRANSACTIONS = true;
 +        AttributesFactory af = new AttributesFactory();
 +        af.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
 +        af.setScope(Scope.DISTRIBUTED_ACK);
 +        af.setDiskStoreName(diskStoreName);
 +        getCache().createRegion(rgnName1, af.create());
 +        getCache().createRegion(rgnName2, af.create());
 +      }
 +    };
 +    origin.invoke(initRegions);
 +    noTrouble.invoke(initRegions);
 +    SerializableRunnable initTroulbeRegions =
 +      new CacheSerializableRunnable("Initialize regions that cause trouble") {
 +      @Override
 +      public void run2() {
 +        GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +        InternalRegionArguments ira = new InternalRegionArguments().setTestCallable(new TXTroubleMaker());
 +        try {
 +          getCache().createDiskStoreFactory().setDiskDirs(getDiskDirs()).create(diskStoreName);
 +          TXManagerImpl.ALLOW_PERSISTENT_TRANSACTIONS = true;
 +          AttributesFactory af = new AttributesFactory();
 +          af.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
 +          af.setScope(Scope.DISTRIBUTED_ACK);
 +          af.setDiskStoreName(diskStoreName);
 +          gfc.createVMRegion(rgnName1, af.create(), ira);
 +          gfc.createVMRegion(rgnName2, af.create(), ira);
 +          gfc.getDistributedSystem().addResourceListener(new ShutdownListener());
 +        } catch (IOException ioe) {
 +          fail(ioe.toString());
 +        }
 +        catch (TimeoutException e) {
 +          fail(e.toString());
 +        }
 +        catch (ClassNotFoundException e) {
 +          fail(e.toString());
 +        }
 +      }
 +    };
 +    trouble1.invoke(initTroulbeRegions);
 +    trouble2.invoke(initTroulbeRegions);
 +
 +    SerializableRunnable doTransaction =
 +      new CacheSerializableRunnable("Run failing transaction") {
 +      @Override
 +      public void run2() {
 +        Cache c = getCache();
 +        Region r1 = c.getRegion(rgnName1);
 +        assertNotNull(r1);
 +        Region r2 = c.getRegion(rgnName2);
 +        assertNotNull(r2);
 +        CacheTransactionManager txmgr = c.getCacheTransactionManager();
 +        txmgr.begin();
 +        r1.put("k1", "k1");
 +        r1.put("k2", "k2");
 +        r1.put(TROUBLE_KEY, TROUBLE_KEY);
 +        r2.put("k1", "k1");
 +        r2.put("k2", "k2");
 +        r2.put(TROUBLE_KEY, TROUBLE_KEY);
 +        try {
 +          txmgr.commit();
 +          fail("Expected an tx incomplete exception");
 +        } catch (CommitIncompleteException yay) {
 +          String msg = yay.getMessage();
 +//          getLogWriter().info("failing exception", yay);
 +          // Each region on a trouble VM should be mentioned (two regions per trouble VM)
 +          int ind=0, match=0;
 +          while((ind = msg.indexOf(rgnName1, ind)) >= 0) {
 +            ind++; match++;
 +          }
 +          assertEquals(2, match);
 +          ind=match=0;
 +          while((ind = msg.indexOf(rgnName2, ind)) >= 0) {
 +            ind++; match++;
 +          }
 +          assertEquals(2, match);
 +          // DiskAccessExcpetions should be mentioned four times
 +          ind=match=0;
 +          while((ind = msg.indexOf(DiskAccessException.class.getName(), ind)) >= 0) {
 +            ind++; match++;
 +          }
 +          assertEquals(4, match);
 +        }
 +      }
 +    };
 +    IgnoredException ee = null;
 +    try {
 +      ee = IgnoredException.addIgnoredException(DiskAccessException.class.getName() + "|" +
 +          CommitIncompleteException.class.getName() + "|" +
 +          CommitReplyException.class.getName());
 +      origin.invoke(doTransaction);
 +    } finally {
 +      if (ee!=null) ee.remove();
 +    }
 +
 +    SerializableCallable allowCacheToShutdown = new SerializableCallable() {
 +      @Override
 +      public Object call() throws Exception {
 +        GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
 +        List<ResourceEventsListener> listeners = cache.getDistributedSystem().getResourceListeners();
 +        for (ResourceEventsListener l : listeners) {
 +          if (l instanceof ShutdownListener) {
 +            ShutdownListener shutListener = (ShutdownListener) l;
 +            shutListener.unblockShutdown();
 +          }
 +        }
 +        return null;
 +      }
 +    };
 +    trouble1.invoke(allowCacheToShutdown);
 +    trouble2.invoke(allowCacheToShutdown);
 +
 +    // Assert proper content on failing VMs
 +    SerializableRunnable assertTroubledContent =
 +      new CacheSerializableRunnable("Assert partail commit data") {
 +      @Override
 +      public void run2() {
 +        final Cache c = getCache();
 +        Wait.waitForCriterion(new WaitCriterion() {
 +          @Override
 +          public boolean done() {
 +            return c.getRegion(rgnName1) == null;
 +          }
 +          
 +          @Override
 +          public String description() {
 +            return null;
 +          }
 +        }, 30000, 1000, true);
 +        Region r2 = c.getRegion(rgnName2);
 +        assertNull(r2);
 +      }
 +    };
 +    trouble1.invoke(assertTroubledContent);
 +    trouble2.invoke(assertTroubledContent);
 +
 +    // Assert proper content on successful VMs
 +    SerializableRunnable assertSuccessfulContent =
 +      new CacheSerializableRunnable("Assert complete commit of data on successful VMs") {
 +      @Override
 +      public void run2() {
 +        Cache c = getCache();
 +        {
 +          Region r1 = c.getRegion(rgnName1);
 +          assertNotNull(r1);
 +          assertEquals("k1", r1.getEntry("k1").getValue());
 +          assertEquals("k2", r1.getEntry("k2").getValue());
 +          assertEquals(TROUBLE_KEY, r1.getEntry(TROUBLE_KEY).getValue());
 +        }
 +        {
 +          Region r2 = c.getRegion(rgnName2);
 +          assertNotNull(r2);
 +          assertEquals("k1", r2.getEntry("k1").getValue());
 +          assertEquals("k2", r2.getEntry("k2").getValue());
 +          assertEquals(TROUBLE_KEY, r2.getEntry(TROUBLE_KEY).getValue());
 +        }
 +      }
 +    };
 +    noTrouble.invoke(assertSuccessfulContent);
 +    
 +    // Assert no content on originating VM
 +    SerializableRunnable assertNoContent =
 +      new CacheSerializableRunnable("Assert data survives on origin VM") {
 +      @Override
 +      public void run2() {
 +        Cache c = getCache();
 +        {
 +          Region r1 = c.getRegion(rgnName1);
 +          assertNotNull(r1);
 +          assertNotNull(r1.getEntry("k1"));
 +          assertNotNull(r1.getEntry("k2"));
 +          assertNotNull(r1.getEntry(TROUBLE_KEY));
 +        }
 +        {
 +          Region r2 = c.getRegion(rgnName2);
 +          assertNotNull(r2);
 +          assertNotNull(r2.getEntry("k1"));
 +          assertNotNull(r2.getEntry("k2"));
 +          assertNotNull(r2.getEntry(TROUBLE_KEY));
 +        }
 +      }
 +    };
 +    origin.invoke(assertNoContent);
 +    } finally {
 +      Invoke.invokeInEveryVM(new SerializableCallable() {
 +        @Override
 +        public Object call() throws Exception {
 +          TXManagerImpl.ALLOW_PERSISTENT_TRANSACTIONS = false;
 +          return null;
 +        }
 +      });
 +    }
 +  }
 +}
 +

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/TXOrderDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/TXOrderDUnitTest.java
index a253f09,0000000..b1d7bab
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/TXOrderDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/TXOrderDUnitTest.java
@@@ -1,434 -1,0 +1,434 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import javax.naming.Context;
 +import javax.transaction.UserTransaction;
 +
 +import com.gemstone.gemfire.CopyHelper;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheEvent;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.PartitionAttributes;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.TransactionEvent;
 +import com.gemstone.gemfire.cache.TransactionListener;
 +import com.gemstone.gemfire.cache.query.IndexType;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.transaction.Person;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.cache.util.TransactionListenerAdapter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * Test the order of operations done on the farside of a tx.
 + *
 + * @author darrel
 + * @since 5.0
 + */
 +public class TXOrderDUnitTest extends CacheTestCase {
 +
 +  private transient Region r;
 +  private transient DistributedMember otherId;
 +  protected transient int invokeCount;
 +  
 +  public TXOrderDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  private VM getOtherVm() {
 +    Host host = Host.getHost(0);
 +    return host.getVM(0);
 +  }
 +    
 +  private void initOtherId() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("Connect") {
 +        public void run2() throws CacheException {
 +          getCache();
 +        }
 +      });
-     this.otherId = (DistributedMember)vm.invoke(TXOrderDUnitTest.class, "getVMDistributedMember");
++    this.otherId = (DistributedMember)vm.invoke(() -> TXOrderDUnitTest.getVMDistributedMember());
 +  }
 +  private void doCommitOtherVm() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("create root") {
 +        public void run2() throws CacheException {
 +          AttributesFactory af = new AttributesFactory();
 +          af.setScope(Scope.DISTRIBUTED_ACK);
 +          Region r1 = createRootRegion("r1", af.create());
 +          Region r2 = r1.createSubregion("r2", af.create());
 +          Region r3 = r2.createSubregion("r3", af.create());
 +          CacheTransactionManager ctm =  getCache().getCacheTransactionManager();
 +          ctm.begin();
 +          r2.put("b", "value1");
 +          r3.put("c", "value2");
 +          r1.put("a", "value3");
 +          r1.put("a2", "value4");
 +          r3.put("c2", "value5");
 +          r2.put("b2", "value6");
 +          ctm.commit();
 +        }
 +      });
 +  }
 +
 +  public static DistributedMember getVMDistributedMember() {
 +    return InternalDistributedSystem.getAnyInstance().getDistributedMember();
 +  }
 +  
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  List expectedKeys;
 +  int clCount = 0;
 +
 +  Object getCurrentExpectedKey() {
 +    Object result = this.expectedKeys.get(this.clCount);
 +    this.clCount += 1;
 +    return result;
 +  }
 +  /**
 +   * make sure listeners get invoked in correct order on far side of tx
 +   */
 +  public void testFarSideOrder() throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(DataPolicy.REPLICATE);
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    CacheListener cl1 = new CacheListenerAdapter() {
 +        public void afterCreate(EntryEvent e) {
 +          assertEquals(getCurrentExpectedKey(), e.getKey());
 +        }
 +      };
 +    af.addCacheListener(cl1);
 +    Region r1 = createRootRegion("r1", af.create());
 +    Region r2 = r1.createSubregion("r2", af.create());
 +    r2.createSubregion("r3", af.create());
 +
 +    TransactionListener tl1 = new TransactionListenerAdapter() {
 +        public void afterCommit(TransactionEvent e) {
 +          assertEquals(6, e.getEvents().size());
 +          ArrayList keys = new ArrayList();
 +          Iterator it = e.getEvents().iterator();
 +          while (it.hasNext()) {
 +            EntryEvent ee = (EntryEvent)it.next();
 +            keys.add(ee.getKey());
 +            assertEquals(null, ee.getCallbackArgument());
 +            assertEquals(true, ee.isCallbackArgumentAvailable());
 +          }
 +          assertEquals(TXOrderDUnitTest.this.expectedKeys, keys);
 +          TXOrderDUnitTest.this.invokeCount = 1;
 +        }
 +      };
 +    CacheTransactionManager ctm =  getCache().getCacheTransactionManager();
 +    ctm.addListener(tl1);
 +
 +    this.invokeCount = 0;
 +    this.clCount = 0;
 +    this.expectedKeys = Arrays.asList(new String[]{"b", "c", "a", "a2", "c2", "b2"});
 +    doCommitOtherVm();
 +    assertEquals(1, this.invokeCount);
 +    assertEquals(6, this.clCount);
 +  }
 +
 +  /**
 +   * test bug#40870
 +   * @throws Exception
 +   */
 +  public void _testFarSideOpForLoad() throws Exception {
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(0);
 +    VM vm2 = host.getVM(1);
 +    vm1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        AttributesFactory af = new AttributesFactory();
 +        af.setDataPolicy(DataPolicy.REPLICATE);
 +        af.setScope(Scope.DISTRIBUTED_ACK);
 +        CacheListener cl1 = new CacheListenerAdapter() {
 +          public void afterCreate(EntryEvent e) {
 +            assertTrue(e.getOperation().isLocalLoad());
 +          }
 +        };
 +        af.addCacheListener(cl1);
 +        CacheLoader cl = new CacheLoader() {
 +          public Object load(LoaderHelper helper) throws CacheLoaderException {
 +            LogWriterUtils.getLogWriter().info("Loading value:"+helper.getKey()+"_value");
 +            return helper.getKey()+"_value";
 +          }
 +          public void close() {
 +          }
 +        };
 +        af.setCacheLoader(cl);
 +        createRootRegion("r1", af.create());
 +        return null;
 +      }
 +    });
 +
 +    vm2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        AttributesFactory af = new AttributesFactory();
 +        af.setDataPolicy(DataPolicy.REPLICATE);
 +        af.setScope(Scope.DISTRIBUTED_ACK);
 +        CacheListener cl1 = new CacheListenerAdapter() {
 +          public void afterCreate(EntryEvent e) {
 +            LogWriterUtils.getLogWriter().info("op:"+e.getOperation().toString());
 +            assertTrue(!e.getOperation().isLocalLoad());
 +          }
 +        };
 +        af.addCacheListener(cl1);
 +        createRootRegion("r1", af.create());
 +        return null;
 +      }
 +    });
 +
 +    vm1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion("r1");
 +        getCache().getCacheTransactionManager().begin();
 +        r.get("obj_2");
 +        getCache().getCacheTransactionManager().commit();
 +        return null;
 +      }
 +    });
 +  }
 +
 +  public void testInternalRegionNotExposed() {
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(0);
 +    VM vm2 = host.getVM(1);
 +    SerializableCallable createRegion = new SerializableCallable() {
 +      public Object call() throws Exception {
 +        ExposedRegionTransactionListener tl = new ExposedRegionTransactionListener();
 +        CacheTransactionManager ctm = getCache().getCacheTransactionManager();
 +        ctm.addListener(tl);
 +        ExposedRegionCacheListener cl = new ExposedRegionCacheListener();
 +        AttributesFactory af = new AttributesFactory();
 +        PartitionAttributes pa = new PartitionAttributesFactory()
 +          .setRedundantCopies(1)
 +          .setTotalNumBuckets(1)
 +          .create();
 +        af.setPartitionAttributes(pa);
 +        af.addCacheListener(cl);
 +        Region pr = createRootRegion("testTxEventForRegion", af.create());
 +        return null;
 +      }
 +    };
 +    vm1.invoke(createRegion);
 +    vm2.invoke(createRegion);
 +    vm1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region pr = getRootRegion("testTxEventForRegion");
 +        CacheTransactionManager ctm = getCache().getCacheTransactionManager();
 +        pr.put(2, "tw");
 +        pr.put(3, "three");
 +        pr.put(4, "four");
 +        ctm.begin();
 +        pr.put(1, "one");
 +        pr.put(2, "two");
 +        pr.invalidate(3);
 +        pr.destroy(4);
 +        ctm.commit();
 +        return null;
 +      }
 +    });
 +    SerializableCallable verifyListener = new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region pr = getRootRegion("testTxEventForRegion");
 +        CacheTransactionManager ctm = getCache().getCacheTransactionManager();
 +        ExposedRegionTransactionListener tl = (ExposedRegionTransactionListener)ctm.getListeners()[0];
 +        ExposedRegionCacheListener cl = (ExposedRegionCacheListener)pr.getAttributes().getCacheListeners()[0];
 +        assertFalse(tl.exceptionOccurred);
 +        assertFalse(cl.exceptionOccurred);
 +        return null;
 +      }
 +    };
 +    vm1.invoke(verifyListener);
 +    vm2.invoke(verifyListener);
 +  }
 +  
 +  class ExposedRegionTransactionListener extends TransactionListenerAdapter {
 +    private boolean exceptionOccurred = false;
 +    @Override
 +    public void afterCommit(TransactionEvent event) {
 +      List<CacheEvent<?, ?>> events = event.getEvents();
 +      for (CacheEvent<?, ?>e : events) {
 +        if (!"/testTxEventForRegion".equals(e.getRegion().getFullPath())) {
 +          exceptionOccurred = true;
 +        }
 +      }
 +    }
 +  }
 +  class ExposedRegionCacheListener extends CacheListenerAdapter {
 +    private boolean exceptionOccurred = false;
 +    @Override
 +    public void afterCreate(EntryEvent event) {
 +      verifyRegion(event);
 +    }
 +    @Override
 +    public void afterUpdate(EntryEvent event) {
 +      verifyRegion(event);
 +    }
 +    private void verifyRegion(EntryEvent event) {
 +      if (!"/testTxEventForRegion".equals(event.getRegion().getFullPath())) {
 +        exceptionOccurred = true;
 +      }
 +    }
 +  }
 +  
 +  private final int TEST_PUT = 0;
 +  private final int TEST_INVALIDATE = 1;
 +  private final int TEST_DESTROY = 2;
 +  /**
 +   * verify that queries on indexes work with transaction
 +   * @throws Exception
 +   */
 +  public void testFarSideIndexOnPut() throws Exception {
 +    doTest(TEST_PUT);
 +  }
 +
 +  public void testFarSideIndexOnInvalidate() throws Exception {
 +    doTest(TEST_INVALIDATE);
 +  }
 +
 +  public void testFarSideIndexOnDestroy() throws Exception {
 +    doTest(TEST_DESTROY);
 +  }
 +
 +  private void doTest(final int op) throws Exception {
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(0);
 +    VM vm2 = host.getVM(1);
 +    SerializableCallable createRegionAndIndex = new SerializableCallable() {
 +      public Object call() throws Exception {
 +        AttributesFactory af = new AttributesFactory();
 +        af.setDataPolicy(DataPolicy.REPLICATE);
 +        af.setScope(Scope.DISTRIBUTED_ACK);
 +        Region region = createRootRegion("sample", af.create());
 +        QueryService qs = getCache().getQueryService();
 +        qs.createIndex("foo", IndexType.FUNCTIONAL, "age", "/sample");
 +        return null;
 +      }
 +    };
 +    vm1.invoke(createRegionAndIndex);
 +    vm2.invoke(createRegionAndIndex);
 +    
 +    //do transactional puts in vm1
 +    vm1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Context ctx = getCache().getJNDIContext();
 +        UserTransaction utx = (UserTransaction)ctx.lookup("java:/UserTransaction");
 +        Region region = getRootRegion("sample");
 +        Integer x = new Integer(0);
 +        utx.begin();
 +        region.create(x, new Person("xyz", 45));
 +        utx.commit();
 +        QueryService qs = getCache().getQueryService();
 +        Query q = qs.newQuery("select * from /sample where age < 50");
 +        assertEquals(1, ((SelectResults)q.execute()).size());
 +        Person dsample = (Person)CopyHelper.copy(region.get(x));
 +        dsample.setAge(55);
 +        utx.begin();
 +        switch (op) {
 +        case TEST_PUT:
 +          region.put(x, dsample);
 +          break;
 +        case TEST_INVALIDATE:
 +          region.invalidate(x);
 +          break;
 +        case TEST_DESTROY:
 +          region.destroy(x);
 +          break;
 +        default:
 +          fail("unknown op");
 +        }
 +        utx.commit();
 +        assertEquals(0, ((SelectResults)q.execute()).size());
 +        return null;
 +      }
 +    });
 +    
 +    //run query and verify results in other vm
 +    vm2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        QueryService qs = getCache().getQueryService();
 +        Query q = qs.newQuery("select * from /sample where age < 50");
 +        assertEquals(0, ((SelectResults)q.execute()).size());
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  public void testBug43353() {
 +    Host host = Host.getHost(0);
 +    VM vm1 = host.getVM(0);
 +    VM vm2 = host.getVM(1);
 +    
 +    SerializableCallable createRegion = new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().createRegionFactory(RegionShortcut.REPLICATE).create(getTestMethodName());
 +        return null;
 +      }
 +    };
 +    
 +    vm1.invoke(createRegion);
 +    vm2.invoke(createRegion);
 +    
 +    vm1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getCache().getRegion(getTestMethodName());
 +        r.put("ikey", "value");
 +        getCache().getCacheTransactionManager().begin();
 +        r.put("key1", new byte[20]);
 +        r.invalidate("ikey");
 +        getCache().getCacheTransactionManager().commit();
 +        return null;
 +      }
 +    });
 +    
 +    vm2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getCache().getRegion(getTestMethodName());
 +        Object v = r.get("key1");
 +        assertNotNull(v);
 +        assertTrue(v instanceof byte[]);
 +        assertNull(r.get("ikey"));
 +        return null;
 +      }
 +    });
 +  }
 +}


[037/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
index d75b28d,0000000..edfee10
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
@@@ -1,2652 -1,0 +1,2655 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal.membership.gms.mgr;
 +
 +import java.io.IOException;
 +import java.io.NotSerializableException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.LinkedHashMap;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.CountDownLatch;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.TimeoutException;
 +import java.util.concurrent.locks.ReadWriteLock;
 +import java.util.concurrent.locks.ReentrantReadWriteLock;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.ForcedDisconnectException;
 +import com.gemstone.gemfire.GemFireConfigException;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.SystemConnectException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.ToDataException;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 +import com.gemstone.gemfire.distributed.Locator;
 +import com.gemstone.gemfire.distributed.internal.AdminMessageType;
 +import com.gemstone.gemfire.distributed.internal.DMStats;
 +import com.gemstone.gemfire.distributed.internal.DSClock;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.DistributionException;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.distributed.internal.DistributionMessage;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.InternalLocator;
 +import com.gemstone.gemfire.distributed.internal.OverflowQueueWithDMStats;
 +import com.gemstone.gemfire.distributed.internal.SizeableRunnable;
 +import com.gemstone.gemfire.distributed.internal.StartupMessage;
 +import com.gemstone.gemfire.distributed.internal.direct.DirectChannel;
 +import com.gemstone.gemfire.distributed.internal.direct.DirectChannelListener;
 +import com.gemstone.gemfire.distributed.internal.direct.ShunnedMemberException;
 +import com.gemstone.gemfire.distributed.internal.membership.DistributedMembershipListener;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
 +import com.gemstone.gemfire.distributed.internal.membership.NetView;
 +import com.gemstone.gemfire.distributed.internal.membership.QuorumChecker;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.GMSMember;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.SuspectMember;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.fd.GMSHealthMonitor;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.Manager;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeave;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.messenger.GMSQuorumChecker;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.SystemTimer;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.admin.remote.RemoteTransportConfig;
++import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.xmlcache.CacheServerCreation;
 +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.log4j.AlertAppender;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +import com.gemstone.gemfire.internal.shared.StringPrintWriter;
 +import com.gemstone.gemfire.internal.tcp.ConnectExceptions;
 +import com.gemstone.gemfire.internal.tcp.MemberShunnedException;
 +import com.gemstone.gemfire.internal.util.Breadcrumbs;
 +
 +public class GMSMembershipManager implements MembershipManager, Manager
 +{
 +  private static final Logger logger = Services.getLogger();
 +  
 +  /** product version to use for multicast serialization */
 +  volatile boolean disableMulticastForRollingUpgrade;
 +  
 +  /**
 +   * set to true if the distributed system that created this manager was
 +   * auto-reconnecting when it was created.
 +   */
 +  boolean wasReconnectingSystem;
 +  
 +  /**
 +   * A quorum checker is created during reconnect and is held
 +   * here so it is available to the UDP protocol for passing off
 +   * the ping-pong responses used in the quorum-checking algorithm. 
 +   */
 +  private volatile QuorumChecker quorumChecker;
 +  
 +  /**
 +   * thread-local used to force use of Messenger for communications, usually to
 +   * avoid deadlock when conserve-sockets=true.  Use of this should be removed
 +   * when connection pools are implemented in the direct-channel 
 +   */
 +  private ThreadLocal<Boolean> forceUseUDPMessaging = new ThreadLocal<Boolean>();
 +  
 +  /**
 +   * Trick class to make the startup synch more
 +   * visible in stack traces
 +   * 
 +   * @see GMSMembershipManager#startupLock
 +   */
 +  static class EventProcessingLock  {
 +    public EventProcessingLock() {
 +    }
 +  }
 +  
 +  static class StartupEvent  {
 +    static final int SURPRISE_CONNECT = 1;
 +    static final int VIEW = 2;
 +    static final int MESSAGE = 3;
 +    
 +    /**
 +     * indicates whether the event is a departure, a surprise connect
 +     * (i.e., before the view message arrived), a view, or a regular
 +     * message
 +     * 
 +     * @see #SURPRISE_CONNECT
 +     * @see #VIEW
 +     * @see #MESSAGE
 +     */
 +    private int kind;
 +    
 +    // Miscellaneous state depending on the kind of event
 +    InternalDistributedMember member;
 +    boolean crashed;
 +    String reason;
 +    DistributionMessage dmsg;
 +    NetView gmsView;
 +    
 +    @Override
 +    public String toString() {
 +      StringBuffer sb = new StringBuffer();
 +      sb.append("kind=");
 +      switch (kind) {
 +      case SURPRISE_CONNECT:
 +        sb.append("connect; member = <" + member + ">");
 +        break;
 +      case VIEW:
 +        String text = gmsView.toString();
 +        sb.append("view <" + text + ">");
 +        break;
 +      case MESSAGE:
 +        sb.append("message <" + dmsg + ">");
 +        break;
 +      default:
 +        sb.append("unknown=<" + kind + ">");
 +        break;
 +      }
 +      return sb.toString();
 +    }
 +
 +    /**
 +     * Create a surprise connect event
 +     * @param member the member connecting
 +     */
 +    StartupEvent(final InternalDistributedMember member) {
 +      this.kind = SURPRISE_CONNECT;
 +      this.member = member;
 +    }
 +    /**
 +     * Indicate if this is a surprise connect event
 +     * @return true if this is a connect event
 +     */
 +    boolean isSurpriseConnect() {
 +      return this.kind == SURPRISE_CONNECT;
 +    }
 +
 +    /**
 +     * Create a view event
 +     * @param v the new view
 +     */
 +    StartupEvent(NetView v) {
 +      this.kind = VIEW;
 +      this.gmsView = v;
 +    }
 +    
 +    /**
 +     * Indicate if this is a view event
 +     * @return true if this is a view event
 +     */
 +    boolean isGmsView() {
 +      return this.kind == VIEW;
 +    }
 +
 +    /**
 +     * Create a message event
 +     * @param d the message
 +     */
 +    StartupEvent(DistributionMessage d) {
 +      this.kind = MESSAGE;
 +      this.dmsg = d;
 +    }
 +    /**
 +     * Indicate if this is a message event
 +     * @return true if this is a message event
 +     */
 +    boolean isDistributionMessage() {
 +      return this.kind == MESSAGE;
 +    }
 +  }
 +  
 +  private int membershipCheckTimeout = DistributionConfig.DEFAULT_SECURITY_PEER_VERIFYMEMBER_TIMEOUT;
 +
 +  /**
 +   * This object synchronizes threads waiting for
 +   * startup to finish.  Updates to {@link #startupMessages}
 +   * are synchronized through this object.
 +   */
 +  protected final EventProcessingLock startupLock = new EventProcessingLock();
 +  
 +  /**
 +   * This is the latest view (ordered list of DistributedMembers) 
 +   * that has been installed
 +   * 
 +   * All accesses to this object are protected via {@link #latestViewLock}
 +   */
 +  protected NetView latestView = new NetView();
 +
 +  /**
 +   * This is the lock for protecting access to latestView
 +   * 
 +   * @see #latestView
 +   */
 +  protected ReadWriteLock latestViewLock = new ReentrantReadWriteLock();
 +  
 +  /**
 +   * This is the listener that accepts our membership events
 +   */
 +  protected com.gemstone.gemfire.distributed.internal.membership.DistributedMembershipListener listener;
 +
 +  /**
 +   * Membership failure listeners - for testing
 +   */
 +  List membershipTestHooks;
 +  
 +  /**
 +   * This is a representation of the local member (ourself)
 +   */
 +  protected InternalDistributedMember address = null; // new DistributedMember(-1);
 +
 +  protected DirectChannel directChannel;
 +
 +  protected MyDCReceiver dcReceiver;
 +  
 +  volatile boolean isJoining;
 +  
 +  /** have we joined successfully? */
 +  volatile boolean hasJoined;
 +  
 +  /**
 +   * Members of the distributed system that we believe have shut down.
 +   * Keys are instances of {@link InternalDistributedMember}, values are 
 +   * Longs indicating the time this member was shunned.
 +   * 
 +   * Members are removed after {@link #SHUNNED_SUNSET} seconds have
 +   * passed.
 +   * 
 +   * Accesses to this list needs to be under the read or write lock of {@link #latestViewLock}
 +   * 
 +   * @see System#currentTimeMillis()
 +   */
 +//  protected final Set shunnedMembers = Collections.synchronizedSet(new HashSet());
 +  protected final Map shunnedMembers = new ConcurrentHashMap();
 +
 +  /**
 +   * Members that have sent a shutdown message.  This is used to suppress
 +   * suspect processing that otherwise becomes pretty aggressive 
 +   * when a member is shutting down.
 +   */
 +  private final Map shutdownMembers = new BoundedLinkedHashMap(1000);
 +  
 +  /**
 +   * per bug 39552, keep a list of members that have been shunned and for
 +   * which a message is printed.  Contents of this list are cleared at the
 +   * same time they are removed from {@link #shunnedMembers}.
 +   * 
 +   * Accesses to this list needs to be under the read or write lock of {@link #latestViewLock}
 +   */
 +  protected final HashSet shunnedAndWarnedMembers = new HashSet();
 +  /**
 +   * The identities and birth-times of others that we have allowed into
 +   * membership at the distributed system level, but have not yet appeared
 +   * in a view.
 +   * <p>
 +   * Keys are instances of {@link InternalDistributedMember}, values are 
 +   * Longs indicating the time this member was shunned.
 +   * <p>
 +   * Members are removed when a view containing them is processed.  If,
 +   * after {@link #surpriseMemberTimeout} milliseconds have passed, a view
 +   * containing the member has not arrived, the member is removed from
 +   * membership and member-left notification is performed. 
 +   * <p>>
 +   * Accesses to this list needs to be under the read or write lock of {@link #latestViewLock}
 +   * 
 +   * @see System#currentTimeMillis()
 +   */
 +  protected final Map<InternalDistributedMember, Long> surpriseMembers = new ConcurrentHashMap();
 +
 +  /**
 +   * the timeout interval for surprise members.  This is calculated from 
 +   * the member-timeout setting
 +   */
 +  protected int surpriseMemberTimeout;
 +  
 +  /**
 +   * javagroups can skip views and omit telling us about a crashed member.
 +   * This map holds a history of suspected members that we use to detect
 +   * crashes.
 +   */
 +  private final Map<InternalDistributedMember, Long> suspectedMembers = new ConcurrentHashMap();
 +  
 +  /**
 +   * the timeout interval for suspected members
 +   */
 +  private final long suspectMemberTimeout = 180000;
 +  
 +  /**
 +   * Length of time, in seconds, that a member is retained in the zombie set
 +   * 
 +   * @see #shunnedMembers
 +   */
 +  static private final int SHUNNED_SUNSET = Integer.getInteger(
 +      "gemfire.shunned-member-timeout", 300).intValue();
 +  
 +  /**
 +   * Set to true when the service should stop.
 +   */
 +  protected volatile boolean shutdownInProgress = false;
 +  
 +  /**
 +   * Set to true when upcalls should be generated for
 +   * events.
 +   */
 +  protected volatile boolean processingEvents = false;
 +  
 +  /**
 +   * This is the latest viewId installed
 +   */
 +  long latestViewId = -1;
 +  
 +  /** distribution manager statistics */
 +  DMStats stats;
 +
 +  /**
 +   A list of messages received during channel startup that couldn't be processed yet.
 +   Additions or removals of this list must be synchronized
 +   via {@link #startupLock}.
 +   @since 5.0
 +   */
 +  protected LinkedList<StartupEvent> startupMessages = new LinkedList<StartupEvent>();
 +  
 +  /**
 +   * ARB: the map of latches is used to block peer handshakes till
 +   * authentication is confirmed.
 +   */
 +  final private HashMap memberLatch = new HashMap();
 +  
 +  /**
 +   * Insert our own MessageReceiver between us and the direct channel, in order
 +   * to correctly filter membership events.
 +   * 
 +   * @author jpenney
 +   * 
 +   */
 +  class MyDCReceiver implements DirectChannelListener
 +  {
 +
 +    DirectChannelListener upCall;
 +    
 +    /**
 +     * Don't provide events until the caller has told us we are ready.
 +     * 
 +     * Synchronization provided via GroupMembershipService.class.
 +     * 
 +     * Note that in practice we only need to delay accepting the first
 +     * client; we don't need to put this check before every call...
 +     *
 +     */
 +   MyDCReceiver(DirectChannelListener up) {
 +      upCall = up;
 +    }
 +
 +    public void messageReceived(DistributionMessage msg) {
 +      // bug 36851 - notify failure detection that we've had contact from a member
 +      services.getHealthMonitor().contactedBy(msg.getSender());
 +      handleOrDeferMessage(msg);
 +    }
 +
 +    public DistributionManager getDM() {
 +     return upCall.getDM();
 +    }
 +
 +  }
 +
 +
 +  /** if we connect to a locator that has NPD enabled then we enable it in this VM */
 +  public void enableNetworkPartitionDetection() {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Network partition detection is being enabled");
 +    }
 +    this.services.getConfig().getDistributionConfig().setEnableNetworkPartitionDetection(true);
 +    this.services.getConfig().setNetworkPartitionDetectionEnabled(true);
 +  }
 +  
 +  /**
 +   * Analyze a given view object, generate events as appropriate
 +   * 
 +   * @param newView
 +   */
 +  protected void processView(long newViewId, NetView newView)
 +  {
 +    // Sanity check...
 +     if (logger.isDebugEnabled()) {
 +      StringBuffer msg = new StringBuffer(200);
 +      msg.append("Membership: Processing view ");
 +      msg.append(newView);
 +      msg.append("} on " + address.toString());
 +      if (!newView.contains(address)) {
 +        logger.info(LocalizedMessage.create(
 +            LocalizedStrings.GroupMembershipService_THE_MEMBER_WITH_ID_0_IS_NO_LONGER_IN_MY_OWN_VIEW_1,
 +            new Object[] {address, newView}));
 +      }
 +    }
 +     
 +//     if (newView.getCrashedMembers().size() > 0) {
 +//       // dump stack for debugging #39827
 +//       OSProcess.printStacks(0);
 +//     }
 +    // We perform the update under a global lock so that other
 +    // incoming events will not be lost in terms of our global view.
 +    latestViewLock.writeLock().lock();
 +    try {
 +      // first determine the version for multicast message serialization
 +      Version version = Version.CURRENT;
 +      for (Iterator<Map.Entry<InternalDistributedMember, Long>> it=surpriseMembers.entrySet().iterator(); it.hasNext(); ) {
 +        InternalDistributedMember mbr = it.next().getKey();
 +        Version itsVersion = mbr.getVersionObject();
 +        if (itsVersion != null && version.compareTo(itsVersion) < 0) {
 +          version = itsVersion;
 +        }
 +      }
 +      for (InternalDistributedMember mbr: newView.getMembers()) {
 +        Version itsVersion = mbr.getVersionObject();
 +        if (itsVersion != null && itsVersion.compareTo(version) < 0) {
 +          version = mbr.getVersionObject();
 +        }
 +      }
 +      disableMulticastForRollingUpgrade = !version.equals(Version.CURRENT);
 +      
 +      if (newViewId < latestViewId) {
 +        // ignore this view since it is old news
 +        return;
 +      }
 +
 +      // Save previous view, for delta analysis
 +      NetView priorView = latestView;
 +      
 +      // update the view to reflect our changes, so that
 +      // callbacks will see the new (updated) view.
 +      latestViewId = newViewId;
 +      latestView = new NetView(newView, newView.getViewId());
 +      
 +      // look for additions
 +      for (int i = 0; i < newView.getMembers().size(); i++) { // additions
 +        InternalDistributedMember m = (InternalDistributedMember)newView.getMembers().get(i);
 +        
 +        // Once a member has been seen via a view, remove them from the
 +        // newborn set
 +        boolean wasSurprise = surpriseMembers.remove(m) != null;
 +        
 +        // bug #45155 - membership view processing was slow, causing a member to connect as "surprise"
 +        // and the surprise timeout removed the member and shunned it, keeping it from being
 +        // recognized as a valid member when it was finally seen in a view
 +//        if (isShunned(m)) {
 +//          warnShuns.add(m);
 +//          continue;
 +//        }
 +
 +        // if it's in a view, it's no longer suspect
 +        suspectedMembers.remove(m);
 +
 +        if (priorView.contains(m) || wasSurprise) {
 +          continue; // already seen
 +        }
 +      
 +        // ARB: unblock any waiters for this particular member.
 +        // i.e. signal any waiting threads in tcpconduit.
 +        String authInit = this.services.getConfig().getDistributionConfig().getSecurityPeerAuthInit();
 +        boolean isSecure = authInit != null && authInit.length() != 0;
 +
 +        if (isSecure) {
 +          CountDownLatch currentLatch;
 +          if ((currentLatch = (CountDownLatch)memberLatch.get(m)) != null) {
 +            currentLatch.countDown();
 +          }
 +        }
 +
 +        if (shutdownInProgress()) {
 +          addShunnedMember(m);
 +          continue; // no additions processed after shutdown begins
 +        } else {
 +          boolean wasShunned = endShun(m); // bug #45158 - no longer shun a process that is now in view
 +          if (wasShunned && logger.isDebugEnabled()) {
 +            logger.debug("No longer shunning {} as it is in the current membership view", m);
 +          }
 +        }
 +        
 +        logger.info(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_MEMBERSHIP_PROCESSING_ADDITION__0_, m));
 +
 +        try {
 +          listener.newMemberConnected(m);
 +        }
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (DistributedSystemDisconnectedException e) {
 +          // don't log shutdown exceptions
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          logger.info(LocalizedMessage.create(
 +              LocalizedStrings.GroupMembershipService_MEMBERSHIP_FAULT_WHILE_PROCESSING_VIEW_ADDITION_OF__0, m), t);
 +        }
 +      } // additions
 +      
 +      // look for departures
 +      for (int i = 0; i < priorView.getMembers().size(); i++) { // departures
 +        InternalDistributedMember m = (InternalDistributedMember)priorView.getMembers().get(i);
 +        if (newView.contains(m)) {
 +          continue; // still alive
 +        }
 +        
 +        if (surpriseMembers.containsKey(m)) {
 +          continue; // member has not yet appeared in a view
 +        }
 +
 +        try {
 +          removeWithViewLock(m,
 +              newView.getCrashedMembers().contains(m) || suspectedMembers.containsKey(m)
 +              , "departed membership view");
 +        }
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          logger.info(LocalizedMessage.create(
 +              LocalizedStrings.GroupMembershipService_MEMBERSHIP_FAULT_WHILE_PROCESSING_VIEW_REMOVAL_OF__0, m), t);
 +        }
 +      } // departures
 +      
 +      // expire surprise members, add others to view
 +      long oldestAllowed = System.currentTimeMillis() - this.surpriseMemberTimeout;
 +      for (Iterator<Map.Entry<InternalDistributedMember, Long>> it=surpriseMembers.entrySet().iterator(); it.hasNext(); ) {
 +        Map.Entry<InternalDistributedMember, Long> entry = it.next();
 +        Long birthtime = (Long)entry.getValue();
 +        if (birthtime.longValue() < oldestAllowed) {
 +          it.remove();
 +          InternalDistributedMember m = entry.getKey();
 +          logger.info(LocalizedMessage.create(
 +            LocalizedStrings.GroupMembershipService_MEMBERSHIP_EXPIRING_MEMBERSHIP_OF_SURPRISE_MEMBER_0, m));
 +          removeWithViewLock(m, true, "not seen in membership view in "
 +              + this.surpriseMemberTimeout + "ms");
 +        }
 +        else {
 +          if (!latestView.contains(entry.getKey())) {
 +            latestView.add(entry.getKey());
 +          }
 +        }
 +      }
 +      // expire suspected members
 +      oldestAllowed = System.currentTimeMillis() - this.suspectMemberTimeout;
 +      for (Iterator it=suspectedMembers.entrySet().iterator(); it.hasNext(); ) {
 +        Map.Entry entry = (Map.Entry)it.next();
 +        Long birthtime = (Long)entry.getValue();
 +        if (birthtime.longValue() < oldestAllowed) {
 +          InternalDistributedMember m = (InternalDistributedMember)entry.getKey();
 +          it.remove();
 +        }
 +      }
 +      try {
 +        listener.viewInstalled(latestView);
 +        startCleanupTimer();
 +      }
 +      catch (DistributedSystemDisconnectedException se) {
 +      }
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +
 +  /**
 +   * the timer used to perform periodic tasks
 +   * 
 +   * Concurrency: protected by {@link #latestViewLock} ReentrantReadWriteLock
 +   */
 +  private SystemTimer cleanupTimer;
 +
 +  private Services services;
 +
 +  private boolean mcastEnabled;
 +
 +  private boolean tcpDisabled;
 +
 +
 +  @Override
 +  public boolean isMulticastAllowed() {
 +    return !disableMulticastForRollingUpgrade;
 +  }
 +
 +  /**
 +   * Joins the distributed system
 +   * 
 +   * @throws GemFireConfigException - configuration error
 +   * @throws SystemConnectException - problem joining
 +   */
 +  private void join() {
 +    services.setShutdownCause(null);
 +    services.getCancelCriterion().cancel(null);
 +    
 +    latestViewLock.writeLock().lock();
 +    try {
 +      try {
 +        this.isJoining = true; // added for bug #44373
 +
 +        // connect
 +        long start = System.currentTimeMillis();
 +
 +        boolean ok = services.getJoinLeave().join();
 +        
 +        if (!ok) {
 +          throw new GemFireConfigException("Unable to join the distributed system.  " +
 +              "Operation either timed out, was stopped or Locator does not exist.");
 +        }
 +
 +        long delta = System.currentTimeMillis() - start;
 +
 +        logger.info(LogMarker.DISTRIBUTION, LocalizedMessage.create(
 +            LocalizedStrings.GroupMembershipService_JOINED_TOOK__0__MS, delta));
 +
 +        NetView initialView = services.getJoinLeave().getView();
 +        latestView = new NetView(initialView, initialView.getViewId());
 +        listener.viewInstalled(latestView);
 +        
 +      } catch (RuntimeException ex) {
 +        throw ex;
 +      }
 +      catch (Exception ex) {
 +        if (ex.getCause() != null && ex.getCause().getCause() instanceof SystemConnectException) {
 +          throw (SystemConnectException)(ex.getCause().getCause());
 +        }
 +        throw new DistributionException(LocalizedStrings.GroupMembershipService_AN_EXCEPTION_WAS_THROWN_WHILE_JOINING.toLocalizedString(), ex);
 +      }
 +      finally {
 +        this.isJoining = false;
 +      }
 +    }
 +    finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +
 +
 +  public GMSMembershipManager(DistributedMembershipListener listener) {
 +    Assert.assertTrue(listener != null);
 +    this.listener = listener;
 +  }
 +  
 +  @Override
 +  public void init(Services services) {
 +    this.services = services;
 +
 +    Assert.assertTrue(services != null);
 +    
 +    this.stats = services.getStatistics();
 +    DistributionConfig config = services.getConfig().getDistributionConfig();
 +    RemoteTransportConfig transport = services.getConfig().getTransport();
 +
 +    this.membershipCheckTimeout = config.getSecurityPeerMembershipTimeout();
 +    this.wasReconnectingSystem = transport.getIsReconnectingDS();
 +    
 +    // cache these settings for use in send()
 +    this.mcastEnabled = transport.isMcastEnabled();
 +    this.tcpDisabled  = transport.isTcpDisabled();
 +
 +    if (!this.tcpDisabled) {
 +      dcReceiver = new MyDCReceiver(listener);
 +    }
 +    
 +    surpriseMemberTimeout = Math.max(20 * DistributionConfig.DEFAULT_MEMBER_TIMEOUT,
 +        20 * config.getMemberTimeout());
 +    surpriseMemberTimeout = Integer.getInteger("gemfire.surprise-member-timeout", surpriseMemberTimeout).intValue();
 +    
 +  }
 +  
 +  @Override
 +  public void start() {
 +    DistributionConfig config = services.getConfig().getDistributionConfig();
 +    RemoteTransportConfig transport = services.getConfig().getTransport();
 +
 +    int dcPort = 0;
 +    if (!tcpDisabled) {
 +      directChannel = new DirectChannel(this, dcReceiver, config);
 +      dcPort = directChannel.getPort();
 +    }
 +
 +    
 +    services.getMessenger().getMemberID().setDirectChannelPort(dcPort);
 +
 +  }
 +  
 +  
 +  @Override
 +  public void joinDistributedSystem() {
 +    long startTime = System.currentTimeMillis();
 +    
 +    try {
 +      join();
 +    }
 +    catch (RuntimeException e) {
 +      if (directChannel != null) {
 +        directChannel.disconnect(e);
 +      }
 +      throw e;
 +    }
 +    
 +    this.address = services.getMessenger().getMemberID();
 +
 +    int dcPort = 0;
 +    if (directChannel != null) {
 +      dcPort = directChannel.getPort();
 +    }
 +    
 +    if (directChannel != null) {
 +      directChannel.setLocalAddr(address);
 +    }
 +
 +    this.hasJoined = true;
 +
 +    // in order to debug startup issues we need to announce the membership
 +    // ID as soon as we know it
 +    logger.info(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_entered_into_membership_in_group_0_with_id_1,
 +        new Object[]{""+(System.currentTimeMillis()-startTime)}));
 +
 +  }
 +  
 +  @Override
 +  public void started() {
 +  }
 +  
 +
 +  /** this is invoked by JoinLeave when there is a loss of quorum in the membership system */
 +  public void quorumLost(Collection<InternalDistributedMember> failures, NetView view) {
 +    // notify of quorum loss if split-brain detection is enabled (meaning we'll shut down) or
 +    // if the loss is more than one member
 +    
 +    boolean notify = failures.size() > 1;
 +    if (!notify) {
 +      notify = services.getConfig().isNetworkPartitionDetectionEnabled();
 +    }
 +    
 +    if (notify) {
 +      List<InternalDistributedMember> remaining = new ArrayList<InternalDistributedMember>(view.getMembers());
 +      remaining.removeAll(failures);
 +      
 +      if (inhibitForceDisconnectLogging) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("<ExpectedException action=add>Possible loss of quorum</ExpectedException>");
 +        }
 +      }
 +      logger.fatal(LocalizedMessage.create(
 +          LocalizedStrings.GroupMembershipService_POSSIBLE_LOSS_OF_QUORUM_DETECTED, new Object[] {failures.size(), failures}));
 +      if (inhibitForceDisconnectLogging) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("<ExpectedException action=remove>Possible loss of quorum</ExpectedException>");
 +        }
 +      }
 +      
 +  
 +      try {
 +        this.listener.quorumLost(new HashSet<InternalDistributedMember>(failures),
 +            remaining);
 +      } catch (CancelException e) {
 +        // safe to ignore - a forced disconnect probably occurred
 +      }
 +    }
 +  }
 +  
 +
 +  @Override
 +  public boolean testMulticast() {
 +    try {
 +      return services.getMessenger().testMulticast(services.getConfig().getMemberTimeout());
 +    } catch (InterruptedException e) {
 +      services.getCancelCriterion().checkCancelInProgress(e);
 +      Thread.currentThread().interrupt();
 +      return false;
 +    }
 +  }
 +  
 +  /**
 +   * Remove a member.  {@link #latestViewLock} must be held
 +   * before this method is called.  If member is not already shunned,
 +   * the uplevel event handler is invoked.
 +   * 
 +   * @param dm
 +   * @param crashed
 +   * @param reason
 +   */
 +  protected void removeWithViewLock(InternalDistributedMember dm,
 +      boolean crashed, String reason) {
 +    boolean wasShunned = isShunned(dm);
 +
 +    // Delete resources
 +    destroyMember(dm, crashed, reason);
 +
 +    if (wasShunned) {
 +      return; // Explicit deletion, no upcall.
 +    }
 +    
 +    try {
 +      listener.memberDeparted(dm, crashed, reason);
 +    }
 +    catch (DistributedSystemDisconnectedException se) {
 +      // let's not get huffy about it
 +    }
 +  }
 +  
 +  /**
 +   * Process a surprise connect event, or place it on the startup queue.
 +   * @param member the member
 +   */
 +  protected void handleOrDeferSurpriseConnect(InternalDistributedMember member) {
 +    synchronized (startupLock) {
 +      if (!processingEvents) {
 +        startupMessages.add(new StartupEvent(member));
 +        return;
 +      }
 +    }
 +    processSurpriseConnect(member);
 +  }
 +  
 +  public void startupMessageFailed(DistributedMember mbr, String failureMessage) {
 +    // fix for bug #40666
 +    addShunnedMember((InternalDistributedMember)mbr);
 +    // fix for bug #41329, hang waiting for replies
 +    try {
 +      listener.memberDeparted((InternalDistributedMember)mbr, true, "failed to pass startup checks");
 +    }
 +    catch (DistributedSystemDisconnectedException se) {
 +      // let's not get huffy about it
 +    }
 +  }
 +
 +  
 +  /**
 +   * Logic for handling a direct connection event (message received
 +   * from a member not in the view).  Does not employ the
 +   * startup queue.
 +   * <p>
 +   * Must be called with {@link #latestViewLock} held.  Waits
 +   * until there is a stable view.  If the member has already
 +   * been added, simply returns; else adds the member.
 +   * 
 +   * @param dm the member joining
 +   */
 +  public boolean addSurpriseMember(DistributedMember dm) {
 +    final InternalDistributedMember member = (InternalDistributedMember)dm;
 +    boolean warn = false;
 +    
 +    latestViewLock.writeLock().lock();
 +    try {
 +      // At this point, the join may have been discovered by
 +      // other means.
 +      if (latestView.contains(member)) {
 +        return true;
 +      }
 +      if (surpriseMembers.containsKey(member)) {
 +        return true;
 +      }
 +      if (member.getVmViewId() < 0) {
 +        logger.warn("adding a surprise member that has not yet joined the distributed system: " + member, new Exception("stack trace"));
 +      }
 +      if (latestView.getViewId() > member.getVmViewId()) {
 +        // tell the process that it should shut down distribution.
 +        // Run in a separate thread so we don't hold the view lock during the request.  Bug #44995
 +        new Thread(Thread.currentThread().getThreadGroup(),
 +            "Removing shunned GemFire node " + member) {
 +          @Override
 +          public void run() {
 +            // fix for bug #42548
 +            // this is an old member that shouldn't be added
 +            logger.warn(LocalizedMessage.create(
 +                LocalizedStrings.GroupMembershipService_Invalid_Surprise_Member, new Object[]{member, latestView}));
 +            requestMemberRemoval(member, "this member is no longer in the view but is initiating connections");
 +          }
 +        }.start();
 +        addShunnedMember(member);
 +        return false;
 +      }
 +
 +      // Adding him to this set ensures we won't remove him if a new
 +      // view comes in and he's still not visible.
 +      surpriseMembers.put(member, Long.valueOf(System.currentTimeMillis()));
 +
 +      if (shutdownInProgress()) {
 +        // Force disconnect, esp. the TCPConduit
 +        String msg = LocalizedStrings.GroupMembershipService_THIS_DISTRIBUTED_SYSTEM_IS_SHUTTING_DOWN.toLocalizedString();
 +        if (directChannel != null) {
 +          try {
 +            directChannel.closeEndpoint(member, msg);
 +          } catch (DistributedSystemDisconnectedException e) {
 +            // ignore - happens during shutdown
 +          }
 +        }
 +        destroyMember(member, false, msg); // for good luck
 +        return true; // allow during shutdown
 +      }
 +
 +      if (isShunned(member)) {
 +        warn = true;
 +        surpriseMembers.remove(member);
 +      } else {
 +
 +        // Now that we're sure the member is new, add them.
 +        // make sure the surprise-member cleanup task is running
 +        if (this.cleanupTimer == null) {
 +          startCleanupTimer();
 +        } // cleanupTimer == null
 +
 +        // Ensure that the member is accounted for in the view
 +        // Conjure up a new view including the new member. This is necessary
 +        // because we are about to tell the listener about a new member, so
 +        // the listener should rightfully expect that the member is in our
 +        // membership view.
 +
 +        // However, we put the new member at the end of the list.  This
 +        // should ensure he's not chosen as an elder.
 +        // This will get corrected when he finally shows up in the
 +        // view.
 +        NetView newMembers = new NetView(latestView, latestView.getViewId());
 +        newMembers.add(member);
 +        latestView = newMembers;
 +      }
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +    if (warn) { // fix for bug #41538 - deadlock while alerting
 +      logger.warn(LocalizedMessage.create(
 +          LocalizedStrings.GroupMembershipService_MEMBERSHIP_IGNORING_SURPRISE_CONNECT_FROM_SHUNNED_MEMBER_0, member));
 +    } else {
 +      listener.newMemberConnected(member);
 +    }
 +    return !warn;
 +  }
 +  
 +
 +  /** starts periodic task to perform cleanup chores such as expire surprise members */
 +  private void startCleanupTimer() {
 +    latestViewLock.writeLock().lock();
 +    try {
 +      if (this.cleanupTimer != null) {
 +        return;
 +      }
 +      DistributedSystem ds = InternalDistributedSystem.getAnyInstance();
 +      if (ds != null && ds.isConnected()) {
 +        this.cleanupTimer = new SystemTimer(ds, true);
 +        SystemTimer.SystemTimerTask st = new SystemTimer.SystemTimerTask() {
 +          @Override
 +          public void run2() {
 +            latestViewLock.writeLock().lock();
 +            try {
 +              long oldestAllowed = System.currentTimeMillis() - surpriseMemberTimeout;
 +              for (Iterator it=surpriseMembers.entrySet().iterator(); it.hasNext(); ) {
 +                Map.Entry entry = (Map.Entry)it.next();
 +                Long birthtime = (Long)entry.getValue();
 +                if (birthtime.longValue() < oldestAllowed) {
 +                  it.remove();
 +                  InternalDistributedMember m = (InternalDistributedMember)entry.getKey();
 +                  logger.info(LocalizedMessage.create(
 +                      LocalizedStrings.GroupMembershipService_MEMBERSHIP_EXPIRING_MEMBERSHIP_OF_SURPRISE_MEMBER_0, m));
 +                  removeWithViewLock(m, true, "not seen in membership view in "
 +                      + surpriseMemberTimeout + "ms");
 +                }
 +              }
 +            } finally {
 +              latestViewLock.writeLock().unlock();
 +            }
 +          }
 +        };
 +        this.cleanupTimer.scheduleAtFixedRate(st, surpriseMemberTimeout, surpriseMemberTimeout/3);
 +      } // ds != null && ds.isConnected()
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +  /**
 +   * Dispatch the distribution message, or place it on the startup queue.
 +   * 
 +   * @param msg the message to process
 +   */
 +  protected void handleOrDeferMessage(DistributionMessage msg) {
 +    synchronized(startupLock) {
 +      if (!processingEvents) {
 +        startupMessages.add(new StartupEvent(msg));
 +        return;
 +      }
 +    }
 +    dispatchMessage(msg);
 +  }
 +  
 +  public void warnShun(DistributedMember m) {
 +    latestViewLock.writeLock().lock();
 +    try {
 +      if (!shunnedMembers.containsKey(m)) {
 +        return; // not shunned
 +      }
 +      if (shunnedAndWarnedMembers.contains(m)) {
 +        return; // already warned
 +      }
 +      shunnedAndWarnedMembers.add(m);
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +    // issue warning outside of sync since it may cause messaging and we don't
 +    // want to hold the view lock while doing that
 +    logger.warn(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_MEMBERSHIP_DISREGARDING_SHUNNED_MEMBER_0, m));
 +  }
 +  
 +  @Override
 +  public void processMessage(DistributionMessage msg) {
 +    handleOrDeferMessage(msg);
 +  }
 +  
 +  /**
 +   * Logic for processing a distribution message.  
 +   * <p>
 +   * It is possible to receive messages not consistent with our view.
 +   * We handle this here, and generate an uplevel event if necessary
 +   * @param msg the message
 +   */
 +  public void dispatchMessage(DistributionMessage msg) {
 +    boolean isNew = false;
 +    InternalDistributedMember m = msg.getSender();
 +    boolean shunned = false;
 +
 +    // First grab the lock: check the sender against our stabilized view.
 +    latestViewLock.writeLock().lock();
 +    try {
 +      if (isShunned(m)) {
 +        if (msg instanceof StartupMessage) {
 +          endShun(m);
 +        }
 +        else {
 +          // fix for bug 41538 - sick alert listener causes deadlock
 +          // due to view lock being held during messaging
 +          shunned = true;
 +        }
 +      } // isShunned
 +
 +      if (!shunned) {
 +        isNew = !latestView.contains(m) && !surpriseMembers.containsKey(m);
 +
 +        // If it's a new sender, wait our turn, generate the event
 +        if (isNew) {
 +          shunned = !addSurpriseMember(m);
 +        } // isNew
 +      }
 +
 +      // Latch the view before we unlock
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +    
 +    if (shunned) { // bug #41538 - shun notification must be outside synchronization to avoid hanging
 +      warnShun(m);
 +      logger.info("Membership: Ignoring message from shunned member <{}>:{}", m, msg);
 +      throw new MemberShunnedException(m);
 +    }
 +    
 +    listener.messageReceived(msg);
 +  }
 +
 +  /**
 +   * Process a new view object, or place on the startup queue
 +   * @param viewArg the new view
 +   */
 +  protected void handleOrDeferViewEvent(NetView viewArg) {
 +    if (this.isJoining) {
 +      // bug #44373 - queue all view messages while joining.
 +      // This is done under the latestViewLock, but we can't block here because
 +      // we're sitting in the UDP reader thread.
 +      synchronized(startupLock) {
 +        startupMessages.add(new StartupEvent(viewArg));
 +        return;
 +      }
 +    }
 +    latestViewLock.writeLock().lock();
 +    try {
 +      synchronized(startupLock) {
 +        if (!processingEvents) {
 +          startupMessages.add(new StartupEvent(viewArg));
 +          return;
 +        }
 +      }
 +      // view processing can take a while, so we use a separate thread
 +      // to avoid blocking a reader thread
 +      NetView newView = viewArg;
 +      long newId = viewArg.getViewId();
 +      LocalViewMessage v = new LocalViewMessage(address, newId, newView,
 +          GMSMembershipManager.this);
 +
 +      listener.messageReceived(v);
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +  
 +  @Override
 +  public void memberSuspected(InternalDistributedMember initiator, InternalDistributedMember suspect, String reason) {
 +    SuspectMember s = new SuspectMember(initiator, suspect, reason);
 +    handleOrDeferSuspect(s);
 +  }
 +
 +  /**
 +   * Process a new view object, or place on the startup queue
 +   * @param suspectInfo the suspectee and suspector
 +   */
 +  protected void handleOrDeferSuspect(SuspectMember suspectInfo) {
 +    latestViewLock.writeLock().lock();
 +    try {
 +      synchronized(startupLock) {
 +        if (!processingEvents) {
 +          return;
 +        }
 +      }
 +      InternalDistributedMember suspect = suspectInfo.suspectedMember;
 +      InternalDistributedMember who = suspectInfo.whoSuspected;
 +      this.suspectedMembers.put(suspect, Long.valueOf(System.currentTimeMillis()));
 +      try {
 +        listener.memberSuspect(suspect, who, suspectInfo.reason);
 +      }
 +      catch (DistributedSystemDisconnectedException se) {
 +        // let's not get huffy about it
 +      }
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +
 +  /**
 +   * Process a potential direct connect.  Does not use
 +   * the startup queue.  It grabs the {@link #latestViewLock} 
 +   * and then processes the event.
 +   * <p>
 +   * It is a <em>potential</em> event, because we don't know until we've
 +   * grabbed a stable view if this is really a new member.
 +   * 
 +   * @param member
 +   */
 +  private void processSurpriseConnect(
 +      InternalDistributedMember member) 
 +  {
 +    addSurpriseMember(member);
 +  }
 +  
 +  /**
 +   * Dispatch routine for processing a single startup event
 +   * @param o the startup event to handle
 +   */
 +  private void processStartupEvent(StartupEvent o) {
 +    // Most common events first
 +    
 +    if (o.isDistributionMessage()) { // normal message
 +      try {
 +        dispatchMessage(o.dmsg);
 +      }
 +      catch (MemberShunnedException e) {
 +        // message from non-member - ignore
 +      }
 +    } 
 +    else if (o.isGmsView()) { // view event
 +      processView(o.gmsView.getViewId(), o.gmsView);
 +    }
 +    else if (o.isSurpriseConnect()) { // connect
 +      processSurpriseConnect(o.member);
 +    }
 +    
 +    else // sanity
 +      throw new InternalGemFireError(LocalizedStrings.GroupMembershipService_UNKNOWN_STARTUP_EVENT_0.toLocalizedString(o));
 +  }
 +  
 +  /**
 +   * Special mutex to create a critical section for
 +   * {@link #startEventProcessing()}
 +   */
 +  private final Object startupMutex = new Object();
 +
 +  
 +  public void startEventProcessing()
 +  {
 +    // Only allow one thread to perform the work
 +    synchronized (startupMutex) {
 +      if (logger.isDebugEnabled())
 +        logger.debug("Membership: draining startup events.");
 +      // Remove the backqueue of messages, but allow
 +      // additional messages to be added.
 +      for (;;) {
 +        StartupEvent ev;
 +        // Only grab the mutex while reading the queue.
 +        // Other events may arrive while we're attempting to
 +        // drain the queue.  This is OK, we'll just keep processing
 +        // events here until we've caught up.
 +        synchronized (startupLock) {
 +          int remaining = startupMessages.size();
 +          if (remaining == 0) {
 +            // While holding the lock, flip the bit so that
 +            // no more events get put into startupMessages, and
 +            // notify all waiters to proceed.
 +            processingEvents = true;
 +            startupLock.notifyAll();
 +            break;  // ...and we're done.
 +          }
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Membership: {} remaining startup message(s)", remaining);
 +          }
 +          ev = (StartupEvent)startupMessages.removeFirst();
 +        } // startupLock
 +        try {
 +          processStartupEvent(ev);
 +        }
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          logger.warn(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_MEMBERSHIP_ERROR_HANDLING_STARTUP_EVENT), t);
 +        }
 +        
 +      } // for
 +      if (logger.isDebugEnabled())
 +        logger.debug("Membership: finished processing startup events.");
 +    } // startupMutex
 +  }
 +
 + 
 +  public void waitForEventProcessing() throws InterruptedException {
 +    // First check outside of a synchronized block.  Cheaper and sufficient.
 +    if (Thread.interrupted()) throw new InterruptedException();
 +    if (processingEvents)
 +      return;
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Membership: waiting until the system is ready for events");
 +    }
 +    for (;;) {
 +      directChannel.getCancelCriterion().checkCancelInProgress(null);
 +      synchronized (startupLock) {
 +        // Now check using a memory fence and synchronization.
 +        if (processingEvents)
 +          break;
 +        boolean interrupted = Thread.interrupted();
 +        try {
 +          startupLock.wait();
 +        }
 +        catch (InterruptedException e) {
 +          interrupted = true;
 +          directChannel.getCancelCriterion().checkCancelInProgress(e);
 +        }
 +        finally {
 +          if (interrupted) {
 +            Thread.currentThread().interrupt();
 +          }
 +        }
 +      } // synchronized
 +    } // for
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Membership: continuing");
 +    }
 +  }
 +
 +  /**
 +   * for testing we need to validate the startup event list
 +   */
 +  public List<StartupEvent> getStartupEvents() {
 +    return this.startupMessages;
 +  }
 +
 +  public ReadWriteLock getViewLock() {
 +    return this.latestViewLock;
 +  }
 +
 +  /**
 +   * Returns a copy (possibly not current) of the current
 +   * view (a list of {@link DistributedMember}s)
 +   */
 +  public NetView getView()
 +  {
 +    // Grab the latest view under a mutex...
 +    NetView v;
 +
 +    latestViewLock.readLock().lock();
 +    v = latestView;
 +    latestViewLock.readLock().unlock();
 +
 +    NetView result = new NetView(v, v.getViewId());
 +    
 +    for (InternalDistributedMember m: v.getMembers()) {
 +      if (isShunned(m)) {
 +        result.remove(m);
 +      }
 +    }
 +    
 +    return result;
 +  }
 +  
 +  /**
 +   * test hook<p>
 +   * The lead member is the eldest member with partition detection enabled.<p>
 +   * If no members have partition detection enabled, there will be no
 +   * lead member and this method will return null.
 +   * @return the lead member associated with the latest view
 +   */
 +  public DistributedMember getLeadMember() {
 +    latestViewLock.readLock().lock();
 +    try {
 +      return latestView == null? null : latestView.getLeadMember();
 +    } finally {
 +      latestViewLock.readLock().unlock();
 +    }
 +  }
 +  
 +  protected boolean isJoining() {
 +    return this.isJoining;
 +  }
 +  
 +  /**
 +   * test hook
 +   * @return the current membership view coordinator
 +   */
 +  public DistributedMember getCoordinator() {
 +    // note - we go straight to JoinLeave because the
 +    // DistributionManager queues view changes in a serial executor, where
 +    // they're asynchronously installed.  The DS may still see the old coordinator
 +    latestViewLock.readLock().lock();
 +    try {
 +      return latestView == null? null : latestView.getCoordinator();
 +    } finally {
 +      latestViewLock.readLock().unlock();
 +    }
 +  }
 +
 +  public boolean memberExists(DistributedMember m) {
 +    latestViewLock.readLock().lock();
 +    NetView v = latestView;
 +    latestViewLock.readLock().unlock();
 +    return v.getMembers().contains(m);
 +  }
 +  
 +  /**
 +   * Returns the identity associated with this member. WARNING: this value will
 +   * be returned after the channel is closed, but in that case it is good for
 +   * logging purposes only. :-)
 +   */
 +  public InternalDistributedMember getLocalMember()
 +  {
 +    return address;
 +  }
 +  
 +  public Services getServices() {
 +    return services;
 +  }
 +
 +  public void postConnect() {
 +  }
 +  
 +  /**
 +   * @see SystemFailure#loadEmergencyClasses()
 +   /**
 +   * break any potential circularity in {@link #loadEmergencyClasses()}
 +   */
 +  private static volatile boolean emergencyClassesLoaded = false;
 +
 +  /**
 +   * inhibits logging of ForcedDisconnectException to keep dunit logs clean
 +   * while testing this feature
 +   */
 +  protected static volatile boolean inhibitForceDisconnectLogging;
 +  
 +  /**
 +   * Ensure that the critical classes from components
 +   * get loaded.
 +   * 
 +   * @see SystemFailure#loadEmergencyClasses()
 +   */
 +  public static void loadEmergencyClasses() {
 +    if (emergencyClassesLoaded) return;
 +    emergencyClassesLoaded = true;
 +    DirectChannel.loadEmergencyClasses();
 +    GMSJoinLeave.loadEmergencyClasses();
 +    GMSHealthMonitor.loadEmergencyClasses();
 +  }
 +  /**
 +   * Close the receiver, avoiding all potential deadlocks and
 +   * eschewing any attempts at being graceful.
 +   * 
 +   * @see SystemFailure#emergencyClose()
 +   */
 +  public void emergencyClose() {
 +    final boolean DEBUG = SystemFailure.TRACE_CLOSE;
 +    
 +    setShutdown(); 
 +
 +    // We can't call close() because they will allocate objects.  Attempt
 +    // a surgical strike and touch the important protocols.
 +    
 +    // MOST important, kill the FD protocols...
 +    services.emergencyClose();
 +    
 +    // Close the TCPConduit sockets...
 +    if (directChannel != null) {
 +      if (DEBUG) {
 +        System.err.println("DEBUG: emergency close of DirectChannel");
 +      }
 +      directChannel.emergencyClose();
 +    }
 +    
 +    if (DEBUG) {
 +      System.err.println("DEBUG: done closing GroupMembershipService");
 +    }
 +  }
 +  
 +  
 +  /**
 +   * in order to avoid split-brain occurring when a member is shutting down due to
 +   * race conditions in view management we add it as a shutdown member when we receive
 +   * a shutdown message.  This is not the same as a SHUNNED member.
 +   */
 +  public void shutdownMessageReceived(InternalDistributedMember id, String reason) {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Membership: recording shutdown status of {}", id);
 +    }
 +    synchronized(this.shutdownMembers) { 
 +      this.shutdownMembers.put(id, id);
 +      services.getHealthMonitor().memberShutdown(id, reason);
 +      services.getJoinLeave().memberShutdown(id, reason);
 +    }
 +  }
 +  
 +  /**
 +   * returns true if a shutdown message has been received from the given address but
 +   * that member is still in the membership view or is a surprise member.
 +   */
 +  public boolean isShuttingDown(InternalDistributedMember mbr) {
 +    synchronized(shutdownMembers) {
 +      return shutdownMembers.containsKey(mbr);
 +    }
 +  }
 +
 +  
 +  public void shutdown() {
 +    setShutdown();
 +    services.stop();
 +  }
 +  
 +  @Override
 +  public void stop() {
 +    
 +    // [bruce] Do not null out the channel w/o adding appropriate synchronization
 +    
 +    logger.debug("MembershipManager closing");
 +    
 +    if (directChannel != null) {
 +      directChannel.disconnect(null);
 +
 +      if (address != null) {
 +        // Make sure that channel information is consistent
 +        // Probably not important in this particular case, but just
 +        // to be consistent...
 +        latestViewLock.writeLock().lock();
 +        try {
 +          destroyMember(address, false, "orderly shutdown");
 +        } finally {
 +          latestViewLock.writeLock().unlock();
 +        }
 +      }
 +    }
 +    
 +    if (cleanupTimer != null) {
 +      cleanupTimer.cancel();
 +    }
 +    
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Membership: channel closed");
 +    }
 +  }
 +  
 +  public void uncleanShutdown(String reason, final Exception e) {
 +    inhibitForcedDisconnectLogging(false);
 +    
 +    if (services.getShutdownCause() == null) {
 +      services.setShutdownCause(e);
 +    }
 +    
 +    if (this.directChannel != null) {
 +      this.directChannel.disconnect(e);
 +    }
 +    
 +    // first shut down communication so we don't do any more harm to other
 +    // members
 +    services.emergencyClose();
 +    
 +    if (e != null) {
 +      try {
 +        if (membershipTestHooks != null) {
 +          List l = membershipTestHooks;
 +          for (Iterator it=l.iterator(); it.hasNext(); ) {
 +            MembershipTestHook dml = (MembershipTestHook)it.next();
 +            dml.beforeMembershipFailure(reason, e);
 +          }
 +        }
 +        listener.membershipFailure(reason, e);
 +        if (membershipTestHooks != null) {
 +          List l = membershipTestHooks;
 +          for (Iterator it=l.iterator(); it.hasNext(); ) {
 +            MembershipTestHook dml = (MembershipTestHook)it.next();
 +            dml.afterMembershipFailure(reason, e);
 +          }
 +        }
 +      }
 +      catch (RuntimeException re) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_EXCEPTION_CAUGHT_WHILE_SHUTTING_DOWN), re);
 +      }
 +    }
 +  }
 +  
 +  /** generate XML for the cache before shutting down due to forced disconnect */
 +  public void saveCacheXmlForReconnect() {
 +    // there are two versions of this method so it can be unit-tested
 +    boolean sharedConfigEnabled = services.getConfig().getDistributionConfig().getUseSharedConfiguration();
 +    saveCacheXmlForReconnect(sharedConfigEnabled);
 +  }
 +  
 +  /** generate XML from the cache before shutting down due to forced disconnect */
 +  public void saveCacheXmlForReconnect(boolean sharedConfigEnabled) {
 +    // first save the current cache description so reconnect can rebuild the cache
 +    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
 +    if (cache != null && (cache instanceof Cache)) {
 +      if (!Boolean.getBoolean("gemfire.autoReconnect-useCacheXMLFile")
 +          && !cache.isSqlfSystem() && !sharedConfigEnabled) {
 +        try {
 +          logger.info("generating XML to rebuild the cache after reconnect completes");
 +          StringPrintWriter pw = new StringPrintWriter(); 
 +          CacheXmlGenerator.generate((Cache)cache, pw, true, false);
 +          String cacheXML = pw.toString();
 +          cache.getCacheConfig().setCacheXMLDescription(cacheXML);
 +          logger.info("XML generation completed: {}", cacheXML);
 +        } catch (CancelException e) {
 +          logger.info(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_PROBLEM_GENERATING_CACHE_XML), e);
 +        }
 +      } else if (sharedConfigEnabled && !cache.getCacheServers().isEmpty()) {
 +        // we need to retain a cache-server description if this JVM was started by gfsh
 +        List<CacheServerCreation> list = new ArrayList<CacheServerCreation>(cache.getCacheServers().size());
 +        for (Iterator it = cache.getCacheServers().iterator(); it.hasNext(); ) {
-           CacheServer cs = (CacheServer)it.next();
-           CacheServerCreation bsc = new CacheServerCreation(cache, cs);
-           list.add(bsc);
++          CacheServerImpl cs = (CacheServerImpl)it.next();
++          if (cs.isDefaultServer()) {
++            CacheServerCreation bsc = new CacheServerCreation(cache, cs);
++            list.add(bsc);
++          }
 +        }
 +        cache.getCacheConfig().setCacheServerCreation(list);
 +        logger.info("CacheServer configuration saved");
 +      }
 +    }
 +  }
 +
 +  public boolean requestMemberRemoval(DistributedMember mbr, String reason) {
 +    if (mbr.equals(this.address)) {
 +      return false;
 +    }
 +    logger.warn(LocalizedMessage.create(
 +        LocalizedStrings.GroupMembershipService_MEMBERSHIP_REQUESTING_REMOVAL_OF_0_REASON_1,
 +        new Object[] {mbr, reason}));
 +    try {
 +      services.getJoinLeave().remove((InternalDistributedMember)mbr, reason);
 +    }
 +    catch (RuntimeException e) {
 +      Throwable problem = e;
 +      if (services.getShutdownCause() != null) {
 +        Throwable cause = services.getShutdownCause();
 +        // If ForcedDisconnectException occurred then report it as actual
 +        // problem.
 +        if (cause instanceof ForcedDisconnectException) {
 +          problem = (Exception) cause;
 +        } else {
 +          Throwable ne = problem;
 +          while (ne.getCause() != null) {
 +            ne = ne.getCause();
 +          }
 +          try {
 +            ne.initCause(services.getShutdownCause());
 +          }
 +          catch (IllegalArgumentException selfCausation) {
 +            // fix for bug 38895 - the cause is already in place
 +          }
 +        }
 +      }
 +      if (!services.getConfig().getDistributionConfig().getDisableAutoReconnect()) {
 +        saveCacheXmlForReconnect();
 +      }
 +      listener.membershipFailure("Channel closed", problem);
 +      throw new DistributedSystemDisconnectedException("Channel closed", problem);
 +    }
 +    return true;
 +  }
 +  
 +  public void suspectMembers(Set members, String reason) {
 +    for (Iterator it=members.iterator(); it.hasNext(); ) {
 +      verifyMember((DistributedMember)it.next(), reason);
 +    }
 +  }
 +  
 +  public void suspectMember(DistributedMember mbr, String reason) {
 +    if (!this.shutdownInProgress && !this.shutdownMembers.containsKey(mbr)) {
 +      verifyMember(mbr, reason);
 +    }
 +  }
 +
 +  /* like memberExists() this checks to see if the given ID is in the current
 +   * membership view.  If it is in the view though we try to contact it
 +   * to see if it's still around.  If we can't contact it then
 +   * suspect messages are sent to initiate final checks
 +   * @param mbr the member to verify
 +   * @param reason why the check is being done (must not be blank/null)
 +   * @return true if the member checks out
 +   */
 +  public boolean verifyMember(DistributedMember mbr, String reason) {
 +    if (mbr != null && memberExists((InternalDistributedMember)mbr)) {
 +      return this.services.getHealthMonitor().checkIfAvailable(mbr, reason, true);
 +    }
 +    return false;
 +  }
 +
 +  /**
 +   * Perform the grossness associated with sending a message over
 +   * a DirectChannel
 +   * 
 +   * @param destinations the list of destinations
 +   * @param content the message
 +   * @param theStats the statistics object to update
 +   * @return all recipients who did not receive the message (null if
 +   * all received it)
 +   * @throws NotSerializableException if the message is not serializable
 +   */
 +  protected Set<InternalDistributedMember> directChannelSend(InternalDistributedMember[] destinations,
 +      DistributionMessage content,
 +      DMStats theStats)
 +      throws NotSerializableException
 +  {
 +    boolean allDestinations;
 +    InternalDistributedMember[] keys;
 +    if (content.forAll()) {
 +      allDestinations = true;
 +      latestViewLock.writeLock().lock();
 +      try {
 +        List<InternalDistributedMember> keySet = latestView.getMembers();
 +        keys = new InternalDistributedMember[keySet.size()];
 +        keys = (InternalDistributedMember[])keySet.toArray(keys);
 +      } finally {
 +        latestViewLock.writeLock().unlock();
 +      }
 +    }
 +    else {
 +      allDestinations = false;
 +      keys = destinations;
 +    }
 +
 +    int sentBytes = 0;
 +    try {
 +      sentBytes = directChannel.send(this, keys, content,
 +          this.services.getConfig().getDistributionConfig().getAckWaitThreshold(),
 +          this.services.getConfig().getDistributionConfig().getAckSevereAlertThreshold());
 +                                     
 +      if (theStats != null) {
 +        theStats.incSentBytes(sentBytes);
 +      }
 +      
 +      if (sentBytes == 0) {
 +        if (services.getCancelCriterion().cancelInProgress() != null) {
 +          throw new DistributedSystemDisconnectedException();
 +        }
 +      }
 +    }
 +    catch (DistributedSystemDisconnectedException ex) {
 +      if (services.getShutdownCause() != null) {
 +        throw new DistributedSystemDisconnectedException("DistributedSystem is shutting down", services.getShutdownCause());
 +      } else {
 +        throw ex; // see bug 41416
 +      }
 +    }
 +    catch (ConnectExceptions ex) {
 +      if (allDestinations)
 +        return null;
 +      
 +      List members = ex.getMembers(); // We need to return this list of failures
 +      
 +      // SANITY CHECK:  If we fail to send a message to an existing member 
 +      // of the view, we have a serious error (bug36202).
 +      NetView view = services.getJoinLeave().getView(); // grab a recent view, excluding shunned members
 +      
 +      // Iterate through members and causes in tandem :-(
 +      Iterator it_mem = members.iterator();
 +      Iterator it_causes = ex.getCauses().iterator();
 +      while (it_mem.hasNext()) {
 +        InternalDistributedMember member = (InternalDistributedMember)it_mem.next();
 +        Throwable th = (Throwable)it_causes.next();
 +        
 +        if (!view.contains(member) || (th instanceof ShunnedMemberException)) {
 +          continue;
 +        }
 +        logger.fatal(LocalizedMessage.create(
 +            LocalizedStrings.GroupMembershipService_FAILED_TO_SEND_MESSAGE_0_TO_MEMBER_1_VIEW_2,
 +            new Object[] {content, member, view}), th);
 +//        Assert.assertTrue(false, "messaging contract failure");
 +      }
 +      return new HashSet<InternalDistributedMember>(members);
 +    } // catch ConnectionExceptions
 +    catch (ToDataException | CancelException e) {
 +      throw e;
 +    }
 +    catch (IOException e) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Membership: directChannelSend caught exception: {}", e.getMessage(), e);
 +      }
 +      if (e instanceof NotSerializableException) {
 +        throw (NotSerializableException)e;
 +      }
 +    }
 +    catch (RuntimeException e) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Membership: directChannelSend caught exception: {}", e.getMessage(), e);
 +      }
 +      throw e;
 +    }
 +    catch (Error e) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Membership: directChannelSend caught exception: {}", e.getMessage(), e);
 +      }
 +      throw e;
 +    }
 +    return null;
 +  }
 +
 +  /*
 +   * (non-Javadoc)
 +   * @see com.gemstone.gemfire.distributed.internal.membership.MembershipManager#isConnected()
 +   */
 +  public boolean isConnected() {
 +    return (this.hasJoined && !this.shutdownInProgress); 
 +  }
 +  
 +  /**
 +   * Returns true if the distributed system is in the process of auto-reconnecting.
 +   * Otherwise returns false.
 +   */
 +  public boolean isReconnectingDS() {
 +    if (this.hasJoined) {
 +      return false;
 +    } else {
 +      return this.wasReconnectingSystem;
 +    }
 +  }
 +  
 +  @Override
 +  public QuorumChecker getQuorumChecker() {
 +    if ( ! (services.isShutdownDueToForcedDisconnect()) ) {
 +      return null;
 +    }
 +    if (this.quorumChecker != null) {
 +      return this.quorumChecker;
 +    }
 +
 +    QuorumChecker impl = services.getMessenger().getQuorumChecker();
 +    this.quorumChecker = impl;
 +    return impl;
 +  }
 +  
 +  @Override
 +  public void releaseQuorumChecker(QuorumChecker checker) {
 +    ((GMSQuorumChecker)checker).suspend();
 +    InternalDistributedSystem system = InternalDistributedSystem.getAnyInstance();
 +    if (system == null || !system.isConnected()) {
 +      checker.close();
 +    }
 +  }
 +  
 +  public Set send(InternalDistributedMember dest, DistributionMessage msg)
 +    throws NotSerializableException {
 +    
 +    InternalDistributedMember dests[] = new InternalDistributedMember[] { dest };
 +    return send (dests, msg, null);
 +  }
 +  
 +  public Set send(InternalDistributedMember[] destinations,
 +      DistributionMessage msg,
 +      DMStats theStats)
 +      throws NotSerializableException
 +  {
 +    Set result = null;
 +    boolean allDestinations = msg.forAll();
 +    
 +    if (services.getCancelCriterion().cancelInProgress() != null) {
 +      throw new DistributedSystemDisconnectedException("Distributed System is shutting down",
 +          services.getCancelCriterion().generateCancelledException(null));
 +    }
 +    
 +    if (playingDead) { // wellness test hook
 +      while (playingDead && !shutdownInProgress) {
 +        try {
 +          Thread.sleep(1000);
 +        } catch (InterruptedException e) {
 +          Thread.currentThread().interrupt();
 +        }
 +      }
 +    }
 +    
 +    if (isJoining()) {
 +      // If we get here, we are starting up, so just report a failure.
 +      if (allDestinations)
 +        return null;
 +      else {
 +        result = new HashSet();
 +        for (int i = 0; i < destinations.length; i ++)
 +          result.add(destinations[i]);
 +        return result;
 +      }
 +    }
 +    
 +    if (msg instanceof AdminMessageType
 +        && this.shutdownInProgress) {
 +      // no admin messages while shutting down - this can cause threads to hang
 +      return new HashSet(Arrays.asList(msg.getRecipients()));
 +    }
 +
 +    // Handle trivial cases
 +    if (destinations == null) {
 +      if (logger.isTraceEnabled())
 +        logger.trace("Membership: Message send: returning early because null set passed in: '{}'", msg);
 +      return null; // trivially: all recipients received the message
 +    }
 +    if (destinations.length == 0) {
 +      if (logger.isTraceEnabled())
 +        logger.trace("Membership: Message send: returning early because empty destination list passed in: '{}'", msg);
 +      return null; // trivially: all recipients received the message
 +    }
 +
 +    msg.setSender(address);
 +    
 +    msg.setBreadcrumbsInSender();
 +    Breadcrumbs.setProblem(null);
 +
 +    boolean useMcast = false;
 +    if (mcastEnabled) {
 +      useMcast = (msg.getMulticast() || allDestinations);
 +    }
 +    
 +    boolean sendViaMessenger = isForceUDPCommunications(); // enable when bug #46438 is fixed: || msg.sendViaUDP();
 +
 +    if (useMcast || tcpDisabled || sendViaMessenger) {
 +      checkAddressesForUUIDs(destinations);
 +      result = services.getMessenger().send(msg);
 +    }
 +    else {
 +      result = directChannelSend(destinations, msg, theStats);
 +    }
 +
 +    // If the message was a broadcast, don't enumerate failures.
 +    if (allDestinations)
 +      return null;
 +    else {
 +      return result;
 +    }
 +  }
 +  
 +  // MembershipManager method
 +  @Override
 +  public void forceUDPMessagingForCurrentThread() {
 +    forceUseUDPMessaging.set(null);
 +  }
 +  
 +  void checkAddressesForUUIDs(InternalDistributedMember[] addresses) {
 +    for (int i=0; i<addresses.length; i++) {
 +      InternalDistributedMember m = addresses[i];
 +      if(m != null) {
 +        GMSMember id = (GMSMember)m.getNetMember();
 +        if (!id.hasUUID()) {
 +          latestViewLock.readLock().lock();
 +          try {
 +            addresses[i] = latestView.getCanonicalID(addresses[i]);
 +          } finally {
 +            latestViewLock.readLock().unlock();
 +          }
 +        }
 +      }
 +    }
 +  }
 +  
 +  private boolean isForceUDPCommunications() {
 +    Boolean forced = forceUseUDPMessaging.get();
 +    return forced == Boolean.TRUE;
 +  }
 +
 +  // MembershipManager method
 +  @Override
 +  public void releaseUDPMessagingForCurrentThread() {
 +    // not currently supported by this manager
 +  }
 +  
 +  public void setShutdown()
 +  {
 +    latestViewLock.writeLock().lock();
 +    shutdownInProgress = true;
 +    latestViewLock.writeLock().unlock();
 +  }
 +
 +  @Override
 +  public boolean shutdownInProgress() {
 +    // Impossible condition (bug36329): make sure that we check DM's
 +    // view of shutdown here
 +    DistributionManager dm = listener.getDM();
 +    return shutdownInProgress || (dm != null && dm.shutdownInProgress());
 +  }
 +  
 +
 +  /**
 +   * Clean up and create consistent new view with member removed.
 +   * No uplevel events are generated.
 +   * 
 +   * Must be called with the {@link #latestViewLock} held.
 +   */
 +  protected void destroyMember(final InternalDistributedMember member,
 +      boolean crashed, final String reason) {
 +    
 +    // Make sure it is removed from the view
 +    latestViewLock.writeLock().lock();
 +    try {
 +      if (latestView.contains(member)) {
 +        NetView newView = new NetView(latestView, latestView.getViewId());
 +        newView.remove(member);
 +        latestView = newView;
 +      }
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +    
 +    surpriseMembers.remove(member);
 +    
 +    // Trickiness: there is a minor recursion
 +    // with addShunnedMembers, since it will
 +    // attempt to destroy really really old members.  Performing the check
 +    // here breaks the recursion.
 +    if (!isShunned(member)) {
 +      addShunnedMember(member);
 +    }
 +
 +    final DirectChannel dc = directChannel;
 +    if (dc != null) {
 +//      if (crashed) {
 +//        dc.closeEndpoint(member, reason);
 +//      }
 +//      else
 +      // Bug 37944: make sure this is always done in a separate thread,
 +      // so that shutdown conditions don't wedge the view lock
 +      { // fix for bug 34010
 +        Thread t = new Thread() {
 +          @Override
 +          public void run() {
 +            try {
 +              Thread.sleep(
 +                  Integer.getInteger("p2p.disconnectDelay", 3000).intValue());
 +            }
 +            catch (InterruptedException ie) {
 +              Thread.currentThread().interrupt();
 +              // Keep going, try to close the endpoint.
 +            }
 +            if (!dc.isOpen()) {
 +              return;
 +            }
 +            if (logger.isDebugEnabled())
 +              logger.debug("Membership: closing connections for departed member {}", member);
 +            // close connections, but don't do membership notification since it's already been done
 +            dc.closeEndpoint(member, reason, false); 
 +          }
 +        };
 +        t.setDaemon(true);
 +        t.setName("disconnect thread for " + member);
 +        t.start();
 +      } // fix for bug 34010
 +    }
 +  }
 +  
 +  /**
 +   * Indicate whether the given member is in the zombie list (dead or dying)
 +   * @param m the member in question
 +   * 
 +   * This also checks the time the given member was shunned, and
 +   * has the side effect of removing the member from the
 +   * list if it was shunned too far in the past.
 +   * 
 +   * Concurrency: protected by {@link #latestViewLock} ReentrantReadWriteLock
 +   * 
 +   * @return true if the given member is a zombie
 +   */
 +  public boolean isShunned(DistributedMember m) {
 +    latestViewLock.writeLock().lock();
 +    try {
 +      if (!shunnedMembers.containsKey(m))
 +        return false;
 +      
 +      // Make sure that the entry isn't stale...
 +      long shunTime = ((Long)shunnedMembers.get(m)).longValue();
 +      long now = System.currentTimeMillis();
 +      if (shunTime + SHUNNED_SUNSET * 1000 > now)
 +        return true;
 +      
 +      // Oh, it _is_ stale.  Remove it while we're here.
 +      endShun(m);
 +      return false;
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +
 +  /**
 +   * Indicate whether the given member is in the surprise member list
 +   * <P>
 +   * Unlike isShunned, this method will not cause expiry of a surprise member.
 +   * That must be done during view processing.
 +   * <p>
 +   * Like isShunned, this method holds the view lock while executing
 +   * 
 +   * Concurrency: protected by {@link #latestViewLock} ReentrantReadWriteLock
 +   * 
 +   * @param m the member in question
 +   * @return true if the given member is a surprise member
 +   */
 +  public boolean isSurpriseMember(DistributedMember m) {
 +    latestViewLock.readLock().lock();
 +    try  {
 +      if (surpriseMembers.containsKey(m)) {
 +        long birthTime = ((Long)surpriseMembers.get(m)).longValue();
 +        long now = System.currentTimeMillis();
 +        return (birthTime >= (now - this.surpriseMemberTimeout));
 +      }
 +      return false;
 +    } finally {
 +      latestViewLock.readLock().unlock();
 +    }
 +  }
 +  
 +  /**
 +   * for testing we need to be able to inject surprise members into
 +   * the view to ensure that sunsetting works properly
 +   * @param m the member ID to add
 +   * @param birthTime the millisecond clock time that the member was first seen
 +   */
 +  public void addSurpriseMemberForTesting(DistributedMember m, long birthTime) {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("test hook is adding surprise member {} birthTime={}", m, birthTime);
 +    }
 +    latestViewLock.writeLock().lock();
 +    try {
 +      surpriseMembers.put((InternalDistributedMember)m, Long.valueOf(birthTime));
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +  }
 +  
 +  /**
 +   * returns the surpriseMemberTimeout interval, in milliseconds
 +   */
 +  public int getSurpriseMemberTimeout() {
 +    return this.surpriseMemberTimeout;
 +  }
 +  
 +  private boolean endShun(DistributedMember m) {
 +    boolean wasShunned = (shunnedMembers.remove(m) != null);
 +    shunnedAndWarnedMembers.remove(m);
 +    return wasShunned;
 +  }
 +  
 + /**
 +   * Add the given member to the shunned list.  Also, purge any shunned
 +   * members that are really really old.
 +   * <p>
 +   * Must be called with {@link #latestViewLock} held and
 +   * the view stable.
 +   * 
 +   * @param m the member to add
 +   */
 +  protected void addShunnedMember(InternalDistributedMember m) {
 +    long deathTime = System.currentTimeMillis() - SHUNNED_SUNSET * 1000;
 +    
 +    surpriseMembers.remove(m); // for safety
 +
 +    // Update the shunned set.
 +    if (!isShunned(m)) {
 +      shunnedMembers.put(m, Long.valueOf(System.currentTimeMillis()));
 +    }
 +
 +    // Remove really really old shunned members.
 +    // First, make a copy of the old set.  New arrivals _a priori_ don't matter,
 +    // and we're going to be updating the list so we don't want to disturb
 +    // the iterator.
 +    Set oldMembers = new HashSet(shunnedMembers.entrySet());
 +    
 +    Set removedMembers = new HashSet();
 +    
 +    Iterator it = oldMembers.iterator();
 +    while (it.hasNext()) {
 +      Map.Entry e = (Map.Entry)it.next();
 +      
 +      // Key is the member.  Value is the time to remove it.
 +      long ll = ((Long)e.getValue()).longValue(); 
 +      if (ll >= deathTime) {
 +        continue; // too new.
 +      }
 +      
 +      InternalDistributedMember mm = (InternalDistributedMember)e.getKey();
 +
 +      if (latestView.contains(mm)) {
 +        // Fault tolerance: a shunned member can conceivably linger but never 
 +        // disconnect.
 +        //
 +        // We may not delete it at the time that we shun it because the view 
 +        // isn't necessarily stable.  (Note that a well-behaved cache member
 +        // will depart on its own accord, but we force the issue here.)
 +        destroyMember(mm, true, "shunned but never disconnected");
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Membership: finally removed shunned member entry <{}>", mm);
 +      }
 +      
 +      removedMembers.add(mm);
 +    }
 +    
 +    // removed timed-out entries from the shunned-members collections
 +    if (removedMembers.size() > 0) {
 +      it = removedMembers.iterator();
 +      while (it.hasNext()) {
 +        InternalDistributedMember idm = (InternalDistributedMember)it.next();
 +        endShun(idm);
 +      }
 +    }
 +  }
 +  
 +  
 +  /**
 +   * Retrieve thread-local data for transport to another thread in hydra
 +   */
 +  public Object getThreadLocalData() {
 +    Map result = new HashMap();
 +    return result;
 +  }
 +  
 +  /**
 +   * for testing verification purposes, this return the port for the
 +   * direct channel, or zero if there is no direct
 +   * channel
 +   */
 +  public int getDirectChannelPort() {
 +    return directChannel == null? 0 : directChannel.getPort();
 +  }
 +  
 +  /**
 +   * for mock testing this allows insertion of a DirectChannel mock
 +   */
 +  protected void setDirectChannel(DirectChannel dc) {
 +    this.directChannel = dc;
 +    this.tcpDisabled = false;
 +  }
 +  
 +  /* non-thread-owned serial channels and high priority channels are not
 +   * included
 +   */
 +  public Map getMessageState(DistributedMember member, boolean includeMulticast) {
 +    Map result = new HashMap();
 +    DirectChannel dc = directChannel;
 +    if (dc != null) {
 +      dc.getChannelStates(member, result);
 +    }
 +    services.getMessenger().getMessageState((InternalDistributedMember)member, result, includeMulticast);
 +    return result;
 +  }
 +
 +  public void waitForMessageState(DistributedMember otherMember, Map state)
 +    throws InterruptedException
 +  {
 +    if (Thread.interrupted()) throw new InterruptedException();
 +    DirectChannel dc = directChannel;
 +    if (dc != null) {
 +      dc.waitForChannelState(otherMember, state);
 +    }
 +    services.getMessenger().waitForMessageState((InternalDistributedMember)otherMember, state);
 +  }
 +  
 +  /* 
 +   * (non-Javadoc)
 +   * MembershipManager method: wait for the given member to be gone.  Throws TimeoutException if
 +   * the wait goes too long
 +   * @see com.gemstone.gemfire.distributed.internal.membership.MembershipManager#waitForDeparture(com.gemstone.gemfire.distributed.DistributedMember)
 +   */
 +  public boolean waitForDeparture(DistributedMember mbr) throws TimeoutException, InterruptedException {
 +    if (Thread.interrupted()) throw new InterruptedException();
 +    boolean result = false;
 +    DirectChannel dc = directChannel;
 +    InternalDistributedMember idm = (InternalDistributedMember)mbr;
 +    int memberTimeout = this.services.getConfig().getDistributionConfig().getMemberTimeout();
 +    long pauseTime = (memberTimeout < 1000) ? 100 : memberTimeout / 10;
 +    boolean wait;
 +    int numWaits = 0;
 +    do {
 +      wait = false;
 +      if (dc != null) {
 +        if (dc.hasReceiversFor(idm)) {
 +          wait = true;
 +        }
 +        if (wait && logger.isDebugEnabled()) {
 +          logger.info("waiting for receivers for {} to shut down", mbr);
 +        }
 +      }
 +      if (!wait) {
 +        latestViewLock.readLock().lock();
 +        try {
 +          wait = this.latestView.contains(idm);
 +        } finally {
 +          latestViewLock.readLock().unlock();
 +        }
 +        if (wait && logger.isDebugEnabled()) {
 +          logger.debug("waiting for {} to leave the membership view", mbr);
 +        }
 +      }
 +      if (!wait) {
 +        // run a message through the member's serial execution queue to ensure that all of its
 +        // current messages have been processed
 +        OverflowQueueWithDMStats serialQueue = listener.getDM().getSerialQueue(idm);
 +        if (serialQueue != null) {
 +          final boolean done[] = new boolean[1];
 +          final FlushingMessage msg = new FlushingMessage(done);
 +          serialQueue.add(new SizeableRunnable(100) {
 +            public void run() {
 +              msg.invoke();
 +            }
 +            public String toString() {
 +              return "Processing fake message";
 +            }
 +          });
 +          synchronized(done) {
 +            while (done[0] == false) {
 +              done.wait(10);
 +            }
 +            result = true;
 +          }
 +        }
 +      }
 +      if (wait) {
 +        numWaits++;
 +        if (numWaits > 40) {
 +          // waited over 4 * memberTimeout ms.  Give up at this point
 +          throw new TimeoutException("waited too long for " + idm + " to be removed");
 +        }
 +        Thread.sleep(pauseTime);
 +      }
 +    } while (wait && (dc != null && dc.isOpen())
 +        && services.getCancelCriterion().cancelInProgress()==null );
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("operations for {} should all be in the cache at this point", mbr);
 +    }
 +    return result;
 +  }
 +  
 +
 +  // TODO remove this overly complex method and replace its use with
 +  // waitForViewChange using the remote member's view ID
 +  public boolean waitForMembershipCheck(InternalDistributedMember remoteId) {
 +    boolean foundRemoteId = false;
 +    CountDownLatch currentLatch = null;
 +    // ARB: preconditions
 +    // remoteId != null
 +    latestViewLock.writeLock().lock();
 +    try {
 +      if (latestView == null) {
 +        // Not sure how this would happen, but see bug 38460.
 +        // No view?? Not found!
 +      }
 +      else if (latestView.contains(remoteId)) {
 +        // ARB: check if remoteId is already in membership view.
 +        // If not, then create a latch if needed and wait for the latch to open.
 +        foundRemoteId = true;
 +      }
 +      else if ((currentLatch = (CountDownLatch)this.memberLatch.get(remoteId)) == null) {
 +        currentLatch = new CountDownLatch(1);
 +        this.memberLatch.put(remoteId, currentLatch);
 +      }
 +    } finally {
 +      latestViewLock.writeLock().unlock();
 +    }
 +
 +    if (!foundRemoteId) {
 +      try {
 +        if (currentLatch.await(membershipCheckTimeout, TimeUnit.MILLISECONDS)) {
 +          foundRemoteId = true;
 +          // @todo 
 +          // ARB: remove latch from memberLatch map if this is the last thread waiting on latch.
 +        }
 +      }
 +      catch (InterruptedException ex) {
 +        // ARB: latch attempt was interrupted.
 +        Thread.currentThread().interrupt();
 +        logger.warn(LocalizedMessage.create(
 +            LocalizedStrings.GroupMembershipService_THE_MEMBERSHIP_CHECK_WAS_TERMINATED_WITH_AN_EXCEPTION));
 +      }
 +    }
 +
 +    // ARB: postconditions
 +    // (foundRemoteId == true) ==> (currentLatch is non-null ==> currentLatch is open)
 +    return foundRemoteId;
 +  }
 +  
 +  /* returns the cause of shutdown, if known */
 +  public Throwable getShutdownCause() {
 +    return services.getShutdownCause();
 +  }
 +
 +//  @Override
 +//  public void membershipFailure(String reason, Exception e) {
 +//

<TRUNCATED>

[018/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsDUnitTest.java
index 4e4b10f,0000000..c93848b
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsDUnitTest.java
@@@ -1,2333 -1,0 +1,2333 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.management;
 +
 +import java.io.Serializable;
 +import java.util.ArrayList;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.concurrent.CountDownLatch;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.atomic.AtomicInteger;
 +
 +import util.TestException;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.AttributesMutator;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.LowMemoryException;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.Pool;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.cache.control.ResourceManager;
 +import com.gemstone.gemfire.cache.execute.Execution;
 +import com.gemstone.gemfire.cache.execute.FunctionAdapter;
 +import com.gemstone.gemfire.cache.execute.FunctionContext;
 +import com.gemstone.gemfire.cache.execute.FunctionException;
 +import com.gemstone.gemfire.cache.execute.FunctionService;
 +import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.ClientServerTestCase;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.GemFireStatSampler;
 +import com.gemstone.gemfire.internal.LocalStatListener;
 +import com.gemstone.gemfire.internal.StatisticsImpl;
 +import com.gemstone.gemfire.internal.cache.DistributedRegion;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
 +import com.gemstone.gemfire.internal.cache.control.HeapMemoryMonitor;
 +import com.gemstone.gemfire.internal.cache.control.InternalResourceManager;
 +import com.gemstone.gemfire.internal.cache.control.InternalResourceManager.ResourceType;
 +import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
 +import com.gemstone.gemfire.internal.cache.control.MemoryThresholds.MemoryState;
 +import com.gemstone.gemfire.internal.cache.control.ResourceAdvisor;
 +import com.gemstone.gemfire.internal.cache.control.ResourceListener;
 +import com.gemstone.gemfire.internal.cache.control.TestMemoryThresholdListener;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * Tests the Heap Memory thresholds of {@link ResourceManager}
 + * @author sbawaska
 + * @author Mitch Thomas
 + * @since 6.0
 + */
 +public class MemoryThresholdsDUnitTest extends ClientServerTestCase {
 +  
 +  public static class Range implements Serializable {
 +    public final static Range DEFAULT = new Range(0, 20);
 +    public final int start;
 +    public final int end;
 +    public Range(int s, int e) {this.start = s; this.end = e;}
 +    public Range(Range r, int shift) {this.start = r.start+shift; this.end=r.end+shift;}
 +    public int width() {return end-start;}
 +  }
 +
 +  final String expectedEx = LocalizedStrings.MemoryMonitor_MEMBER_ABOVE_CRITICAL_THRESHOLD
 +                            .getRawText().replaceAll("\\{[0-9]+\\}", ".*?");
 +  final String addExpectedExString =
 +    "<ExpectedException action=add>" + expectedEx + "</ExpectedException>";
 +  final String removeExpectedExString =
 +    "<ExpectedException action=remove>" + expectedEx + "</ExpectedException>";
 +  final String expectedBelow = LocalizedStrings.MemoryMonitor_MEMBER_BELOW_CRITICAL_THRESHOLD
 +                              .getRawText().replaceAll("\\{[0-9]+\\}", ".*?");
 +  final String addExpectedBelow =
 +  "<ExpectedException action=add>" + expectedBelow + "</ExpectedException>";
 +  final String removeExpectedBelow =
 +"<ExpectedException action=remove>" + expectedBelow + "</ExpectedException>";
 +
 +  final String expectedFunctionEx = " cannot be executed";
 +  final String addExpectedFunctionExString =
 +    "<ExpectedException action=add>" + expectedFunctionEx + "</ExpectedException>";
 +  final String removeExpectedFunctionExString =
 +    "<ExpectedException action=remove>" + expectedFunctionEx + "</ExpectedException>";
 +  
 +  public MemoryThresholdsDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    Invoke.invokeInEveryVM(this.setHeapMemoryMonitorTestMode);
 +    IgnoredException.addIgnoredException(expectedEx);
 +    IgnoredException.addIgnoredException(expectedBelow);
 +  }
 +
 +  @Override
 +  protected void preTearDownClientServerTestCase() throws Exception {
 +    Invoke.invokeInEveryVM(resetResourceManager);
 +  }
 +
 +  public void testPRClientPutRejection() throws Exception {
 +    doClientServerTest("parRegReject", true/*createPR*/);
 +  }
 +
 +  public void testDistributedRegionClientPutRejection() throws Exception {
 +    doClientServerTest("distrReject", false/*createPR*/);
 +  }
 +
 +  private void doClientServerTest(final String regionName, boolean createPR)
 +      throws Exception {
 +    //create region on the server
 +    final Host host = Host.getHost(0);
 +    final VM server = host.getVM(0);
 +    final VM client = host.getVM(1);
 +
 +    ServerPorts ports = startCacheServer(server, 0f, 90f, regionName, createPR, false, 0);
 +    startClient(client, server, ports.getPort(), regionName);
 +    doPuts(client, regionName, false/*catchServerException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, false/*catchServerException*/,
 +        false/*catchLowMemoryException*/, Range.DEFAULT);
 +
 +    //make the region sick in the server
 +    server.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        InternalResourceManager irm = (InternalResourceManager)getCache().
 +                                    getResourceManager();
 +        irm.setCriticalHeapPercentage(90f);
 +        
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        irm.getHeapMonitor().updateStateAndSendEvent(950);
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        return null;
 +      }
 +    });
 +
 +    //make sure client puts are rejected
 +    doPuts(client, regionName, true/*catchServerException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, true/*catchServerException*/,
 +        false/*catchLowMemoryException*/, new Range(Range.DEFAULT, Range.DEFAULT.width()+1));
 +  }
 +
 +  public void testDistributedRegionRemotePutRejectionLocalDestroy() throws Exception {
 +    doDistributedRegionRemotePutRejection(true, false);
 +  }
 +  public void testDistributedRegionRemotePutRejectionCacheClose() throws Exception {
 +    doDistributedRegionRemotePutRejection(false, true);
 +  }
 +  public void testDistributedRegionRemotePutRejectionBelowThreshold() throws Exception {
 +    doDistributedRegionRemotePutRejection(false, false);
 +  }
 +  /**
 +   * test that puts in a server are rejected when a remote VM crosses
 +   * critical threshold
 +   * @throws Exception
 +   */
 +  private void doDistributedRegionRemotePutRejection(boolean localDestroy, boolean cacheClose) throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +
 +    final String regionName = "rejectRemoteOp";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 0f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +
 +    doPuts(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, Range.DEFAULT);
 +
 +    //make server2 critical
 +    setUsageAboveCriticalThreshold(server2);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, false);
 +
 +    //make sure that local server1 puts are rejected
 +    doPuts(server1, regionName, false/*catchRejectedException*/,
 +        true/*catchLowMemoryException*/);
 +    Range r1 = new Range(Range.DEFAULT, Range.DEFAULT.width()+1);
 +    doPutAlls(server1, regionName, false/*catchRejectedException*/,
 +        true/*catchLowMemoryException*/, r1);
 +
 +    if (localDestroy) {
 +    //local destroy the region on sick member
 +    server2.invoke(new SerializableCallable("local destroy") {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion().getSubregion(regionName);
 +        r.localDestroyRegion();
 +        return null;
 +      }
 +    });
 +    } else if (cacheClose) {
 +      server2.invoke(new SerializableCallable() {
 +        public Object call() throws Exception {
 +          getCache().close();
 +          return null;
 +        }
 +      });
 +    } else {
 +      setUsageBelowEviction(server2);
 +    }
 +    
 +    //wait for remote region destroyed message to be processed
 +    server1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "remote localRegionDestroyed message not received";
 +          }
 +          public boolean done() {
 +            DistributedRegion dr = (DistributedRegion)getRootRegion().
 +                                                getSubregion(regionName);
 +            return dr.getMemoryThresholdReachedMembers().size() == 0;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30000, 10, true);
 +        return null;
 +      }
 +    });
 +
 +    //make sure puts succeed
 +    doPuts(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    Range r2 = new Range(r1, r1.width()+1);
 +    doPutAlls(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, r2);
 +  }
 +
 +  public void testBug45513() {
 +    ResourceManager rm = getCache().getResourceManager();
 +    assertEquals(0.0f, rm.getCriticalHeapPercentage());
 +    assertEquals(0.0f, rm.getEvictionHeapPercentage());
 +    
 +    rm.setEvictionHeapPercentage(50);
 +    rm.setCriticalHeapPercentage(90);
 +    
 +    // verify
 +    assertEquals(50.0f, rm.getEvictionHeapPercentage());
 +    assertEquals(90.0f, rm.getCriticalHeapPercentage());
 +    
 +    getCache().createRegionFactory(RegionShortcut.REPLICATE_HEAP_LRU).create(getName());
 +    
 +    assertEquals(50.0f, rm.getEvictionHeapPercentage());
 +    assertEquals(90.0f, rm.getCriticalHeapPercentage());
 +  }
 +
 +  /**
 +   * test that puts in a client are rejected when a remote VM crosses
 +   * critical threshold
 +   * @throws Exception
 +   */
 +  public void testDistributedRegionRemoteClientPutRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    final VM client = host.getVM(2);
 +
 +    final String regionName = "rejectRemoteClientOp";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 0f, 0f, regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 0f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    startClient(client, server1, ports1.getPort(), regionName);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +
 +    doPuts(client, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, Range.DEFAULT);
 +
 +    //make server2 critical
 +    setUsageAboveCriticalThreshold(server2);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, false);
 +
 +    //make sure that client puts are rejected
 +    doPuts(client, regionName, true/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, true/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, new Range(Range.DEFAULT, Range.DEFAULT.width()+1));
 +  }
 +
 +
 +  /**
 +   * test that disabling threshold does not cause remote event and
 +   * remote DISABLED events are delivered
 +   * @throws Exception
 +   */
 +  public void testDisabledThresholds() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +
 +    final String regionName = "disableThresholdPr";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 0f, 0f, regionName, true/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 0f, 0f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +
 +    setUsageAboveEvictionThreshold(server1);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 0, false);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 0, true);
 +
 +    setThresholds(server1, 80f, 0f);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 1, false);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 1, true);
 +
 +    setUsageAboveCriticalThreshold(server1);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 0, false);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 0, true);
 +
 +    setThresholds(server1, 0f, 0f);
 +    verifyListenerValue(server1, MemoryState.EVICTION_DISABLED, 1, false);
 +    verifyListenerValue(server2, MemoryState.EVICTION_DISABLED, 1, true);
 +
 +    setThresholds(server1, 0f, 90f);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, false);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +
 +    //verify that stats on server2 are not changed by events on server1
 +    server2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        assertEquals(0, irm.getStats().getEvictionStartEvents());
 +        assertEquals(0, irm.getStats().getHeapCriticalEvents());
 +        assertEquals(0, irm.getStats().getCriticalThreshold());
 +        assertEquals(0, irm.getStats().getEvictionThreshold());
 +        return null;
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Make sure appropriate events are delivered when moving
 +   * between states.
 +   * 
 +   * @throws Exception
 +   */
 +  public void testEventDelivery() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +
 +    final String regionName = "testEventDelivery";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 0f, 0f, regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 80f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    registerLoggingTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +
 +    //NORMAL -> CRITICAL
 +    server2.invoke(new SerializableCallable("NORMAL->CRITICAL") {
 +      public Object call() throws Exception {
 +        GemFireCacheImpl gfCache = (GemFireCacheImpl)getCache();
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(950);
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        return null;
 +      }
 +    });
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 1, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 0, true);
 +
 +    //make sure we get two events on remote server
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 1, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 0, true);;
 +
 +    //CRITICAL -> EVICTION
 +    server2.invoke(new SerializableCallable("CRITICAL->EVICTION") {
 +      public Object call() throws Exception {
 +        GemFireCacheImpl gfCache = (GemFireCacheImpl)getCache();
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(850);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        return null;
 +      }
 +    });
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 0, true);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 0, true);;
 +    
 +    //EVICTION -> EVICTION
 +    server2.invoke(new SerializableCallable("EVICTION->EVICTION") {
 +      public Object call() throws Exception {
 +        GemFireCacheImpl gfCache = (GemFireCacheImpl)getCache();
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(840);
 +        return null;
 +      }
 +    });
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 0, true);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 0, true);
 +
 +    //EVICTION -> NORMAL
 +    server2.invoke(new SerializableCallable("EVICTION->NORMAL") {
 +      public Object call() throws Exception {
 +        GemFireCacheImpl gfCache = (GemFireCacheImpl)getCache();
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(750);
 +        return null;
 +      }
 +    });
 +
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 1, true);
 +    
 +    LogWriterUtils.getLogWriter().info("before NORMAL->CRITICAL->NORMAL");
 +    //NORMAL -> EVICTION -> NORMAL
 +    server2.invoke(new SerializableCallable("NORMAL->CRITICAL->NORMAL") {
 +      public Object call() throws Exception {
 +        GemFireCacheImpl gfCache = (GemFireCacheImpl)getCache();
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(950);
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(750);
 +        return null;
 +      }
 +    });
 +    LogWriterUtils.getLogWriter().info("after NORMAL->CRITICAL->NORMAL");
 +
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 2, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 3, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 2, true);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 2, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 3, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 2, true);
 +    
 +    //NORMAL -> EVICTION
 +    server2.invoke(new SerializableCallable("NORMAL->EVICTION") {
 +      public Object call() throws Exception {
 +        GemFireCacheImpl gfCache = (GemFireCacheImpl)getCache();
 +        gfCache.getResourceManager().getHeapMonitor().updateStateAndSendEvent(850);
 +        return null;
 +      }
 +    });
 +
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 2, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 4, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 2, true);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 2, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 4, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 2, true);
 +  }
 +
 +  public void testCleanAdvisorClose() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    final VM server3 = host.getVM(2);
 +
 +    final String regionName = "testEventOrger";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 0f, 0f, regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    verifyProfiles(server1, 2);
 +    verifyProfiles(server2, 2);
 +
 +    server2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        closeCache();
 +        return null;
 +      }
 +    });
 +
 +    verifyProfiles(server1, 1);
 +
 +    startCacheServer(server3, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    verifyProfiles(server1, 2);
 +    verifyProfiles(server3, 2);
 +  }
 +
 +  public void testPR_RemotePutRejectionLocalDestroy() throws Exception {
 +    prRemotePutRejection(false, true, false);
 +  }
 +
 +  public void testPR_RemotePutRejectionCacheClose() throws Exception {
 +    prRemotePutRejection(true, false, false);
 +  }
 +
 +  public void testPR_RemotePutRejection() throws Exception {
 +    prRemotePutRejection(false, false, false);
 +  }
 +
 +  public void testPR_RemotePutRejectionLocalDestroyWithTx() throws Exception {
 +    prRemotePutRejection(false, true, true);
 +  }
 +
 +  public void testPR_RemotePutRejectionCacheCloseWithTx() throws Exception {
 +    prRemotePutRejection(true, false, true);
 +  }
 +
 +  public void testPR_RemotePutRejectionWithTx() throws Exception {
 +    prRemotePutRejection(false, false, true);
 +  }
 +
 +  private void prRemotePutRejection(boolean cacheClose, boolean localDestroy, final boolean useTx) throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM accessor = host.getVM(0);
 +    final VM server1 = host.getVM(1);
 +    final VM server2 = host.getVM(2);
 +    final VM server3 = host.getVM(3);
 +
 +    final String regionName = "testPrRejection";
 +    final int redundancy = 1;
 +
 +    final ServerPorts ports1 = startCacheServer(server1, 80f, 90f, regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    ServerPorts ports2 = startCacheServer(server2, 80f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    ServerPorts ports3 = startCacheServer(server3, 80f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getServerProperties());
 +        getCache();
 +        AttributesFactory factory = new AttributesFactory();        
 +        PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +        paf.setRedundantCopies(redundancy);
 +        paf.setLocalMaxMemory(0);
 +        paf.setTotalNumBuckets(11);
 +        factory.setPartitionAttributes(paf.create());
 +        createRegion(regionName, factory.create());
 +        return null;
 +      }
 +    });
 +    
 +    doPuts(accessor, regionName, false, false);
 +    final Range r1 = Range.DEFAULT;
 +    doPutAlls(accessor, regionName, false, false, r1);
 +    
 +    SerializableCallable getMyId = new SerializableCallable() {
 +      public Object call() throws Exception {        
 +        return ((GemFireCacheImpl)getCache()).getMyId();
 +      }
 +    };
 +    
 +    final DistributedMember server1Id = 
 +      (DistributedMember)server1.invoke(getMyId); 
 +    
 +    setUsageAboveCriticalThreshold(server1);
 +     
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        final PartitionedRegion pr = (PartitionedRegion)getRootRegion().
 +                                getSubregion(regionName);
 +        final String regionPath = getRootRegion().getSubregion(regionName).getFullPath();
 +        //server1 is sick, look for a key on server1, and attempt put again
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "remote bucket not marked sick";
 +          }
 +          public boolean done() {
 +            boolean keyFoundOnSickMember = false;
 +            boolean caughtException = false;
 +            for (int i=0; i<20; i++) {
 +              Integer key = Integer.valueOf(i);
 +              int hKey = PartitionedRegionHelper.getHashKey(pr, null, key, null, null);
 +              Set<InternalDistributedMember> owners = pr.getRegionAdvisor().getBucketOwners(hKey);
 +              if (owners.contains(server1Id)) {
 +                keyFoundOnSickMember = true;
 +                try {
 +                  if (useTx) getCache().getCacheTransactionManager().begin();
 +                  pr.getCache().getLogger().fine("SWAP:putting in tx:"+useTx);
 +                  pr.put(key, "value");
 +                  if (useTx) getCache().getCacheTransactionManager().commit();
 +                } catch (LowMemoryException ex) {
 +                  caughtException = true;
 +                  if (useTx) getCache().getCacheTransactionManager().rollback();
 +                }
 +              } else {
 +                //puts on healthy member should continue
 +                pr.put(key, "value");
 +              }
 +            }
 +            return keyFoundOnSickMember && caughtException;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30000, 10, true);
 +        return null;
 +      }
 +    });
 +
 +    {
 +      Range r2 = new Range(r1, r1.width()+1);
 +      doPutAlls(accessor, regionName, false, true, r2);
 +    }
 +
 +    if (localDestroy) {
 +    //local destroy the region on sick member
 +      server1.invoke(new SerializableCallable("local destroy sick member") {
 +        public Object call() throws Exception {
 +          Region r = getRootRegion().getSubregion(regionName);
 +          LogWriterUtils.getLogWriter().info("PRLocalDestroy");
 +          r.localDestroyRegion();
 +          return null;
 +        }
 +      });
 +    } else if (cacheClose) {
 +      //close cache on sick member
 +      server1.invoke(new SerializableCallable("close cache sick member") {
 +        public Object call() throws Exception {
 +          getCache().close();
 +          return null;
 +        }
 +      });
 +    } else {
 +      setUsageBelowEviction(server1);
 +    }
 +    
 +    //do put all in a loop to allow distribution of message
 +    accessor.invoke(new SerializableCallable("Put in a loop") {
 +      public Object call() throws Exception {
 +        final Region r = getRootRegion().getSubregion(regionName);
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {            
 +            return "pr should have gone un-critical";
 +          }
 +          public boolean done() {
 +            boolean done = true;
 +            for (int i=0; i<20; i++) {
 +              try {
 +                r.put(i,"value");
 +              } catch (LowMemoryException e) {
 +                //expected
 +                done = false;
 +              }
 +            }            
 +            return done;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30000, 10, true);
 +        return null;
 +      }
 +    });
 +    doPutAlls(accessor, regionName, false, false, r1);
 +  }
 +
 +  // this test is DISABLED due to test issues.  It sometimes
 +  // fails with a TransactionDataNotColocatedException.  See bug #52222
 +  public void disabledtestTxCommitInCritical() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM accessor = host.getVM(0);
 +    final VM server1 = host.getVM(1);
 +    final VM server2 = host.getVM(2);
 +    final VM server3 = host.getVM(3);
 +
 +    final String regionName = "testPrRejection";
 +    final int redundancy = 1;
 +
 +    final ServerPorts ports1 = startCacheServer(server1, 80f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    ServerPorts ports2 = startCacheServer(server2, 80f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    ServerPorts ports3 = startCacheServer(server3, 80f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +    registerTestMemoryThresholdListener(server3);
 +    
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getServerProperties());
 +        getCache();
 +        AttributesFactory factory = new AttributesFactory();        
 +        PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +        paf.setRedundantCopies(redundancy);
 +        paf.setLocalMaxMemory(0);
 +        paf.setTotalNumBuckets(11);
 +        factory.setPartitionAttributes(paf.create());
 +        createRegion(regionName, factory.create());
 +        return null;
 +      }
 +    });
 +    
 +    doPuts(accessor, regionName, false, false);
 +    final Range r1 = Range.DEFAULT;
 +    doPutAlls(accessor, regionName, false, false, r1);
 +    
 +    SerializableCallable getMyId = new SerializableCallable() {
 +      public Object call() throws Exception {        
 +        return ((GemFireCacheImpl)getCache()).getMyId();
 +      }
 +    };
 +    
 +    final DistributedMember server1Id = 
 +      (DistributedMember)server1.invoke(getMyId); 
 +    
 +    final Integer lastKey = (Integer)accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        final PartitionedRegion pr = (PartitionedRegion)getRootRegion().getSubregion(regionName);
 +        getCache().getCacheTransactionManager().begin();
 +        for (int i=0; i< 20; i++) {
 +          Integer key = Integer.valueOf(i);
 +          int hKey = PartitionedRegionHelper.getHashKey(pr, key);
 +          Set<InternalDistributedMember> owners = pr.getRegionAdvisor().getBucketOwners(hKey);
 +          if (owners.contains(server1Id)) {
 +            pr.put(key, "txTest");
 +            return i;
 +          }
 +        }
 +        return null;
 +      }
 +    });
 +    assertNotNull(lastKey);
 +    
 +    setUsageAboveCriticalThreshold(server1);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        final PartitionedRegion pr = (PartitionedRegion)getRootRegion().getSubregion(regionName);
 +        assertTrue(getCache().getCacheTransactionManager().exists());
 +        boolean exceptionThrown = false;
 +        for (int i= lastKey; i< 20; i++) {
 +          Integer key = Integer.valueOf(i);
 +          int hKey = PartitionedRegionHelper.getHashKey(pr, key);
 +          Set<InternalDistributedMember> owners = pr.getRegionAdvisor().getBucketOwners(hKey);
 +          if (owners.contains(server1Id)) {
 +            try {
 +              pr.put(key, "txTest");
 +            } catch (LowMemoryException e) {
 +              exceptionThrown = true;
 +              break;
 +            }
 +          }
 +        }
 +        if (!exceptionThrown) {
 +          fail("expected exception not thrown");
 +        }
 +        getCache().getCacheTransactionManager().commit();
 +        int seenCount = 0;
 +        for (int i=0; i<20; i++) {
 +          if ("txTest".equals(pr.get(i))) {
 +            seenCount++;
 +          }
 +        }
 +        assertEquals(1, seenCount);
 +        return null;
 +      }
 +    });
 +  }
 +
 +  public void testDRFunctionExecutionRejection() throws Exception {
 +    IgnoredException.addIgnoredException("LowMemoryException");
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    final VM client = host.getVM(2);
 +    final String regionName = "drFuncRej";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 80f, 90f, regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 80f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    startClient(client, server1, ports1.getPort(), regionName);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +    
 +    final RejectFunction function = new RejectFunction();
 +    final RejectFunction function2 = new RejectFunction("noRejFunc", false);
 +    Invoke.invokeInEveryVM(new SerializableCallable("register function") {
 +      public Object call() throws Exception {
 +        FunctionService.registerFunction(function);
 +        FunctionService.registerFunction(function2);
 +        return null;
 +      }
 +    });
 +
 +    doPutAlls(server1, regionName, false, false, Range.DEFAULT);
 +    doPuts(server1, regionName, false, false);
 +
 +    server1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function);
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +        .execute(function2);
 +        return null;
 +      }
 +    });
 +    //should not fail
 +    server1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onMembers(getSystem()).execute(function);
 +        FunctionService.onMembers(getSystem()).execute(function2);
 +        return null;
 +      }
 +    });    
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function).getResult(30, TimeUnit.SECONDS);
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function2).getResult(30, TimeUnit.SECONDS);
 +        return null;
 +      }
 +    });
 +    
 +    setUsageAboveCriticalThreshold(server2);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +
 +    server1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          getCache().getLoggerI18n().fine(addExpectedFunctionExString);
 +          FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +            .execute(function);
 +          getCache().getLoggerI18n().fine(removeExpectedFunctionExString);
 +          fail("expected low memory exception was not thrown");
 +        } catch (LowMemoryException e) {
 +          //expected
 +        }
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +        .execute(function2);
 +        return null;
 +      }
 +    });
 +
 +    server1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          getCache().getLoggerI18n().fine(addExpectedFunctionExString);
 +          FunctionService.onMembers(getSystem()).execute(function);
 +          getCache().getLoggerI18n().fine(removeExpectedFunctionExString);
 +          fail("expected low memory exception was not thrown");
 +        } catch (LowMemoryException e) {
 +          //expected
 +        }
 +        FunctionService.onMembers(getSystem()).execute(function2);
 +        return null;
 +      }
 +    });
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          getCache().getLoggerI18n().fine(addExpectedFunctionExString);
 +          FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +            .execute(function);
 +          getCache().getLoggerI18n().fine(removeExpectedFunctionExString);
 +          fail("expected low memory exception was not thrown");
 +        } catch (FunctionException e) {
 +          if (!(e.getCause().getCause() instanceof LowMemoryException)) {
 +            Assert.fail("unexpected exception ", e);
 +          }
 +          //expected
 +        }
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function2);
 +        return null;
 +      }
 +    });
 +  }
 +
 +  // this test is DISABLED due to intermittent failures.  See bug #52222
 +  public void disabledtestPRFunctionExecutionRejection() throws Exception {
 +    IgnoredException.addIgnoredException("LowMemoryException");
 +    final Host host = Host.getHost(0);
 +    final VM accessor = host.getVM(0);
 +    final VM server1 = host.getVM(1);
 +    final VM server2 = host.getVM(2);
 +    final VM client = host.getVM(3);
 +    final String regionName = "prFuncRej";
 +
 +    final ServerPorts ports1 = startCacheServer(server1, 80f, 90f, regionName, true/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 80f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, 0);
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getServerProperties());
 +        getCache();
 +        AttributesFactory factory = new AttributesFactory();
 +        PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +        paf.setRedundantCopies(0);
 +        paf.setLocalMaxMemory(0);
 +        paf.setTotalNumBuckets(11);
 +        factory.setPartitionAttributes(paf.create());
 +        createRegion(regionName, factory.create());
 +        return null;
 +      }
 +    });
 +    
 +    startClient(client, server1, ports1.getPort(), regionName);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +    
 +    final RejectFunction function = new RejectFunction();
 +    final RejectFunction function2 = new RejectFunction("noRejFunc", false);
 +    Invoke.invokeInEveryVM(new SerializableCallable("register function") {
 +      public Object call() throws Exception {
 +        FunctionService.registerFunction(function);
 +        FunctionService.registerFunction(function2);
 +        return null;
 +      }
 +    });
 +
 +    doPutAlls(accessor, regionName, false, false, Range.DEFAULT);
 +    doPuts(accessor, regionName, false, false);
 +
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function);
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +        .execute(function2);
 +        return null;
 +      }
 +    });
 +    //should not fail
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onMembers(getSystem()).execute(function);
 +        FunctionService.onMembers(getSystem()).execute(function2);
 +        return null;
 +      }
 +    });    
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function);
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function2);
 +        return null;
 +      }
 +    });
 +    
 +    setUsageAboveCriticalThreshold(server2);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          getCache().getLoggerI18n().fine(addExpectedFunctionExString);
 +          FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +            .execute(function);
 +          getCache().getLoggerI18n().fine(removeExpectedFunctionExString);
 +          fail("expected low memory exception was not thrown");
 +        } catch (LowMemoryException e) {
 +          //expected
 +        }
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +        .execute(function2);
 +        return null;
 +      }
 +    });
 +
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          getCache().getLoggerI18n().fine(addExpectedFunctionExString);
 +          FunctionService.onMembers(getSystem()).execute(function);
 +          getCache().getLoggerI18n().fine(removeExpectedFunctionExString);
 +          fail("expected low memory exception was not thrown");
 +        } catch (LowMemoryException e) {
 +          //expected
 +        }
 +        FunctionService.onMembers(getSystem()).execute(function2);
 +        return null;
 +      }
 +    });
 +
 +    server1.invoke(addExpectedFunctionException);
 +    server2.invoke(addExpectedFunctionException);
 +
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +            .execute(function);
 +          fail("expected low memory exception was not thrown");
 +        } catch (FunctionException e) {
 +          if (!(e.getCause().getCause() instanceof LowMemoryException)) {
 +            Assert.fail("unexpected exception", e);
 +          }
 +          //expected
 +        }
 +        FunctionService.onRegion(getRootRegion().getSubregion(regionName))
 +          .execute(function2);
 +        return null;
 +      }
 +    });
 +
 +    server1.invoke(removeExpectedFunctionException);
 +    server2.invoke(removeExpectedFunctionException);
 +
 +    final DistributedMember server2Id = (DistributedMember)server2.invoke(
 +        new SerializableCallable() {
 +          public Object call() throws Exception {
 +            return ((GemFireCacheImpl)getCache()).getMyId();
 +          }
 +        });
 +
 +    //test function execution on healthy & sick members
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        PartitionedRegion pr = (PartitionedRegion)getRootRegion().
 +                          getSubregion(regionName);
 +        Object sickKey1 = null;
 +        Object sickKey2 = null;
 +        Object healthyKey = null;
 +        for (int i=0; i < 20; i++) {
 +          Object key = i;
 +          DistributedMember m = pr.getMemberOwning(key);
 +          if (m.equals(server2Id)) {
 +            if (sickKey1 == null) {
 +              sickKey1 = key;
 +              //execute
 +              Set s = new HashSet();
 +              s.add(sickKey1);
 +              Execution e = FunctionService.onRegion(pr);
 +              try {
 +                getCache().getLoggerI18n().fine(addExpectedFunctionExString);
 +                e.withFilter(s).withArgs((Serializable)s).execute(function);
 +                getCache().getLoggerI18n().fine(removeExpectedFunctionExString);
 +                fail("expected LowMemoryExcception was not thrown");
 +              } catch (LowMemoryException ex) {
 +                //expected
 +              }
 +            } else if (sickKey2 == null) {
 +              sickKey2 = key;
 +              //execute
 +              Set s = new HashSet();
 +              s.add(sickKey1);
 +              s.add(sickKey2);
 +              Execution e = FunctionService.onRegion(pr);
 +              try {
 +                e.withFilter(s).withArgs((Serializable)s).execute(function);
 +                fail("expected LowMemoryExcception was not thrown");
 +              } catch (LowMemoryException ex) {
 +                //expected
 +              }
 +            }
 +          } else {
 +            healthyKey = key;
 +            //execute
 +            Set s = new HashSet();
 +            s.add(healthyKey);
 +            Execution e = FunctionService.onRegion(pr);
 +            e.withFilter(s).withArgs((Serializable)s).execute(function);
 +          }
 +          if (sickKey1 != null && sickKey2 != null && healthyKey != null) {
 +            break;
 +          }
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  public void testFunctionExecutionRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    final VM client = host.getVM(2);
 +    final String regionName = "FuncRej";
 +
 +    ServerPorts ports1 = startCacheServer(server1, 80f, 90f, regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    ServerPorts ports2 = startCacheServer(server2, 80f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    startClient(client, server1, ports1.getPort(), regionName);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +    
 +    final RejectFunction function = new RejectFunction();
 +    final RejectFunction function2 = new RejectFunction("noRejFunc", false);
 +    Invoke.invokeInEveryVM(new SerializableCallable("register function") {
 +      public Object call() throws Exception {
 +        FunctionService.registerFunction(function);
 +        FunctionService.registerFunction(function2);
 +        return null;
 +      }
 +    });
 +
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Pool p = PoolManager.find("pool1");
 +        assertTrue(p != null);
 +        FunctionService.onServers(p).execute(function);
 +        FunctionService.onServers(p).execute(function2);
 +        return null;
 +      }
 +    });
 +    
 +    final DistributedMember s1 = (DistributedMember)server1.invoke(getDistributedMember);
 +
 +    server2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        FunctionService.onMembers(getSystem()).execute(function);
 +        FunctionService.onMember(getSystem(), s1).execute(function);
 +        FunctionService.onMembers(getSystem()).execute(function2);
 +        FunctionService.onMember(getSystem(), s1).execute(function2);
 +        return null;
 +      }
 +    });
 +
 +    setUsageAboveCriticalThreshold(server1);
 +
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +
 +    server1.invoke(addExpectedFunctionException);
 +    server2.invoke(addExpectedFunctionException);
 +
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Pool p = PoolManager.find("pool1");
 +        assertTrue(p != null);
 +        try {
 +          FunctionService.onServers(p).execute(function);
 +          fail("expected LowMemoryExcception was not thrown");
 +        } catch (ServerOperationException e) {
 +          if (!(e.getCause().getMessage().matches(".*low.*memory.*"))) {
 +            Assert.fail("unexpected exception", e);
 +          }
 +          //expected
 +        }
 +        FunctionService.onServers(p).execute(function2);
 +        return null;
 +      }
 +    });
 +
 +    server2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        try {
 +          FunctionService.onMembers(getSystem()).execute(function);
 +          fail("expected LowMemoryExcception was not thrown");
 +        } catch (LowMemoryException e) {          
 +          //expected
 +        }
 +        try {
 +          FunctionService.onMember(getSystem(), s1).execute(function);
 +          fail("expected LowMemoryExcception was not thrown");
 +        } catch (LowMemoryException e) {
 +          //expected
 +        }
 +        FunctionService.onMembers(getSystem()).execute(function2);
 +        FunctionService.onMember(getSystem(), s1).execute(function2);
 +        return null;
 +      }
 +    });
 +    server1.invoke(removeExpectedFunctionException);
 +    server2.invoke(removeExpectedFunctionException);
 +  }
 +
 +  SerializableCallable getDistributedMember = new SerializableCallable() {
 +    public Object call() throws Exception {
 +      return ((GemFireCacheImpl)getCache()).getMyId();
 +    };
 +  };
 +
 +  /**
 +   * Starts up a CacheServer.
 +   * @return a {@link ServerPorts} containing the CacheServer ports.
 +   */
 +  private ServerPorts startCacheServer(VM server, final float evictionThreshold, final float criticalThreshold, final String regionName,
 +      final boolean createPR, final boolean notifyBySubscription, final int prRedundancy) throws Exception {
 +
 +    return (ServerPorts) server.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getServerProperties());
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +
 +        InternalResourceManager irm = cache.getResourceManager();
 +        HeapMemoryMonitor hmm = irm.getHeapMonitor();
 +        hmm.setTestMaxMemoryBytes(1000);
 +        HeapMemoryMonitor.setTestBytesUsedForThresholdSet(500);
 +        irm.setEvictionHeapPercentage(evictionThreshold);
 +        irm.setCriticalHeapPercentage(criticalThreshold);
 +
 +        AttributesFactory factory = new AttributesFactory();
 +        if (createPR) {
 +          PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +          paf.setRedundantCopies(prRedundancy);
 +          paf.setTotalNumBuckets(11);
 +          factory.setPartitionAttributes(paf.create());
 +        } else {
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setDataPolicy(DataPolicy.REPLICATE);
 +        }
 +        Region region = createRegion(regionName, factory.create());
 +        if (createPR) {
 +          assertTrue(region instanceof PartitionedRegion);
 +        } else {
 +          assertTrue(region instanceof DistributedRegion);
 +        }
 +        CacheServer cacheServer = getCache().addCacheServer();
 +        int port = AvailablePortHelper.getRandomAvailableTCPPorts(1)[0];
 +        cacheServer.setPort(port);
 +        cacheServer.setNotifyBySubscription(notifyBySubscription);
 +        cacheServer.start();
 +        
 +        return new ServerPorts(port);
 +      }
 +    });
 +  }
 +
 +  private void startClient(VM client, final VM server, final int serverPort,
 +      final String regionName) {
 +
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getClientProps());
 +        getCache();
 +
 +        PoolFactory pf = PoolManager.createFactory();
 +        pf.addServer(NetworkUtils.getServerHostName(server.getHost()), serverPort);
 +        pf.create("pool1");
 +        
 +        AttributesFactory af = new AttributesFactory();
 +        af.setScope(Scope.LOCAL);
 +        af.setPoolName("pool1");        
 +        createRegion(regionName, af.create());
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void doPuts(VM vm, final String regionName,
 +      final boolean catchServerException, final boolean catchLowMemoryException) {
 +
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion().getSubregion(regionName);
 +        try {
 +          r.put(Integer.valueOf(0), "value-1");
 +          if (catchServerException || catchLowMemoryException) {
 +            fail("An expected ResourceException was not thrown");
 +          }
 +        } catch (ServerOperationException ex) {
 +          if (!catchServerException) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +          if (!(ex.getCause() instanceof LowMemoryException)) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +        } catch (LowMemoryException low) {
 +          if (!catchLowMemoryException) {
 +            Assert.fail("Unexpected exception: ", low);
 +          }
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void doPutAlls(VM vm, final String regionName,
 +      final boolean catchServerException, final boolean catchLowMemoryException, 
 +      final Range rng) {
 +
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion().getSubregion(regionName);
 +        Map<Integer, String> temp = new HashMap<Integer, String>();
 +        for (int i=rng.start; i<rng.end; i++) {
 +          Integer k = Integer.valueOf(i);
 +          temp.put(k, "value-"+i);
 +        }
 +        try {
 +          r.putAll(temp);
 +          if (catchServerException || catchLowMemoryException) {
 +            fail("An expected ResourceException was not thrown");
 +          }
 +          for (Map.Entry<Integer, String> me: temp.entrySet()) {
 +            assertEquals(me.getValue(), r.get(me.getKey()));
 +          }
 +        } catch (ServerOperationException ex) {
 +          if (!catchServerException) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +          if (!(ex.getCause() instanceof LowMemoryException)) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +          for(Integer me: temp.keySet()) {
 +            assertFalse("Key " + me + " should not exist", r.containsKey(me));
 +          }
 +        } catch (LowMemoryException low) {
 +          LogWriterUtils.getLogWriter().info("Caught LowMemoryException", low);
 +          if (!catchLowMemoryException) {
 +            Assert.fail("Unexpected exception: ", low);
 +          }
 +          for(Integer me: temp.keySet()) {
 +            assertFalse("Key " + me + " should not exist", r.containsKey(me));
 +          }
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void setUsageAboveCriticalThreshold(VM vm) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        ((GemFireCacheImpl)getCache()).getResourceManager().getHeapMonitor().updateStateAndSendEvent(950);
 +        HeapMemoryMonitor.setTestBytesUsedForThresholdSet(950);
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void setUsageAboveEvictionThreshold(VM vm) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        HeapMemoryMonitor.setTestBytesUsedForThresholdSet(850);
 +        ((GemFireCacheImpl)getCache()).getResourceManager().getHeapMonitor().updateStateAndSendEvent(850);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void setUsageBelowEviction(VM vm) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        ((GemFireCacheImpl)getCache()).getResourceManager().getHeapMonitor().updateStateAndSendEvent(750);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void setThresholds(VM server, final float evictionThreshold,
 +      final float criticalThreshold) {
 +    
 +    server.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        ResourceManager irm = getCache().getResourceManager();
 +        irm.setCriticalHeapPercentage(criticalThreshold);
 +        irm.setEvictionHeapPercentage(evictionThreshold);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void registerTestMemoryThresholdListener(VM vm) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        TestMemoryThresholdListener listener = new TestMemoryThresholdListener();
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        irm.addResourceListener(ResourceType.HEAP_MEMORY, listener);
 +        assertTrue(irm.getResourceListeners(ResourceType.HEAP_MEMORY).contains(listener));
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void registerLoggingTestMemoryThresholdListener(VM vm) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        TestMemoryThresholdListener listener = new TestMemoryThresholdListener(true);
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        irm.addResourceListener(ResourceType.HEAP_MEMORY, listener);
 +        assertTrue(irm.getResourceListeners(ResourceType.HEAP_MEMORY).contains(listener));
 +        return null;
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Verifies that the test listener value on the given vm is what is expected
 +   * Note that for remote events useWaitCriterion must be true
 +   * @param vm the vm where verification should take place
 +   * @param state
 +   * @param value the expected value
 +   * @param useWaitCriterion must be true for remote events
 +   */
 +  private void verifyListenerValue(VM vm, final MemoryState state,
 +      final int value, final boolean useWaitCriterion) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        WaitCriterion wc = null;
 +        Set<ResourceListener> listeners = getGemfireCache().getResourceManager().getResourceListeners(ResourceType.HEAP_MEMORY);
 +        TestMemoryThresholdListener tmp_listener = null;
 +        Iterator<ResourceListener> it = listeners.iterator();
 +        while (it.hasNext()) {
 +          ResourceListener<MemoryEvent> l = it.next();
 +          if (l instanceof TestMemoryThresholdListener) {
 +            tmp_listener = (TestMemoryThresholdListener) l;
 +            break;
 +          }
 +        }
 +        final TestMemoryThresholdListener listener = tmp_listener == null ? null : tmp_listener;
 +        switch(state) {
 +        case CRITICAL:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              public String description() {
 +                return "Remote CRITICAL assert failed "+listener.toString();
 +              }
 +              public boolean done() {
 +                return value == listener.getCriticalThresholdCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getCriticalThresholdCalls());
 +          }
 +          break;
 +        case CRITICAL_DISABLED:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              public String description() {
 +                return "Remote CRITICAL_DISABLED assert failed "+listener.toString();
 +              }
 +              public boolean done() {
 +                return value == listener.getCriticalDisabledCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getCriticalDisabledCalls());
 +          }
 +          break;
 +        case EVICTION:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              public String description() {
 +                return "Remote EVICTION assert failed "+listener.toString();
 +              }
 +              public boolean done() {
 +                return value == listener.getEvictionThresholdCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getEvictionThresholdCalls());
 +          }
 +          break;
 +        case EVICTION_DISABLED:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              public String description() {
 +                return "Remote EVICTION_DISABLED assert failed "+listener.toString();
 +              }
 +              public boolean done() {
 +                return value == listener.getEvictionDisabledCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getEvictionDisabledCalls());
 +          }
 +          break;
 +        case NORMAL:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              public String description() {
 +                return "Remote NORMAL assert failed "+listener.toString();
 +              }
 +              public boolean done() {
 +                return value == listener.getNormalCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getNormalCalls());
 +          }
 +          break;
 +          default:
 +            throw new IllegalStateException("Unknown memory state");
 +        }
 +        if (useWaitCriterion) {
 +          Wait.waitForCriterion(wc, 30000, 10, true);
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void verifyProfiles(VM vm, final int numberOfProfiles) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        final ResourceAdvisor ra = irm.getResourceAdvisor();
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "verify profiles failed. Current profiles: " + ra.adviseGeneric();
 +          }
 +          public boolean done() {
 +            return numberOfProfiles == ra.adviseGeneric().size();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30000, 10, true);
 +        return null;
 +      }
 +    });
 +  }
 +
 +  protected Properties getClientProps() {
 +    Properties p = new Properties();
 +    p.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    p.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    return p;
 +  }
 +
 +  protected Properties getServerProperties() {
 +    Properties p = new Properties();
 +    p.setProperty(DistributionConfig.LOCATORS_NAME, "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +    return p;
 +  }
 +
 +  private SerializableCallable setHeapMemoryMonitorTestMode = new SerializableCallable() {
 +    public Object call() throws Exception {
 +      HeapMemoryMonitor.setTestDisableMemoryUpdates(true);
 +      return null;
 +    }
 +  };
 +  
 +  private SerializableCallable resetResourceManager = new SerializableCallable() {
 +    public Object call() throws Exception {
 +      InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +      // Reset CRITICAL_UP by informing all that heap usage is now 1 byte (0 would disable).
 +      irm.getHeapMonitor().updateStateAndSendEvent(1);
 +      Set<ResourceListener> listeners = irm.getResourceListeners(ResourceType.HEAP_MEMORY);
 +      Iterator<ResourceListener> it = listeners.iterator();
 +      while (it.hasNext()) {
 +        ResourceListener<MemoryEvent> l = it.next();
 +        if (l instanceof TestMemoryThresholdListener) {
 +          ((TestMemoryThresholdListener)l).resetThresholdCalls();
 +        }
 +      }
 +      irm.getHeapMonitor().setTestMaxMemoryBytes(0);
 +      HeapMemoryMonitor.setTestDisableMemoryUpdates(false);
 +      return null;
 +    }
 +  };
 +
 +  private class RejectFunction extends FunctionAdapter {
 +    private boolean optimizeForWrite = true;
 +    private String id = "RejectFunction";
 +    public RejectFunction() {
 +    }
 +    public RejectFunction(String id, boolean optimizeForWrite) {
 +      this.id = id;
 +      this.optimizeForWrite = optimizeForWrite;
 +    }
 +    @Override
 +    public void execute(FunctionContext context) {
 +      if (context instanceof RegionFunctionContext) {
 +        RegionFunctionContext regionContext = (RegionFunctionContext)context;
 +        Region dataSet = regionContext.getDataSet();
 +        dataSet.get(1);
 +        regionContext.getResultSender().lastResult("executed");
 +      } else {
 +        context.getResultSender().lastResult("executed");
 +      }
 +    }
 +    @Override
 +    public String getId() {
 +      return id;
 +    }
 +
 +    @Override
 +    public boolean hasResult() {
 +      return true;
 +    }
 +    @Override
 +    public boolean optimizeForWrite() {
 +      return optimizeForWrite;
 +    }
 +    public void setOptimizeForWrite(boolean optimizeForWrite) {
 +      this.optimizeForWrite = optimizeForWrite;
 +    }
 +    public boolean isHA() {
 +      return false;
 +    }
 +  }
 +
 +  /**
 +   * putting this test here because junit does not have host stat sampler enabled
 +   */
 +  public void testLocalStatListenerRegistration() throws Exception{
 +    final CountDownLatch latch = new CountDownLatch(1);
 +    Cache cache = getCache();
 +    InternalDistributedSystem internalSystem = (InternalDistributedSystem)cache.
 +                                                getDistributedSystem();
 +    final GemFireStatSampler sampler = internalSystem.getStatSampler();
 +    sampler.waitForInitialization(10000); // fix: remove infinite wait 
 +    final LocalStatListener l = new LocalStatListener(){
 +      public void statValueChanged(double value) {
 +        latch.countDown();
 +      }
 +    };
 +    final String tenuredPoolName = HeapMemoryMonitor.getTenuredMemoryPoolMXBean().getName();
 +    LogWriterUtils.getLogWriter().info("TenuredPoolName:"+tenuredPoolName);
 +    final List list = internalSystem.getStatsList();
 +    assertFalse(list.isEmpty());
 +    
 +    // fix: found race condition here...
 +    WaitCriterion wc = new WaitCriterion() {
 +      public boolean done() {
 +        int i=0;
 +        synchronized (list) {
 +          for (Object o : list) {
 +            LogWriterUtils.getLogWriter().info("List:"+(++i)+":"+o);
 +            if (o instanceof StatisticsImpl) {
 +              StatisticsImpl si = (StatisticsImpl)o;
 +              LogWriterUtils.getLogWriter().info("stat:"+si.getTextId());
 +              if (si.getTextId().contains(tenuredPoolName)) {
 +                sampler.addLocalStatListener(l, si, "currentUsedMemory");
 +                return true;
 +              }
 +            }
 +          }
 +        }
 +        return false;
 +      }
 +      public String description() {
 +        return "Waiting for " + tenuredPoolName + " statistics to be added to create listener for";
 +      }
 +    };
 +    Wait.waitForCriterion(wc, 5000, 10, true);
 +    
 +    assertTrue("expected at least one stat listener, found " +
 +        sampler.getLocalListeners().size(),
 +        sampler.getLocalListeners().size() > 0);            
 +    long maxTenuredMemory = HeapMemoryMonitor.getTenuredPoolMaxMemory();
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +    Region r = createRegion(getUniqueName()+"region", factory.create());
 +    //keep putting objects (of size 1% of maxTenuredMemory) and wait for stat callback
 +    //if we don't get a callback after 75 attempts, throw exception
 +    int count = 0;
 +    while (true) {
 +      count++;
 +      if (count > 75) {
 +        throw new TestException("Did not receive a stat listener callback");
 +      }
 +      byte[] value = new byte[(int)(maxTenuredMemory*0.01)];
 +      r.put("key-"+count, value);
 +      if (latch.await(50, TimeUnit.MILLISECONDS)) {
 +        break;
 +      } else {
 +        continue;
 +      }
 +    }
 +    r.close();
 +  }
 +  
 +  /**
 +   * Test that LocalRegion cache Loads are not stored in the Region
 +   * if the VM is in a critical state, then test that they are allowed
 +   * once the VM is no longer critical
 +   * @throws Exception
 +   */
 +  public void testLRLoadRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM vm = host.getVM(2);
 +    final String rName = getUniqueName();
 +    final float criticalHeapThresh = 0.90f;
 +    final int fakeHeapMaxSize = 1000;
 +
-     vm.invoke(DistributedTestCase.class, "disconnectFromDS");
++    vm.invoke(() -> DistributedTestCase.disconnectFromDS());
 +    
 +    vm.invoke(new CacheSerializableRunnable("test LocalRegion load passthrough when critical") {
 +      @Override
 +      public void run2() throws CacheException {
 +        InternalResourceManager irm = (InternalResourceManager)getCache().getResourceManager();
 +        HeapMemoryMonitor hmm = irm.getHeapMonitor();
 +        long fakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh - 0.5f));  // below critical by 50%
 +        assertTrue(fakeHeapMaxSize > 0);
 +        irm.getHeapMonitor().setTestMaxMemoryBytes(fakeHeapMaxSize);
 +        HeapMemoryMonitor.setTestBytesUsedForThresholdSet(fakeHeapUsage);
 +        irm.setCriticalHeapPercentage((criticalHeapThresh * 100.0f));
 +        AttributesFactory<Integer, String> af = new AttributesFactory<Integer, String>();
 +        af.setScope(Scope.LOCAL);
 +        final AtomicInteger numLoaderInvocations = new AtomicInteger();
 +        af.setCacheLoader(new CacheLoader<Integer, String>() {
 +          public String load(LoaderHelper<Integer, String> helper)
 +          throws CacheLoaderException {
 +            numLoaderInvocations.incrementAndGet();
 +            return helper.getKey().toString();
 +          }
 +          public void close() {}
 +        });
 +        Region<Integer, String> r = getCache().createRegion(rName, af.create());
 +        
 +        assertFalse(hmm.getState().isCritical());
 +        int expectedInvocations = 0;
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        {
 +          Integer k = new Integer(1);
 +          assertEquals(k.toString(), r.get(k));
 +        }
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        expectedInvocations++; expectedInvocations++;
 +        r.getAll(createRanges(10, 12));
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        fakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh + 0.1f));  // usage above critical by 10%
 +        assertTrue(fakeHeapUsage > 0);
 +        assertTrue(fakeHeapUsage <= fakeHeapMaxSize);
 +        hmm.updateStateAndSendEvent(fakeHeapUsage);
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        
 +        assertTrue(hmm.getState().isCritical());
 +        { 
 +          Integer k = new Integer(2);
 +          assertEquals(k.toString(), r.get(k));
 +        }
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        expectedInvocations++; expectedInvocations++;
 +        r.getAll(createRanges(13, 15));
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +
 +        fakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh - 0.3f));  // below critical by 30%
 +        assertTrue(fakeHeapMaxSize > 0);
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        hmm.updateStateAndSendEvent(fakeHeapUsage);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        assertFalse(hmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(3);
 +          assertEquals(k.toString(), r.get(k));
 +        }
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        expectedInvocations++; expectedInvocations++;
 +        r.getAll(createRanges(16, 18));
 +        assertEquals(expectedInvocations, numLoaderInvocations.get());
 +
 +        // Do extra validation that the entry doesn't exist in the local region
 +        for (Integer i: createRanges(2, 2, 13, 15)) {
 +          if (r.containsKey(i)) {
 +            fail("Expected containsKey return false for key" + i);
 +          }
 +          if (r.getEntry(i) != null) {
 +            fail("Expected getEntry to return null for key" + i);
 +          }
 +        }
 +      }
 +    });
 +  }
 +
 +  /** Create a list of integers consisting of the ranges defined by the provided
 +  * argument e.g..  createRanges(1, 4, 10, 12) means create ranges 1 through 4 and
 +  * 10 through 12 and should yield the list:
 +  * 1, 2, 3, 4, 10, 11, 12
 +  */ 
 +  public static List<Integer> createRanges(int... startEnds) {
 +    assert startEnds.length % 2 == 0;
 +    ArrayList<Integer> ret = new ArrayList<Integer>();
 +    for (int si=0; si<startEnds.length; si++) { 
 +      final int start = startEnds[si++];
 +      final int end = startEnds[si];
 +      assert end >= start;
 +      ret.ensureCapacity(ret.size() + ((end-start)+1));
 +      for (int i=start; i<=end; i++) {
 +        ret.add(new Integer(i));
 +      }
 +    }
 +    return ret;
 +  }
 +
 +  
 +  /**
 +   * Test that DistributedRegion cacheLoade and netLoad are passed through to the 
 +   * calling thread if the local VM is in a critical state.  Once the VM has moved
 +   * to a safe state then test that they are allowed.
 +   * @throws Exception
 +   */
 +  public void testDRLoadRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM replicate1 = host.getVM(2);
 +    final VM replicate2 = host.getVM(3);
 +    final String rName = getUniqueName();
 +    final float criticalHeapThresh = 0.90f;
 +    final int fakeHeapMaxSize = 1000;
 +
 +    // Make sure the desired VMs will have a fresh DS.
-     AsyncInvocation d1 = replicate1.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
-     AsyncInvocation d2 = replicate2.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
++    AsyncInvocation d1 = replicate1.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
++    AsyncInvocation d2 = replicate2.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
 +    d1.join();
 +    assertFalse(d1.exceptionOccurred());
 +    d2.join();
 +    assertFalse(d2.exceptionOccurred());
 +    CacheSerializableRunnable establishConnectivity = new CacheSerializableRunnable("establishcConnectivity") {
 +      @Override
 +      public void run2() throws CacheException {
 +        getSystem();
 +      }
 +    };
 +    replicate1.invoke(establishConnectivity);
 +    replicate2.invoke(establishConnectivity);
 +    
 +    CacheSerializableRunnable createRegion = new CacheSerializableRunnable("create DistributedRegion") {
 +      @Override
 +      public void run2() throws CacheException {
 +        // Assert some level of connectivity
 +        InternalDistributedSystem ds = getSystem();
 +        assertTrue(ds.getDistributionManager().getNormalDistributionManagerIds().size() >= 1);
 +        
 +        final long fakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh - 0.5f));  // below critical by 50%
 +        InternalResourceManager irm = (InternalResourceManager)getCache().getResourceManager();
 +        HeapMemoryMonitor hmm = irm.getHeapMonitor();
 +        assertTrue(fakeHeapMaxSize > 0);
 +        hmm.setTestMaxMemoryBytes(fakeHeapMaxSize);
 +        HeapMemoryMonitor.setTestBytesUsedForThresholdSet(fakeHeapUsage);
 +        irm.setCriticalHeapPercentage((criticalHeapThresh * 100.0f));
 +        AttributesFactory<Integer, String> af = new AttributesFactory<Integer, String>();
 +        af.setScope(Scope.DISTRIBUTED_ACK);
 +        af.setDataPolicy(DataPolicy.REPLICATE);
 +        getCache().createRegion(rName, af.create());
 +      }
 +    };
 +    replicate1.invoke(createRegion);
 +    replicate2.invoke(createRegion);
 +    
 +    replicate1.invoke(addExpectedException);
 +    replicate2.invoke(addExpectedException);
 +    
 +    final Integer expected = (Integer)replicate1.invoke(new SerializableCallable("test Local DistributedRegion Load") {
 +      public Object call() throws Exception {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        AttributesMutator<Integer, String> am = r.getAttributesMutator();
 +        am.setCacheLoader(new CacheLoader<Integer, String>() {
 +          final AtomicInteger numLoaderInvocations = new AtomicInteger();
 +          public String load(LoaderHelper<Integer, String> helper) throws CacheLoaderException {
 +            Integer expectedInvocations = (Integer)helper.getArgument();
 +            final int actualInvocations = this.numLoaderInvocations.getAndIncrement();
 +            if (expectedInvocations.intValue() != actualInvocations) {
 +              throw new CacheLoaderException("Expected " + expectedInvocations 
 +                  + " invocations, actual is " + actualInvocations);
 +            }
 +            return helper.getKey().toString();
 +          }
 +          public void close() {}
 +        });
 +
 +        int expectedInvocations = 0;
 +        HeapMemoryMonitor hmm = ((InternalResourceManager)getCache().getResourceManager()).getHeapMonitor();
 +        assertFalse(hmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(1);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +
 +        long newfakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh + 0.1f));  // usage above critical by 10%
 +        assertTrue(newfakeHeapUsage > 0);
 +        assertTrue(newfakeHeapUsage <= fakeHeapMaxSize);
 +        hmm.updateStateAndSendEvent(newfakeHeapUsage);
 +        assertTrue(hmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(2); 
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +
 +        newfakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh - 0.3f));  // below critical by 30%
 +        assertTrue(fakeHeapMaxSize > 0);
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        hmm.updateStateAndSendEvent(newfakeHeapUsage);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        assertFalse(hmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(3);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        return new Integer(expectedInvocations);
 +      }
 +    });
 +
 +    final CacheSerializableRunnable validateData1 = new CacheSerializableRunnable("Validate data 1") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer i1 = new Integer(1);
 +        assertTrue(r.containsKey(i1));
 +        assertNotNull(r.getEntry(i1));
 +        Integer i2 = new Integer(2);
 +        assertFalse(r.containsKey(i2));
 +        assertNull(r.getEntry(i2));
 +        Integer i3 = new Integer(3);
 +        assertTrue(r.containsKey(i3));
 +        assertNotNull(r.getEntry(i3));
 +      }
 +    };
 +    replicate1.invoke(validateData1);
 +    replicate2.invoke(validateData1);
 +    
 +    replicate2.invoke(new SerializableCallable("test DistributedRegion netLoad") {
 +      public Object call() throws Exception {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        HeapMemoryMonitor hmm = ((InternalResourceManager)getCache().getResourceManager()).getHeapMonitor();
 +        assertFalse(hmm.getState().isCritical());
 +        
 +        int expectedInvocations = expected.intValue();
 +        {
 +          Integer k = new Integer(4);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        
 +        // Place in a critical state for the next test
 +        long newfakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh + 0.1f));  // usage above critical by 10%
 +        assertTrue(newfakeHeapUsage > 0);
 +        assertTrue(newfakeHeapUsage <= fakeHeapMaxSize);
 +        hmm.updateStateAndSendEvent(newfakeHeapUsage);
 +        assertTrue(hmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(5);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +
 +        newfakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh - 0.3f));  // below critical by 30%
 +        assertTrue(fakeHeapMaxSize > 0);
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        hmm.updateStateAndSendEvent(newfakeHeapUsage);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        assertFalse(hmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(6);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        return new Integer(expectedInvocations);
 +      }
 +    });
 +    
 +    replicate1.invoke(removeExpectedException);
 +    replicate2.invoke(removeExpectedException);
 +    
 +    final CacheSerializableRunnable validateData2 = new CacheSerializableRunnable("Validate data 2") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer i4 = new Integer(4);
 +        assertTrue(r.containsKey(i4));
 +        assertNotNull(r.getEntry(i4));
 +        Integer i5 = new Integer(5);
 +        assertFalse(r.containsKey(i5));
 +        assertNull(r.getEntry(i5));
 +        Integer i6 = new Integer(6);
 +        assertTrue(r.containsKey(i6));
 +        assertNotNull(r.getEntry(i6));
 +      }
 +    };
 +    replicate1.invoke(validateData2);
 +    replicate2.invoke(validateData2);
 +  }
 +  
 +  /**
 +   * Test that a Partitioned Region loader invocation is rejected
 +   * if the VM with the bucket is in a critical state.
 +   * @throws Exception
 +   */
 +  public void testPRLoadRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM accessor = host.getVM(1);
 +    final VM ds1 = host.getVM(2);
 +    final String rName = getUniqueName();
 +    final float criticalHeapThresh = 0.90f;
 +    final int fakeHeapMaxSize = 1000;
 +
 +    // Make sure the desired VMs will have a fresh DS.
-     AsyncInvocation d0 = accessor.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
-     AsyncInvocation d1 = ds1.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
++    AsyncInvocation d0 = accessor.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
++    AsyncInvocation d1 = ds1.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
 +    d0.join();
 +    assertFalse(d0.exceptionOccurred());
 +    d1.join();
 +    assertFalse(d1.exceptionOccurred());
 +    CacheSerializableRunnable establishConnectivity = new CacheSerializableRunnable("establishcConnectivity") {
 +      @Override
 +      public void run2() throws CacheException { getSystem();  }
 +    };
 +    ds1.invoke(establishConnectivity);
 +    accessor.invoke(establishConnectivity);
 +
 +    ds1.invoke(createPR(rName, false, fakeHeapMaxSize, criticalHeapThresh));
 +    accessor.invoke(createPR(rName, true, fakeHeapMaxSize, criticalHeapThresh));
 +    
 +    final AtomicInteger expectedInvocations = new AtomicInteger(0);
 +
 +    Integer ex = (Integer) accessor.invoke(new SerializableCallable("Invoke loader from accessor, non-critical") {
 +      public Object call() throws Exception {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer k = new Integer(1);
 +        Integer expectedInvocations0 = new Integer(expectedInvocations.getAndIncrement());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations0)); // should load for new key
 +        assertTrue(r.containsKey(k));
 +        Integer expectedInvocations1 = new Integer(expectedInvocations.get());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations1)); // no load
 +        assertEquals(k.toString(), r.get(k, expectedInvocations1)); // no load
 +        return expectedInvocations1;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +
 +    ex = (Integer)ds1.invoke(new SerializableCallable("Invoke loader from datastore, non-critical") {
 +      public Object call() throws Exception {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer k = new Integer(2);
 +        Integer expectedInvocations1 = new Integer(expectedInvocations.getAndIncrement());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations1)); // should load for new key
 +        assertTrue(r.containsKey(k));
 +        Integer expectedInvocations2 = new Integer(expectedInvocations.get());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations2)); // no load
 +        assertEquals(k.toString(), r.get(k, expectedInvocations2)); // no load
 +        String oldVal = r.remove(k);
 +        assertFalse(r.containsKey(k));
 +        assertEquals(k.toString(), oldVal);
 +        return expectedInvocations2;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +
 +    accessor.invoke(addExpectedException);
 +    ds1.invoke(addExpectedException);
 +
 +    ex = (Integer)ds1.invoke(new SerializableCallable("Set critical state, assert local load behavior") {
 +      public Object call() throws Exception {
 +        long newfakeHeapUsage = Math.round(fakeHeapMaxSize * (criticalHeapThresh + 0.1f));  // usage above critical by 10%
 +        assertTrue(newfakeHeapUsage > 0);
 +        assertTrue(newfakeHeapUsage <= fakeHeapMaxSize);
 +        HeapMemoryMonitor hmm = ((InternalResourceManager)getCache().getResourceManager()).getHeapMonitor();
 +        hmm.updateStateAndSendEvent(newfakeHeapUsage);
 +        assertTrue(hmm.getState().isCritical());
 +        final Integer k = new Integer(2); // reload with same key again and again
 +        final Integer expectedInvocations3 = new 

<TRUNCATED>


[045/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexManager.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexManager.java
index 3784327,0000000..7a0b1a9
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexManager.java
@@@ -1,1718 -1,0 +1,1721 @@@
 +/*
 + * 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.
 + */
 +/*
 + * IndexManager.java
 + *
 + * Created on February 15, 2005, 11:49 AM
 + */
 +package com.gemstone.gemfire.cache.query.internal.index;
 +
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.HashMap;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.concurrent.ArrayBlockingQueue;
 +import java.util.concurrent.BlockingQueue;
 +import java.util.concurrent.Callable;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentMap;
 +import java.util.concurrent.ExecutionException;
 +import java.util.concurrent.FutureTask;
 +import java.util.concurrent.atomic.AtomicLong;
 +import java.util.concurrent.LinkedBlockingQueue;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.query.AmbiguousNameException;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.IndexExistsException;
 +import com.gemstone.gemfire.cache.query.IndexInvalidException;
 +import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
 +import com.gemstone.gemfire.cache.query.IndexNameConflictException;
 +import com.gemstone.gemfire.cache.query.IndexStatistics;
 +import com.gemstone.gemfire.cache.query.IndexType;
 +import com.gemstone.gemfire.cache.query.MultiIndexCreationException;
 +import com.gemstone.gemfire.cache.query.NameResolutionException;
 +import com.gemstone.gemfire.cache.query.QueryException;
 +import com.gemstone.gemfire.cache.query.TypeMismatchException;
 +import com.gemstone.gemfire.cache.query.internal.CompiledPath;
 +import com.gemstone.gemfire.cache.query.internal.CompiledValue;
 +import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
 +import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
 +import com.gemstone.gemfire.cache.query.internal.MapIndexable;
 +import com.gemstone.gemfire.cache.query.internal.NullToken;
 +import com.gemstone.gemfire.cache.query.internal.QueryMonitor;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserver;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
 +import com.gemstone.gemfire.cache.query.internal.index.AbstractIndex.InternalIndexStatistics;
 +import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.cache.BucketRegion;
 +import com.gemstone.gemfire.internal.cache.CachePerfStats;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.RegionEntry;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.TXStateProxy;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
 +
 +/**
 + * @author vaibhav
 + * @author asif
 + */
 +public class IndexManager  {
 +  private static final Logger logger = LogService.getLogger();
 +
 +  public static final int ADD_ENTRY = 1;
 +  public static final int UPDATE_ENTRY = 2;
 +  public static final int REMOVE_ENTRY = 3;
 +  //Asif : This action is to rerun Index creation after
 +  //clear is called on the region
 +  public static final int RECREATE_INDEX = 4;
 +  protected final Region region;
 +
 +  private final boolean isOverFlowToDisk;
 +  private final boolean offHeap;
 +  private final boolean indexMaintenanceSynchronous;
 +  private int numCreators = 0;
 +  private int numUpdatersInProgress = 0;
 +  private int numUpdatersInWaiting = 0;
 +  private int iternameCounter = 0;
 +  /*
 +   * Map containing <IndexTask, FutureTask<IndexTask> or Index>. IndexTask
 +   * represents an index thats completely created or one thats in create phase.
 +   * This is done in order to avoid synchronization on the indexes.
 +   */
 +  private final ConcurrentMap indexes = new ConcurrentHashMap();
 +  //TODO Asif : Fix the appropriate size of the Map & the concurrency level
 +  private ConcurrentMap canonicalizedIteratorNameMap = new ConcurrentHashMap();
 +  private IndexUpdaterThread updater;
 +
 +  // Threshold for Queue.
 +  private final int INDEX_MAINTENANCE_BUFFER = Integer.getInteger("gemfire.AsynchIndexMaintenanceThreshold", -1).intValue();
 +
 +  public static boolean JOIN_OPTIMIZATION = !Boolean.getBoolean("gemfire.index.DisableJoinOptimization");
 +  
 +  // Added for test purposes only.
 +  public static boolean INPLACE_OBJECT_MODIFICATION_FOR_TEST = false;    
 +
 +  //Added for testing only
 +  public static boolean IS_TEST_LDM = false; 
 +
 +  public static boolean IS_TEST_EXPANSION = false;
 +  
 +  
 +
 +  /**
 +   * System property to maintain the ReverseMap to take care in-place modification of the 
 +   * objects by the application. 
 +   * In case of in-place modification the EntryEvent will not have the old-value, without this
 +   * the old-values are not removed from the index-maps thus resulting in inconsistent results.
 +   */
 +  public static final boolean INPLACE_OBJECT_MODIFICATION =     
 +    Boolean.valueOf(System.getProperty("gemfire.index.INPLACE_OBJECT_MODIFICATION", "false")).booleanValue(); 
 +
 +  /**
 +   * System property to turn-off the compact-index support.
 +   */
 +  public static final boolean RANGEINDEX_ONLY =     
 +    Boolean.valueOf(System.getProperty("gemfire.index.RANGEINDEX_ONLY", "false")).booleanValue();
 +
 +  /** For test purpose only */
 +  public static boolean TEST_RANGEINDEX_ONLY = false;
 +  public static final String INDEX_ELEMARRAY_THRESHOLD_PROP = "index_elemarray_threshold";
 +  public static final String INDEX_ELEMARRAY_SIZE_PROP = "index_elemarray_size";
 +  public static final int INDEX_ELEMARRAY_THRESHOLD = Integer.parseInt(System.getProperty(INDEX_ELEMARRAY_THRESHOLD_PROP,"100"));
 +  public static final int INDEX_ELEMARRAY_SIZE = Integer.parseInt(System.getProperty(INDEX_ELEMARRAY_SIZE_PROP,"5"));
 +  public final static AtomicLong SAFE_QUERY_TIME = new AtomicLong(0);
 +  public static boolean ENABLE_UPDATE_IN_PROGRESS_INDEX_CALCULATION = true;
 +  /** The NULL constant */
 +  public static final Object NULL = new NullToken();
 +
 +  public static TestHook testHook;
 +
 +  //private int numCreatorsInWaiting = 0;
 +  // @todo ericz
 +  // there should be a read/write lock PER INDEX in order to maximize
 +  // the concurrency of query execution.
 +  public IndexManager(Region region) {
 +    this.region = region;
 +    // must be a SortedMap to ensure the indexes are iterated over in fixed
 +    // order
 +    // to avoid deadlocks when acquiring locks
 +    //indexes = Collections.synchronizedSortedMap(new TreeMap());
 +    indexMaintenanceSynchronous = region.getAttributes()
 +        .getIndexMaintenanceSynchronous();
 +    isOverFlowToDisk = region.getAttributes().getEvictionAttributes()
 +        .getAction().isOverflowToDisk();
 +    this.offHeap = region.getAttributes().getOffHeap();
 +    if (!indexMaintenanceSynchronous) {
 +      final LoggingThreadGroup group =
 +        LoggingThreadGroup.createThreadGroup("QueryMonitor Thread Group", logger);
 +      updater = new IndexUpdaterThread(group, this.INDEX_MAINTENANCE_BUFFER,
 +                                       "OqlIndexUpdater:" + region.getFullPath());
 +      updater.start();
 +    }
 +  }
 +   
 +  /**
 +   * Stores the largest combination of current time + delta
 +   * If there is a large delta/hiccup in timings, this allows us to calculate the 
 +   * correct results for a query but, reevaluate more aggressively.
 +   * But the large hiccup will eventually be rolled off as time is always increasing
 +   * This is a fix for #47475
 +   * 
 +   * @param operationTime the last modified time from version tag
 +   * @param currentCacheTime
 +   */
 +  public static boolean setIndexBufferTime(long operationTime, long currentCacheTime) {
 +    long timeDifference = currentCacheTime - operationTime;
 +    return setNewLargestValue(SAFE_QUERY_TIME, currentCacheTime + timeDifference);
 +  }
 +  
 +  /** only for test purposes 
 +   * This should not be called from any product code.  Calls from product code will 
 +   * possibly cause continous reevaluation (performance issue) OR
 +   * incorrect query results (functional issue)
 +   **/
 +  public static void resetIndexBufferTime() {
 +    SAFE_QUERY_TIME.set(0);
 +  }
 +  
 +  /**
 +   * Calculates whether we need to reevluate the key for the region entry
 +   * We added a way to determine whether to reevaluate an entry for query execution
 +   * The method is to keep track of the delta and current time in a single long value
 +   * The value is then used by the query to determine if a region entry needs to be reevaluated,
 +   * based on subtracting the value with the query execution time.  This provides a delta + some false positive time (dts)
 +   * If the dts + last modified time of the region entry is > query start time, 
 +   * we can assume that it needs to be reevaluated
 +   *
 +   * This is to fix bug 47475, where references to region entries can be held
 +   * by the executing query either directly or indirectly (iterators can hold 
 +   * references for next) but the values underneath could change.
 +   * 
 +   * Small amounts of false positives are ok as it will have a slight impact on performance
 +   * @param queryStartTime
 +   * @param lastModifiedTime
 +   */
 +  public static boolean needsRecalculation(long queryStartTime, long lastModifiedTime) {
 +    return ENABLE_UPDATE_IN_PROGRESS_INDEX_CALCULATION && queryStartTime <= SAFE_QUERY_TIME.get() - queryStartTime + lastModifiedTime;
 +  }
 +  
 +  /**
 +   * 
 +   * @param value
 +   * @param newValue
 +   */
 +  private static boolean setNewLargestValue(AtomicLong value, long newValue) {
 +    boolean done = false;
 +    while (!done) {
 +      long oldValue = value.get();
 +      if (oldValue < newValue ) {
 +        return value.compareAndSet(oldValue, newValue);
 +      }
 +      else {
 +        done = true;
 +      }
 +    }
 +    return false;
 +  }
 +
 +  /** Test Hook */
 +  public interface TestHook {
 +    public void hook(final int spot) throws RuntimeException;
 +  }
 +  
 +  /**
 +   * The Region this IndexManager is associated with
 +   * 
 +   * @return the Region for this IndexManager
 +   */
 +  public Region getRegion() {
 +    return region;
 +  }
 +
 +  /**
 +   * Used by tests to access the updater thread to determine its progress
 +   */
 +  public IndexUpdaterThread getUpdaterThread() {
 +    return this.updater;
 +  }
 +
 +  // @todo need more specific list of exceptions
 +  /**
 +   * Create an index that can be used when executing queries.
 +   * 
 +   * @param indexName the name of this index, used for statistics collection
 +   * @param indexType the type of index
 +   * @param origIndexedExpression the expression to index on, a function
 +   *          dependent on region entries individually.
 +   * @param origFromClause expression that evaluates to the collection(s) that
 +   *          will be queried over, must contain one and only one region path.
 +   * @return the newly created Index
 +   */
 +  public Index createIndex(String indexName, IndexType indexType,
 +      String origIndexedExpression, String origFromClause, String imports,
 +      ExecutionContext externalContext, PartitionedIndex prIndex, boolean loadEntries)
 +      throws IndexNameConflictException, IndexExistsException,
 +      IndexInvalidException {
 +    
 +    if (QueryMonitor.isLowMemory()) {
 +      throw new IndexInvalidException(LocalizedStrings.IndexCreationMsg_CANCELED_DUE_TO_LOW_MEMORY.toLocalizedString());
 +    }
 +    
 +    boolean oldReadSerialized = DefaultQuery.getPdxReadSerialized();
 +    DefaultQuery.setPdxReadSerialized(this.region.getCache(), true);
 +
 +    TXStateProxy tx = null;
 +    if (!((GemFireCacheImpl)this.region.getCache()).isClient()) {
 +      tx = ((TXManagerImpl) this.region.getCache().getCacheTransactionManager()).internalSuspend();
 +    }
 +
 +    try {
 +      String projectionAttributes = "*"; // for now this is the only option
 +
 +      if (getIndex(indexName) != null) { 
 +        throw new IndexNameConflictException(LocalizedStrings.
 +            IndexManager_INDEX_NAMED_0_ALREADY_EXISTS.toLocalizedString(indexName)); 
 +      }
 +
 +      IndexCreationHelper helper = null;
 +      boolean isCompactOrHash = false;
 +      if (indexType != IndexType.PRIMARY_KEY) {
 +        helper = new FunctionalIndexCreationHelper(origFromClause,
 +            origIndexedExpression, projectionAttributes, imports, region.getCache(),
 +            externalContext, this);
 +        //Asif: For now support Map index as non compact .expand later
 +        //The limitation for compact range index also apply to hash index for now
 +        isCompactOrHash = shouldCreateCompactIndex((FunctionalIndexCreationHelper)helper);
 +      } else if (indexType == IndexType.PRIMARY_KEY) {
 +        helper = new PrimaryKeyIndexCreationHelper(origFromClause,
 +            origIndexedExpression, projectionAttributes, region.getCache(),
 +            externalContext, this);
 +      } else {
 +        throw new AssertionError("Don't know how to set helper for " + indexType);
 +      }
 +      if (!isCompactOrHash && indexType != IndexType.PRIMARY_KEY) {
 +        
 +        if (indexType == IndexType.HASH ) {
 +          if (!isIndexMaintenanceTypeSynchronous()) {
 +            throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_HASH_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_ASYNC_MAINTENANCE.toLocalizedString());
 +          } 
 +          throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_HASH_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_MULTIPLE_ITERATORS.toLocalizedString());
 +        }
 +        // Overflow is not supported with range index.
 +        if(isOverFlowRegion()) {
 +          throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_REGIONS_WHICH_OVERFLOW_TO_DISK_THE_REGION_INVOLVED_IS_0.toLocalizedString(region.getFullPath()));
 +        }
 +        // OffHeap is not supported with range index.
 +        if(isOffHeap()) {
 +          if (!isIndexMaintenanceTypeSynchronous()) {
 +            throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_OFF_HEAP_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_ASYNC_MAINTENANCE_THE_REGION_IS_0.toLocalizedString(region.getFullPath()));
 +          } 
 +          throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_OFF_HEAP_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_MULTIPLE_ITERATORS_THE_REGION_IS_0.toLocalizedString(region.getFullPath()));
 +        }
 +      }
 +
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Started creating index with indexName: {} On region: {}", indexName, region.getFullPath());
 +      }
 +      
 +      if (IndexManager.testHook != null) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("IndexManager TestHook is set.");
 +        }
 +        
 +        if (((LocalRegion)this.region).isInitialized()) {
 +          testHook.hook(1);
 +        } else {
 +          testHook.hook(0);
 +        }
 +      }
 +
 +      IndexTask indexTask = new IndexTask(indexName, indexType, origFromClause,
 +          origIndexedExpression, helper, isCompactOrHash, prIndex, loadEntries);
 +      FutureTask<Index> indexFutureTask = new FutureTask<Index>(indexTask);
 +      Object oldIndex = this.indexes.putIfAbsent(indexTask, indexFutureTask);
 +
 +      Index index = null;
 +
 +      boolean interrupted = false;
 +      try {
 +        if (oldIndex == null){
 +            // Initialize index.
 +            indexFutureTask.run();
 +            // Set the index.
 +            index = (Index)indexFutureTask.get();
 +        } else {
 +          // Index with same name or characteristic already exists.
 +          // Check if index creation is complete.
 +          if (!(oldIndex instanceof Index)){
 +            // Some other thread is creating the same index.
 +            // Wait for index to be initialized from other thread.
 +            ((FutureTask)oldIndex).get();
 +          }
 +
 +          // The Index is successfully created, throw appropriate error message
 +          // from this thread.
 +          if (getIndex(indexName) != null) {
 +            throw new IndexNameConflictException(LocalizedStrings.
 +                IndexManager_INDEX_NAMED_0_ALREADY_EXISTS.toLocalizedString(indexName));
 +          } else {
 +            throw new IndexExistsException(LocalizedStrings.
 +                IndexManager_SIMILAR_INDEX_EXISTS.toLocalizedString());          
 +          }
 +        }
 +      } catch (InterruptedException ie){
 +        interrupted = true;
 +      } catch (ExecutionException ee){
 +        Throwable c = ee.getCause();
 +        if (c instanceof IndexNameConflictException) {
 +          throw (IndexNameConflictException)c;
 +        } else if (c instanceof IndexExistsException){
 +          throw (IndexExistsException)c;
 +        } else if (c instanceof IMQException) {
 +          throw new IndexInvalidException(c.getMessage());
 +        }
 +        throw new IndexInvalidException(ee);
 +
 +      } finally {
 +        // If the index is not successfully created, remove IndexTask from 
 +        // the map.
 +        if (oldIndex == null && index == null){
 +          Object ind = this.indexes.get(indexTask);
 +          if (ind != null && !(ind instanceof Index)){
 +            this.indexes.remove(indexTask);
 +          }
 +        }
 +        if (interrupted){
 +          Thread.currentThread().interrupt();
 +        }
 +      }
 +      assert (index != null);
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Completed creating index with indexName: {} On region: {}", indexName, region.getFullPath());
 +      }
 +      return index;
 +
 +    } finally {
 +      DefaultQuery.setPdxReadSerialized(this.region.getCache(), oldReadSerialized);
 +      
 +      if (tx != null) {
 +        ((TXManagerImpl) this.region.getCache().getCacheTransactionManager())
 +        .resume(tx);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Return true if we should create CompactRangeIndex
 +   * Required conditions: indexedExpression is a path expression,
 +   * fromClause has only one iterator and it is directly on the
 +   * region values.
 +   * Currently we have to use the "fat" implementation when asynchronous
 +   * index updates are on.
 +   */   
 +  private boolean shouldCreateCompactIndex(FunctionalIndexCreationHelper helper) {
 +    if (RANGEINDEX_ONLY || TEST_RANGEINDEX_ONLY){
 +      return false;
 +    }
 +    
 +    // compact range index is not supported on asynchronous index maintenance.
 +    // since compact range index maintains reference to region entry, in case of
 +    // asynchronous updates the window between cache operation updating the 
 +    // index increases causing query thread to return new value before doing
 +    // index evaluation (resulting in wrong value. There is still a small window
 +    // which can be addressed by the sys property:
 +    // gemfire.index.acquireCompactIndexLocksWithRegionEntryLocks
 +    if (!getRegion().getAttributes().getIndexMaintenanceSynchronous()) {
 +      return false;
 +    } 
 +    
 +    // indexedExpression requirement
 +    CompiledValue cv = helper.getCompiledIndexedExpression();
 +    int nodeType;
 +    do {
 +      nodeType = cv.getType();
 +      if (nodeType == CompiledValue.PATH) {
 +        cv = ((CompiledPath)cv).getReceiver();
 +      }
 +    } while (nodeType == CompiledValue.PATH);
 +    // end of path, nodeType at this point should be an Identifier
 +    if (nodeType != OQLLexerTokenTypes.Identifier && nodeType != OQLLexerTokenTypes.METHOD_INV) {
 +      if (nodeType == OQLLexerTokenTypes.TOK_LBRACK && !helper.isMapTypeIndex() && helper.modifiedIndexExpr instanceof MapIndexable) {
 +        if (((MapIndexable)helper.modifiedIndexExpr).getIndexingKeys().size() == 1) {
 +          
 +        }
 +        else {
 +          return false;
 +        }
 +      }
 +      else {
 +        return false;
 +      }
 +    } 
 +    
 +    // fromClause requirement
 +    List iterators = helper.getIterators();
 +    if (iterators.size() != 1) {
 +      return false;
 +    }
 +    // "missing link" must be "value". Later to support key, entry, etc.
 +    CompiledValue missingLink = helper.missingLink;
 +    if (helper.isFirstIteratorRegionEntry) {
 +      return true;
 +    } else if (!(missingLink instanceof CompiledPath)) {
 +      return false;
 +
 +    }
 +    String tailId = ((CompiledPath)missingLink).getTailID();
 +    if (!(tailId.equals("value") || tailId.equals("key"))) {
 +      return false;
 +    } 
 +    return true;
 +  }
 +
 +  public Index getIndex(String indexName) {
 +    IndexTask indexTask = new IndexTask(indexName);
 +    Object ind = this.indexes.get(indexTask);
 +    // Check if the returned value is instance of Index (this means
 +    // the index is not in create phase, its created successfully).
 +    if (ind instanceof Index){
 +      return (Index)ind;
 +    }
 +    return null;
 +  }
 +
 +  public void addIndex(String indexName, Index index) {
 +    IndexTask indexTask = new IndexTask(indexName);
 +    this.indexes.put(indexTask, index);
 +  }
 +
 +  /**
 +   * Get the Index with the specified indexType, fromClause, indexedExpression
 +   * TODO: Asif :Check if synchronization is needed while obtaining Array of
 +   * Indexes as similar to what we have used during index updates. This function
 +   * will get the exact index , if available, else will return null
 +   * 
 +   * @param indexType the type of index
 +   * @param definitions the String array containing the required defintions of the
 +   *          fromClause of the index
 +   * @param indexedExpression the indexedExpression for the index
 +   * @param context ExecutionContext
 +   * @return the sole index of the region with these parameters, or null if
 +   *         there isn't one
 +   * @throws NameResolutionException 
 +   * @throws TypeMismatchException 
 +   * @throws AmbiguousNameException 
 +   */
 +  public IndexData getIndex(IndexType  indexType, String[] definitions,
 +      CompiledValue indexedExpression, ExecutionContext context) 
 +  throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
 +    IndexData indxData = null;
 +    int qItrSize = definitions.length;
 +    Iterator it = this.indexes.values().iterator();
 +    StringBuffer sb = new StringBuffer();
 +    indexedExpression.generateCanonicalizedExpression(sb, context);
 +    String indexExprStr = sb.toString();
 +    while (it.hasNext()) {
 +      int mapping[] = new int[qItrSize];
 +      Object ind = it.next();
 +      // Check if the returned value is instance of Index (this means
 +      // the index is not in create phase, its created successfully).
 +      if (!(ind instanceof Index)){
 +        continue;
 +      }
 +      Index index = (Index)ind;    
 +      if( !((IndexProtocol)ind).isMatchingWithIndexExpression(indexedExpression,
 +          indexExprStr, context) || index.getType() != indexType) {
 +        continue;
 +      }
 +      
 +      int matchLevel = getMatchLevel(definitions, 
 +          ((IndexProtocol)index).getCanonicalizedIteratorDefinitions(), mapping); 
 +        
 +      if (matchLevel == 0){
 +        indxData = new IndexData((IndexProtocol) index, 0/*Exact Match*/, mapping);
 +        break;
 +      }
 +
 +    }
 +    return indxData;
 +  }
 +
 +  public int compareIndexData(IndexType indexType, String[] indexDefinitions,
 +      String indexExpression, IndexType otherType, String[] otherDefinitions,
 +      String otherExpression, int mapping[]) {
 +
 +    int matchLevel = -2;
 +
 +    if (indexExpression.equals(otherExpression) && indexType == otherType) {
 +      /* Asif : A match level of zero means exact match. */
 +      matchLevel = getMatchLevel(otherDefinitions, indexDefinitions, mapping);
 +    }
 +    return matchLevel;
 +  }
 +  
 +  /**
 +   * Asif : Returns the best available Index based on the available iterators in
 +   * the Group
 +   * 
 +   * TODO: Asif :Check if synchronization is needed while obtaining Array of
 +   * Indexes as similar to what we have used during index updates
 +   * 
 +   * @param indexType Primary or Range Index
 +   * @param definitions String array containing the canonicalized definitions of
 +   *          the Iterators of the Group
 +   * @param indexedExpression Index Expression path(CompiledValue) on which
 +   *          index needs to be created
 +   * @param context ExecutionContext object
 +   * @return IndexData object
 +   * @throws NameResolutionException 
 +   * @throws TypeMismatchException 
 +   * @throws AmbiguousNameException 
 +   */
 +  public IndexData getBestMatchIndex(IndexType indexType, String[] definitions,
 +      CompiledValue indexedExpression, ExecutionContext context) 
 +  throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
 +
 +    Index bestIndex = null;
 +    Index bestPRIndex = null;
 +    int[] bestMapping = null;
 +
 +    int qItrSize = definitions.length;
 +    int bestIndexMatchLevel = qItrSize;
 +    Iterator iter = this.indexes.values().iterator();
 +    StringBuffer sb = new StringBuffer();
 +    indexedExpression.generateCanonicalizedExpression(sb, context);
 +    String indexExprStr = sb.toString();
 +    PartitionedIndex prIndex = null;
 +    Index prevBestPRIndex = null;
 +    Index prevBestIndex = null;
 +
 +    Index index;
 +    while (iter.hasNext()) {
 +      Object ind = iter.next();
 +      // Check if the value is instance of FutureTask, this means
 +      // the index is in create phase.
 +      if (ind instanceof FutureTask){
 +        continue;
 +      }
 +      
 +      //If the index is still empty
 +      if(!((AbstractIndex)ind).isPopulated()) {
 +        continue;
 +      }
 +
 +      index = (Index)ind;    
 +      
 +      if (index instanceof PartitionedIndex) {
 +        prIndex = (PartitionedIndex)index;
 +        // Get one of the bucket index. This index will be
 +        // available on all the buckets.
 +        index = prIndex.getBucketIndex();
 +        if (index == null) {
 +          continue;
 +        }
 +      }
 +      
 +      //System.out.println(" Index = "+index);
 +      //Use simple strategy just pick first compatible index
 +      if ( ((IndexProtocol)index).isMatchingWithIndexExpression(indexedExpression,indexExprStr,
 +          context) && index.getType() == indexType ){
 +  
 +        // For PR the matched index needs to be available on all the query buckets.
 +        if (prIndex != null) {
 +          try {
 +
 +            // Protect the PartitionedIndex from being removed when it is being used.
 +            if (!prIndex.acquireIndexReadLockForRemove()) {
 +              continue;
 +            }
 +
 +            prIndex.verifyAndCreateMissingIndex(context.getBucketList());
 +          } catch (Exception ex) {
 +            // Index is not there on all buckets. 
 +            // ignore this index.
 +            prIndex.releaseIndexReadLockForRemove();
 +            prIndex = null;
 +            continue;
 +          }
 +        } else {
 +          // For index on replicated regions
 +          if (!((AbstractIndex)index).acquireIndexReadLockForRemove()) {
 +            continue;
 +          }
 +        }
 +        
 +        /*
 +         * Asif : A match level of zero means exact match. A match level greater
 +         * than 0 means the query from clauses have extra iterators as compared
 +         * to Index resultset ( This does not neccessarily mean that Index
 +         * resultset is not having extra fields. It is just that the criteria
 +         * for match level is the absence or presence of extra iterators. The
 +         * order of preference will be 0 , <0 , > 0 for first cut.
 +         */
 +        String indexDefinitions[] = ((IndexProtocol) index).getCanonicalizedIteratorDefinitions();
 +        
 +        int mapping[] = new int[qItrSize];
 +        int matchLevel = getMatchLevel(definitions, indexDefinitions, mapping);
 +        
 +        if (matchLevel == 0) {
 +          prevBestPRIndex = bestPRIndex;
 +          bestPRIndex = prIndex;
 +          prevBestIndex = bestIndex;
 +          bestIndex = index;
 +          bestIndexMatchLevel = matchLevel;
 +          bestMapping = mapping;
 +
 +          // If we chose new index we should release lock on previous index
 +          // chosen as bestIndex.
 +         if (prIndex != null && prevBestPRIndex != null && prevBestPRIndex instanceof PartitionedIndex) {
 +            ((PartitionedIndex) prevBestPRIndex).releaseIndexReadLockForRemove();
 +            prevBestPRIndex = null;
 +          } else if (prevBestIndex != null) {
 +            ((AbstractIndex) prevBestIndex).releaseIndexReadLockForRemove();
 +            prevBestIndex = null;
 +          } 
 +          break;
 +        } else if ((bestIndexMatchLevel > 0 && matchLevel < bestIndexMatchLevel)
 +            || (bestIndexMatchLevel < 0 && matchLevel < 0 && matchLevel > bestIndexMatchLevel)) {
 +          prevBestPRIndex = bestPRIndex;
 +          bestPRIndex = prIndex;
 +          prevBestIndex = bestIndex;
 +          bestIndex = index;
 +          bestIndexMatchLevel = matchLevel;
 +          bestMapping = mapping;
 +        }
 +
 +        // release the lock if this index is not chosen as bestIndex.
 +        if (prIndex != null && bestPRIndex != prIndex) {
 +          prIndex.releaseIndexReadLockForRemove();
 +          prIndex = null;
 +        } else if(bestIndex != index) {
 +          ((AbstractIndex)index).releaseIndexReadLockForRemove();
 +          index = null;
 +        }
 +
 +        // If we chose new index we should release lock on previous  index
 +        // chosen as bestIndex.
 +        if (prevBestPRIndex != null && prevBestPRIndex instanceof PartitionedIndex) {
 +          ((PartitionedIndex) prevBestPRIndex).releaseIndexReadLockForRemove();
 +          prevBestPRIndex = null;
 +        } else if (prevBestIndex != null) {
 +          ((AbstractIndex) prevBestIndex).releaseIndexReadLockForRemove();
 +          prevBestIndex = null;
 +        }
 +      }
 +    }
 +    if (bestIndex != null) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("The best index found for index expression: {} is: {} with Match-level: {} and mapping: {}", indexExprStr, bestIndex, bestIndexMatchLevel, Arrays.toString(bestMapping));
 +      }
 +    }
 +    return bestIndex != null ? new IndexData((IndexProtocol) bestIndex,
 +        bestIndexMatchLevel, bestMapping) : null;
 +  }
 +
 +  /*
 +   * Asif : This function returns the best match index. The crietria used to
 +   * identify best match index is based currently , relative to the query from
 +   * clause. If the iterators of query from clause exactly match the index from
 +   * clause , then match level is zero & is the best match. If the query from
 +   * clause contain extra iterators , not available in index from clause, then
 +   * mach level is > 0 & is not the best. If the match level is < 0 that means
 +   * Index from clause have some extra iterators as compared to query. The int
 +   * array gives the mapping of query iterator's position relative to the index
 +   * resultset fields . The position is '1' based index. That is for the first
 +   * query iterator ( 0 position), the mapping will contain 1 which can be
 +   * thought of as Index ResultSet value at the field with name index_iter1. If
 +   * the second query iterator has a value 3 , that means for (1 position)
 +   * iterator , the field will have name index_iter3
 +   */
 +  private static int getMatchLevel(String[] queryDefintions,
 +      String[] indexDefinitions, int[] mapping) {
 +    int qItrLen = queryDefintions.length;
 +    int indxItrLen = indexDefinitions.length;
 +    // Asif : We know that because index expressions have matched that
 +    // itself indicates that the first iterator, which is regon iterator
 +    // has matched. So the index field position of the first RuntimeIterator
 +    // of the Query group is 1
 +    mapping[0] = 1;
 +    int matchLevel = qItrLen - 1;
 +    for (int i = 1; i < qItrLen; ++i) {
 +      for (int j = 1; j < indxItrLen; ++j) {
 +        if (queryDefintions[i].equals(indexDefinitions[j])) {
 +          mapping[i] = ++j;
 +          --matchLevel;
 +          break;
 +        }
 +      }
 +    }
 +    if (matchLevel == 0 && indxItrLen > qItrLen) {
 +      matchLevel = qItrLen - indxItrLen;
 +    }
 +    return matchLevel;
 +  }
 +
 +  /*
 +   * private static int getMatchLevel(String fromClause, String iFromClause) {
 +   * if (fromClause.equals(iFromClause)) return 0; if
 +   * (fromClause.startsWith(iFromClause)) { int cnt = -1; int index =
 +   * fromClause.indexOf(',', iFromClause.length() + 1); while (index > 0) {
 +   * cnt--; index = fromClause.indexOf(',', index + 1); } return cnt; } else if
 +   * (iFromClause.startsWith(fromClause)) { int cnt = 1; int index =
 +   * iFromClause.indexOf(',', fromClause.length() + 1); while (index > 0) {
 +   * cnt++; index = iFromClause.indexOf(',', index + 1); } return cnt; } //No
 +   * compatible return Integer.MAX_VALUE; }
 +   */
 +  /**
 +   * Get a collection of all the indexes. If the IndexType is specified
 +   * returns only the matching indexes.   
 +   * @param indexType the type of indexes to get. Currently must be
 +   *          Indexable.FUNCTIONAL_SORTED
 +   * @return the collection of indexes for the specified region and type
 +   */
 +  public Collection getIndexes(IndexType indexType) {
 +    ArrayList list = new ArrayList();
 +    Iterator it = this.indexes.values().iterator();
 +    while (it.hasNext()) {
 +      Object ind = it.next();
 +      // Check if the value is instance of FutureTask, this means
 +      // the index is in create phase.
 +      if (ind instanceof FutureTask){
 +        continue;
 +      }
 +      Index index = (Index)ind;
 +
 +      // Check if indexType needs to be matched.
 +      if (indexType == null) { // No type check.
 +        list.add(index);
 +      } else if(index.getType() == indexType) {
 +        list.add(index);
 +      }
 +    }
 +    return list;
 +  }  
 +  
 +  /**
 +   * Get a collection of all the indexes managed by IndexManager
 +   * 
 +   * @return the collection of indexes on the specified region
 +   */
 +  public Collection getIndexes() {
 +    return getIndexes(null);
 +  }
 +
 +  // @todo need more specific list of exceptions
 +  /**
 +   * Remove the specified index.
 +   * 
 +   * @param index the Index to remove
 +   */
 +  public void removeIndex(Index index) {
 +    if (index.getRegion() != this.region) 
 +    { 
 +      throw new IllegalArgumentException(LocalizedStrings.
 +          IndexManager_INDEX_DOES_NOT_BELONG_TO_THIS_INDEXMANAGER.toLocalizedString()); 
 +    }
 +    //Asif: We will just remove the Index from the map. Since the
 +    // TreeMap is synchronized & the operation of adding a newly created
 +    // index is in synch there will not be any situation where the unintended
 +    // Index gets removed( in case of same Index Name scenario).
 +    // If query obtains the Index handle which is getting removed , that
 +    // is OK as we are not clearing data maps . The destroy though marks
 +    // the index invalid , that is OK. Because of this flag a query
 +    // may or may not use the Index
 +    IndexTask indexTask = new IndexTask(index.getName());
 +    if (this.indexes.remove(indexTask) != null) {
 +      AbstractIndex indexHandle = (AbstractIndex) index;
 +      indexHandle.destroy();
 +    }
 +  }
 +
 +  // @todo need more specific list of exceptions
 +  /**
 +   * Remove all the indexes managed by IndexManager
 +   */
 +  public int removeIndexes() {
 +    // Remove indexes which are available (create completed).
 +    int numIndexes = 0;
 +    Iterator it = this.indexes.entrySet().iterator();
 +    while (it.hasNext()) {
 +      Map.Entry entry = (Map.Entry)it.next();
 +      Object ind = entry.getValue();
 +      // Check if the returned value is instance of Index (this means
 +      // the index is not in create phase, its created successfully).
 +      if (!(ind instanceof Index)){
 +        continue;
 +      }
 +      numIndexes++;
 +      IndexTask indexTask = (IndexTask)entry.getKey();
 +      this.indexes.remove(indexTask);
 +    }
 +    return numIndexes;
 +  }
 +  
 +
 +  /**
 +   * Asif : This function is invoked during clear operation on Region. It causes
 +   * re execution of Index Initialization query on the region & before doing
 +   * this it makes theexisting data maps null. This is needed so that index does
 +   * not miss any entry being put in the region when the Region.clear is in
 +   * progress
 +   * 
 +   * @throws QueryException
 +   */
 +  public void rerunIndexCreationQuery() throws QueryException {
 +    try {
 +      QueryObserver observer = QueryObserverHolder.getInstance();
 +      observer.beforeRerunningIndexCreationQuery();
 +    }
 +    catch (Exception e) {
 +      //Asif Ignore any exception as this should not hamper normal code flow
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("IndexMananger::rerunIndexCreationQuery: Exception in callback beforeRerunningIndexcreationQuery", e);
 +      }
 +    }
 +    if (isIndexMaintenanceTypeSynchronous()) {
 +      recreateAllIndexesForRegion();
 +    }
 +    else {
 +      //System.out.println("Aynchronous update");
 +      updater.addTask(RECREATE_INDEX, null, IndexProtocol.OTHER_OP);
 +    }
 +  }
 +
 +  /**
 +   * populates all the indexes in the region
 +   */
 +  public void populateIndexes(Collection<Index> indexSet) throws MultiIndexCreationException {
 +    waitBeforeUpdate();
 +    if(region.getCache().getLogger().infoEnabled()) {
 +      region.getCache().getLogger().info("Populating indexes for region " + region.getName());
 +    }
 +    boolean throwException = false;
 +    HashMap<String, Exception> exceptionsMap = new HashMap<String, Exception>();
 +    try {
 +      Iterator entryIter = ((LocalRegion) region).getBestIterator(true);
 +      while (entryIter.hasNext()) {
 +        RegionEntry entry = (RegionEntry) entryIter.next();
 +        if (entry == null || entry.isInvalidOrRemoved()) {
 +          continue;
 +        }
 +        // Fault in the value once before index update so that every index
 +        // update does not have
 +        // to read the value from disk every time.
 +        // TODO OFFHEAP: this optimization (calling getValue to make sure it is faulted in to disk) has a performance problem.
 +        // It also decompresses and deserializes the value and then throws that away. In the case of a heap region the deserialized
 +        // value would be cached in a VMCachedDeserializable. But for compression and/or off-heap the decompression and/or deserialization
 +        // this call does is lost and has to be done again. We could just add a method to RegionEntry that faults the value in without returning it.
 +        // Even better (but more work): could we create a wrapper around RegionEntry that we create here to wrap "entry" and pass the wrapper to addIndexMapping?
 +        // Any indexes that store a reference to the RegionEntry would need to ask the wrapper for the real one but any of them
 +        // that want the value could get it from the wrapper. The first time the wrapper is asked for the value it could get it from
 +        // the real RegionEntry it wraps and cache a reference to that value. I think that gives us the best of both worlds.
 +        entry.getValue((LocalRegion)this.region);
 +        Iterator<Index> indexSetIterator = indexSet.iterator();
 +        while(indexSetIterator.hasNext()) {
 +          AbstractIndex index = (AbstractIndex) indexSetIterator.next();
 +          if (!index.isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Adding to index :{}{} value :{}", index.getName(), this.region.getFullPath(), entry.getKey());
 +            }
 +            long start = ((AbstractIndex) index).updateIndexUpdateStats();
 +            try {
 +              index.addIndexMapping(entry);
 +            } catch (IMQException e) {
 +              if(logger.isDebugEnabled()) {
 +                logger.debug("Adding to index failed for: {}, {}", index.getName(), e.getMessage(), e);
 +              }
 +              exceptionsMap.put(index.indexName, e);
 +              indexSetIterator.remove();
 +              throwException = true;
 +            }
 +            ((AbstractIndex) index).updateIndexUpdateStats(start);
 +          }
 +        }
 +      }
 +      setPopulateFlagForIndexes(indexSet);
 +      if (throwException) {
 +        throw new MultiIndexCreationException(exceptionsMap);
 +      }
 +    } finally {
 +      notifyAfterUpdate();
 +    }
 +  }
 +  
 +  /**
 +   * Sets the {@link AbstractIndex#isPopulated} after 
 +   * populating all the indexes in this region
 +   */
 +  public void setPopulateFlagForIndexes(Collection<Index> indexSet) {
 +    for (Object ind : indexSet) {
 +      AbstractIndex index = (AbstractIndex) ind;
-       if (!index.isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
++      if (!index.isPopulated()) {
 +        index.setPopulated(true);
 +      }
 +    }
 +  }
 +  
 +  public void updateIndexes(RegionEntry entry, int action, int opCode) throws QueryException {
 +    updateIndexes(entry, action, opCode, false);
 +  }
 +
 +  // @todo need more specific list of exceptions
 +  /**
 +   * Callback for IndexManager to update indexes Called from AbstractRegionMap.
 +   * 
 +   * @param entry the RegionEntry being updated
 +   * @param action action to be taken (IndexManager.ADD_ENTRY,
 +   *          IndexManager.UPDATE_ENTRY, IndexManager.REMOVE_ENTRY)
 +   * @param opCode one of IndexProtocol.OTHER_OP, BEFORE_UPDATE_OP, AFTER_UPDATE_OP.
 +   * @throws com.gemstone.gemfire.cache.query.IndexMaintenanceException
 +   */
 +  public void updateIndexes(RegionEntry entry, int action, int opCode, boolean isDiskRecoveryInProgress)
 +      throws QueryException {
 +    if(isDiskRecoveryInProgress) {
 +      assert !((LocalRegion)this.region).isInitialized();
 +    } else {
 +      assert Assert.assertHoldsLock(entry,true);  
 +    }
 +    if(logger.isDebugEnabled()) {
 +      logger.debug("IndexManager.updateIndexes {} + action: {}", entry.getKey(), action);
 +    }
 +    if (entry == null) return;
 +    if (isIndexMaintenanceTypeSynchronous()) {
 +      //System.out.println("Synchronous update");
 +      processAction(entry, action, opCode);
 +    }
 +    else {
 +      //System.out.println("Aynchronous update");
 +      updater.addTask(action, entry, opCode);
 +    }
 +  }
 +
 +  /**
 +   * @param opCode one of IndexProtocol.OTHER_OP, BEFORE_UPDATE_OP, AFTER_UPDATE_OP.
 +   */
 +  private void processAction(RegionEntry entry, int action, int opCode)
 +      throws QueryException {
 +    final long startPA = getCachePerfStats().startIndexUpdate();
 +    DefaultQuery.setPdxReadSerialized(this.region.getCache(), true);
 +    TXStateProxy tx = null;
 +    if (!((GemFireCacheImpl)this.region.getCache()).isClient()) {
 +      tx = ((TXManagerImpl) this.region.getCache().getCacheTransactionManager()).internalSuspend();
 +    }
 +
 +    try {
 +      //Asif: Allow the thread to update iff there is no current index
 +      //creator thread in progress. There will not be any issue if
 +      // allow the updater thread to proceed if there is any index
 +      //creator thread in waiting , but that can cause starvation
 +      //for index creator thread. So we will give priorityto index
 +      //creation thread
 +      if (IndexManager.testHook != null) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("IndexManager TestHook is set.");
 +        }
 +        testHook.hook(6); //ConcurrentIndexInitOnOverflowRegionDUnitTest
 +      }
 +      
 +      long start = 0;
 +      boolean indexLockAcquired = false;
 +      switch (action) {
 +        case ADD_ENTRY: {
 +          if (IndexManager.testHook != null) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("IndexManager TestHook in ADD_ENTRY.");
 +            }
 +            testHook.hook(5);
 +          }
 +          // this action is only called after update
 +          assert opCode == IndexProtocol.OTHER_OP;
 +          
 +          //Asif The behaviour can arise if an index creation has already
 +          // acted upon a newly added entry , but by the time callback
 +          // occurs , the index is added to the map & thus
 +          // the add operation will now have an effect of update.
 +          // so we need to remove the mapping even if it is an Add action
 +          // as otherwise the new results will get added into the
 +          // old results instead of replacement
 +          Iterator iter = this.indexes.values().iterator();
 +          while (iter.hasNext()) {
 +            Object ind = iter.next();
 +            // Check if the value is instance of FutureTask, this means
 +            // the index is in create phase.
 +            if (ind instanceof FutureTask){
 +              continue;
 +            }
 +            IndexProtocol index = (IndexProtocol)ind;            
 +            
 +            if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
 +              // Asif : If the current Index contains an entry inspite
 +              // of add operation , this can only mean that Index
 +              // has already acted on it during creation, so do not
 +              // apply IMQ on it
 +              if (!index.containsEntry(entry)) {
 +                if (logger.isDebugEnabled()) {
 +                  logger.debug("Adding to index: {}{} value: {}", index.getName(), this.region.getFullPath(), entry.getKey());
 +                }
 +                start = ((AbstractIndex) index).updateIndexUpdateStats();
 +
 +                index.addIndexMapping(entry);
 +
 +                ((AbstractIndex) index).updateIndexUpdateStats(start);
 +              }
 +            }
 +          }
 +          break;
 +        }
 +        case UPDATE_ENTRY: {
 +
 +          if (IndexManager.testHook != null) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("IndexManager TestHook in UPDATE_ENTRY.");
 +            }
 +            testHook.hook(5);
 +            testHook.hook(9); //QueryDataInconsistencyDUnitTest
 +          }
 +
 +          // this action is only called with opCode AFTER_UPDATE_OP
 +          assert opCode == IndexProtocol.AFTER_UPDATE_OP;
 +          Iterator iter = this.indexes.values().iterator();
 +          while (iter.hasNext()) {
 +            Object ind = iter.next();
 +            // Check if the value is instance of FutureTask, this means
 +            // the index is in create phase.
 +            if (ind instanceof FutureTask){
 +              continue;
 +            }
 +            IndexProtocol index = (IndexProtocol)ind;
 +            
 +            if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
 +                if (logger.isDebugEnabled()) {
 +                  logger.debug("Updating index: {}{} value: ", index.getName(), this.region.getFullPath(), entry.getKey());
 +                }
 +                start = ((AbstractIndex) index).updateIndexUpdateStats();
 +
 +                index.addIndexMapping(entry);
 +
 +                ((AbstractIndex) index).updateIndexUpdateStats(start);
 +            }
 +          }
 +          break;
 +        }
 +        case REMOVE_ENTRY: {
 +          
 +          if (IndexManager.testHook != null) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("IndexManager TestHook in REMOVE_ENTRY.");
 +            }
 +            testHook.hook(5);
 +            testHook.hook(10);
 +          }
 +          Iterator iter = this.indexes.values().iterator();
 +          while (iter.hasNext()) {
 +            Object ind = iter.next();
 +            // Check if the value is instance of FutureTask, this means
 +            // the index is in create phase.
 +            if (ind instanceof FutureTask) {
 +              continue;
 +            }
 +            IndexProtocol index = (IndexProtocol) ind;
 +  
 +            if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
 +              AbstractIndex abstractIndex = (AbstractIndex) index;
 +              if (logger.isDebugEnabled()) {
 +                logger.debug("Removing from index: {}{} value: {}", index.getName(), this.region.getFullPath(), entry.getKey());
 +              }
 +              start = ((AbstractIndex) index).updateIndexUpdateStats();
 +              
 +              index.removeIndexMapping(entry, opCode);
 +
 +              ((AbstractIndex) index).updateIndexUpdateStats(start);
 +            }
 +          }
 +          break;
 +        }
 +        default: {
 +          throw new IndexMaintenanceException(LocalizedStrings.IndexManager_INVALID_ACTION.toLocalizedString());
 +        }
 +      }
 +    }
 +    finally {
 +      DefaultQuery.setPdxReadSerialized(this.region.getCache(), false);
 +      if (tx != null) {
 +        ((TXManagerImpl) this.region.getCache().getCacheTransactionManager())
 +          .resume(tx);
 +      }
 +      getCachePerfStats().endIndexUpdate(startPA);
 +    }
 +  }
 +
 +  private void waitBeforeUpdate() {
 +    synchronized (indexes) {
 +      ++numCreators;
 +      // Asif : If there exists any updater thread in progress
 +      // we should not allow index creation to proceed.
 +      while (numUpdatersInProgress > 0) {
 +        ((LocalRegion) getRegion()).getCancelCriterion()
 +            .checkCancelInProgress(null);
 +        boolean interrupted = Thread.interrupted();
 +        try {
 +          indexes.wait();
 +        } catch (InterruptedException ie) {
 +          interrupted = true;
 +        } finally {
 +          if (interrupted) {
 +            Thread.currentThread().interrupt();
 +          }
 +        }
 +      } // while
 +    }
 +  }
 +  
 +  private void notifyAfterUpdate() {
 +    synchronized (indexes) {
 +      --numCreators;
 +      // ASIF: If the creator is in progress , this itself
 +      // means that there is no Update active. The updater threads
 +      // are either in wait state or there are no threads at all.
 +      // Since we do not want any update to progress , if there is
 +      // any creator thread in lock seeking mode ( meaning that it has
 +      // entered the previous synch block) . We will not issue
 +      // any notify till the creator count drops to zero &
 +      // also unless there is any updater thread in waiting
 +      if (numCreators == 0 && numUpdatersInWaiting > 0) {
 +        indexes.notifyAll();
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Recreates all indexes for this region. This operation blocks all updates
 +   * on all indexes while recreate is in progress. This is required as recreate
 +   * does NOT lock region entries before index update and hence might cause
 +   * inconsistencies in index if concurrent region entry operations are
 +   * going on.
 +   *  
 +   */
 +  private void recreateAllIndexesForRegion() {
 +
 +    long start = 0;
 +    waitBeforeUpdate();
 +    try {
 +      // opCode is ignored for this operation
 +      Iterator iter = this.indexes.values().iterator();
 +      while (iter.hasNext()) {
 +        Object ind = iter.next();
 +        // Check if the value is instance of FutureTask, this means
 +        // the index is in create phase.
 +        if (ind instanceof FutureTask) {
 +          continue;
 +        }
 +        IndexProtocol index = (IndexProtocol) ind;
 +        if (index.getType() == IndexType.FUNCTIONAL || index.getType() == IndexType.HASH) {
 +          AbstractIndex aIndex = ((AbstractIndex) index);
 +          start = ((AbstractIndex) index).updateIndexUpdateStats();
 +          ((AbstractIndex) index).recreateIndexData();
 +          ((AbstractIndex) index).updateIndexUpdateStats(start);
 +
 +        }
 +      }
 +    } catch (Exception e) {
 +      throw new IndexInvalidException(e);
 +    } finally {
 +      notifyAfterUpdate();
 +    }
 +  }
 +
 +  /**
 +   * Wait for index initialization before entry create, update, invalidate or destroy
 +   * operation.
 +   * 
 +   * Note: If the region has a disk region then we should wait for index
 +   * initialization before getting region entry lock to avoid deadlock (#44431).
 +   */
 +  public void waitForIndexInit() {
 +    synchronized (this.indexes) {
 +      ++this.numUpdatersInWaiting;
 +      while (this.numCreators > 0) {
 +        ((LocalRegion)this.getRegion()).getCancelCriterion().checkCancelInProgress(null);
 +        boolean interrupted = Thread.interrupted();
 +        try {
 +          this.indexes.wait();
 +        }
 +        catch (InterruptedException ie) {
 +          interrupted = true;
 +        }
 +        finally {
 +          if (interrupted) {
 +            Thread.currentThread().interrupt();
 +          }
 +        }
 +      } // while
 +      --this.numUpdatersInWaiting;
 +      ++this.numUpdatersInProgress;
 +    }
 +  }
 +
 +  /**
 +   * Necessary finally block call for above method.
 +   */
 +  public void countDownIndexUpdaters() {
 +    synchronized (this.indexes) {
 +       --this.numUpdatersInProgress;
 +      //Asif: Since Index creator threads can progress only if
 +      // there is no update threads in progress, thus we need to issue
 +      // notify all iff there are any creator threads in action & also
 +      // if the upDateInProgress Count has dipped to 0
 +      if (this.numUpdatersInProgress == 0 && this.numCreators > 0) {
 +        this.indexes.notifyAll();
 +      }
 +    }
 +  }
 +
 +  private CachePerfStats getCachePerfStats() {
 +    return ((LocalRegion)this.region).getCachePerfStats();
 +  }
 +  /**
 +   * Callback for destroying IndexManager Called after Region.destroy() called
 +   */
 +  public void destroy() throws QueryException {
 +    this.indexes.clear();
 +    if (!isIndexMaintenanceTypeSynchronous()) updater.shutdown();
 +  }
 +  
 +  /**
 +   * Removes indexes for a destroyed bucket region from the list of bucket indexes 
 +   * in the {@link PartitionedIndex}.
 +   * @param prRegion the partition region that this bucket belongs to
 +   * @throws QueryException
 +   */
 +  public void removeBucketIndexes(PartitionedRegion prRegion) throws QueryException {
 +    IndexManager parentManager = prRegion.getIndexManager();
 +    if (parentManager != null) {
 +      Iterator bucketIndexIterator = indexes.values().iterator();
 +      while (bucketIndexIterator.hasNext()) {
 +        Index bucketIndex = (Index)bucketIndexIterator.next();
 +        Index prIndex = parentManager.getIndex(bucketIndex.getName());
 +        if (prIndex instanceof PartitionedIndex) {
 +          ((PartitionedIndex)prIndex).removeFromBucketIndexes(this.region, bucketIndex);
 +        }
 +      }
 +    }
 +  }
 +
 +  @Override
 +  public String toString() {
 +    StringBuffer sb = new StringBuffer();
 +    Iterator iter = this.indexes.values().iterator();
 +    while (iter.hasNext()) {
 +      Object ind = iter.next();
 +      // Check if the value is instance of FutureTask, this means
 +      // the index is in create phase.
 +      if (ind instanceof FutureTask){
 +        continue;
 +      }
 +      sb.append(((Index)ind).toString()).append('\n');    
 +    }
 +    return sb.toString();
 +  }
 +
 +  public boolean isIndexMaintenanceTypeSynchronous() {
 +    return this.indexMaintenanceSynchronous;
 +  }
 +
 +  public boolean isOverFlowRegion() {
 +    return this.isOverFlowToDisk;
 +  }
 +  public boolean isOffHeap() {
 +    return this.offHeap;
 +  }
 +
 +  public static boolean isObjectModificationInplace() {
 +    return (INPLACE_OBJECT_MODIFICATION || INPLACE_OBJECT_MODIFICATION_FOR_TEST);
 +  }
 +  /**
 +   * Asif : This function is used exclusively by Index Manager. It gets the
 +   * unique Iterator name for a Iterator definition, if it already exists, else
 +   * creates a unqiue name & also stores it in a map for subsequent use
 +   * 
 +   * @param definition String containing definition of the iterator
 +   * @return String containing the name of the Iterator
 +   */
 +  public String putCanonicalizedIteratorNameIfAbsent(String definition) {
 +    String str = null;
 +    synchronized(canonicalizedIteratorNameMap) {
 +      if ((str = (String) this.canonicalizedIteratorNameMap.get(definition)) == null) {
 +        str = new StringBuffer("index_iter").append(this.getIncrementedCounter())
 +            .toString();
 +        String temp;
 +        if ((temp = (String) this.canonicalizedIteratorNameMap.putIfAbsent(
 +            definition, str)) != null) {
 +          str = temp;
 +        }
 +      }
 +    }
 +    return str;
 +  }
 +
 +  public void putCanonicalizedIteratorName(String definition, String name) {
 +    synchronized(canonicalizedIteratorNameMap) {
 +      this.canonicalizedIteratorNameMap.put(definition, name);
 +    }
 +  }
 +  
 +  private synchronized int getIncrementedCounter() {
 +    return ++this.iternameCounter;
 +  }
 +
 +  /**
 +   * Asif : Given a definition returns the canonicalized iterator name for the
 +   * definition. If the definition does not exist , null is returned
 +   * 
 +   * @param definition
 +   * @return String
 +   */
 +  public String getCanonicalizedIteratorName(String definition) {
 +    return ((String) (this.canonicalizedIteratorNameMap.get(definition)));
 +  }
 +
 +  ////////////////////// Inner Classes //////////////////////
 + 
 +  public class IndexUpdaterThread extends Thread  {
 +
 +    private volatile boolean running = true;
 +
 +    private volatile boolean shutdownRequested = false;
 +
 +    private volatile BlockingQueue pendingTasks;
 +
 +    /**
 +     * Creates instance of IndexUpdaterThread
 +     * @param updateThreshold
 +     * @param threadName
 +     */
 +    IndexUpdaterThread(ThreadGroup group, int updateThreshold, String threadName) {
 +      super(group, threadName);
 +      // Check if threshold is set.
 +      if (updateThreshold > 0){
 +        // Create a bounded queue.
 +        pendingTasks = new ArrayBlockingQueue(updateThreshold);
 +      } else {
 +        // Create non-bounded queue.
 +        pendingTasks = new LinkedBlockingQueue();
 +      }
 +      this.setDaemon(true);
 +    }
 +
 +    public void addTask(int action, RegionEntry entry, int opCode) {
 +      Object[] task = new Object[3];
 +      task[0] = Integer.valueOf(action);
 +      task[1] = entry;
 +      task[2] = Integer.valueOf(opCode);  // !!!:ezoerner:20081029 change to valueOf jdk 1.5+
 +      pendingTasks.add(task);
 +    }
 +
 +    /**
 +     * Stops this thread. Does not return until it has stopped.
 +     */
 +    public void shutdown() {
 +      if (!this.running) {
 +        return;
 +      }
 +      this.shutdownRequested = true;
 +      this.interrupt();
 +      try {
 +        this.join();
 +      } catch (InterruptedException ignore) {
 +        Thread.currentThread().interrupt();
 +        // just return, we're done
 +      }
 +    }
 +
 +    @Override
 +    public void run() {
 +      // async writers main loop
 +      // logger.debug("DiskRegion writer started (writer=" + this + ")");
 +      com.gemstone.gemfire.CancelCriterion stopper = ((LocalRegion)region).getCancelCriterion();
 +      try {
 +        while (!this.shutdownRequested) {
 +          // Termination checks
 +          SystemFailure.checkFailure();
 +          if (stopper.cancelInProgress() != null) {
 +            break;
 +          }
 +          try {
 +            Object[] task = (Object[])pendingTasks.take();
 +            if (this.shutdownRequested) {
 +              break;
 +            }
 +            updateIndexes(task);
 +          }
 +          catch (InterruptedException ignore) {
 +            return; // give up (exit the thread)
 +          }
 +        }
 +      }
 +      finally {
 +        this.running = false;
 +      }
 +    }
 +
 +    private void updateIndexes(Object[] task) {
 +      int action = ((Integer)task[0]).intValue();
 +      RegionEntry entry = (RegionEntry)task[1];
 +      int opCode = ((Integer)task[2]).intValue();
 +      //System.out.println("entry = "+entry.getKey());
 +      if (entry != null || action == RECREATE_INDEX) {
 +        try {
 +          if (action == RECREATE_INDEX) {
 +            recreateAllIndexesForRegion();
 +          } else {
 +            if (entry != null) {
 +              entry.setUpdateInProgress(true);
 +            }
 +            processAction(entry, action, opCode);
 +          }
 +        }
 +        catch (Exception e) {
 +          e.printStackTrace();
 +        } finally {
 +          if (entry != null && action != RECREATE_INDEX) {
 +            entry.setUpdateInProgress(false);
 +          }
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Used by tests to determine if the updater thread has finished updating
 +     * its indexes. The list is cleared without synchronization, which makes
 +     * this methods somewhat unsafe from a threading point of view.
 +     */
 +    public synchronized boolean isDone() {
 +      return this.pendingTasks.size() == 0;
 +    }
 +
 +  }
 +  
 +  /**
 +   * Index Task used to create the index. This is used along with the
 +   * FutureTask to take care of, same index creation request from multiple
 +   * threads. At any time only one thread succeeds and other threads waits
 +   * for the completion of the index creation. This avoids usage of
 +   * synchronization which could block any index creation.
 +   */
 +  public class IndexTask implements Callable<Index> {
 +
 +    public String indexName;
 +
 +    public IndexType indexType;
 +
 +    public IndexCreationHelper helper;
 +
 +    public String origFromClause;
 +
 +    public String  origIndexedExpression;
 +
 +    public boolean isCompactOrHash = false;
 +    
 +    public boolean isLDM = false;
 +    
 +    public PartitionedIndex prIndex;
 +    
 +    public boolean loadEntries;
 +    
 +    IndexTask (String indexName, IndexType type, String origFromClause, String origIndexedExpression, IndexCreationHelper helper, boolean isCompactOrHash, PartitionedIndex prIndex, boolean loadEntries){
 +      this.indexName = indexName;
 +      this.indexType = type;
 +      this.origFromClause = origFromClause;
 +      this.origIndexedExpression = origIndexedExpression;
 +      this.helper = helper;
 +      this.isCompactOrHash = isCompactOrHash;
 +      this.prIndex = prIndex;
 +      this.loadEntries = loadEntries;
 +    }
 +
 +    /* For name based index search */
 +    IndexTask (String indexName){
 +      this.indexName = indexName;
 +    }
 +
 +    @Override
 +    public boolean equals (Object other){
 +      if (other == null) {
 +        return false;
 +      }
 +      IndexTask otherIndexTask = (IndexTask) other;
 +      // compare indexName.
 +      if (this.indexName.equals(otherIndexTask.indexName)){
 +        return true;
 +      }
 +
 +      if (otherIndexTask.helper == null || this.helper == null) {
 +        return false;
 +      }
 +
 +      String[] indexDefinitions = this.helper.getCanonicalizedIteratorDefinitions();
 +      int[] mapping = new int[indexDefinitions.length];
 +      // compare index based on its type, expression and definition.
 +      if(compareIndexData(this.indexType, indexDefinitions,
 +          this.helper.getCanonicalizedIndexedExpression(), otherIndexTask.indexType,
 +          otherIndexTask.helper.getCanonicalizedIteratorDefinitions(),
 +          otherIndexTask.helper.getCanonicalizedIndexedExpression(), mapping) == 0)
 +      {
 +        return true;
 +      }
 +      return false;
 +    }
 +
 +    public int hashCode(){
 +      // It returns a constant number as the equality check is based on
 +      // the OR condition between the indexName and its characteristics
 +      // (involving type, expression and definition), because of this
 +      // its not possible to come-up with an accurate hash code.
 +      return 99;
 +    }
 +
 +    /*
 +     * Creates and initializes the index.
 +     */
 +    public Index call() {
 +      Index index = null;
 +      String indexedExpression = helper.getCanonicalizedIndexedExpression();
 +      String fromClause = helper.getCanonicalizedFromClause();
 +      String projectionAttributes = helper.getCanonicalizedProjectionAttributes();
 +      String[] definitions = helper.getCanonicalizedIteratorDefinitions();
 +      IndexStatistics stats = null;    
 +      this.isLDM = IndexManager.IS_TEST_LDM;
 +
 +      if (this.prIndex != null) {
 +        stats = this.prIndex.getStatistics();
 +      }
 +      //Hash index not supported for overflow but we "thought" we were so let's maintain backwards compatibility
 +      //and create a regular compact range index instead
 +      if (indexType == IndexType.HASH && isOverFlowRegion()) {
 +        indexType = IndexType.FUNCTIONAL;
 +      }
 +      if (indexType == IndexType.PRIMARY_KEY) {
 +        index = new PrimaryKeyIndex(indexName, region, fromClause,indexedExpression,
 +             projectionAttributes, origFromClause,
 +            origIndexedExpression, definitions, stats);
 +        logger.info("Using Primary Key index implementation for '{}' on region {}", indexName, region.getFullPath());
 +      } else if (indexType == IndexType.HASH){
 +        index = new HashIndex(indexName, region, fromClause,
 +            indexedExpression,  projectionAttributes, origFromClause,
 +            origIndexedExpression, definitions, stats);
 +        
 +        logger.info("Using Hash index implementation for '{}' on region {}", indexName, region.getFullPath());
 +      }
 +      else {
 +        //boolean isCompact = !helper.isMapTypeIndex() && shouldCreateCompactIndex((FunctionalIndexCreationHelper)helper);
 +        if (this.isCompactOrHash || this.isLDM) {
 +          if (indexType == IndexType.FUNCTIONAL && !helper.isMapTypeIndex()) {
 +            index = new CompactRangeIndex(indexName, region, fromClause,
 +                indexedExpression,  projectionAttributes, origFromClause,
 +                origIndexedExpression, definitions, stats);
 +            logger.info("Using Compact Range index implementation for '{}' on region {}", indexName, region.getFullPath());       
 +          }
 +          else {
 +            FunctionalIndexCreationHelper fich = (FunctionalIndexCreationHelper)helper;            
 +            index = new CompactMapRangeIndex(indexName, region, fromClause, indexedExpression,
 +                projectionAttributes, origFromClause,
 +               origIndexedExpression, definitions, fich.isAllKeys(), fich.multiIndexKeysPattern,
 +               fich.mapKeys, stats);
 +            logger.info("Using Compact Map Range index implementation for '{}' on region {}", indexName, region.getFullPath());   
 +          }
 +        }
 +        else {
 +          assert indexType == IndexType.FUNCTIONAL;
 +          if ( !helper.isMapTypeIndex() ) {
 +            index = new RangeIndex(indexName, region, fromClause, 
 +                indexedExpression,   projectionAttributes, origFromClause,
 +                origIndexedExpression, definitions, stats);
 +            logger.info("Using Non-Compact index implementation for '{}' on region {}", indexName, region.getFullPath());   
 +          }
 +          else {
 +            FunctionalIndexCreationHelper fich = (FunctionalIndexCreationHelper)helper;            
 +            index = new MapRangeIndex(indexName, region, fromClause, indexedExpression,
 +                 projectionAttributes, origFromClause,
 +                origIndexedExpression, definitions, fich.isAllKeys(), fich.multiIndexKeysPattern,
 +                fich.mapKeys, stats);
 +            logger.info("Using Non-Compact Map index implementation for '{}' on region {}", indexName, region.getFullPath());
 +          }
 +        }
 +      }
 +      ((AbstractIndex)index).setPRIndex(prIndex);
 +     
 +      if (index.getType() != IndexType.PRIMARY_KEY) {
 +        AbstractIndex aIndex = ((AbstractIndex) index);
 +        aIndex.instantiateEvaluator(helper);
 +        waitBeforeUpdate();
 +        boolean indexCreatedSuccessfully = false;
 +        try {
 +          ((LocalRegion)region).setFlagForIndexCreationThread(true);
 +          aIndex.initializeIndex(loadEntries);
 +          logger.info((loadEntries ? "Initialized and loaded entries into the index "
 +                        : "Initialized but entries not yet loaded into the index "
 +                            + indexName + " on region: " + region.getFullPath()));
 +          aIndex.markValid(true);
 +          indexCreatedSuccessfully = true;
 +          if(loadEntries) {
 +            aIndex.setPopulated(true);
 +            if (this.prIndex != null) {
 +              ((AbstractIndex)this.prIndex).setPopulated(true);
 +            }
 +          }
 +          indexes.put(this, index);
 +          if (region instanceof BucketRegion && prIndex != null) {
 +            prIndex.addToBucketIndexes(region, index);
 +            prIndex.incNumBucketIndexes();
 +          }
 +        } catch (Exception e) {
 +          throw new IndexInvalidException(e);
 +        }
 +        finally {
 +          notifyAfterUpdate();
 +          ((LocalRegion)region).setFlagForIndexCreationThread(false);
 +          if (!indexCreatedSuccessfully){
 +            ((InternalIndexStatistics)index.getStatistics()).close();
 +          }
 +        }
 +      } else {
 +        // For PrimaryKey index
 +        ((AbstractIndex)index).setPopulated(true);
 +        indexes.put(this, index);
 +        if (region instanceof BucketRegion && prIndex != null) {
 +          prIndex.addToBucketIndexes(region, index);
 +        }
++        if (this.prIndex != null) {
++          ((AbstractIndex)this.prIndex).setPopulated(true);
++        }
 +      }
 +      return index;
 +    }
 +  }   
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/PrimaryKeyIndexCreationHelper.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/PrimaryKeyIndexCreationHelper.java
index b43f491,0000000..8c54f19
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/PrimaryKeyIndexCreationHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/PrimaryKeyIndexCreationHelper.java
@@@ -1,124 -1,0 +1,135 @@@
 +/*
 + * 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.
 + */
 +/*
 + * PrimaryIndexCreationHelper.java
 + *
 + * Created on March 20, 2005, 7:21 PM
 + */
 +package com.gemstone.gemfire.cache.query.internal.index;
 +
- import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
++import java.util.List;
++
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.query.IndexInvalidException;
- import com.gemstone.gemfire.cache.query.internal.*;
++import com.gemstone.gemfire.cache.query.internal.CompiledIteratorDef;
++import com.gemstone.gemfire.cache.query.internal.CompiledValue;
++import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
++import com.gemstone.gemfire.cache.query.internal.RuntimeIterator;
 +import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
- import java.util.List;
++import com.gemstone.gemfire.internal.cache.PartitionedRegion;
++import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +
 +/**
 + * 
 + * @author vaibhav
 + */
 +public class PrimaryKeyIndexCreationHelper extends IndexCreationHelper  {
 +
 +  ExecutionContext context = null;
 +  
 +  final Region region;
 +
 +  public PrimaryKeyIndexCreationHelper(String fromClause,
 +      String indexedExpression, String projectionAttributes, Cache cache,
 +      ExecutionContext  externalContext, IndexManager imgr) throws IndexInvalidException {
 +    super(fromClause, projectionAttributes, cache);
 +    if( externalContext == null) {
 +      context = new ExecutionContext(null, cache);
 +    }else {
 +      this.context = externalContext;
 +    }
 +    context.newScope(1);
 +    this.region = imgr.region;
 +    prepareFromClause( imgr);
 +    prepareIndexExpression(indexedExpression);
 +    prepareProjectionAttributes(projectionAttributes);
 +  }
 +
 +  private void prepareFromClause(IndexManager imgr)
 +      throws IndexInvalidException {
 +    List list = this.compiler.compileFromClause(fromClause);
 +    if (list.size() > 1) { throw new IndexInvalidException(LocalizedStrings.PrimaryKeyIndexCreationHelper_THE_FROMCLAUSE_FOR_A_PRIMARY_KEY_INDEX_SHOULD_ONLY_HAVE_ONE_ITERATOR_AND_THE_COLLECTION_MUST_BE_A_REGION_PATH_ONLY.toLocalizedString()); }
 +    try {
 +      CompiledIteratorDef iterDef = (CompiledIteratorDef) list.get(0);
 +      if (iterDef.getCollectionExpr().getType() != OQLLexerTokenTypes.RegionPath) { throw new IndexInvalidException(LocalizedStrings.PrimaryKeyIndexCreationHelper_THE_FROMCLAUSE_FOR_A_PRIMARY_KEY_INDEX_SHOULD_BE_A_REGION_PATH_ONLY.toLocalizedString()); }
 +      iterDef.computeDependencies(this.context);
 +      RuntimeIterator rIter = (iterDef.getRuntimeIterator(this.context));
 +      String definition = rIter.getDefinition();
 +      this.canonicalizedIteratorDefinitions = new String[1];
 +      this.canonicalizedIteratorDefinitions[0] = definition;
-       //    Asif: Bind the Index_Internal_ID to the RuntimeIterator
-       String name = imgr.putCanonicalizedIteratorNameIfAbsent(definition);
++      //    Asif: Bind the Index_Internal_ID to the RuntimeIterator      
++      PartitionedRegion pr = this.context.getPartitionedRegion();
++      this.canonicalizedIteratorNames = new String[1];
++      String name = null;
++      if (pr != null) {
++        name = pr.getIndexManager().putCanonicalizedIteratorNameIfAbsent(definition);
++      } else {
++        name = imgr.putCanonicalizedIteratorNameIfAbsent(definition);
++      }
 +      rIter.setIndexInternalID(name);
 +      this.canonicalizedIteratorNames = new String[1];
 +      this.canonicalizedIteratorNames[0] = name;
-       this.fromClause = new StringBuffer(definition).append(' ').append(name)
-           .toString();
++      this.fromClause = new StringBuffer(definition).append(' ').append(name).toString();
 +      context.bindIterator(rIter);
 +    }
 +    catch (IndexInvalidException e) {
 +      throw e; //propagate
 +    }
 +    catch (Exception e) {
 +      throw new IndexInvalidException(e); // wrap any other exceptions
 +    }
 +  }
 +
 +  private void prepareIndexExpression(String indexedExpression)
 +      throws IndexInvalidException {
 +    List indexedExprs = this.compiler
 +        .compileProjectionAttributes(indexedExpression);
 +    if (indexedExprs == null || indexedExprs.size() != 1) { throw new IndexInvalidException(LocalizedStrings.PrimaryKeyIndexCreationHelper_INVALID_INDEXED_EXPRESSOION_0.toLocalizedString(indexedExpression)); }
 +    CompiledValue expr = (CompiledValue) ((Object[]) indexedExprs.get(0))[1];
 +    if (expr.getType() == CompiledValue.LITERAL)
 +        throw new IndexInvalidException(LocalizedStrings.PrimaryKeyIndexCreationHelper_INVALID_INDEXED_EXPRESSOION_0.toLocalizedString(indexedExpression));
 +    try {
 +      StringBuffer sb = new StringBuffer();
 +      expr.generateCanonicalizedExpression(sb, context);
 +      this.indexedExpression = sb.toString();
 +    }
 +    catch (Exception e) {
 +      //e.printStackTrace();
 +      throw new IndexInvalidException(LocalizedStrings.PrimaryKeyIndexCreationHelper_INVALID_INDEXED_EXPRESSOION_0_N_1.toLocalizedString(new Object[] {indexedExpression, e.getMessage()}));
 +    }
 +  }
 +
 +  private void prepareProjectionAttributes(String projectionAttributes)
 +      throws IndexInvalidException {
 +    if (projectionAttributes != null && !projectionAttributes.equals("*")) { throw new IndexInvalidException(LocalizedStrings.PrimaryKeyIndexCreationHelper_INVALID_PROJECTION_ATTRIBUTES_0.toLocalizedString(projectionAttributes)); }
 +    this.projectionAttributes = projectionAttributes;
 +  }
 +
 +  public Region getRegion() {
 +    return region;
 +  }
 +
 +  public List getIterators() {
 +    return null;
 +  }
 +
 +  public CompiledValue getCompiledIndexedExpression() {
 +    return null;
 +  }
 +  
 +}


[042/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DMStats.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DMStats.java
index 7bf5b80,0000000..6091b83
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DMStats.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DMStats.java
@@@ -1,619 -1,0 +1,622 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal;
 +
 +/**
 + * Defines the interface used to access and modify DM statistics.
 + *
 + * @author Darrel Schneider
 + *
 + */
 +public interface DMStats {
 +
 +  /**
 +   * Returns the total number of messages sent by the distribution
 +   * manager 
 +   */
 +  public long getSentMessages();
 +
 +  /**
 +   * Increments the total number of messages sent by the distribution
 +   * manager 
 +   */
 +  public void incSentMessages(long messages);
 +
 +  public void incTOSentMsg();
 +  /**
 +   * Returns the total number of transaction commit messages
 +   * sent by the distribution manager 
 +   */
 +  public long getSentCommitMessages();
 +
 +  /**
 +   * Increments the total number of transaction commit messages
 +   * sent by the distribution manager 
 +   */
 +  public void incSentCommitMessages(long messages);
 +
 +  /**
 +   * Returns the total number commits that had to wait for an ack
 +   * before completion.
 +   */
 +  public long getCommitWaits();
 +
 +  /**
 +   * Increments the number of commit waits by one.
 +   */
 +  public void incCommitWaits();
 +
 +  /**
 +   * Returns the total number of nanoseconds spent sending messages.
 +   */
 +  public long getSentMessagesTime();
 +
 +  /**
 +   * Increments the total number of nanoseconds spent sending messages.
 +   */
 +  public void incSentMessagesTime(long nanos);
 +
 +  /**
 +   * Returns the total number of messages broadcast by the distribution
 +   * manager 
 +   */
 +  public long getBroadcastMessages();
 +
 +  /**
 +   * Increments the total number of messages broadcast by the distribution
 +   * manager 
 +   */
 +  public void incBroadcastMessages(long messages);
 +
 +  /**
 +   * Returns the total number of nanoseconds spent sending messages.
 +   */
 +  public long getBroadcastMessagesTime();
 +
 +  /**
 +   * Increments the total number of nanoseconds spend sending messages.
 +   */
 +  public void incBroadcastMessagesTime(long nanos);
 +
 +  /**
 +   * Returns the total number of messages received by the distribution
 +   * manager
 +   */
 +  public long getReceivedMessages();
 +
 +  /**
 +   * Increments the total number of messages received by the distribution
 +   * manager 
 +   */
 +  public void incReceivedMessages(long messages);
 +
 +  /**
 +   * Returns the total number of message bytes received by the distribution
 +   * manager
 +   */
 +  public long getReceivedBytes();
 +
 +  /**
 +   * Increments the total number of message bytes received by the distribution
 +   * manager 
 +   */
 +  public void incReceivedBytes(long bytes);
 +
 +  /**
 +   * Increments the total number of message bytes sent by the distribution
 +   * manager 
 +   */
 +  public void incSentBytes(long bytes);
 +
 +  /**
 +   * Returns the total number of messages processed by the distribution
 +   * manager
 +   */
 +  public long getProcessedMessages();
 +
 +  /**
 +   * Increments the total number of messages processed by the distribution
 +   * manager 
 +   */
 +  public void incProcessedMessages(long messages);
 +
 +  /**
 +   * Returns the total number of nanoseconds spent processing messages.
 +   */
 +  public long getProcessedMessagesTime();
 +
 +  /**
 +   * Increments the total number of nanoseconds spent processing messages.
 +   */
 +  public void incProcessedMessagesTime(long nanos);
 +
 +  /**
 +   * Returns the total number of nanoseconds spent scheduling messages to be processed.
 +   */
 +  public long getMessageProcessingScheduleTime();
 +
 +  public void incBatchSendTime(long start);
 +  public void incBatchCopyTime(long start);
 +  public void incBatchWaitTime(long start);
 +  public void incBatchFlushTime(long start);
 +  /**
 +   * Increments the total number of nanoseconds spent scheduling messages to be processed.
 +   */
 +  public void incMessageProcessingScheduleTime(long nanos);
 +
 +  public int getOverflowQueueSize();
 +  
 +  public void incOverflowQueueSize(int messages);
 +  
 +  public int getNumProcessingThreads();
 +  
 +  public void incNumProcessingThreads(int threads);
 +
 +  public int getNumSerialThreads();
 +  
 +  public void incNumSerialThreads(int threads);
 +
 +  public void incMessageChannelTime(long val);
++
++  public void incUDPDispatchRequestTime(long val);
++  public long getUDPDispatchRequestTime();
 +  
 +  public long getReplyMessageTime();
 +  public void incReplyMessageTime(long val);
 +
 +  public long getDistributeMessageTime();
 +  public void incDistributeMessageTime(long val);
 +  
 +  public long startSocketWrite(boolean sync);
 +  public void endSocketWrite(boolean sync, long start, int bytesWritten, int retries);
 +  /**
 +   * increments
 +   * the number of unicast writes performed and the number of bytes written
 +   * @since 5.0
 +   */
 +  public void incUcastWriteBytes(int bytesWritten);
 +  /**
 +   * increment the number of unicast datagram payload bytes received and
 +   * the number of unicast reads performed
 +   */
 +  public void incUcastReadBytes(int amount);
 +  /**
 +   * increment the number of multicast datagrams sent and
 +   * the number of multicast bytes transmitted
 +   */
 +  public void incMcastWriteBytes(int bytesWritten);
 +  /**
 +   * increment the number of multicast datagram payload bytes received, and
 +   * the number of mcast messages read
 +   */
 +  public void incMcastReadBytes(int amount);
 +  /**
 +   * returns the current value of the mcastWrites statistic
 +   */
 +  public int getMcastWrites();
 +  public int getMcastReads();
 +
 +  public long startSerialization();
 +  public void endSerialization(long start, int bytes);
 +  public long startDeserialization();
 +  public void endDeserialization(long start, int bytes);
 +  public long startMsgSerialization();
 +  public void endMsgSerialization(long start);
 +  public long startMsgDeserialization();
 +  public void endMsgDeserialization(long start);
 +
 +  public int getNodes();
 +  public void setNodes(int val);
 +  public void incNodes(int val);
 +  public int getReplyWaitsInProgress();
 +  public int getReplyWaitsCompleted();
 +  public long getReplyWaitTime();
 +  /**
 +   * @return the timestamp that marks the start of the operation
 +   */
 +  public long startReplyWait();
 +  /**
 +   * @param startNanos the timestamp taken when the operation started
 +   * @param initTime the time the operation begain (before msg transmission) 
 +   */
 +  public void endReplyWait(long startNanos, long initTime);
 +
 +  /**
 +   * Increments the number of message replies that have timed out
 +   *
 +   * @since 3.5
 +   */
 +  public void incReplyTimeouts();
 +
 +  /**
 +   * Returns the number of message replies that have timed out
 +   *
 +   * @since 3.5
 +   */
 +  public long getReplyTimeouts();
 +
 +  /**
 +   * @since 4.1
 +   */
 +  public void incReceivers();
 +  /**
 +   * @since 4.1
 +   */
 +  public void decReceivers();
 +  /**
 +   * @since 4.1
 +   */
 +  public void incFailedAccept();
 +  /**
 +   * @since 4.1
 +   */
 +  public void incFailedConnect();
 +  /**
 +   * @since 4.1.1
 +   */
 +  public void incReconnectAttempts();
 +  /**
 +   * @since 4.1
 +   */
 +  public void incLostLease();
 +  /**
 +   * @since 4.1
 +   */
 +  public void incSenders(boolean shared, boolean preserveOrder);
 +  /**
 +   * @since 4.1
 +   */
 +  public void decSenders(boolean shared, boolean preserveOrder);
 +  /**
 +   * @since 4.1
 +   */
 +  public int getSendersSU();
 +  /**
 +   * increment the number of unicast UDP retransmission requests received from
 +   * other processes
 +   * @since 5.0
 +   */
 +  public void incUcastRetransmits();
 +  /**
 +   * increment the number of multicast UDP retransmissions sent to
 +   * other processes
 +   * @since 5.0
 +   */
 +  public void incMcastRetransmits();
 +  /**
 +   * returns the current number of multicast retransmission requests
 +   * processed
 +   */
 +  public int getMcastRetransmits();
 +  /**
 +   * increment the number of multicast UDP retransmission requests sent to
 +   * other processes
 +   * @since 5.0
 +   */
 +  public void incMcastRetransmitRequests();
 +
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncSocketWritesInProgress();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncSocketWrites();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncSocketWriteRetries();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncSocketWriteBytes();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncSocketWriteTime();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncQueues();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueues(int inc);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncQueueFlushesInProgress();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncQueueFlushesCompleted();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncQueueFlushTime();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long startAsyncQueueFlush();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void endAsyncQueueFlush(long start);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncQueueTimeouts();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueueTimeouts(int inc);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncQueueSizeExceeded();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueueSizeExceeded(int inc);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncDistributionTimeoutExceeded();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncDistributionTimeoutExceeded();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncQueueSize();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueueSize(long inc);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncQueuedMsgs();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueuedMsgs();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncDequeuedMsgs();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncDequeuedMsgs();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncConflatedMsgs();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncConflatedMsgs();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncThreads();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncThreads(int inc);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncThreadInProgress();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public int getAsyncThreadCompleted();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncThreadTime();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long startAsyncThread();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void endAsyncThread(long start);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncQueueAddTime();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueueAddTime(long inc);
 +  /**
 +   * @since 4.2.2
 +   */
 +  public long getAsyncQueueRemoveTime();
 +  /**
 +   * @since 4.2.2
 +   */
 +  public void incAsyncQueueRemoveTime(long inc);
 +
 +  /**
 +   * @since 5.0.2.4 
 +   */
 +  public void incReceiverBufferSize(int inc, boolean direct);
 +  /**
 +   * @since 5.0.2.4 
 +   */
 +  public void incSenderBufferSize(int inc, boolean direct);
 +  /**
 +   * @since 5.0.2.4 
 +   */
 +  public long startSocketLock();
 +  /**
 +   * @since 5.0.2.4 
 +   */
 +  public void endSocketLock(long start);
 +
 +  /**
 +   * @since 5.0.2.4 
 +   */
 +  public long startBufferAcquire();
 +  /**
 +   * @since 5.0.2.4 
 +   */
 +  public void endBufferAcquire(long start);
 +
 +  /**
 +   * increment/decrement the number of thread-owned receivers with the given
 +   * domino count
 +   * @param value
 +   * @param dominoCount thread-owned connection chain count
 +   */
 +  public void incThreadOwnedReceivers(long value, int dominoCount);
 +  
 +  /**
 +   * Called when a new message is received.
 +   * @param newMsg true if a new message being received was detected; false if
 +   *   this is just additional data for a message already detected.
 +   * @param bytes the number of bytes read, so far, for the message being received. 
 +   * @since 5.0.2
 +   */
 +  public void incMessagesBeingReceived(boolean newMsg, int bytes);
 +  /**
 +   * Called when we finish processing a received message.
 +   * @param bytes the number of bytes read off the wire for the message we have finished with.
 +   * @since 5.0.2
 +   */
 +  public void decMessagesBeingReceived(int bytes);
 +
 +  public void incReplyHandOffTime(long start);
 +  
 +  /**
 +   * Returns 1 if the system elder is this member, else returns 0.
 +   * @return 1 if the system elder is this member, else returns 0
 +   */
 +  public int getElders();
 +  public void incElders(int val);
 +  
 +  /**
 +   * Returns the number of initial image reply messages sent from this member
 +   * which have not yet been acked.  
 +   */
 +  public int getInitialImageMessagesInFlight();
 +
 +  public void incInitialImageMessagesInFlight(int val);
 +  
 +  /**
 +   * Returns the number of initial images this member is currently requesting. 
 +   */
 +  public int getInitialImageRequestsInProgress();
 +  
 +  public void incInitialImageRequestsInProgress(int val);
 +
 +  public void incPdxSerialization(int bytesWritten);
 +
 +  public void incPdxDeserialization(int i);
 +
 +  public long startPdxInstanceDeserialization();
 +
 +  public void endPdxInstanceDeserialization(long start);
 +  public void incPdxInstanceCreations();
 +  
 +  //Stats for GMSHealthMonitor
 +  public long getHeartbeatRequestsSent();
 +  
 +  public void incHeartbeatRequestsSent();
 +  
 +  public long getHeartbeatRequestsReceived();
 +  
 +  public void incHeartbeatRequestsReceived();
 +  
 +  public long getHeartbeatsSent();
 +  
 +  public void incHeartbeatsSent();
 +
 +  public long getHeartbeatsReceived();
 +  
 +  public void incHeartbeatsReceived();
 +  
 +
 +  public long getSuspectsSent();
 +  
 +  public void incSuspectsSent();
 +
 +  public long getSuspectsReceived();
 +  
 +  public void incSuspectsReceived();
 +  
 +  
 +  public long getFinalCheckRequestsSent();
 +  
 +  public void incFinalCheckRequestsSent();
 +  
 +  public long getFinalCheckRequestsReceived();
 +  
 +  public void incFinalCheckRequestsReceived();
 +  
 +  public long getFinalCheckResponsesSent();
 +  
 +  public void incFinalCheckResponsesSent();
 +  
 +  public long getFinalCheckResponsesReceived();
 +  
 +  public void incFinalCheckResponsesReceived();
 +  
 +  
 +  public long getTcpFinalCheckRequestsSent();
 +  
 +  public void incTcpFinalCheckRequestsSent();
 +
 +  public long getTcpFinalCheckRequestsReceived();
 +  
 +  public void incTcpFinalCheckRequestsReceived();
 +  
 +  public long getTcpFinalCheckResponsesSent();
 +  
 +  public void incTcpFinalCheckResponsesSent();
 +
 +  public long getTcpFinalCheckResponsesReceived();
 +  
 +  public void incTcpFinalCheckResponsesReceived();
 +
 +  
 +  public long getUdpFinalCheckRequestsSent();
 +  
 +  public void incUdpFinalCheckRequestsSent();
 +  
 +//  UDP final check is implemented using HeartbeatRequestMessage and HeartbeatMessage
 +//  So the following code is commented out.
 +  
 +//  public long getUdpFinalCheckRequestsReceived();
 +//  
 +//  public void incUdpFinalCheckRequestsReceived();
 +//  
 +//  public long getUdpFinalCheckResponsesSent();
 +//  
 +//  public void incUdpFinalCheckResponsesSent();
 +
 +  public long getUdpFinalCheckResponsesReceived();
 +  
 +  public void incUdpFinalCheckResponsesReceived();
 +}


[005/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectDUnitTest.java
index 0d80574,0000000..70c7171
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectDUnitTest.java
@@@ -1,1173 -1,0 +1,1173 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.io.File;
 +import java.io.FileWriter;
 +import java.io.IOException;
 +import java.io.PrintWriter;
 +import java.util.Iterator;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.concurrent.TimeUnit;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.LossAction;
 +import com.gemstone.gemfire.cache.MembershipAttributes;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.RegionExistsException;
 +import com.gemstone.gemfire.cache.ResumptionAction;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.Locator;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.ReconnectListener;
 +import com.gemstone.gemfire.distributed.internal.InternalLocator;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +@SuppressWarnings("serial")
 +public class ReconnectDUnitTest extends CacheTestCase
 +{
 +  static int locatorPort;
 +  static Locator locator;
 +  static DistributedSystem savedSystem;
 +  static int locatorVMNumber = 3;
 +  static Thread gfshThread;
 +  
 +  Properties dsProperties;
 +  
 +  public ReconnectDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    this.locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    final int locPort = this.locatorPort;
 +    Host.getHost(0).getVM(locatorVMNumber)
 +      .invoke(new SerializableRunnable("start locator") {
 +      public void run() {
 +        try {
 +          InternalDistributedSystem ds = InternalDistributedSystem.getConnectedInstance();
 +          if (ds != null) {
 +            ds.disconnect();
 +          }
 +          locatorPort = locPort;
 +          Properties props = getDistributedSystemProperties();
 +          locator = Locator.startLocatorAndDS(locatorPort, new File(""), props);
 +          IgnoredException.addIgnoredException("com.gemstone.gemfire.ForcedDisconnectException||Possible loss of quorum");
 +//          MembershipManagerHelper.getMembershipManager(InternalDistributedSystem.getConnectedInstance()).setDebugJGroups(true);
 +        } catch (IOException e) {
 +          Assert.fail("unable to start locator", e);
 +        }
 +      }
 +    });
 +
 +    beginCacheXml();
 +    createRegion("myRegion", createAtts());
 +    finishCacheXml("MyDisconnect");
 +    //Cache cache = getCache();
 +    closeCache();
 +    getSystem().disconnect();
 +    LogWriterUtils.getLogWriter().fine("Cache Closed ");
 +  }
 +
 +  @Override
 +  public Properties getDistributedSystemProperties() {
 +    if (dsProperties == null) {
 +      dsProperties = super.getDistributedSystemProperties();
 +      dsProperties.put(DistributionConfig.MAX_WAIT_TIME_FOR_RECONNECT_NAME, "20000");
 +      dsProperties.put(DistributionConfig.ENABLE_NETWORK_PARTITION_DETECTION_NAME, "true");
 +      dsProperties.put(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME, "false");
 +      dsProperties.put(DistributionConfig.LOCATORS_NAME, "localHost["+this.locatorPort+"]");
 +      dsProperties.put(DistributionConfig.MCAST_PORT_NAME, "0");
 +      dsProperties.put(DistributionConfig.MEMBER_TIMEOUT_NAME, "1000");
 +      dsProperties.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +    }
 +    return dsProperties;
 +  }
 +  
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    try {
 +      Host.getHost(0).getVM(locatorVMNumber).invoke(new SerializableRunnable("stop locator") {
 +        public void run() {
 +          if (locator != null) {
 +            LogWriterUtils.getLogWriter().info("stopping locator " + locator);
 +            locator.stop();
 +          }
 +        }
 +      });
 +    } finally {
 +      Invoke.invokeInEveryVM(new SerializableRunnable() {
 +        public void run() {
 +          ReconnectDUnitTest.savedSystem = null;
 +        }
 +      });
 +      disconnectAllFromDS();
 +    }
 +  }
 +
 +  /**
 +   * Creates some region attributes for the regions being created.
 +   * */
 +  private RegionAttributes createAtts()
 +  {
 +    AttributesFactory factory = new AttributesFactory();
 +
 +    {
 +      // TestCacheListener listener = new TestCacheListener(){}; // this needs to be serializable
 +      //callbacks.add(listener);
 +      //factory.setDataPolicy(DataPolicy.REPLICATE);
 +      factory.setDataPolicy(DataPolicy.REPLICATE);
 +      factory.setScope(Scope.DISTRIBUTED_ACK);
 +      // factory.setCacheListener(listener);
 +    }
 +
 +    return factory.create();
 +  }
 +
 +  // quorum check fails, then succeeds
 +  public void testReconnectWithQuorum() throws Exception {
 +    IgnoredException.addIgnoredException("killing member's ds");
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    
 +    final int locPort = locatorPort;
 +
 +    final String xmlFileLoc = (new File(".")).getAbsolutePath();
 +    
 +    // disable disconnects in the locator so we have some stability
 +    host.getVM(locatorVMNumber).invoke(new SerializableRunnable("disable force-disconnect") {
 +      public void run() {
 +        GMSMembershipManager mgr = (GMSMembershipManager)MembershipManagerHelper
 +            .getMembershipManager(InternalDistributedSystem.getConnectedInstance());
 +        mgr.disableDisconnectOnQuorumLossForTesting();
 +      }}
 +    );
 +
 +    SerializableCallable create = new SerializableCallable(
 +    "Create Cache and Regions from cache.xml") {
 +      public Object call() throws CacheException
 +      {
 +        //      DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to create region");
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put("cache-xml-file", xmlFileLoc+"/MyDisconnect-cache.xml");
 +        props.put("max-num-reconnect-tries", "2");
 +        props.put("log-file", "autoReconnectVM"+VM.getCurrentVMNum()+"_"+getPID()+".log");
 +        Cache cache = new CacheFactory(props).create();
 +        IgnoredException.addIgnoredException("com.gemstone.gemfire.ForcedDisconnectException||Possible loss of quorum");
 +        Region myRegion = cache.getRegion("root/myRegion");
 +        ReconnectDUnitTest.savedSystem = cache.getDistributedSystem();
 +        myRegion.put("MyKey1", "MyValue1");
 +//        MembershipManagerHelper.getMembershipManager(cache.getDistributedSystem()).setDebugJGroups(true); 
 +        // myRegion.put("Mykey2", "MyValue2");
 +        return savedSystem.getDistributedMember();
 +      }
 +    };
 +    
 +    System.out.println("creating caches in vm0, vm1 and vm2");
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +    vm2.invoke(create);
 +    
 +    // view is [locator(3), vm0(15), vm1(10), vm2(10)]
 +    
 +    /* now we want to cause vm0 and vm1 to force-disconnect.  This may cause the other
 +     * non-locator member to also disconnect, depending on the timing
 +     */
 +    System.out.println("disconnecting vm0");
 +    forceDisconnect(vm0);
 +    Wait.pause(10000);
 +    System.out.println("disconnecting vm1");
 +    forceDisconnect(vm1);
 +
 +    /* now we wait for them to auto-reconnect */
 +    try {
 +      System.out.println("waiting for vm0 to reconnect");
 +      waitForReconnect(vm0);
 +      System.out.println("waiting for vm1 to reconnect");
 +      waitForReconnect(vm1);
 +      System.out.println("done reconnecting vm0 and vm1");
 +    } catch (Exception e) {
 +      ThreadUtils.dumpAllStacks();
 +      throw e;
 +    }
 +  }
 +  
 +  public void testReconnectOnForcedDisconnect() throws Exception  {
 +    doTestReconnectOnForcedDisconnect(false);
 +  }
 +  
 +  /** bug #51335 - customer is also trying to recreate the cache */
 +  // this test is disabled due to a high failure rate during CI test runs.
 +  // see bug #52160
 +  public void disabledtestReconnectCollidesWithApplication() throws Exception  {
 +    doTestReconnectOnForcedDisconnect(true);
 +  }
 +  
 +  public void doTestReconnectOnForcedDisconnect(final boolean createInAppToo) throws Exception {
 +
 +    IgnoredException.addIgnoredException("killing member's ds");
 +//    getSystem().disconnect();
 +//    getLogWriter().fine("Cache Closed ");
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    
 +    final int locPort = locatorPort;
 +    final int secondLocPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +
 +    DistributedTestUtils.deleteLocatorStateFile(locPort, secondLocPort);
 +
 +
 +    final String xmlFileLoc = (new File(".")).getAbsolutePath();
 +
 +    SerializableCallable create1 = new SerializableCallable(
 +    "Create Cache and Regions from cache.xml") {
 +      public Object call() throws CacheException
 +      {
 +        //      DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to create region");
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put("cache-xml-file", xmlFileLoc+"/MyDisconnect-cache.xml");
 +        props.put("max-wait-time-reconnect", "1000");
 +        props.put("max-num-reconnect-tries", "2");
 +//        props.put("log-file", "autoReconnectVM"+VM.getCurrentVMNum()+"_"+getPID()+".log");
 +        Cache cache = new CacheFactory(props).create();
 +        Region myRegion = cache.getRegion("root/myRegion");
 +        ReconnectDUnitTest.savedSystem = cache.getDistributedSystem();
 +        myRegion.put("MyKey1", "MyValue1");
 +        // myRegion.put("Mykey2", "MyValue2");
 +        return savedSystem.getDistributedMember();
 +      }
 +    };
 +
 +    SerializableCallable create2 = new SerializableCallable(
 +    "Create Cache and Regions from cache.xml") {
 +      public Object call() throws CacheException
 +      {
 +        //            DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to create region");
 +        locatorPort = locPort;
 +        final Properties props = getDistributedSystemProperties();
 +        props.put("cache-xml-file", xmlFileLoc+"/MyDisconnect-cache.xml");
 +        props.put("max-wait-time-reconnect", "5000");
 +        props.put("max-num-reconnect-tries", "2");
 +        props.put("start-locator", "localhost["+secondLocPort+"]");
 +        props.put("locators", props.get("locators")+",localhost["+secondLocPort+"]");
 +//        props.put("log-file", "autoReconnectVM"+VM.getCurrentVMNum()+"_"+getPID()+".log");
 +        getSystem(props);
 +//        MembershipManagerHelper.getMembershipManager(system).setDebugJGroups(true);
 +        final Cache cache = getCache();
 +        ReconnectDUnitTest.savedSystem = cache.getDistributedSystem();
 +        Region myRegion = cache.getRegion("root/myRegion");
 +        //myRegion.put("MyKey1", "MyValue1");
 +        myRegion.put("Mykey2", "MyValue2");
 +        assertNotNull(myRegion.get("MyKey1"));
 +        //getLogWriter().fine("MyKey1 value is : "+myRegion.get("MyKey1"));
 +        if (createInAppToo) {
 +          Thread recreateCacheThread = new Thread("ReconnectDUnitTest.createInAppThread") {
 +            public void run() {
 +              while (!cache.isClosed()) {
 +                Wait.pause(100);
 +              }
 +              try {
 +                new CacheFactory(props).create();
 +                LogWriterUtils.getLogWriter().error("testReconnectCollidesWithApplication failed - application thread was able to create a cache");
 +              } catch (IllegalStateException cacheExists) {
 +                // expected
 +              }
 +            }
 +          };
 +          recreateCacheThread.setDaemon(true);
 +          recreateCacheThread.start();
 +        }
 +        return cache.getDistributedSystem().getDistributedMember();
 +      }
 +    };
 +
 +    vm0.invoke(create1);
 +    DistributedMember dm = (DistributedMember)vm1.invoke(create2);
 +    forceDisconnect(vm1);
 +    DistributedMember newdm = (DistributedMember)vm1.invoke(new SerializableCallable("wait for reconnect(1)") {
 +      public Object call() {
 +        final DistributedSystem ds = ReconnectDUnitTest.savedSystem;
 +        ReconnectDUnitTest.savedSystem = null;
 +        Wait.waitForCriterion(new WaitCriterion() {
 +          public boolean done() {
 +            return ds.isReconnecting();
 +          }
 +          public String description() {
 +            return "waiting for ds to begin reconnecting";
 +          }
 +        }, 30000, 1000, true);
 +        LogWriterUtils.getLogWriter().info("entering reconnect wait for " + ds);
 +        LogWriterUtils.getLogWriter().info("ds.isReconnecting() = " + ds.isReconnecting());
 +        boolean failure = true;
 +        try {
 +          ds.waitUntilReconnected(60, TimeUnit.SECONDS);
 +          ReconnectDUnitTest.savedSystem = ds.getReconnectedSystem();
 +          InternalLocator locator = (InternalLocator)Locator.getLocator();
 +          assertTrue("Expected system to be restarted", ds.getReconnectedSystem() != null);
 +          assertTrue("Expected system to be running", ds.getReconnectedSystem().isConnected());
 +          assertTrue("Expected there to be a locator", locator != null);
 +          assertTrue("Expected locator to be restarted", !locator.isStopped());
 +          failure = false;
 +          return ds.getReconnectedSystem().getDistributedMember();
 +        } catch (InterruptedException e) {
 +          LogWriterUtils.getLogWriter().warning("interrupted while waiting for reconnect");
 +          return null;
 +        } finally {
 +          if (failure) {
 +            ds.disconnect();
 +          }
 +        }
 +      }
 +    });
 +    assertNotSame(dm, newdm);
 +    // force another reconnect and show that stopReconnecting works
 +    forceDisconnect(vm1);
 +    boolean stopped = (Boolean)vm1.invoke(new SerializableCallable("wait for reconnect and stop") {
 +      public Object call() {
 +        final DistributedSystem ds = ReconnectDUnitTest.savedSystem;
 +        ReconnectDUnitTest.savedSystem = null;
 +        Wait.waitForCriterion(new WaitCriterion() {
 +          public boolean done() {
 +            return ds.isReconnecting() || ds.getReconnectedSystem() != null;
 +          }
 +          public String description() {
 +            return "waiting for reconnect to commence in " + ds;
 +          }
 +          
 +        }, 10000, 1000, true);
 +        ds.stopReconnecting();
 +        assertFalse(ds.isReconnecting());
 +        DistributedSystem newDs = InternalDistributedSystem.getAnyInstance();
 +        if (newDs != null) {
 +          LogWriterUtils.getLogWriter().warning("expected distributed system to be disconnected: " + newDs);
 +          return false;
 +        }
 +        return true;
 +      }
 +    });
 +    assertTrue("expected DistributedSystem to disconnect", stopped);
 +
 +    // recreate the system in vm1 without a locator and crash it 
 +    dm = (DistributedMember)vm1.invoke(create1);
 +    forceDisconnect(vm1);
 +    newdm = waitForReconnect(vm1);
 +    assertNotSame("expected a reconnect to occur in member", dm, newdm);
 +    DistributedTestUtils.deleteLocatorStateFile(locPort);
 +    DistributedTestUtils.deleteLocatorStateFile(secondLocPort);
 +  }
 +  
 +  private DistributedMember getDMID(VM vm) {
 +    return (DistributedMember)vm.invoke(new SerializableCallable("get ID") {
 +      public Object call() {
 +        ReconnectDUnitTest.savedSystem = InternalDistributedSystem.getAnyInstance();
 +        return ReconnectDUnitTest.savedSystem.getDistributedMember();
 +      }
 +    });
 +  }
 +  
 +  private DistributedMember waitForReconnect(VM vm) {
 +    return (DistributedMember)vm.invoke(new SerializableCallable("wait for Reconnect and return ID") {
 +      public Object call() {
 +    	System.out.println("waitForReconnect invoked");
 +        final DistributedSystem ds = ReconnectDUnitTest.savedSystem;
 +        ReconnectDUnitTest.savedSystem = null;
 +        Wait.waitForCriterion(new WaitCriterion() {
 +          public boolean done() {
 +            return ds.isReconnecting();
 +          }
 +          public String description() {
 +            return "waiting for ds to begin reconnecting";
 +          }
 +        }, 30000, 1000, true);
 +        long waitTime = 120;
 +        LogWriterUtils.getLogWriter().info("VM"+VM.getCurrentVMNum() + " waiting up to "+waitTime+" seconds for reconnect to complete");
 +        try {
 +          ds.waitUntilReconnected(waitTime, TimeUnit.SECONDS);
 +        } catch (InterruptedException e) {
 +          fail("interrupted while waiting for reconnect");
 +        }
 +        assertTrue("expected system to be reconnected", ds.getReconnectedSystem() != null);
 +        int oldViewId = MembershipManagerHelper.getMembershipManager(ds).getLocalMember().getVmViewId();
 +        int newViewId = ((InternalDistributedMember)ds.getReconnectedSystem().getDistributedMember()).getVmViewId();
 +        if ( !(newViewId > oldViewId) ) {
 +          fail("expected a new ID to be assigned.  oldViewId="+oldViewId + "; newViewId=" + newViewId);
 +        }
 +        return ds.getReconnectedSystem().getDistributedMember();
 +      }
 +    });
 +  }
 +  
 +  
 +  public void testReconnectALocator() throws Exception {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm3 = host.getVM(3);
 +    DistributedMember dm, newdm;
 +    
 +    final int locPort = locatorPort;
 +    final int secondLocPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +
 +    DistributedTestUtils.deleteLocatorStateFile(locPort, secondLocPort);
 +
 +    final String xmlFileLoc = (new File(".")).getAbsolutePath();
 +
 +    //This locator was started in setUp.
 +    File locatorViewLog = new File(vm3.getWorkingDirectory(), "locator"+locatorPort+"views.log");
 +    assertTrue("Expected to find " + locatorViewLog.getPath() + " file", locatorViewLog.exists());
 +    long logSize = locatorViewLog.length();
 +
 +    vm0.invoke(new SerializableRunnable("Create a second locator") {
 +      public void run() throws CacheException
 +      {
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put("max-wait-time-reconnect", "1000");
 +        props.put("max-num-reconnect-tries", "2");
 +        props.put("locators", props.get("locators")+",localhost["+locPort+"]");
 +        props.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +        try {
 +          Locator.startLocatorAndDS(secondLocPort, null, props);
 +        } catch (IOException e) {
 +          Assert.fail("exception starting locator", e);
 +        }
 +      }
 +    });
 +
 +    File locator2ViewLog = new File(vm0.getWorkingDirectory(), "locator"+secondLocPort+"views.log");
 +    assertTrue("Expected to find " + locator2ViewLog.getPath() + " file", locator2ViewLog.exists());
 +    long log2Size = locator2ViewLog.length();
 +
 +    // create a cache in vm1 so there is more weight in the system
 +    SerializableCallable create1 = new SerializableCallable(
 +    "Create Cache and Regions from cache.xml") {
 +      public Object call() throws CacheException
 +      {
 +        //      DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to create region");
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put("cache-xml-file", xmlFileLoc+"/MyDisconnect-cache.xml");
 +        props.put("max-wait-time-reconnect", "1000");
 +        props.put("max-num-reconnect-tries", "2");
 +        ReconnectDUnitTest.savedSystem = getSystem(props);
 +        Cache cache = getCache();
 +        Region myRegion = cache.getRegion("root/myRegion");
 +        myRegion.put("MyKey1", "MyValue1");
 +        // myRegion.put("Mykey2", "MyValue2");
 +        return savedSystem.getDistributedMember();
 +      }
 +    };
 +    vm1.invoke(create1);
 +
 +    
 +    try {
 +      
 +      dm = getDMID(vm0);
 +      createGfshWaitingThread(vm0);
 +      forceDisconnect(vm0);
 +      newdm = waitForReconnect(vm0);
 +      assertGfshWaitingThreadAlive(vm0);
 +
 +      boolean running = (Boolean)vm0.invoke(new SerializableCallable("check for running locator") {
 +        public Object call() {
 +          WaitCriterion wc = new WaitCriterion() {
 +            public boolean done() {
 +              return Locator.getLocator() != null;
 +            }
 +            public String description() {
 +              return "waiting for locator to restart";
 +            }
 +          };
 +          Wait.waitForCriterion(wc, 30000, 1000, false);
 +          if (Locator.getLocator() == null) {
 +            LogWriterUtils.getLogWriter().error("expected to find a running locator but getLocator() returns null");
 +            return false;
 +          }
 +          if (((InternalLocator)Locator.getLocator()).isStopped()) {
 +            LogWriterUtils.getLogWriter().error("found a stopped locator");
 +            return false;
 +          }
 +          return true;
 +        }
 +      });
 +      if (!running) {
 +        fail("expected the restarted member to be hosting a running locator");
 +      }
 +      
 +      assertNotSame("expected a reconnect to occur in the locator", dm, newdm);
 +
 +      // the log should have been opened and appended with a new view
 +      assertTrue("expected " + locator2ViewLog.getPath() + " to grow in size",
 +          locator2ViewLog.length() > log2Size);
 +      // the other locator should have logged a new view
 +      assertTrue("expected " + locatorViewLog.getPath() + " to grow in size",
 +          locatorViewLog.length() > logSize);
 +
 +    } finally {
 +      vm0.invoke(new SerializableRunnable("stop locator") {
 +        public void run() {
 +          Locator loc = Locator.getLocator();
 +          if (loc != null) {
 +            loc.stop();
 +          }
 +          if (gfshThread != null && gfshThread.isAlive()) {
 +            gfshThread.interrupt();
 +          }
 +          gfshThread = null;
 +        }
 +      });
 +      DistributedTestUtils.deleteLocatorStateFile(locPort);
 +      DistributedTestUtils.deleteLocatorStateFile(secondLocPort);
 +    }
 +  }
 +  
 +  @SuppressWarnings("serial")
 +  private void createGfshWaitingThread(VM vm) {
 +    vm.invoke(new SerializableRunnable("create Gfsh-like waiting thread") {
 +      public void run() {
 +        final Locator loc = Locator.getLocator();
 +        assertNotNull(loc);
 +        gfshThread = new Thread("ReconnectDUnitTest_Gfsh_thread") {
 +          public void run() {
 +            try {
 +              ((InternalLocator)loc).waitToStop();
 +            } catch (InterruptedException e) {
 +              System.out.println(Thread.currentThread().getName() + " interrupted - exiting");
 +            }
 +          }
 +        };
 +        gfshThread.setDaemon(true);
 +        gfshThread.start();
 +        System.out.println("created gfsh thread: " + gfshThread);
 +      }
 +    });
 +  }
 +  
 +  @SuppressWarnings("serial")
 +  private void assertGfshWaitingThreadAlive(VM vm) {
 +    vm.invoke(new SerializableRunnable("assert gfshThread is still waiting") {
 +      public void run() {
 +        assertTrue(gfshThread.isAlive());
 +      }
 +    });
 +  }
 +  
 +  /**
 +   * Test the reconnect behavior when the required roles are missing.
 +   * Reconnect is triggered as a Reliability policy. The test is to
 +   * see if the reconnect is triggered for the configured number of times
 +   */
 +  
 +  public void testReconnectWithRoleLoss() throws TimeoutException,
 +      RegionExistsException  {
 +
 +    final String rr1 = "RoleA";
 +    final String rr2 = "RoleB";
 +    final String[] requiredRoles = { rr1, rr2 };
 +    final int locPort = locatorPort;
 +    final String xmlFileLoc = (new File(".")).getAbsolutePath();
 +
 +
 +    beginCacheXml();
 +
 +    locatorPort = locPort;
 +    Properties config = getDistributedSystemProperties();
 +    config.put(DistributionConfig.ROLES_NAME, "");
 +    config.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +//    config.put("log-file", "roleLossController.log");
 +    //creating the DS
 +    getSystem(config);
 +
 +    MembershipAttributes ra = new MembershipAttributes(requiredRoles,
 +        LossAction.RECONNECT, ResumptionAction.NONE);
 +
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(Scope.DISTRIBUTED_ACK);
 +
 +    RegionAttributes attr = fac.create();
 +    createRootRegion("MyRegion", attr);
 +
 +    //writing the cachexml file.
 +
 +    File file = new File("RoleReconnect-cache.xml");
 +    try {
 +      PrintWriter pw = new PrintWriter(new FileWriter(file), true);
 +      CacheXmlGenerator.generate(getCache(), pw);
 +      pw.close();
 +    }
 +    catch (IOException ex) {
 +      Assert.fail("IOException during cache.xml generation to " + file, ex);
 +    }
 +    closeCache();
 +    getSystem().disconnect();
 +
 +    LogWriterUtils.getLogWriter().info("disconnected from the system...");
 +    Host host = Host.getHost(0);
 +
 +    VM vm0 = host.getVM(0);
 +
 +    // Recreating from the cachexml.
 +
 +    SerializableRunnable roleLoss = new CacheSerializableRunnable(
 +        "ROLERECONNECTTESTS") {
 +      public void run2() throws CacheException, RuntimeException
 +      {
 +        LogWriterUtils.getLogWriter().info("####### STARTING THE REAL TEST ##########");
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put("cache-xml-file", xmlFileLoc+File.separator+"RoleReconnect-cache.xml");
 +        props.put("max-wait-time-reconnect", "200");
 +        final int timeReconnect = 3;
 +        props.put("max-num-reconnect-tries", "3");
 +        props.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +        props.put("log-file", "roleLossVM0.log");
 +
 +        getSystem(props);
 +
 +        addReconnectListener();
 +        
 +        system.getLogWriter().info("<ExpectedException action=add>" 
 +            + "CacheClosedException" + "</ExpectedException");
 +        try{
 +          getCache();
 +          throw new RuntimeException("The test should throw a CancelException ");
 +        }
 +        catch (CancelException ignor){ // can be caused by role loss during intialization.
 +          LogWriterUtils.getLogWriter().info("Got Expected CancelException ");
 +        }
 +        finally {
 +          system.getLogWriter().info("<ExpectedException action=remove>" 
 +              + "CacheClosedException" + "</ExpectedException");
 +        }
 +        LogWriterUtils.getLogWriter().fine("roleLoss Sleeping SO call dumprun.sh");
 +        WaitCriterion ev = new WaitCriterion() {
 +          public boolean done() {
 +            return reconnectTries >= timeReconnect;
 +          }
 +          public String description() {
 +            return "Waiting for reconnect count " + timeReconnect + " currently " + reconnectTries;
 +          }
 +        };
 +        Wait.waitForCriterion(ev, 60 * 1000, 200, true);
 +        LogWriterUtils.getLogWriter().fine("roleLoss done Sleeping");
 +        assertEquals(timeReconnect,
 +            reconnectTries);
 +      }
 +
 +    };
 +
 +    vm0.invoke(roleLoss);
 +
 +
 +  }
 +  
 +     
 +  
 +  public static volatile int reconnectTries;
 +  
 +  public static volatile boolean initialized = false;
 +  
 +  public static volatile boolean initialRolePlayerStarted = false;
 +   
 +  //public static boolean rPut;
 +  public static Integer reconnectTries(){
 +    return new Integer(reconnectTries);
 +  }
 +  
 +  public static Boolean isInitialized(){
 +	  return new Boolean(initialized);
 +  }
 +  
 +  public static Boolean isInitialRolePlayerStarted(){
 +	  return new Boolean (initialRolePlayerStarted);
 +  }
 +  
 +  
 +  // See #50944 before enabling the test.  This ticket has been closed with wontFix
 +  // for the 2014 8.0 release.
 +  public void DISABLED_testReconnectWithRequiredRoleRegained()throws Throwable {
 +
 +    final String rr1 = "RoleA";
 +    //final String rr2 = "RoleB";
 +    final String[] requiredRoles = { rr1 };
 +    //final boolean receivedPut[] = new boolean[1];
 +
 +    final Integer[] numReconnect = new Integer[1];
 +    numReconnect[0] = new Integer(-1);
 +    final String myKey = "MyKey";
 +    final String myValue = "MyValue"; 
 +    final String regionName = "MyRegion";
 +    final int locPort = locatorPort;
 +
 +    // CREATE XML FOR MEMBER THAT WILL SEE ROLE LOSS (in this VM)
 +    beginCacheXml();
 +
 +    locatorPort = locPort;
 +    Properties config = getDistributedSystemProperties();
 +    config.put(DistributionConfig.ROLES_NAME, "");
 +    config.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +    //creating the DS
 +    getSystem(config);
 +
 +    MembershipAttributes ra = new MembershipAttributes(requiredRoles,
 +        LossAction.RECONNECT, ResumptionAction.NONE);
 +
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(Scope.DISTRIBUTED_ACK);
 +    fac.setDataPolicy(DataPolicy.REPLICATE);
 +
 +    RegionAttributes attr = fac.create();
 +    createRootRegion(regionName, attr);
 +
 +    //writing the cachexml file.
 +
 +    File file = new File("RoleRegained.xml");
 +    try {
 +      PrintWriter pw = new PrintWriter(new FileWriter(file), true);
 +      CacheXmlGenerator.generate(getCache(), pw);
 +      pw.close();
 +    }
 +    catch (IOException ex) {
 +      Assert.fail("IOException during cache.xml generation to " + file, ex);
 +    }
 +    closeCache();
 +    //disconnectFromDS();
 +    getSystem().disconnect(); //added
 +
 +    // ################################################################### //
 +    //
 +    Host host = Host.getHost(0);
 +    final VM vm0 = host.getVM(0);
 +    final VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(new CacheSerializableRunnable("reset reconnect count") {
 +      @Override
 +      public void run2() throws CacheException {
 +        reconnectTries = 0;
 +      }
 +    });
 +
 +    SerializableRunnable roleAPlayerForCacheInitialization = 
 +        getRoleAPlayerForCacheInitializationRunnable(vm0, locPort, regionName,
 +            "starting roleAplayer, which will initialize, wait for "
 +                + "vm0 to initialize, and then close its cache to cause role loss");
 +    AsyncInvocation avkVm1 = vm1.invokeAsync(roleAPlayerForCacheInitialization);
 +    
 +    CacheSerializableRunnable roleLoss = getRoleLossRunnable(vm1, locPort, regionName, myKey, myValue,
 +        "starting role loss vm.  When the role is lost it will start"
 +            + " trying to reconnect");
 +    final AsyncInvocation roleLossAsync = vm0.invokeAsync(roleLoss);
 +    
 +    LogWriterUtils.getLogWriter().info("waiting for role loss vm to start reconnect attempts");
 +
 +    WaitCriterion ev = new WaitCriterion() {
 +      public boolean done() {
 +        if (!roleLossAsync.isAlive()) {
 +          return true;
 +        }
-         Object res = vm0.invoke(ReconnectDUnitTest.class, "reconnectTries");
++        Object res = vm0.invoke(() -> ReconnectDUnitTest.reconnectTries());
 +        if (((Integer)res).intValue() != 0) {
 +          return true;
 +        }
 +        return false;
 +      }
 +      public String description() {
 +        return "waiting for event";
 +      }
 +    };
 +    Wait.waitForCriterion(ev, 120 * 1000, 200, true);
 +
 +    VM vm2 = host.getVM(2);
 +    if (roleLossAsync.isAlive()) {
 +
 +      SerializableRunnable roleAPlayer = getRoleAPlayerRunnable(locPort, regionName, myKey, myValue,
 +          "starting roleAPlayer in a different vm."
 +              + "  After this reconnect should succeed in vm0");
 +
 +      vm2.invoke(roleAPlayer);
 +
 +      //      long startTime = System.currentTimeMillis();
 +      /*
 +      while (numReconnect[0].intValue() > 0){
 +        if((System.currentTimeMillis()-startTime )> 120000)
 +          fail("The test failed because the required role not satisfied" +
 +               "and the number of reconnected tried is not set to zero for " +
 +               "more than 2 mins");
 +        try{
 +          Thread.sleep(15);
 +        }catch(Exception ee){
 +          getLogWriter().severe("Exception : "+ee);
 +        }
 +      }*/
 +      LogWriterUtils.getLogWriter().info("waiting for vm0 to finish reconnecting");
 +      ThreadUtils.join(roleLossAsync, 120 * 1000);
 +    }
 +
 +    if (roleLossAsync.getException() != null){
 +      Assert.fail("Exception in Vm0", roleLossAsync.getException());
 +    }
 +
 +    ThreadUtils.join(avkVm1, 30 * 1000);
 +    if (avkVm1.getException() != null){
 +      Assert.fail("Exception in Vm1", avkVm1.getException());
 +    }
 +
 +  }
 +  
 +  private CacheSerializableRunnable getRoleLossRunnable(final VM otherVM, final int locPort,
 +      final String regionName, final String myKey, final Object myValue,
 +      final String startupMessage) {
 +
 +    return new CacheSerializableRunnable("roleloss runnable") {
 +      public void run2()
 +      {
 +        Thread t = null;
 +        try {
 +          //  closeCache();
 +          //  getSystem().disconnect();
 +          LogWriterUtils.getLogWriter().info(startupMessage);
 +          WaitCriterion ev = new WaitCriterion() {
 +            public boolean done() {
-               return ((Boolean)otherVM.invoke(ReconnectDUnitTest.class, "isInitialRolePlayerStarted")).booleanValue();
++              return ((Boolean)otherVM.invoke(() -> ReconnectDUnitTest.isInitialRolePlayerStarted())).booleanValue();
 +            }
 +            public String description() {
 +              return null;
 +            }
 +          };
 +          Wait.waitForCriterion(ev, 10 * 1000, 200, true);
 +
 +          LogWriterUtils.getLogWriter().info("Starting the test and creating the cache and regions etc ...");
 +          locatorPort = locPort;
 +          Properties props = getDistributedSystemProperties();
 +          props.put("cache-xml-file", "RoleRegained.xml");
 +          props.put("max-wait-time-reconnect", "3000");
 +          props.put("max-num-reconnect-tries", "8");
 +          props.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +
 +          getSystem(props);
 +          system.getLogWriter().info("<ExpectedException action=add>" 
 +              + "CacheClosedException" + "</ExpectedException");
 +
 +          try {
 +            getCache();
 +          } catch (CancelException e) {
 +            // can happen if RoleA goes away during initialization
 +            LogWriterUtils.getLogWriter().info("cache threw CancelException while creating the cache");      
 +          }
 +          
 +          initialized = true;
 +          
 +          addReconnectListener();
 +
 +          ev = new WaitCriterion() {
 +            public boolean done() {
 +              LogWriterUtils.getLogWriter().info("ReconnectTries=" + reconnectTries);
 +              return reconnectTries != 0;
 +            }
 +            public String description() {
 +              return null;
 +            }
 +          };
 +          Wait.waitForCriterion(ev, 30 * 1000, 200, true);
 +
 +          //        long startTime = System.currentTimeMillis();
 +
 +          ev = new WaitCriterion() {
 +            String excuse;
 +            public boolean done() {
 +              if (InternalDistributedSystem.getReconnectCount() != 0) {
 +                excuse = "reconnectCount is " + reconnectTries
 +                    + " waiting for it to be zero";
 +                return false;
 +              }
 +              Object key = null;
 +              Object value= null;
 +              Region.Entry keyValue = null;
 +              try {
 +                Cache cache = CacheFactory.getAnyInstance();
 +                if (cache == null) {
 +                  excuse = "no cache";
 +                  return false;
 +                }
 +                Region myRegion = cache.getRegion(regionName);
 +                if (myRegion == null) {
 +                  excuse = "no region";
 +                  return false;
 +                }
 +
 +                Set keyValuePair = myRegion.entrySet();
 +                Iterator it = keyValuePair.iterator();
 +                while (it.hasNext()) {
 +                  keyValue = (Region.Entry)it.next();
 +                  key = keyValue.getKey();
 +                  value = keyValue.getValue();
 +                }
 +                if (key == null) {
 +                  excuse = "key is null";
 +                  return false;
 +                }
 +                if (!myKey.equals(key)) {
 +                  excuse = "key is wrong";
 +                  return false;
 +                }
 +                if (value == null) {
 +                  excuse = "value is null";
 +                  return false;
 +                }
 +                if (!myValue.equals(value)) {
 +                  excuse = "value is wrong";
 +                  return false;
 +                }
 +                LogWriterUtils.getLogWriter().info("All assertions passed");
 +                LogWriterUtils.getLogWriter().info("MyKey : "+key+" and myvalue : "+value);
 +                return true;
 +              }
 +              catch (CancelException ecc){ 
 +                // ignor the exception because the cache can be closed/null some times 
 +                // while in reconnect.
 +              }
 +              catch(RegionDestroyedException rex){
 +
 +              }
 +              finally {
 +                LogWriterUtils.getLogWriter().info("waiting for reconnect.  Current status is '"+excuse+"'");
 +              }
 +              return false;
 +            }
 +            public String description() {
 +              return excuse;
 +            }
 +          };
 +
 +          Wait.waitForCriterion(ev,  60 * 1000, 200, true); // was 5 * 60 * 1000
 +
 +          Cache cache = CacheFactory.getAnyInstance();
 +          if (cache != null) {
 +            cache.getDistributedSystem().disconnect();
 +          }
 +        } 
 +        catch (VirtualMachineError e) {
 +          SystemFailure.initiateFailure(e);
 +          throw e;
 +        }
 +        catch (Error th) {
 +          LogWriterUtils.getLogWriter().severe("DEBUG", th);
 +          throw th;
 +        } finally {
 +          if (t != null) {
 +            ThreadUtils.join(t, 2 * 60 * 1000);
 +          }
 +          // greplogs won't care if you remove an exception that was never added,
 +          // and this ensures that it gets removed.
 +          system.getLogWriter().info("<ExpectedException action=remove>" 
 +              + "CacheClosedException" + "</ExpectedException");
 +        }
 +
 +      }
 +
 +    }; // roleloss runnable
 +  }
 +
 +  private CacheSerializableRunnable getRoleAPlayerRunnable(
 +      final int locPort, final String regionName, final String myKey, final String myValue,
 +      final String startupMessage) {
 +    return new CacheSerializableRunnable(
 +        "second RoleA player") {
 +      public void run2() throws CacheException
 +      {
 +        LogWriterUtils.getLogWriter().info(startupMessage);
 +        //closeCache();
 +        // getSystem().disconnect();
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +        props.put(DistributionConfig.ROLES_NAME, "RoleA");
 +
 +        getSystem(props);
 +        getCache();
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(Scope.DISTRIBUTED_ACK);
 +        fac.setDataPolicy(DataPolicy.REPLICATE);
 +
 +        RegionAttributes attr = fac.create();
 +        Region region = createRootRegion(regionName, attr);
 +        LogWriterUtils.getLogWriter().info("STARTED THE REQUIREDROLES CACHE");
 +        try{
 +          Thread.sleep(120);
 +        }
 +        catch (Exception ee) {
 +          fail("interrupted");
 +        }
 +
 +        region.put(myKey,myValue);
 +        try {
 +          Thread.sleep(5000); // why are we sleeping for 5 seconds here?
 +          // if it is to give time to avkVm0 to notice us we should have
 +          // him signal us that he has seen us and then we can exit.
 +        }
 +        catch(InterruptedException ee){
 +          fail("interrupted");
 +        }
 +        LogWriterUtils.getLogWriter().info("RolePlayer is done...");
 +
 +
 +      }
 +
 +
 +    };
 +  }
 +  
 +  
 +  private CacheSerializableRunnable getRoleAPlayerForCacheInitializationRunnable(
 +      final VM otherVM, final int locPort, final String regionName,
 +      final String startupMessage) {
 +    return new CacheSerializableRunnable(
 +        "first RoleA player") {
 +      public void run2() throws CacheException
 +      {
 +        //  closeCache();
 +        // getSystem().disconnect();
 +        LogWriterUtils.getLogWriter().info(startupMessage);
 +        locatorPort = locPort;
 +        Properties props = getDistributedSystemProperties();
 +        props.put(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +        props.put(DistributionConfig.ROLES_NAME, "RoleA");
 +
 +        getSystem(props);
 +        getCache();
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(Scope.DISTRIBUTED_ACK);
 +        fac.setDataPolicy(DataPolicy.REPLICATE);
 +
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(regionName, attr);
 +        LogWriterUtils.getLogWriter().info("STARTED THE REQUIREDROLES CACHE");
 +        initialRolePlayerStarted = true;
 +
-         while(!((Boolean)otherVM.invoke(ReconnectDUnitTest.class, "isInitialized")).booleanValue()){
++        while(!((Boolean)otherVM.invoke(() -> ReconnectDUnitTest.isInitialized())).booleanValue()){
 +          try{
 +            Thread.sleep(15);
 +          }catch(InterruptedException ignor){
 +            fail("interrupted");
 +          }
 +        }
 +        LogWriterUtils.getLogWriter().info("RoleAPlayerInitializer is done...");
 +        closeCache();
 +
 +      }
 +    };
 +  }
 +  
 +  
 +  void addReconnectListener() {
 +    reconnectTries = 0; // reset the count for this listener
 +    LogWriterUtils.getLogWriter().info("adding reconnect listener");
 +    ReconnectListener reconlis = new ReconnectListener() {
 +      public void reconnecting(InternalDistributedSystem oldSys) {
 +        LogWriterUtils.getLogWriter().info("reconnect listener invoked");
 +        reconnectTries++;
 +      }
 +      public void onReconnect(InternalDistributedSystem system1, InternalDistributedSystem system2) {}
 +    };
 +    InternalDistributedSystem.addReconnectListener(reconlis);
 +  }
 +  
 +  private void waitTimeout() throws InterruptedException
 +  {
 +    Thread.sleep(500);
 +
 +  }
 +  public boolean forceDisconnect(VM vm) {
 +    return (Boolean)vm.invoke(new SerializableCallable("crash distributed system") {
 +      public Object call() throws Exception {
 +        // since the system will disconnect and attempt to reconnect
 +        // a new system the old reference to DTC.system can cause
 +        // trouble, so we first null it out.
 +        DistributedTestCase.system = null;
 +        final DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
 +        final Locator oldLocator = Locator.getLocator();
 +        MembershipManagerHelper.crashDistributedSystem(msys);
 +        if (oldLocator != null) {
 +          WaitCriterion wc = new WaitCriterion() {
 +            public boolean done() {
 +              return msys.isReconnecting();
 +            }
 +            public String description() {
 +              return "waiting for locator to start reconnecting: " + oldLocator;
 +            }
 +          };
 +          Wait.waitForCriterion(wc, 10000, 50, true);
 +        }
 +        return true;
 +      }
 +    });
 +  }
 +  
 +  private static int getPID() {
 +    String name = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();            
 +    int idx = name.indexOf('@'); 
 +    try {             
 +      return Integer.parseInt(name.substring(0,idx));
 +    } catch(NumberFormatException nfe) {
 +      //something changed in the RuntimeMXBean name
 +    }                         
 +    return 0;
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectedCacheServerDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectedCacheServerDUnitTest.java
index 2b97a9a,0000000..6daf213
mode 100755,000000..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectedCacheServerDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ReconnectedCacheServerDUnitTest.java
@@@ -1,68 -1,0 +1,95 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
++import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
++import com.gemstone.gemfire.internal.cache.CacheServerLauncher;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +
 +
 +public class ReconnectedCacheServerDUnitTest extends CacheTestCase {
 +
 +  public ReconnectedCacheServerDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  private static final long serialVersionUID = 1L;
 +  
 +  private boolean addedCacheServer = false;
 +  
 +  @Override
 +  public void setUp() {
 +    getCache();
 +    if (cache.getCacheServers().isEmpty()) {
 +      cache.addCacheServer();
 +      addedCacheServer = true;
 +    }
 +  }
 +  
 +  @Override
 +  protected final void preTearDownCacheTestCase() throws Exception {
 +    if (addedCacheServer && cache != null && !cache.isClosed()) {
 +      // since I polluted the cache I should shut it down in order
 +      // to avoid affecting other tests
 +      cache.close();
 +    }
 +  }
 +
 +  public void testCacheServerConfigRetained() {
 +    // make sure the environment isn't polluted
 +    assertFalse(Boolean.getBoolean("gemfire.autoReconnect-useCacheXMLFile"));
 +
 +    GemFireCacheImpl gc = (GemFireCacheImpl)cache;
 +    
 +    // fool the system into thinking cluster-config is being used
 +    GMSMembershipManager mgr = (GMSMembershipManager)MembershipManagerHelper
 +           .getMembershipManager(gc.getDistributedSystem());
 +    mgr.saveCacheXmlForReconnect(true);
 +    
 +    // the cache server config should now be stored in the cache's config
 +    assertFalse(gc.getCacheServers().isEmpty());
 +    assertNotNull(gc.getCacheConfig().getCacheServerCreation());
 +  }
 +
++  public void testDefaultCacheServerNotCreatedOnReconnect() {
++    
++    assertFalse(Boolean.getBoolean("gemfire.autoReconnect-useCacheXMLFile"));
++    
++    GemFireCacheImpl gc = (GemFireCacheImpl)cache;
++
++    // fool the system into thinking cluster-config is being used
++    GMSMembershipManager mgr = (GMSMembershipManager)MembershipManagerHelper
++        .getMembershipManager(gc.getDistributedSystem());
++    final boolean sharedConfigEnabled = true;
++    mgr.saveCacheXmlForReconnect(sharedConfigEnabled);
++
++    // the cache server config should now be stored in the cache's config
++    assertFalse(gc.getCacheServers().isEmpty());
++    int numServers = gc.getCacheServers().size();
++
++    assertNotNull(gc.getCacheConfig().getCacheServerCreation());
++
++    InternalDistributedSystem system = gc.getDistributedSystem();
++    system.createAndStartCacheServers(gc.getCacheConfig().getCacheServerCreation(), gc);
++
++    assertEquals("found these cache servers:" + gc.getCacheServers(),
++        numServers, gc.getCacheServers().size());
++      
++  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionMembershipListenerDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionMembershipListenerDUnitTest.java
index d539b82,0000000..0572c76
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionMembershipListenerDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionMembershipListenerDUnitTest.java
@@@ -1,420 -1,0 +1,420 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.List;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionEvent;
 +import com.gemstone.gemfire.cache.RegionMembershipListener;
 +import com.gemstone.gemfire.cache.util.RegionMembershipListenerAdapter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
 +import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.CacheProfile;
 +import com.gemstone.gemfire.internal.cache.DistributedRegion;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * Test {@link RegionMembershipListener}
 + *
 + * @author darrel
 + * @since 5.0
 + */
 +public class RegionMembershipListenerDUnitTest extends CacheTestCase {
 +
 +  private transient MyRML myListener;
 +  private transient MyRML mySRListener;
 +  private transient Region r; // root region
 +  private transient Region sr; // subregion
 +  protected transient DistributedMember otherId;
 +  
 +  public RegionMembershipListenerDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    DistributedRegion.TEST_HOOK_ADD_PROFILE = true;
 +  }
 +  
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    DistributedRegion.TEST_HOOK_ADD_PROFILE = false;
 +  }
 +
 +  protected VM getOtherVm() {
 +    Host host = Host.getHost(0);
 +    return host.getVM(0);
 +  }
 +    
 +  private void initOtherId() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("Connect") {
 +        public void run2() throws CacheException {
 +          getCache();
 +        }
 +      });
-     this.otherId = (DistributedMember)vm.invoke(RegionMembershipListenerDUnitTest.class, "getVMDistributedMember");
++    this.otherId = (DistributedMember)vm.invoke(() -> RegionMembershipListenerDUnitTest.getVMDistributedMember());
 +  }
 +  protected void createRootOtherVm(final String rName) {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("create root") {
 +        public void run2() throws CacheException {
 +          Region r= createRootRegion(rName, createRootRegionAttributes(null));
 +          r.createSubregion("mysub", createSubRegionAttributes(null));
 +        }
 +      });
 +  }
 +  protected RegionAttributes createRootRegionAttributes(CacheListener[] cacheListeners) {
 +    AttributesFactory af = new AttributesFactory();
 +    if (cacheListeners != null) {
 +      af.initCacheListeners(cacheListeners);
 +    }
 +    return af.create();   
 +  }
 +  protected RegionAttributes createSubRegionAttributes(CacheListener[] cacheListeners) {
 +    return createRootRegionAttributes(cacheListeners);
 +  }
 +
 +  protected void destroyRootOtherVm(final String rName) {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("local destroy root") {
 +        public void run2() throws CacheException {
 +          getRootRegion(rName).localDestroyRegion();
 +        }
 +      });
 +  }
 +  protected void closeRootOtherVm(final String rName) {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("close root") {
 +        public void run2() throws CacheException {
 +          getRootRegion(rName).close();
 +        }
 +      });
 +  }
 +  private void closeCacheOtherVm() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("close cache") {
 +        public void run2() throws CacheException {
 +          getCache().close();
 +        }
 +      });
 +  }
 +
 +  private void crashCacheOtherVm() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("crash cache") {
 +        public void run2() throws CacheException {
 +          // shut down the gms before the distributed system to simulate
 +          // a crash.  In post-5.1.x, this could use SystemFailure.initFailure()
 +          GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +          InternalDistributedSystem sys = (InternalDistributedSystem)cache.getDistributedSystem();
 +          MembershipManagerHelper.crashDistributedSystem(sys);
 +        }
 +      });
 +  }
 +
 +  public static DistributedMember getVMDistributedMember() {
 +    return InternalDistributedSystem.getAnyInstance().getDistributedMember();
 +  }
 +  
 +  protected void createRootRegionWithListener(String rName) throws CacheException {
 +    int to = getOpTimeout();
 +    this.myListener = new MyRML(to);
 +    this.r = createRootRegion(rName, createRootRegionAttributes(new CacheListener[]{this.myListener}));
 +    this.mySRListener = new MyRML(to);
 +    this.sr = this.r.createSubregion("mysub", createSubRegionAttributes(new CacheListener[]{this.mySRListener}));
 +  }
 +  
 +  public int getOpTimeout() {
 +    return getSystem().getDistributionManager().getConfig().getMemberTimeout() * 3;    
 +  }
 +  
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  /**
 +   * tests {@link RegionMembershipListener#initialMembers}
 +   */
 +  public void testInitialMembers() throws CacheException {
 +    final String rName = getUniqueName();
 +    initOtherId();
 +    createRootRegionWithListener(rName);
 +    assertInitialMembers(null);
 +    createRootOtherVm(rName);
 +
 +    // now close the region in the controller
 +    // and recreate it and see if initMembers includes otherId
 +    closeRoots();
 +    
 +    createRootRegionWithListener(rName);
 +    assertInitialMembers(this.otherId);
 +  }
 +  protected void closeRoots() {
 +    this.r.close();
 +  }
 +  protected List<DistributedMember> assertInitialMembers(final DistributedMember expectedId) {
 +    final List<DistributedMember> l;
 +    if (expectedId == null) {
 +      l = Arrays.asList(new DistributedMember[]{});
 +    } else {
 +      l = Arrays.asList(new DistributedMember[]{expectedId});
 +    }
 +    assertTrue(this.myListener.lastOpWasInitialMembers());
 +    assertEquals(l, this.myListener.getInitialMembers());
 +    assertTrue(this.mySRListener.lastOpWasInitialMembers());
 +    assertEquals(l, this.mySRListener.getInitialMembers());
 +    // test new methods added for #43098
 +    if (expectedId != null) {
 +      Cache cache = (Cache)this.r.getRegionService();
 +      //assertEquals(l, new ArrayList(cache.getMembers()));
 +      assertEquals(l, new ArrayList(cache.getMembers(this.r)));
 +      assertEquals(l, new ArrayList(cache.getMembers(this.sr)));
 +    }
 +    return l;
 +  }
 +
 +  /**
 +   * tests {@link RegionMembershipListener#afterRemoteRegionCreate}
 +   */
 +  public void testCreate() throws CacheException {
 +    final String rName = getUniqueName();
 +    initOtherId();
 +    createRootRegionWithListener(rName);
 +    createRootOtherVm(rName);
 +    assertTrue(this.myListener.lastOpWasCreate());
 +    {
 +      RegionEvent e = this.myListener.getLastEvent();
 +      assertEquals(this.otherId, e.getDistributedMember());
 +      assertEquals(Operation.REGION_CREATE, e.getOperation());
 +      assertEquals(true, e.isOriginRemote());
 +      assertEquals(false, e.isDistributed());
 +      assertEquals(this.r, e.getRegion());
 +      // the test now uses a hook to get the member's DistributionAdvisor profile in the callback argument
 +      assertTrue(e.getCallbackArgument() instanceof Profile);
 +//      assertEquals(null, e.getCallbackArgument());
 +    }
 +    assertTrue(this.mySRListener.lastOpWasCreate());
 +    {
 +      RegionEvent e = this.mySRListener.getLastEvent();
 +      assertEquals(this.otherId, e.getDistributedMember());
 +      assertEquals(Operation.REGION_CREATE, e.getOperation());
 +      assertEquals(true, e.isOriginRemote());
 +      assertEquals(false, e.isDistributed());
 +      assertEquals(this.sr, e.getRegion());
 +      // the test now uses a hook to get the member's DistributionAdvisor profile in the callback argument
 +      assertTrue(e.getCallbackArgument() instanceof Profile);
 +//      assertEquals(null, e.getCallbackArgument());
 +    }
 +  }
 +  /**
 +   * tests {@link RegionMembershipListener#afterRemoteRegionDeparture}
 +   */
 +  public void testDeparture() throws CacheException {
 +    final String rName = getUniqueName();
 +    initOtherId();
 +    createRootRegionWithListener(rName);
 +    createRootOtherVm(rName);
 +    assertOpWasCreate();
 +
 +    destroyRootOtherVm(rName);
 +    assertOpWasDeparture();
 +    
 +    createRootOtherVm(rName);
 +    assertOpWasCreate();
 +    
 +    closeRootOtherVm(rName);
 +    assertOpWasDeparture();
 +
 +    createRootOtherVm(rName);
 +    assertOpWasCreate();
 +
 +    closeCacheOtherVm();
 +    assertOpWasDeparture();
 +  }
 +  protected void assertOpWasDeparture() {
 +    assertTrue(this.myListener.lastOpWasDeparture());
 +    assertEventStuff(this.myListener.getLastEvent(), this.otherId, this.r);
 +    assertTrue(this.mySRListener.lastOpWasDeparture());
 +    assertEventStuff(this.mySRListener.getLastEvent(), this.otherId, this.sr);
 +  }
 +  public static void assertEventStuff(RegionEvent e, DistributedMember em, Region er) {
 +    assertEquals(em, e.getDistributedMember());
 +    assertEquals(Operation.REGION_CLOSE, e.getOperation());
 +    assertEquals(true, e.isOriginRemote());
 +    assertEquals(false, e.isDistributed());
 +    assertEquals(er, e.getRegion());
 +    assertEquals(null, e.getCallbackArgument());
 +  }
 +  protected void assertOpWasCreate() {
 +    assertTrue(this.myListener.lastOpWasCreate());
 +    assertTrue(this.mySRListener.lastOpWasCreate());
 +  }
 +
 +  /**
 +   * tests {@link RegionMembershipListener#afterRemoteRegionCrash}
 +   */
 +  public void testCrash() throws CacheException {
 +    final String rName = getUniqueName();
 +    initOtherId();
 +    createRootRegionWithListener(rName);
 +    createRootOtherVm(rName);
 +    try {
 +      assertTrue(this.myListener.lastOpWasCreate()); // root region
 +      assertTrue(this.mySRListener.lastOpWasCreate()); // subregion
 +      MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
 +      
 +      crashCacheOtherVm();
 +      int to = getOpTimeout();
 +      MembershipManagerHelper.waitForMemberDeparture(system, this.otherId, to);
 +      this.myListener.waitForCrashOp();
 +      {
 +        RegionEvent e = this.myListener.getLastEvent();
 +        assertEquals(this.otherId, e.getDistributedMember());
 +        assertEquals(Operation.REGION_CLOSE, e.getOperation());
 +        assertEquals(true, e.isOriginRemote());
 +        assertEquals(false, e.getOperation().isDistributed());
 +        assertEquals(this.r, e.getRegion());
 +        assertEquals(null, e.getCallbackArgument());
 +      }
 +      this.mySRListener.waitForCrashOp();
 +      {
 +        RegionEvent e = this.mySRListener.getLastEvent();
 +        assertEquals(this.otherId, e.getDistributedMember());
 +        assertEquals(Operation.REGION_CLOSE, e.getOperation());
 +        assertEquals(true, e.isOriginRemote());
 +        assertEquals(false, e.getOperation().isDistributed());
 +        assertEquals(this.sr, e.getRegion());
 +        assertEquals(null, e.getCallbackArgument());
 +      }
 +    } finally {
 +      MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
 +      disconnectAllFromDS();
 +    }
 +  }
 +  enum Op {Initial, Create, Departure, Crash};  
 +  public class MyRML extends RegionMembershipListenerAdapter {
 +    private final int timeOut; 
 +    volatile Op lastOp;  
 +    private volatile RegionEvent lastEvent;
 +    private volatile DistributedMember[] initialMembers;
 +    private volatile boolean memberInitialized; // was the member initialized when afterRemoteRegionCreate was called?
 +    
 +    public MyRML(int to) {  this.timeOut = to;  }
 +    
 +    public boolean lastOpWasInitialMembers() {
 +      return waitForOp(Op.Initial);
 +    }
 +    public boolean lastOpWasCreate() {
 +      boolean result =  waitForOp(Op.Create);
 +      if (result) {
 +        // bug #44684 - afterRemoteRegionCreate should not be invoked before the remote region is initialized
 +        assertTrue("bug #44684 - expected remote member to be initialized when afterRemoteRegionCreate was invoked",
 +            this.memberInitialized);
 +      }
 +      return result;
 +    }
 +    public boolean lastOpWasDeparture() {
 +      return waitForOp(Op.Departure);
 +    }
 +    public String getOpName(Op op) {
 +      if (op == null) {
 +        return "null";
 +      }
 +      switch (op) {
 +      case Initial: return "Initial";
 +      case Create: return "Create";
 +      case Departure: return "Departure";
 +      case Crash: return "Crash";
 +      default: return "Unknown";
 +      }
 +    }
 +    private boolean waitForOp(final Op op) {
 +      WaitCriterion ev = new WaitCriterion() {
 +        public boolean done() {
 +          return MyRML.this.lastOp == op;
 +        }
 +        public String description() {
 +          return MyRML.this.toString() + " waiting for Op " + op + " when lastOp was " + getOpName(MyRML.this.lastOp);
 +        }
 +      };
 +      LogWriterUtils.getLogWriter().info(this.toString() + " waiting for Op " + getOpName(op)
 +          + " when lastOp was " + getOpName(this.lastOp));
 +      Wait.waitForCriterion(ev, this.timeOut, 200, true);
 +      assertEquals(op, this.lastOp);
 +      return true;
 +    }
 +    
 +    public void waitForCrashOp() {
 +      waitForOp(Op.Crash);
 +    }
 +    public RegionEvent getLastEvent() {
 +      return this.lastEvent;
 +    }
 +    public List getInitialMembers() {
 +      return Arrays.asList(this.initialMembers);
 +    }
 +    
 +    public void initialMembers(Region r, DistributedMember[] initialMembers) {
 +      this.lastOp = Op.Initial;
 +      this.lastEvent = null;
 +      this.initialMembers = initialMembers;
 +      LogWriterUtils.getLogWriter().info(this.toString() + " received initialMembers notification for region " + r
 +          + " with members " + Arrays.deepToString(initialMembers));
 +    }
 +    public void afterRemoteRegionCreate(RegionEvent event) {
 +      this.lastOp = Op.Create;
 +      this.lastEvent = event;
 +      CacheProfile cacheProfile = (CacheProfile)event.getCallbackArgument();
 +      if (cacheProfile != null) {
 +        this.memberInitialized = cacheProfile.regionInitialized;
 +        if (!this.memberInitialized) {
 +          LogWriterUtils.getLogWriter().warning("afterRemoteRegionCreate invoked when member is not done initializing!", new Exception("stack trace"));
 +        }
 +        LogWriterUtils.getLogWriter().info(this.toString() + " received afterRemoteRegionCreate notification for event " + event);
 +      } else {
 +        LogWriterUtils.getLogWriter().warning("afterRemoteRegionCreate was expecting a profile in the event callback but there was none. " +
 +        		" This indicates a problem with the test hook DistributedRegion.TEST_HOOK_ADD_PROFILE");
 +      }
 +    }
 +    public void afterRemoteRegionDeparture(RegionEvent event) {
 +      this.lastOp = Op.Departure;
 +      this.lastEvent = event;
 +      LogWriterUtils.getLogWriter().info(this.toString() + " received afterRemoteRegionDeparture notification for event " + event);
 +    }
 +    public void afterRemoteRegionCrash(RegionEvent event) {
 +      this.lastOp = Op.Crash;
 +      this.lastEvent = event;
 +      LogWriterUtils.getLogWriter().info(this.toString() + " received afterRemoteRegionCrash notification for event " + event);
 +    }
 +  }
 +}


[062/100] [abbrv] incubator-geode git commit: GEODE-478: Message class length field overflows if size is > 2GB

Posted by ud...@apache.org.
GEODE-478: Message class length field overflows if size is > 2GB

Message size is now restricted to 1GB.  If this is exceeded a
MessageTooLargeException is thrown.

I think the original intent of this ticket was to have messaging handle
the carving up of the message into multiple Messages somehow, but I think
this is the correct approach.  This will ensure that the problem doesn't
cause the current connection to be terminated and the operation retried
on another server and make sure that the exception gets back to the point
of initiation.

Barry already has a way to avoid large messages in WAN senders that can
be ported to Geode.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/1e3f89dd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/1e3f89dd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/1e3f89dd

Branch: refs/heads/feature/GEODE-870
Commit: 1e3f89ddcd4bfebe0e3e9c3e0f61478826d5fdde
Parents: 9899940
Author: Bruce Schuchardt <bs...@pivotal.io>
Authored: Mon Feb 22 08:14:56 2016 -0800
Committer: Bruce Schuchardt <bs...@pivotal.io>
Committed: Mon Feb 22 08:14:56 2016 -0800

----------------------------------------------------------------------
 .../cache/client/internal/OpExecutorImpl.java   | 14 +++-
 .../internal/DistributionManager.java           |  2 +-
 .../gms/mgr/GMSMembershipManager.java           |  3 -
 .../cache/tier/sockets/BaseCommand.java         | 40 ++++------
 .../cache/tier/sockets/CacheClientProxy.java    |  8 +-
 .../internal/cache/tier/sockets/Message.java    | 78 ++++++++++++--------
 .../tier/sockets/MessageTooLargeException.java  | 29 ++++++++
 .../internal/cache/tier/sockets/Part.java       |  6 +-
 .../command/TXSynchronizationCommand.java       |  5 +-
 .../gemfire/distributed/LocatorDUnitTest.java   | 11 ++-
 .../cache/tier/sockets/MessageJUnitTest.java    | 47 ++++++++++--
 .../codeAnalysis/sanctionedSerializables.txt    |  1 +
 12 files changed, 168 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
index ca14b76..5d05fe5 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
@@ -35,6 +35,7 @@ import com.gemstone.gemfire.CancelCriterion;
 import com.gemstone.gemfire.CancelException;
 import com.gemstone.gemfire.CopyException;
 import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.GemFireIOException;
 import com.gemstone.gemfire.SerializationException;
 import com.gemstone.gemfire.cache.CacheRuntimeException;
 import com.gemstone.gemfire.cache.RegionDestroyedException;
@@ -59,6 +60,7 @@ import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 import com.gemstone.gemfire.internal.cache.TXStateProxy;
 import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
 import com.gemstone.gemfire.internal.cache.tier.BatchException;
+import com.gemstone.gemfire.internal.cache.tier.sockets.MessageTooLargeException;
 import com.gemstone.gemfire.internal.cache.wan.BatchException70;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
@@ -167,6 +169,8 @@ public class OpExecutorImpl implements ExecutablePool {
           Object result = executeWithPossibleReAuthentication(conn, op);
           success = true;
           return result;
+        } catch (MessageTooLargeException e) {
+          throw new GemFireIOException("unable to transmit message to server", e);
         }
         catch (Exception e) {
           //This method will throw an exception if we need to stop
@@ -655,7 +659,15 @@ public class OpExecutorImpl implements ExecutablePool {
         logger.debug("OpExecutor.handleException on Connection to {}", conn.getServer(),e);
       }
     }
-    if (e instanceof NotSerializableException) {
+    
+    // first take care of all exceptions that should not invalidate the
+    // connection and do not need to be logged
+    
+    if (e instanceof MessageTooLargeException) {
+      title = null;
+      exToThrow = new GemFireIOException("message is too large to transmit", e);
+    }
+    else if (e instanceof NotSerializableException) {
       title = null; //no message
       exToThrow = new SerializationException("Pool message failure", e);
     }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
index 51bfb53..24b0697 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
@@ -2630,7 +2630,7 @@ public class DistributionManager
     // "RMI TCP Connection(259)-10.80.10.55":
     //  waiting to lock monitor 0x080f6598 (object 0xe3bacd90, a com.gemstone.gemfire.distributed.internal.membership.jgroup.JGroupMembershipManager$ViewLock),
     //  which is held by "View Message Processor"
-    // NEED to sync on viewLock first.
+    // NEED to prevent view changes while installing a listener.
     DistributionChannel ch = this.channel;
     if (ch != null) {
       MembershipManager mgr = ch.getMembershipManager();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
index edfee10..3d554fa 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
@@ -1393,9 +1393,6 @@ public class GMSMembershipManager implements MembershipManager, Manager
    * @return the current membership view coordinator
    */
   public DistributedMember getCoordinator() {
-    // note - we go straight to JoinLeave because the
-    // DistributionManager queues view changes in a serial executor, where
-    // they're asynchronously installed.  The DS may still see the old coordinator
     latestViewLock.readLock().lock();
     try {
       return latestView == null? null : latestView.getCoordinator();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
index dd13f19..bef4bf1 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
@@ -176,6 +176,16 @@ public abstract class BaseCommand implements Command {
       }
       
     }   
+    catch (TransactionException
+        | CopyException
+        | SerializationException
+        | CacheWriterException
+        | CacheLoaderException
+        | GemFireSecurityException
+        | PartitionOfflineException
+        | MessageTooLargeException e) {
+      handleExceptionNoDisconnect(msg, servConn, e);
+    }
     catch (EOFException eof) {
       BaseCommand.handleEOFException(msg, servConn, eof);
       // TODO:Asif: Check if there is any need for explicitly returning
@@ -183,35 +193,13 @@ public abstract class BaseCommand implements Command {
     }
     catch (InterruptedIOException e) { // Solaris only
       BaseCommand.handleInterruptedIOException(msg, servConn, e);
-      return;
     }
     catch (IOException e) {
       BaseCommand.handleIOException(msg, servConn, e);
-      return;
     }
     catch (DistributedSystemDisconnectedException e) {
       BaseCommand.handleShutdownException(msg, servConn, e);
-      return;
-    }
-    catch (PartitionOfflineException e) { // fix for bug #42225
-      handleExceptionNoDisconnect(msg, servConn, e);
-    }
-    catch (GemFireSecurityException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
     }
-    catch (CacheLoaderException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    }
-    catch (CacheWriterException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    } catch (SerializationException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    } catch (CopyException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    } catch (TransactionException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    }
-    
     catch (VirtualMachineError err) {
       SystemFailure.initiateFailure(err);
       // If this ever returns, rethrow the error.  We're poisoned
@@ -223,11 +211,6 @@ public abstract class BaseCommand implements Command {
     } finally {
       EntryLogger.clearSource();
     }
-    /*
-     * finally { // Keep track of the fact that a message is no longer being //
-     * processed. servConn.setNotProcessingMessage();
-     * servConn.clearRequestMsg(); }
-     */
   }
 
   /**
@@ -656,6 +639,9 @@ public abstract class BaseCommand implements Command {
     if (logger.isDebugEnabled()) {
       logger.debug("{}: Wrote exception: {}", servConn.getName(), e.getMessage(), e);
     }
+    if (e instanceof MessageTooLargeException) {
+      throw (IOException)e;
+    }
   }
 
   protected static void writeErrorResponse(Message origMsg, int messageType,

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
index 69ae6d8..f650fee 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
@@ -2616,8 +2616,9 @@ public class CacheClientProxy implements ClientSession {
             }
           }
           clientMessage = null;
-        }
-        catch (IOException e) {
+        } catch (MessageTooLargeException e) {
+          logger.warn("Message too large to send to client: {}, {}", clientMessage, e.getMessage());
+        } catch (IOException e) {
           // Added the synchronization below to ensure that exception handling
           // does not occur while stopping the dispatcher and vice versa.
           synchronized (this._stopDispatchingLock) {
@@ -2960,6 +2961,9 @@ public class CacheClientProxy implements ClientSession {
         }
         // The exception handling code was modeled after the MessageDispatcher
         // run method
+      } catch (MessageTooLargeException e) {
+        logger.warn("Message too large to send to client: {}, {}", clientMessage, e.getMessage());
+
       } catch (IOException e) {
         synchronized (this._stopDispatchingLock) {
           // Pause or unregister proxy

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
index 4bfd44b..a6495e2 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
@@ -82,6 +82,11 @@ import com.gemstone.gemfire.internal.util.BlobHelper;
  */
 public class Message  {
 
+  /**
+   * maximum size of an outgoing message.  See GEODE-478
+   */
+  static final int MAX_MESSAGE_SIZE = Integer.getInteger("gemfire.client.max-message-size", 1073741824).intValue();
+
   private static final Logger logger = LogService.getLogger();
   
   private static final int PART_HEADER_SIZE = 5; // 4 bytes for length, 1 byte for isObject
@@ -197,6 +202,14 @@ public class Message  {
       this.partsList = newPartsList;
     }
   }
+  
+  /**
+   * For boundary testing we may need to inject mock parts
+   * @param parts
+   */
+  void setParts(Part[] parts) {
+    this.partsList = parts;
+  }
 
   public void setTransactionId(int transactionId) {
     this.messageModified = true;
@@ -521,57 +534,60 @@ public class Message  {
       if (cb == null) {
         throw new IOException("No buffer");
       }
+      int msgLen = 0;
       synchronized(cb) {
-        int numOfSecureParts = 0;
-        Part securityPart = this.getSecurityPart();
-        boolean isSecurityHeader = false;
+        long totalPartLen = 0;
+        long headerLen = 0;
+        int partsToTransmit = this.numberOfParts;
         
-        if (securityPart != null) {
-          isSecurityHeader = true;
-          numOfSecureParts = 1;
-        }
-        else if (this.securePart != null) {
-          // This is a client sending this message.
-          securityPart = this.securePart;
-          isSecurityHeader = true;
-          numOfSecureParts = 1;          
-        }
-
-        int totalPartLen = 0;
-        for (int i=0;i<this.numberOfParts;i++){
+        for (int i=0; i < this.numberOfParts; i++) {
           Part part = this.partsList[i];
+          headerLen += PART_HEADER_SIZE;
           totalPartLen += part.getLength();
         }
 
-        if(numOfSecureParts == 1) {
+        Part securityPart = this.getSecurityPart();
+        if (securityPart == null) {
+          securityPart = this.securePart;
+        }
+        if (securityPart != null) {
+          headerLen += PART_HEADER_SIZE;
           totalPartLen += securityPart.getLength();
+          partsToTransmit++;
         }
-        int msgLen = (PART_HEADER_SIZE * (this.numberOfParts + numOfSecureParts)) + totalPartLen;
+
+        if ( (headerLen + totalPartLen) > Integer.MAX_VALUE ) {
+          throw new MessageTooLargeException("Message size (" + (headerLen + totalPartLen) 
+              + ") exceeds maximum integer value");
+        }
+        
+        msgLen = (int)(headerLen + totalPartLen);
+        
+        if (msgLen > MAX_MESSAGE_SIZE) {
+          throw new MessageTooLargeException("Message size(" + msgLen
+              + ") exceeds gemfire.client.max-message-size setting (" + MAX_MESSAGE_SIZE + ")");
+        }
+        
         cb.clear();
-        packHeaderInfoForSending(msgLen, isSecurityHeader);
-        for (int i=0;i<this.numberOfParts + numOfSecureParts;i++) {
-          Part part = null;
-          if(i == this.numberOfParts) {
-            part = securityPart;
-          }
-          else {
-            part = partsList[i];
-          }
+        packHeaderInfoForSending(msgLen, (securityPart != null));
+        for (int i=0; i < partsToTransmit; i++) {
+          Part part = (i == this.numberOfParts) ? securityPart : partsList[i];
+
           if (cb.remaining() < PART_HEADER_SIZE) {
             flushBuffer();
           }
+          
           int partLen = part.getLength();
           cb.putInt(partLen);
           cb.put(part.getTypeCode());
           if (partLen <= cb.remaining()) {
-            part.sendTo(cb);
+            part.writeTo(cb);
           } else {
             flushBuffer();
-            // send partBytes
             if (this.sockCh != null) {
-              part.sendTo(this.sockCh, cb);
+              part.writeTo(this.sockCh, cb);
             } else {
-              part.sendTo(this.os, cb);
+              part.writeTo(this.os, cb);
             }
             if (this.msgStats != null) {
               this.msgStats.incSentBytes(partLen);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
new file mode 100755
index 0000000..e5cac59
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
@@ -0,0 +1,29 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
+
+import java.io.IOException;
+
+public class MessageTooLargeException extends IOException {
+
+  private static final long serialVersionUID = -8970585803331525833L;
+  
+  public MessageTooLargeException(String message) {
+    super(message);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
index c681621..80b5c0a 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
@@ -284,7 +284,7 @@ public class Part {
    * A stream is used because the client is configured for old IO (instead of nio).
    * @param buf the buffer to use if any data needs to be copied to one
    */
-  public final void sendTo(OutputStream out, ByteBuffer buf) throws IOException {
+  public final void writeTo(OutputStream out, ByteBuffer buf) throws IOException {
     if (getLength() > 0) {
       if (this.part instanceof byte[]) {
         byte[] bytes = (byte[])this.part;
@@ -318,7 +318,7 @@ public class Part {
    * Precondition: caller has already checked the length of this part
    * and it will fit into "buf".
    */
-  public final void sendTo(ByteBuffer buf) {
+  public final void writeTo(ByteBuffer buf) {
     if (getLength() > 0) {
       if (this.part instanceof byte[]) {
         buf.put((byte[])this.part);
@@ -350,7 +350,7 @@ public class Part {
    * so they need to be written directly to the socket.
    * Precondition: buf contains nothing that needs to be sent
    */
-  public final void sendTo(SocketChannel sc, ByteBuffer buf) throws IOException {
+  public final void writeTo(SocketChannel sc, ByteBuffer buf) throws IOException {
     if (getLength() > 0) {
       final int BUF_MAX = buf.capacity();
       if (this.part instanceof byte[]) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
index 82e8114..1975601 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
@@ -30,6 +30,7 @@ import com.gemstone.gemfire.internal.cache.tier.Command;
 import com.gemstone.gemfire.internal.cache.tier.MessageType;
 import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand;
 import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
+import com.gemstone.gemfire.internal.cache.tier.sockets.MessageTooLargeException;
 import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 
@@ -153,8 +154,8 @@ public class TXSynchronizationCommand extends BaseCommand {
                       txMgr.removeHostedTXState(txState.getTxId());
                     } catch (IOException e) {
                       // not much can be done here
-                      if (isDebugEnabled) {
-                        logger.debug("Problem writing reply to client", e);
+                      if (isDebugEnabled || (e instanceof MessageTooLargeException)) {
+                        logger.warn("Problem writing reply to client", e);
                       }
                     }
                     servConn.setAsTrue(RESPONDED);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index b3f627a..3095885 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@ -114,6 +114,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
   
   ////////  Test Methods
 
+  public void testRepeat() throws Exception {
+    long giveup = System.currentTimeMillis() + (120 * 60000);
+    do {
+      testCollocatedLocatorWithSecurity();
+      tearDown(); setUp();
+    } while (System.currentTimeMillis() < giveup);
+  }
+
   
   /**
    * SQLFire uses a colocated locator in a dm-type=normal VM.  This tests that
@@ -209,7 +217,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
       properties.put("start-locator", locators);
       properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
       system = (InternalDistributedSystem)DistributedSystem.connect(properties);
-      System.out.println("done connecting distributed system");
+      System.out.println("done connecting distributed system.  Membership view is " +
+        MembershipManagerHelper.getMembershipManager(system).getView());
       
       assertEquals("should be the coordinator", system.getDistributedMember(), MembershipManagerHelper.getCoordinator(system));
       NetView view = MembershipManagerHelper.getMembershipManager(system).getView();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
index 3dc5a7d..b7bd47a 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
@@ -38,15 +38,17 @@ public class MessageJUnitTest {
   Socket mockSocket;
   MessageStats mockStats;
   ByteBuffer msgBuffer;
+  ServerConnection mockServerConnection;
   
   @Before
   public void setUp() throws Exception {
     mockSocket = mock(Socket.class);
-    message = new Message(5, Version.CURRENT);
-    assertEquals(5, message.getNumberOfParts());
+    message = new Message(2, Version.CURRENT);
+    assertEquals(2, message.getNumberOfParts());
     mockStats = mock(MessageStats.class);
     msgBuffer = ByteBuffer.allocate(1000);
-    message.setComms(mockSocket, msgBuffer, mockStats);
+    mockServerConnection = mock(ServerConnection.class);
+    message.setComms(mockServerConnection, mockSocket, msgBuffer, mockStats);
   }
 
   @Test
@@ -60,8 +62,8 @@ public class MessageJUnitTest {
   @Test
   public void numberOfPartsIsAdjusted() {
     int numParts = message.getNumberOfParts();
-    message.setNumberOfParts(2*numParts);
-    assertEquals(2*numParts, message.getNumberOfParts());
+    message.setNumberOfParts(2*numParts+1);
+    assertEquals(2*numParts+1, message.getNumberOfParts());
     message.addBytesPart(new byte[1]);
     message.addIntPart(2);
     message.addLongPart(3);
@@ -70,6 +72,41 @@ public class MessageJUnitTest {
     assertEquals(5, message.getNextPartNumber());
   }
   
+  @Test
+  public void messageLongerThanMaxIntIsRejected() throws Exception {
+    Part[] parts = new Part[2];
+    Part mockPart1 = mock(Part.class);
+    when(mockPart1.getLength()).thenReturn(Integer.MAX_VALUE/2);
+    parts[0] = mockPart1;
+    parts[1] = mockPart1;
+    message.setParts(parts);
+    try {
+      message.send();
+    } catch (MessageTooLargeException e) {
+      assertTrue(e.getMessage().contains("exceeds maximum integer value"));
+      return;
+    }
+    fail("expected an exception but none was thrown");
+  }
+  
+  @Test
+  public void maxMessageSizeIsRespected() throws Exception {
+    Part[] parts = new Part[2];
+    Part mockPart1 = mock(Part.class);
+    when(mockPart1.getLength()).thenReturn(Message.MAX_MESSAGE_SIZE/2);
+    parts[0] = mockPart1;
+    parts[1] = mockPart1;
+    message.setParts(parts);
+    try {
+      message.send();
+    } catch (MessageTooLargeException e) {
+      assertFalse(e.getMessage().contains("exceeds maximum integer value"));
+      return;
+    }
+    fail("expected an exception but none was thrown");
+  }
+  
+  
   // TODO many more tests are needed
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt b/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
index 3747416..f3c1c5d 100644
--- a/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
+++ b/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
@@ -376,6 +376,7 @@ com/gemstone/gemfire/internal/cache/tier/BatchException,true,-670707410779130556
 com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientNotifier$2,false,this$0:com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientNotifier
 com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy$MessageDispatcher$1,true,0,this$0:com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy$MessageDispatcher
 com/gemstone/gemfire/internal/cache/tier/sockets/ClientTombstoneMessage$TOperation,false
+com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException,true,-8970585803331525833
 com/gemstone/gemfire/internal/cache/tier/sockets/UnregisterAllInterest,true,5026160621257178459
 com/gemstone/gemfire/internal/cache/tx/TransactionalOperation$ServerRegionOperation,false
 com/gemstone/gemfire/internal/cache/versions/ConcurrentCacheModificationException,false


[036/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketAdvisor.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketAdvisor.java
index 98e72bd,0000000..a6649c3
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketAdvisor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BucketAdvisor.java
@@@ -1,3002 -1,0 +1,3002 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.DataInput;
 +import java.io.DataOutput;
 +import java.io.IOException;
 +import java.io.ObjectInputStream;
 +import java.io.Serializable;
 +import java.util.AbstractSet;
 +import java.util.Collection;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Queue;
 +import java.util.Random;
 +import java.util.Set;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.Semaphore;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.atomic.AtomicReference;
 +import java.util.concurrent.locks.Lock;
 +import java.util.concurrent.locks.ReadWriteLock;
 +import java.util.concurrent.locks.ReentrantReadWriteLock;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.client.internal.locator.SerializationHelper;
 +import com.gemstone.gemfire.cache.partition.PartitionListener;
 +import com.gemstone.gemfire.distributed.DistributedLockService;
 +import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 +import com.gemstone.gemfire.distributed.LockNotHeldException;
 +import com.gemstone.gemfire.distributed.LockServiceDestroyedException;
 +import com.gemstone.gemfire.distributed.internal.DM;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.MembershipListener;
 +import com.gemstone.gemfire.distributed.internal.ReplyProcessor21;
 +import com.gemstone.gemfire.distributed.internal.locks.DLockService;
 +import com.gemstone.gemfire.distributed.internal.locks.DistributedMemberLock;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.cache.partitioned.Bucket;
 +import com.gemstone.gemfire.internal.cache.partitioned.BucketProfileUpdateMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.DeposePrimaryBucketMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.DeposePrimaryBucketMessage.DeposePrimaryBucketResponse;
 +import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +import com.gemstone.gemfire.internal.util.StopWatch;
 +
 +/**
 + * Specialized {@link CacheDistributionAdvisor} for {@link BucketRegion 
 + * BucketRegions}. The <code>BucketAdvisor</code> is owned by a {@link 
 + * ProxyBucketRegion} and may outlive a <code>BucketRegion</code>.
 + * 
 + * @author Kirk Lund
 + */
 +@SuppressWarnings("synthetic-access")
- public final class BucketAdvisor extends CacheDistributionAdvisor  {
++public class BucketAdvisor extends CacheDistributionAdvisor  {
 +  private static final Logger logger = LogService.getLogger();
 +
 +  public static final boolean ENFORCE_SAFE_CLOSE = false;
 +    //TODO: Boolean.getBoolean("gemfire.BucketAdvisor.debug.enforceSafeClose");
 +  
 +  /** Reference to the InternalDistributedMember that is primary. */
 +  private final AtomicReference primaryMember = new AtomicReference();
 +  
 +  /** 
 +   * Advice requests for {@link #adviseProfileUpdate()} delegate to the 
 +   * partitioned region's <code>RegionAdvisor</code> to include members with 
 +   * {@link ProxyBucketRegion}s as well as real {@link BucketRegion}s. 
 +   */
 +  protected final RegionAdvisor regionAdvisor;
 +
 +  /** 
 +   * The bucket primary will be holding this distributed lock. Protected by
 +   * synchronized(this). 
 +   */
 +  private DistributedMemberLock primaryLock;
 +
 +  //private static final byte MASK_HOSTING       = 1; // 0001 
 +  //private static final byte MASK_VOLUNTEERING  = 2; // 0010
 +  //private static final byte MASK_OTHER_PRIMARY = 4; // 0100
 +  //private static final byte MASK_IS_PRIMARY    = 8; // 1000
 +  
 +  private static final byte NO_PRIMARY_NOT_HOSTING    = 0;  // 0000_0000
 +  private static final byte NO_PRIMARY_HOSTING        = 1;  // 0000_0001
 +  private static final byte OTHER_PRIMARY_NOT_HOSTING = 4;  // 0000_0100
 +  private static final byte OTHER_PRIMARY_HOSTING     = 5;  // 0000_0101
 +  private static final byte VOLUNTEERING_HOSTING      = 3;  // 0000_0011
 +  private static final byte BECOMING_HOSTING          = 15; // 0000_1111
 +  private static final byte IS_PRIMARY_HOSTING        = 9;  // 0000_1001
 +  private static final byte CLOSED                    = 16; // 0001_0000
 +  
 +  /** 
 +   * The current state of this BucketAdvisor which tracks which member is
 +   * primary and whether or not this member is hosting a real Bucket.
 +   */
 +  private byte primaryState = NO_PRIMARY_NOT_HOSTING;
 +  
 +  /**
 +   * This delegate handles all volunteering for primary status. Lazily created.
 +   * Protected by synchronization(this).
 +   */
 +  private VolunteeringDelegate volunteeringDelegate;
 +
 +  /**
 +   * A random number generator
 +   * 
 +   * @see #getPreferredNode()
 +   */
 +  static private final Random myRand = new Random();
 +  
 +  /** 
 +   * Used by {@link #updateRedundancy()} to determine if stat change is
 +   * required. Access and mutation are done while synchronized on this
 +   * advisor.
 +   * 
 +   * @guarded.By this
 +   */
 +  private boolean redundancySatisfied = true;
 +  
 +  /** 
 +   * Used by {@link #incLowRedundancyBucketCount(int)} to determine if 
 +   * redundancy for this bucket has ever been satisfied. Only buckets which 
 +   * lose redundancy after having redundancy will generate a redundancy loss 
 +   * alert. 
 +   * <p>
 +   * Access and mutation are done while synchronized on this advisor.
 +   * 
 +   * @guarded.By this
 +   */
 +  private boolean redundancyEverSatisfied = false; 
 +  
 +  /**
 +   * A read/write lock to prevent making this bucket not primary while a write
 +   * is in progress on the bucket.
 +   */
 +  private final ReadWriteLock primaryMoveLock = new ReentrantReadWriteLock();
 +  private final Lock activeWriteLock = primaryMoveLock.readLock();
 +  private final Lock activePrimaryMoveLock = primaryMoveLock.writeLock();
 +  
 +  /**
 +   * The advisor for the bucket region that we are colocated with, if this region
 +   * is a colocated region.
 +   */
 +  private BucketAdvisor parentAdvisor;
 +
 +  private volatile int redundancy = -1;
 +  
 +  /**
 +   * The member that is responsible for choosing the primary
 +   * for this bucket. While this field is set and this member
 +   * exists, this bucket won't try to become primary.
 +   */
 +  private volatile InternalDistributedMember primaryElector;
 +  
 +  private volatile BucketProfile localProfile;
 +  
 +  private volatile boolean everHadPrimary = false;
 +
 +  private BucketAdvisor startingBucketAdvisor;
 +  
 +  private PartitionedRegion pRegion;
 +
 +  private volatile boolean shadowBucketDestroyed;
 +
 +  /** 
 +   * Constructs a new BucketAdvisor for the Bucket owned by RegionAdvisor.
 +   * 
 +   * @param bucket the bucket to provide metadata and advice for
 +   * @param regionAdvisor advisor for the PartitionedRegion
 +   */
 +  private BucketAdvisor(Bucket bucket, 
 +                       RegionAdvisor regionAdvisor) {
 +    super(bucket);
 +    this.regionAdvisor = regionAdvisor;
 +    this.pRegion = this.regionAdvisor.getPartitionedRegion();
 +    resetParentAdvisor(bucket.getId());
 +  }
 +  
 +  public static BucketAdvisor createBucketAdvisor(Bucket bucket, RegionAdvisor regionAdvisor) {
 +    BucketAdvisor advisor = new BucketAdvisor(bucket, regionAdvisor);
 +    advisor.initialize();
 +    return advisor;
 +  }
 +
 +  // For SQLFabric ALTER TABLE that may change colocation
 +  public void resetParentAdvisor(int bucketId) {
 +    PartitionedRegion colocatedRegion = ColocationHelper
 +        .getColocatedRegion(this.pRegion);
 +    if (colocatedRegion != null) {
 +      if (colocatedRegion.isFixedPartitionedRegion()) {
 +        List<FixedPartitionAttributesImpl> fpas = colocatedRegion
 +            .getFixedPartitionAttributesImpl();
 +        if (fpas != null) {
 +          for (FixedPartitionAttributesImpl fpa : fpas) {
 +            if (fpa.hasBucket(bucketId)) {
 +              this.parentAdvisor = colocatedRegion.getRegionAdvisor()
 +                  .getBucketAdvisor(fpa.getStartingBucketID());
 +              break;
 +            }
 +          }
 +        }
 +      }
 +      else {
 +        this.parentAdvisor = colocatedRegion.getRegionAdvisor()
 +            .getBucketAdvisor(bucketId);
 +      }
 +    }
 +    else {
 +      this.parentAdvisor = null;
 +    }
 +  }
 +
 +  private void assignStartingBucketAdvisor() {
 +    if (this.pRegion.isFixedPartitionedRegion()) {
 +      List<FixedPartitionAttributesImpl> fpas = this.pRegion
 +          .getFixedPartitionAttributesImpl();
 +      if (fpas != null) {
 +        int bucketId = getBucket().getId();
 +        for (FixedPartitionAttributesImpl fpa : fpas) {
 +          if (fpa.hasBucket(bucketId) && bucketId != fpa.getStartingBucketID()) {
 +            startingBucketAdvisor = this.regionAdvisor.getBucketAdvisor(
 +                fpa.getStartingBucketID());
 +            break;
 +          }
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Returns the lock that prevents the primary from moving while active writes
 +   * are in progress. This should be locked before checking if the local bucket
 +   * is primary.
 +   *  
 +   * @return the lock for in-progress write operations
 +   */
 +  public Lock getActiveWriteLock() {
 +    return this.activeWriteLock;
 +  }
 +  
 +  /**
 +   * Returns the lock that prevents the parent's primary from moving while
 +   * active writes are in progress. This should be locked before checking if the
 +   * local bucket is primary.
 +   * 
 +   * @return the lock for in-progress write operations
 +   */  
 +  Lock getParentActiveWriteLock() {
 +    if (this.parentAdvisor != null) {
 +      return this.parentAdvisor.getActiveWriteLock();
 +    }
 +    return null;
 +  }
 +
 +  /**
 +   * Try to lock the primary bucket to make sure no operation is on-going at
 +   * current bucket.  
 +   * 
 +   */
 +  public void tryLockIfPrimary() {
 +    if (isPrimary()) {
 +      try {
 +        this.activePrimaryMoveLock.lock();
 +      } finally {
 +        this.activePrimaryMoveLock.unlock();
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Makes this <code>BucketAdvisor</code> give up being a primary and become
 +   * a secondary. Does nothing if not currently the primary.
 +   * 
 +   * @return true if this advisor has been deposed as primary
 +   */
 +  public boolean deposePrimary() {
 +    if (isPrimary()) {
 +      this.activePrimaryMoveLock.lock();
 +      boolean needToSendProfileUpdate = false;
 +      try {
 +        removePrimary(getDistributionManager().getId());
 +        synchronized(this) {
 +          if (!isPrimary()) {
 +            //releasePrimaryLock();
 +            needToSendProfileUpdate = true;
 +            return true;
 +          } else {
 +            return false; // failed for some reason
 +          }
 +        }
 +      } finally {
 +        this.activePrimaryMoveLock.unlock();
 +        if (needToSendProfileUpdate) {
 +          if (this.getBucket() instanceof BucketRegionQueue) {
 +            BucketRegionQueue brq = (BucketRegionQueue)this.getBucket();
 +            brq.decQueueSize(brq.size());
 +          }
 +          sendProfileUpdate();
 +        }
 +      }
 +    } else {
 +      sendProfileUpdate();
 +      return true;
 +    }
 +  }
 +  
 +  /**
 +   * This calls deposePrimary on every colocated child that is directly
 +   * colocated to this bucket's PR. Those each in turn do the same to their
 +   * child buckets and so on before returning. Each depose will send a dlock
 +   * release message to the grantor, wait for reply, and then also send a
 +   * profile update.
 +   * <p>
 +   * Caller must synchronize on this BucketAdvisor.
 +
 +   * @return true if children were all deposed as primaries
 +   * @guarded.By this
 +   */
 +  private boolean deposePrimaryForColocatedChildren() {
 +    boolean deposedChildPrimaries = true;
 +    
 +    // getColocatedChildRegions returns only the child PRs directly colocated
 +    // with thisPR...
 +    List<PartitionedRegion> colocatedChildPRs = 
 +        ColocationHelper.getColocatedChildRegions(this.pRegion);
 +    if (colocatedChildPRs != null) {
 +      for (PartitionedRegion pr : colocatedChildPRs) {
 +        Bucket b = pr.getRegionAdvisor().getBucket(getBucket().getId());
 +        if (b != null) {
 +          BucketAdvisor ba = b.getBucketAdvisor();
 +          deposedChildPrimaries = ba.deposePrimary() && deposedChildPrimaries;
 +        }
 +      }
 +    }    
 +    return deposedChildPrimaries;
 +  }
 +
 +  private boolean deposeOtherPrimaryBucketForFixedPartition() {
 +    boolean deposedOtherPrimaries = true;
 +    int bucketId = getBucket().getId();
 +    List<FixedPartitionAttributesImpl> fpas = this.pRegion
 +        .getFixedPartitionAttributesImpl();
 +    if (fpas != null) {
 +      for (FixedPartitionAttributesImpl fpa : fpas) {
 +        if (fpa.getStartingBucketID() == bucketId) {
 +          for (int i = (bucketId+1); i <= fpa.getLastBucketID(); i++) {
 +            Bucket b = regionAdvisor.getBucket(i);
 +            if (b != null) {
 +              BucketAdvisor ba = b.getBucketAdvisor();
 +              deposedOtherPrimaries = ba.deposePrimary()
 +                  && deposedOtherPrimaries;
 +            }
 +          }
 +        }
 +        else {
 +          continue;
 +        }
 +      }
 +    }
 +    return deposedOtherPrimaries;
 +  }
 +  
 +  void removeBucket() {
 +    setHosting(false);
 +  }
 +  
 +  /**
 +   * Increment or decrement lowRedundancyBucketCount stat and generate 
 +   * alert only once per loss of redundancy for PR but only if redundancy
 +   * has ever been satisfied.
 +   * <p>
 +   * Caller must synchronize on this BucketAdvisor.
 +   * 
 +   * @param val the value to increment or decrement by
 +   * @guarded.By this
 +   */
 +  private void incLowRedundancyBucketCount(int val) {
 +    final int HAS_LOW_REDUNDANCY = 0;
 +    final int ALREADY_GENERATED_WARNING = 1;
 +    
 +    final PartitionedRegionStats stats = getPartitionedRegionStats();
 +    final boolean[] lowRedundancyFlags = 
 +        this.regionAdvisor.getLowRedundancyFlags();
 +    final int configuredRedundancy =
 +        this.pRegion.getRedundantCopies();
 +    
 +    synchronized (lowRedundancyFlags) {
 +      stats.incLowRedundancyBucketCount(val);
 +      
 +      if (stats.getLowRedundancyBucketCount() == 0) {
 +        // all buckets are fully redundant
 +        lowRedundancyFlags[HAS_LOW_REDUNDANCY] = false; // reset
 +        lowRedundancyFlags[ALREADY_GENERATED_WARNING] = false; // reset
 +        stats.setActualRedundantCopies(configuredRedundancy);
 +      }
 +      
 +      else {
 +        // one or more buckets are not fully redundant
 +        int numBucketHosts = getBucketRedundancy() + 1;
 +        int actualRedundancy = Math.max(numBucketHosts - 1, 0); // zero or more
 +        
 +        if (actualRedundancy < stats.getActualRedundantCopies()) {
 +          // need to generate an alert for this lower actual redundancy
 +          lowRedundancyFlags[ALREADY_GENERATED_WARNING] = false;
 +        }
 +        
 +        if (!lowRedundancyFlags[HAS_LOW_REDUNDANCY] || 
 +            !lowRedundancyFlags[ALREADY_GENERATED_WARNING]) {
 +          // either we have lower redundancy or we never generated an alert
 +          
 +          lowRedundancyFlags[HAS_LOW_REDUNDANCY] = true;
 +          stats.setActualRedundantCopies(actualRedundancy);
 +          
 +          // this bucket will only generate alert if redundancyEverSatisfied
 +          if (!lowRedundancyFlags[ALREADY_GENERATED_WARNING] && 
 +              this.redundancyEverSatisfied) {
 +            
 +            lowRedundancyFlags[ALREADY_GENERATED_WARNING] = true;
 +            logger.warn(LocalizedMessage.create(
 +                LocalizedStrings.BucketAdvisor_REDUNDANCY_HAS_DROPPED_BELOW_0_CONFIGURED_COPIES_TO_1_ACTUAL_COPIES_FOR_2,
 +                new Object[] { Integer.valueOf(configuredRedundancy), Integer.valueOf(actualRedundancy), this.pRegion.getFullPath()}));
 +          }
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Return (and possibly choose) a thread-sticky member from whose data store
 +   * this bucket's values should be read
 +   * @return member to use for reads, null if none available
 +   */
 +  public InternalDistributedMember getPreferredNode() {
 +
 +    if (isHosting()) {
 +      getPartitionedRegionStats().incPreferredReadLocal();
 +      return getDistributionManager().getId();      
 +    }
 +    
 +    Profile locProfiles[] = this.profiles; // volatile read
 +    if (locProfiles.length == 0) {
 +      return null;
 +    }
 +    getPartitionedRegionStats().incPreferredReadRemote();
 +  
 +    if (locProfiles.length == 1) { // only one choice!
 +      return locProfiles[0].peerMemberId; 
 +    }
 +    
 +    // Pick one at random.
 +    int i = myRand.nextInt(locProfiles.length);
 +    return locProfiles[i].peerMemberId;
 +    }
 +  
 +  /**
 +   * Returns the thread-safe queue of primary volunteering tasks for the
 +   * parent Partitioned Region.
 +   * 
 +   * @return the queue of primary volunteering tasks
 +   */
 +  Queue getVolunteeringQueue() {
 +    return this.regionAdvisor.getVolunteeringQueue();
 +  }
 +  
 +  /**
 +   * Returns the semaphore which controls the number of threads allowed to
 +   * consume from the {@link #getVolunteeringQueue volunteering queue}.
 +   * 
 +   * @return the semaphore which controls the number of volunteering threads
 +   */
 +  Semaphore getVolunteeringSemaphore() {
 +    return this.regionAdvisor.getVolunteeringSemaphore();
 +  }
 +  
 +  /** 
 +   * Returns the PartitionedRegionStats.
 +   * 
 +   * @return the PartitionedRegionStats
 +   */ 
 +  PartitionedRegionStats getPartitionedRegionStats() {
 +    return this.regionAdvisor.getPartitionedRegionStats();
 +  }
 +  
 +  /**
 +   * Concurrency: protected by synchronizing on *this*
 +   */
 +  @Override
 +  protected void profileCreated(Profile profile) {
 +    this.regionAdvisor.incrementBucketCount(profile);
 +    super.profileCreated(profile);
 +    if (updateRedundancy() > 0) {
 +      // wake up any threads in waitForRedundancy or waitForPrimary
 +      this.notifyAll(); 
 +    }
 +    this.regionAdvisor.updateBucketStatus(this.getBucket().getId(),
 +        profile.peerMemberId, false);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Profile added {} Profile : {}", getBucket().getFullPath(), profile);
 +    }
 +    synchronized (this){
 +      updateServerBucketProfile();
 +    }
 +  }
 +
 +  /**
 +   * Concurrency: protected by synchronizing on *this*
 +   */
 +  @Override
 +  protected void profileUpdated(Profile profile) {
 +    super.profileUpdated(profile);
 +    if (updateRedundancy() > 0) {
 +      // wake up any threads in waitForRedundancy or waitForPrimary
 +      this.notifyAll(); 
 +    }
 +    this.regionAdvisor.updateBucketStatus(this.getBucket().getId(), 
 +        profile.peerMemberId, false);
 +    
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Profile updated {} Profile : {}", getBucket().getFullPath(), profile);
 +    }
 +    synchronized (this) {
 +      updateServerBucketProfile();
 +    }
 +  }
 +
 +  /**
 +   * Concurrency: protected by synchronizing on *this*
 +   */
 +  @Override
 +  protected void profileRemoved(Profile profile) {
 +    if (profile != null) {
 +      this.regionAdvisor.updateBucketStatus(this.getBucket().getId(), 
 +          profile.getDistributedMember(), true);
 +      this.regionAdvisor.decrementsBucketCount(profile);
 +    }
 +    updateRedundancy();
 +    
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Profile removed {} the member lost {} Profile : {}", getBucket().getFullPath(),
 +          profile.getDistributedMember(), profile);
 +    }
 +    synchronized (this) {
 +      updateServerBucketProfile();
 +    }
 +  }
 +
 +  @Override
 +  public boolean shouldSyncForCrashedMember(InternalDistributedMember id) {
 +    BucketProfile profile = (BucketProfile)getProfile(id);
 +    return (profile != null) && (profile.isPrimary);
 +  }
 +  
 +  @Override
 +  public DistributedRegion getRegionForDeltaGII() {
 +    DistributedRegion result = super.getRegionForDeltaGII();
 +    if (result == null && getAdvisee() instanceof ProxyBucketRegion) {
 +      result = ((ProxyBucketRegion)getAdvisee()).getHostedBucketRegion();
 +    }
 +    return result;
 +  }
 +
 +
 +
 +  
 +  /**
 +   * Called by the RegionAdvisor.profileRemoved, this method
 +   * tests to see if the missing member is the primary elector
 +   * for this bucket.
 +   * 
 +   * We can't call this method from BucketAdvisor.profileRemoved,
 +   * because the primaryElector may not actually host the bucket.
 +   * @param profile
 +   */
 +  public void checkForLostPrimaryElector(Profile profile) {
 +    //If the member that went away was in the middle of creating
 +    //the bucket, finish the bucket creation.
 +    if(this.primaryElector != null && this.primaryElector.equals(profile.getDistributedMember())) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Bucket {} lost the member responsible for electing the primary. Finishing bucket creation", getBucket().getFullPath());
 +      }
 +      this.primaryElector = getBucket().getDistributionManager().getId();
 +      this.getBucket().getDistributionManager().getWaitingThreadPool().execute(new Runnable() {
 +        public void run() {
 +          getBucket().getPartitionedRegion().getRedundancyProvider().finishIncompleteBucketCreation(getBucket().getId());
 +        }
 +      });
 +    }
 +  }
 +
 +  /**
 +   * Only allows profiles that actually hosting this bucket. If the profile is
 +   * primary, then primaryMember will be set to that member but only
 +   * if we are not already the primary.
 +   * 
 +   * @param profile the profile to add (must be a BucketProfile)
 +   * @param forceProfile true will force profile to be added even if member is
 +   * not in distributed view
 +   * 
 +   * @see #adviseProfileUpdate() 
 +   */
 +  @Override
 +  public boolean putProfile(Profile profile, boolean forceProfile) {
 +    assert profile instanceof BucketProfile;
 +    BucketProfile bp = (BucketProfile) profile;
 +
 +    // Only hosting buckets will be initializing, the isInitializing boolean is to
 +    // allow for early entry into the advisor for GII purposes
 +    if ( ! bp.isHosting && ! bp.isInitializing) {
 +      if (logger.isTraceEnabled(LogMarker.DA)) {
 +        logger.trace(LogMarker.DA, "BucketAdvisor#putProfile early out");
 +      }
 +      return false;  // Do not allow introduction of proxy profiles, they don't provide anything useful
 +      // isHosting = false, isInitializing = false
 +    }
 +    if (logger.isTraceEnabled(LogMarker.DA)) {
 +      logger.trace(LogMarker.DA, "BucketAdvisor#putProfile profile=<{}> force={}; profile = {}", profile, forceProfile, bp);
 +    }
 +    // isHosting = false, isInitializing = true
 +    // isHosting = true,  isInitializing = false
 +    // isHosting = true,  isInitializing = true... (false state)
 +    
 +    final boolean applied;
 +    synchronized(this) {
 +      // force new membership version in the advisor so that the
 +      // state flush mechanism can capture any updates to the bucket
 +      // MIN_VALUE is intended as a somewhat unique value for potential debug purposes
 +      profile.initialMembershipVersion = Long.MIN_VALUE;
 +      applied = super.putProfile(profile, forceProfile);
 +      // skip following block if isPrimary to avoid race where we process late
 +      // arriving OTHER_PRIMARY profile after we've already become primary
 +      if (applied && !isPrimary()) {  // TODO is it safe to change the bucket state if the profile was not applied?  -- mthomas 2/13/08
 +        if (bp.isPrimary) {
 +          setPrimaryMember(bp.getDistributedMember());
 +        } else {
 +          notPrimary(bp.getDistributedMember());
 +        }
 +      } // if: !isPrimary
 +      
 +    } // synchronized
 +    return applied;
 +  }
 +
 +  private static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
 +    if (map.isEmpty()) {
 +      return new SetFromMap<E>(map);
 +    }
 +    throw new IllegalArgumentException();
 +  }
 +
 +  private static class SetFromMap<E> extends AbstractSet<E> implements
 +      Serializable {
 +    private static final long serialVersionUID = 2454657854757543876L;
 +
 +    // must named as it, to pass serialization compatibility test.
 +    private Map<E, Boolean> m;
 +
 +    private transient Set<E> backingSet;
 +
 +    SetFromMap(final Map<E, Boolean> map) {
 +      super();
 +      m = map;
 +      backingSet = map.keySet();
 +    }
 +
 +    @Override
 +    public boolean equals(Object object) {
 +      return backingSet.equals(object);
 +    }
 +
 +    @Override
 +    public int hashCode() {
 +      return backingSet.hashCode();
 +    }
 +
 +    @Override
 +    public boolean add(E object) {
 +      return m.put(object, Boolean.TRUE) == null;
 +    }
 +
 +    @Override
 +    public void clear() {
 +      m.clear();
 +    }
 +
 +    @Override
 +    public String toString() {
 +      return backingSet.toString();
 +    }
 +
 +    @Override
 +    public boolean contains(Object object) {
 +      return backingSet.contains(object);
 +    }
 +
 +    @Override
 +    public boolean containsAll(Collection<?> collection) {
 +      return backingSet.containsAll(collection);
 +    }
 +
 +    @Override
 +    public boolean isEmpty() {
 +      return m.isEmpty();
 +    }
 +
 +    @Override
 +    public boolean remove(Object object) {
 +      return m.remove(object) != null;
 +    }
 +
 +    @Override
 +    public boolean retainAll(Collection<?> collection) {
 +      return backingSet.retainAll(collection);
 +    }
 +
 +    @Override
 +    public Object[] toArray() {
 +      return backingSet.toArray();
 +    }
 +
 +    @Override
 +    public <T> T[] toArray(T[] contents) {
 +      return backingSet.toArray(contents);
 +    }
 +
 +    @Override
 +    public Iterator<E> iterator() {
 +      return backingSet.iterator();
 +    }
 +
 +    @Override
 +    public int size() {
 +      return m.size();
 +    }
 +
 +    @SuppressWarnings("unchecked")
 +    private void readObject(ObjectInputStream stream) throws IOException,
 +        ClassNotFoundException {
 +      stream.defaultReadObject();
 +      backingSet = m.keySet();
 +    }
 +  }
 +
 +  private void updateServerBucketProfile() {
 +    // check to see if it is clientBucketProfile add it to the RegionAdvisor
 +    // data structure which maintains the newly created clientBucketProfile
 +    // don't add more than once, but replace existing profile
 +    int bucketId = this.getBucket().getId();
 +    Set<ServerBucketProfile> serverProfiles = this.regionAdvisor
 +        .getClientBucketProfiles(bucketId);
 +    if (serverProfiles == null) {
 +      serverProfiles = newSetFromMap(new ConcurrentHashMap<ServerBucketProfile, Boolean>());
 +      this.regionAdvisor.setClientBucketProfiles(bucketId, serverProfiles);
 +    }
 +    serverProfiles.clear();
 +    for (Profile p : this.profiles) {
 +      if (p instanceof ServerBucketProfile) {
 +        serverProfiles.add((ServerBucketProfile)p);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Only for local profile.
 +   * @param p
 +   */
 +  public synchronized void updateServerBucketProfile(BucketProfile p) {
 +    this.localProfile = p;
 +  }
 +
 +  public BucketProfile getLocalProfile() {
 +    return this.localProfile;
 +  }
 +  
 +  @Override
 +  public boolean removeId(ProfileId memberId, 
 +                          boolean crashed,
 +                          boolean destroyed,
 +                          boolean fromMembershipListener) {
 +    boolean hadBucketRegion = super.removeId(memberId, crashed, destroyed, fromMembershipListener);
 +    if (hadBucketRegion) {
 +      // do NOT call notPrimary under synchronization
 +      try {
 +        notPrimary((InternalDistributedMember)memberId);
 +      } catch (CancelException e) {
 +        // must be closing the cache - no need to try to become primary
 +      }
 +    }
 +    return hadBucketRegion;
 +  }
 +
 +  /**
 +   * Removes the profile for the specified member. If that profile is marked
 +   * as primary, this will call {@link #notPrimary(InternalDistributedMember)}.
 +   * 
 +   * @param memberId the member to remove the profile for
 +   * @param serialNum specific serial number to remove
 +   * @return true if a matching profile for the member was found
 +   */
 +  @Override
 +  public boolean removeIdWithSerial(InternalDistributedMember memberId,
 +                                    int serialNum, boolean regionDestroyed) {
 +    boolean hadBucketRegion = super.removeIdWithSerial(memberId, serialNum, regionDestroyed);
 +    if (hadBucketRegion) {
 +      // do NOT call notPrimary under synchronization
 +      notPrimary(memberId);
 +    }
 +    forceNewMembershipVersion();
 +    return hadBucketRegion;
 +  }
 +
 +  @Override
 +  public Set adviseProfileExchange() {
 +    // delegate up to RegionAdvisor to include members that might have 
 +    // ProxyBucketRegion without a real BucketRegion
 +    Assert.assertTrue(this.regionAdvisor.isInitialized());
 +    return this.regionAdvisor.adviseBucketProfileExchange();
 +  }
 +
 +  @Override
 +  public Set adviseProfileUpdate() {
 +    // delegate up to RegionAdvisor to include members that might have 
 +    // ProxyBucketRegion without a real BucketRegion
 +    return this.regionAdvisor.adviseGeneric();
 +  }
 +  
 +  /**
 +   * Sets hosting to false and returns without closing. Calling closeAdvisor
 +   * will actually close this advisor.
 +   */
 +  @Override
 +  public void close() {
 +    // ok, so BucketRegion extends DistributedRegion which calls close on the
 +    // advisor, BUT the ProxyBucketRegion truly owns the advisor and only it
 +    // should be able to close the advisor...
 +    //
 +    // if a BucketRegion closes, it will call this method and we want to change
 +    // our state to NOT_HOSTING
 +    //
 +    // see this.closeAdvisor()
 +    setHosting(false);
 +  }
 +  
 +  /** 
 +   * Blocks until there is a known primary and return that member, but only
 +   * if there are real bucket regions that exist. If there are no real
 +   * bucket regions within the distribution config's member-timeout setting
 +   * * 3 (time required to eject a member) + 15000, then 
 +   * this returns null.
 +   *
 +   * kbanks: reworked this method to avoid JIT issue #40639 
 +   *
 +   * @return the member who is primary for this bucket
 +   */
 +  public final InternalDistributedMember getPrimary() {
 +    InternalDistributedMember primary = getExistingPrimary();
 +    if(primary == null){
 +        primary = waitForNewPrimary();
 +    }
 +    return primary;
 +  }
 +
 +  /** 
 +   * This method was split out from getPrimary() due to bug #40639
 +   * and is only intended to be called from within that method.
 +   * @see #getPrimary()
 +   * @return the existing primary (if it is still in the view) otherwise null
 +   */
 +  private final InternalDistributedMember getExistingPrimary() {
 +    return basicGetPrimaryMember();
 +  }
 +  
 +  /**
 +   * If the current member is primary for this bucket return true, otherwise, 
 +   * give some time for the current member to become primary and
 +   * then return whether it is a primary (true/false).
 +   */
 +  public final boolean isPrimaryWithWait() {
 +    if (this.isPrimary()) {
 +      return true;
 +    }
 +    // wait for the current member to become primary holder
 +    InternalDistributedMember primary = waitForNewPrimary(); 
 +    if(primary != null) {
 +        return true;
 +    }
 +    return false;
 +  }
 +
 +  /** 
 +   * This method was split out from getPrimary() due to bug #40639
 +   * and is only intended to be called from within that method.
 +   * @see #getPrimary()
 +   * @return the new primary
 +   */
 +  private final InternalDistributedMember waitForNewPrimary() {
 +    DM dm = this.regionAdvisor.getDistributionManager();
 +    DistributionConfig config = dm.getConfig();
 +    // failure detection period
 +    long timeout = config.getMemberTimeout() * 3;
 +    // plus time for a new member to become primary
 +    timeout += Long.getLong("gemfire.BucketAdvisor.getPrimaryTimeout",
 +                            15 * 1000);
 +    InternalDistributedMember newPrimary = waitForPrimaryMember(timeout);
 +    return newPrimary;
 +  }
 +  
 +   /** 
 +   * Marks member as not primary. Initiates volunteerForPrimary if this
 +   * member is hosting a real bucket. This method does nothing
 +   * if the member parameter is the current member.
 +   * 
 +   * @param member the member who is not primary
 +   */
 +  public void notPrimary(InternalDistributedMember member) {
 +    //Fix for 43569. Only the deposePrimary call should
 +    //make the local member drop the primary lock.
 +    if(!member.equals(getDistributionManager().getId())) {
 +      removePrimary(member);
 +    }
 +  }
 + 
 +  /** 
 +   * Marks member as not primary. Initiates volunteerForPrimary if this
 +   * member is hosting a real bucket.
 +   * 
 +   * @param member the member who is not primary
 +   */
 +  public void removePrimary(InternalDistributedMember member) {
 +    boolean needToVolunteerForPrimary = false;
 +    if (!isClosed()) { // hole: requestPrimaryState not hosting
 +      initializationGate();
 +    }
 +    boolean lostPrimary = false;
 +    try {
 +      synchronized(this) {
 +        boolean wasPrimary = isPrimary() && this.getDistributionManager().getId().equals(member);
 +        final InternalDistributedMember currentPrimary = (InternalDistributedMember) this.primaryMember.get();
 +        if (currentPrimary != null && currentPrimary.equals(member)) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("[BucketAdvisor.notPrimary] {} for {}", member, this);
 +          }
 +          this.primaryMember.set(null);
 +        } 
 +        else {
 +          return;
 +        }
 +        
 +        if (isClosed()) { 
 +          // possibly closed if caller comes from outside this advisor
 +          return; // return quietly
 +        }
 +        // member is primary... need to change state to NO_PRIMARY_xxx
 +        if (isHosting()) {
 +          requestPrimaryState(NO_PRIMARY_HOSTING);
 +          if (this.pRegion.isFixedPartitionedRegion()) {
 +            InternalDistributedMember primaryMember = this.regionAdvisor
 +                .adviseFixedPrimaryPartitionDataStore(this.getBucket().getId());
 +            if (primaryMember == null || primaryMember.equals(member)) {
 +              needToVolunteerForPrimary = true;
 +            }
 +            else {
 +              needToVolunteerForPrimary = false;
 +            }
 +          }
 +          else {
 +            needToVolunteerForPrimary = true;
 +          }
 +        }
 +        else {
 +          requestPrimaryState(NO_PRIMARY_NOT_HOSTING);
 +        }
 +        if(wasPrimary) {
 +          lostPrimary = true;
 +        }
 +
 +        // try to fix yet another cause of bug 36881
 +        findAndSetPrimaryMember();
 +      }
 +    } finally {
 +      if (lostPrimary) {
 +        Bucket br = this.regionAdvisor.getBucket(getBucket().getId());
 +        if( br != null && br instanceof BucketRegion) {
 +          ((BucketRegion)br).beforeReleasingPrimaryLockDuringDemotion();
 +        }
 +
 +        releasePrimaryLock();
 +        // this was a deposePrimary call so we need to depose children as well
 +        deposePrimaryForColocatedChildren();
 +        if (this.pRegion.isFixedPartitionedRegion()) {
 +          deposeOtherPrimaryBucketForFixedPartition();
 +        }
 +      }
 +    }
 +    
 +    if (needToVolunteerForPrimary) {
 +      volunteerForPrimary();
 +    }
 +  }
 +  
 +  /** 
 +   * Returns the ProxyBucketRegion which owns this advisor.
 +   * 
 +   * @return the ProxyBucketRegion which owns this advisor
 +   */
 +  public ProxyBucketRegion getProxyBucketRegion() {
 +    return (ProxyBucketRegion)getAdvisee();
 +  }
 +
 +  /** 
 +   * Actually close this advisor for real. Called by ProxyBucketRegion only. 
 +   * Calling this method actually closes this advisor whereas {@link #close()}
 +   * only sets hosting to false.
 +   */
 +  protected void closeAdvisor() {
 +    boolean wasPrimary;
 +    synchronized(this) {
 +      if (isClosed()) {
 +        return;
 +      }
 +      wasPrimary = isPrimary();
 +      super.close();
 +      this.requestPrimaryState(CLOSED);
 +      if (!this.redundancySatisfied){
 +        incLowRedundancyBucketCount(-1);
 +        this.redundancySatisfied = true;
 +      }
 +      this.localProfile = null;
 +    }
 +    if(wasPrimary) {
 +      releasePrimaryLock();
 +    }
 +  }
 +  
 +  /** 
 +   * Returns true if this advisor has been closed.
 +   * 
 +   * @return true if this advisor has been closed
 +   */
 +  protected boolean isClosed() {
 +    synchronized(this) {
 +      return this.primaryState == CLOSED;
 +    }
 +  }
 +
 +  /** 
 +   * Returns true if this member is currently marked as primary.
 +   * 
 +   * @return true if this member is currently marked as primary
 +   */
 +  public boolean isPrimary() {
 +    synchronized(this) {
 +      return this.primaryState == IS_PRIMARY_HOSTING;
 +    }
 +  }
 +  
 +  /** 
 +   * Returns true if this member is currently volunteering for primary. 
 +   * 
 +   * @return true if this member is currently volunteering for primary
 +   */
 +  protected boolean isVolunteering() {
 +    synchronized(this) {
 +      return this.primaryState == VOLUNTEERING_HOSTING;
 +    }
 +  }
 +
 +  /** 
 +   * Returns true if this member is currently attempting to become primary. 
 +   * 
 +   * @return true if this member is currently attempting to become primary
 +   */
 +  protected boolean isBecomingPrimary() {
 +    synchronized(this) {
 +      return this.primaryState == BECOMING_HOSTING && 
 +             this.volunteeringDelegate != null &&
 +             this.volunteeringDelegate.isAggressive();
 +    }
 +  }
 +
 +  /** 
 +   * Returns true if this member is currently hosting real bucket.
 +   * 
 +   * @return true if this member is currently hosting real bucket
 +   */
 +  public boolean isHosting() {
 +    synchronized(this) {
 +      return this.primaryState == NO_PRIMARY_HOSTING ||
 +             this.primaryState == OTHER_PRIMARY_HOSTING ||
 +             this.primaryState == VOLUNTEERING_HOSTING ||
 +             this.primaryState == BECOMING_HOSTING ||
 +             this.primaryState == IS_PRIMARY_HOSTING;
 +    }
 +  }
 +  
 +  /**
 +   * Attempt to acquire lock for primary until a primary exists. Caller hands
 +   * off responsibility to an executor (waiting pool) and returns early.
 +   */
 +  public void volunteerForPrimary() {
 +    if (primaryElector != null) {
 +      return;
 +    }
 +    initializationGate();
 +
 +    synchronized (this) {
 +      if (isVolunteering() || isClosed() || !isHosting()) {
 +        // only one thread should be attempting to volunteer at one time
 +        return;
 +      }
 +      // if member is still not initialized then don't volunteer for primary
 +      final GemFireCacheImpl cache = (GemFireCacheImpl)getBucket().getCache();
 +      if (!cache.doVolunteerForPrimary(this)) {
 +        return;
 +      }
 +      if (this.volunteeringDelegate == null) {
 +        this.volunteeringDelegate = new VolunteeringDelegate();
 +      }
 +      this.volunteeringDelegate.volunteerForPrimary();
 +    }
 +  }
 +
 +  /**
 +   * Makes this <code>BucketAdvisor</code> become the primary if it is already
 +   * a secondary.
 +   * 
 +   * @param isRebalance true if directed to become primary by rebalancing
 +   * @return true if this advisor succeeds in becoming the primary
 +   */
 +  public boolean becomePrimary(boolean isRebalance) {
 +    initializationGate();
 +
 +    long startTime 
 +        = getPartitionedRegionStats().startPrimaryTransfer(isRebalance);
 +    try {
 +      long waitTime = 2000; // time each iteration will wait
 +      while (!isPrimary()) {
 +        this.getAdvisee().getCancelCriterion().checkCancelInProgress(null);
 +        boolean attemptToBecomePrimary = false;
 +        boolean attemptToDeposePrimary = false;
 +        
 +        if (Thread.currentThread().isInterrupted()) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Breaking from becomePrimary loop due to thread interrupt flag being set");
 +          }
 +          break;
 +        }
 +        if (isClosed() || !isHosting()) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Breaking from becomePrimary loop because {} is closed or not hosting", this);
 +          }
 +          break;
 +        }
 +        
 +        VolunteeringDelegate vDelegate = null;
 +        synchronized (this) {
 +          if (isVolunteering()) {
 +            // standard volunteering attempt already in progress...
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Waiting for volunteering thread {}. Time left: {} ms", this, waitTime);
 +            }
 +            this.wait(waitTime); // spurious wakeup ok
 +            continue;
 +            
 +          } else if (isBecomingPrimary()) {
 +            // reattempt to depose otherPrimary...
 +            attemptToDeposePrimary = true;
 +            
 +          } else {
 +              // invoke becomePrimary AFTER sync is released in this thread...
 +              vDelegate = this.volunteeringDelegate;
 +              if (vDelegate == null) {
 +                vDelegate = new VolunteeringDelegate();
 +                this.volunteeringDelegate = vDelegate;
 +              }
 +          } // else
 +        } // synchronized
 +        
 +        if (vDelegate != null) {
 +          // Use the snapshot 'vDelegate' instead of 'this.volunteeringDelegate' since we are not synced here.
 +          attemptToBecomePrimary = vDelegate.reserveForBecomePrimary(); // no sync! 
 +        }
 +          
 +        // release synchronization and then call becomePrimary
 +        if (attemptToBecomePrimary) {
 +          synchronized (this) {
 +            if (this.volunteeringDelegate == null) {
 +              this.volunteeringDelegate = new VolunteeringDelegate();
 +            }
 +            this.volunteeringDelegate.volunteerForPrimary();
 +            attemptToDeposePrimary = true;
 +          } // synchronized
 +          Thread.sleep(10);
 +        } // attemptToBecomePrimary
 +          
 +        // RACE: slight race condition with thread that's actually requesting the lock
 +
 +        if (attemptToDeposePrimary) {
 +          InternalDistributedMember otherPrimary = getPrimary();
 +          if (otherPrimary != null && 
 +              !getDistributionManager().getId().equals(otherPrimary)) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Attempting to depose primary on {} for {}", otherPrimary, this);
 +            }
 +            DeposePrimaryBucketResponse response = 
 +                DeposePrimaryBucketMessage.send(
 +                    otherPrimary, 
 +                    this.pRegion, 
 +                    getBucket().getId());
 +            if (response != null) {
 +              response.waitForRepliesUninterruptibly();
 +              if (logger.isDebugEnabled()) {
 +                logger.debug("Deposed primary on {}", otherPrimary);
 +              }
 +            }
 +          }
 +          Thread.sleep(10);
 +        } // attemptToDeposePrimary
 +        
 +      } // while
 +      
 +    } catch (InterruptedException e) {
 +      // abort and return null
 +      Thread.currentThread().interrupt();
 +      
 +    } finally {
 +      getPartitionedRegionStats().endPrimaryTransfer(
 +          startTime, isPrimary(), isRebalance);
 +    }
 +    
 +    return isPrimary();
 +  }
 +  
 +  /**
 +   * Check the primary member shortcut.  Does not query the advisor.  Should
 +   * only be used when the advisor should not be consulted directly.
 +   *  
 +   * @return the member or null if no primary exists
 +   */
 +  public final InternalDistributedMember basicGetPrimaryMember() {
 +    return (InternalDistributedMember) this.primaryMember.get();
 +  }
 +  
 +  /** 
 +   * Invoked when the primary lock has been acquired by this VM.
 +   * 
 +   * @return true if successfully changed state to IS_PRIMARY
 +   */
 +  protected boolean acquiredPrimaryLock() {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Acquired primary lock for BucketID {} PR : {}", getBucket().getId(), regionAdvisor.getPartitionedRegion().getFullPath());
 +    }
 +    boolean changedStateToIsPrimary = false;
 +    //Hold the primary move lock until we send a 
 +    //profile update. This will prevent writes
 +    //from occurring until all members know that
 +    //this member is now the primary.
 +    boolean shouldInvokeListeners = false;
 +    activePrimaryMoveLock.lock();
 +    try {
 +      synchronized (this) {
 +        if (isHosting() && (isVolunteering() || isBecomingPrimary())) {
 +          Bucket br = this.regionAdvisor.getBucket(getBucket().getId());
 +          if (br != null && br instanceof BucketRegion) {
 +            ((BucketRegion)br).beforeAcquiringPrimaryState();
 +          }
 +          if (requestPrimaryState(IS_PRIMARY_HOSTING)) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("Acquired primary lock for setting primary now BucketID {} PR : {}",
 +                  getBucket().getId(), regionAdvisor.getPartitionedRegion().getFullPath());
 +            }
 +            setPrimaryMember(getDistributionManager().getId());
 +            changedStateToIsPrimary = true;
 +            if (hasPrimary() && isPrimary()) {
 +              shouldInvokeListeners = true;
 +            }
 +          }
 +        }
 +      }
 +
 +      if(shouldInvokeListeners) {
 +        invokePartitionListeners();
 +      }
 +      return changedStateToIsPrimary;
 +    }
 +    finally {
 +      try {
 +        if (changedStateToIsPrimary) {
 +          // send profile update AFTER releasing sync
 +          sendProfileUpdate();
 +
 +          Bucket br = this.regionAdvisor.getBucket(getBucket().getId());
 +          if( br != null && br instanceof BucketRegion) {
 +            ((BucketRegion)br).processPendingSecondaryExpires();
 +          }
 +          if (br instanceof BucketRegionQueue) { // Shouldn't it be AbstractBucketRegionQueue
 +            // i.e. this stats is not getting incremented for HDFSBucketRegionQueue!!
 +            BucketRegionQueue brq = (BucketRegionQueue)br;
 +            brq.incQueueSize(brq.size());
 +          }
 +          if( br != null && br instanceof BucketRegion) {
 +            ((BucketRegion)br).afterAcquiringPrimaryState();
 +          }
 +        }
 +        else {
 +          // release primary lock AFTER releasing sync
 +          releasePrimaryLock();
 +        }
 +      } finally {
 +        activePrimaryMoveLock.unlock();
 +      }
 +    }
 +  }
 +
 +  private void invokePartitionListeners() {
 +    PartitionListener[] listeners = this.pRegion
 +        .getPartitionListeners();
 +    if (listeners == null || listeners.length == 0) {
 +      return;
 +    }
 +    for (int i = 0; i < listeners.length; i++) {
 +      PartitionListener listener = listeners[i];
 +      if (listener != null) {
 +        listener.afterPrimary(getBucket().getId());
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Lazily gets the lock for acquiring primary lock. Caller must handle null.
 +   * If DLS, Cache, or DistributedSystem are shutting down then null will be
 +   * returned. If DLS does not yet exist and createDLS is false then null will
 +   * be returned.
 +   * 
 +   * @param createDLS true will create DLS if it does not exist
 +   * @return distributed lock indicating primary member or null
 +   */
 +  DistributedMemberLock getPrimaryLock(boolean createDLS) {
 +    synchronized(this) {
 +      if (this.primaryLock == null) {
 +        DistributedLockService dls = DistributedLockService.getServiceNamed(
 +            PartitionedRegionHelper.PARTITION_LOCK_SERVICE_NAME);
 +        if (dls == null) {
 +          if (!createDLS || getProxyBucketRegion().getCache().isClosed()) {
 +            return null;  // cache closure has destroyed the DLS
 +          }
 +          try { // TODO: call GemFireCache#getPartitionedRegionLockService
 +            dls = DLockService.create(
 +                PartitionedRegionHelper.PARTITION_LOCK_SERVICE_NAME, 
 +                getAdvisee().getSystem(), 
 +                true /*distributed*/, 
 +                true /*destroyOnDisconnect*/,
 +                true /*automateFreeResources*/);
 +          }
 +          catch (IllegalArgumentException e) {
 +            // indicates that the DLS is already created
 +            dls = DistributedLockService.getServiceNamed(
 +                PartitionedRegionHelper.PARTITION_LOCK_SERVICE_NAME);
 +            if (dls == null) {
 +              // another thread destroyed DLS after this thread called create
 +              return null; // ok, caller will loop if necessary
 +            }
 +          }
 +          // TODO: we need a good NotConnectedException to replace 
 +          //       IllegalStateException and ShutdownException
 +          //       perhaps: DistributedSystemUnavailableException
 +          catch (IllegalStateException e) {
 +            // create still throws IllegalStateException if isDisconnecting is true
 +            return null;
 +          }
 +          catch (DistributedSystemDisconnectedException e) {
 +            // this would certainly prevent us from creating a DLS... messy
 +            return null;
 +          }
 +        }
 +        this.primaryLock = new DistributedMemberLock(
 +            dls, 
 +            getAdvisee().getName(), DistributedMemberLock.NON_EXPIRING_LEASE,
 +            DistributedMemberLock.LockReentryPolicy.PREVENT_SILENTLY);
 +      }
 +      return this.primaryLock;
 +    }
 +  }
 +
 +  protected void acquirePrimaryRecursivelyForColocated() {
 +    final List<PartitionedRegion> colocatedWithList = ColocationHelper
 +        .getColocatedChildRegions(regionAdvisor.getPartitionedRegion());
 +    if (colocatedWithList != null) {
 +      for (PartitionedRegion childPR : colocatedWithList) {
 +        Bucket b = childPR.getRegionAdvisor().getBucket(getBucket().getId());
 +        BucketAdvisor childBA = b.getBucketAdvisor();
 +        Assert.assertHoldsLock(childBA, false);
 +        boolean acquireForChild = false;
 +
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("BucketAdvisor.acquirePrimaryRecursivelyForColocated: about to take lock for bucket: {} of PR: {} with isHosting={}",
 +              getBucket().getId(), childPR.getFullPath(), childBA.isHosting());
 +        }
 +        childBA.activePrimaryMoveLock.lock();
 +        try {
 +          if (childBA.isHosting()) {
 +            if (isPrimary()) {
 +              if (!childBA.isPrimary()) {
 +                childBA.setVolunteering();
 +                boolean acquired = childBA.acquiredPrimaryLock();
 +                acquireForChild = true;
 +                if (acquired && this.pRegion.isFixedPartitionedRegion()) {
 +                  childBA.acquirePrimaryForRestOfTheBucket();
 +                }
 +              }else {
 +                acquireForChild = true;
 +              }
 +            }
 +          } // if isHosting
 +          if (acquireForChild) {
 +            childBA.acquirePrimaryRecursivelyForColocated();
 +          }
 +        }
 +        finally {
 +          childBA.activePrimaryMoveLock.unlock();
 +        }
 +      }
 +    }
 +  }
 +
 +  protected void acquirePrimaryForRestOfTheBucket() {
 +    List<FixedPartitionAttributesImpl> fpas = this.pRegion
 +        .getFixedPartitionAttributesImpl();
 +    if (fpas != null) {
 +      int bucketId = getBucket().getId();
 +      for (FixedPartitionAttributesImpl fpa : fpas) {
 +        if (fpa.getStartingBucketID() == bucketId) {
 +          for (int i = bucketId + 1; i <= fpa.getLastBucketID();) {
 +            Bucket b = regionAdvisor.getBucket(i++);
 +            if (b != null) {
 +              BucketAdvisor ba = b.getBucketAdvisor();
 +              ba.activePrimaryMoveLock.lock();
 +              try {
 +                if (ba.isHosting()) {
 +                  if (!ba.isPrimary()) {
 +                    ba.setVolunteering();
 +                    ba.acquiredPrimaryLock();
 +                  }
 +                }
 +              } finally {
 +                ba.activePrimaryMoveLock.unlock();
 +              }
 +            }
 +          }
 +        }
 +        else {
 +          continue;
 +        }
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Sets volunteering to true. Returns true if the state of volunteering was
 +   * changed. Returns false if voluntering was already equal to true. Caller
 +   * should do nothing if false is returned.
 +   */
 +  protected boolean setVolunteering() {
 +    synchronized(this) {
 +      return requestPrimaryState(VOLUNTEERING_HOSTING);
 +    }
 +  }
 +
 +  /**
 +   * Sets becoming primary to true. Returns true if the state of becoming was
 +   * changed. Returns false if becoming was already equal to true. Caller
 +   * should do nothing if false is returned.
 +   */
 +  protected boolean setBecoming() {
 +    synchronized(this) {
 +      return requestPrimaryState(BECOMING_HOSTING);
 +    }
 +  }
 +  
 +  /** 
 +   * Wait briefly for a primary member to be identified.
 +   * 
 +   * @param timeout time in milliseconds to wait for a primary
 +   * @return the primary bucket host
 +   */
 +  protected InternalDistributedMember waitForPrimaryMember(long timeout) {
 +    synchronized (this) {
 +      // let's park this thread and wait for a primary!
 +      StopWatch timer = new StopWatch(true);
 +      long warnTime = getDistributionManager().getConfig().getAckWaitThreshold() * 1000L;
 +      boolean loggedWarning = false;
 +      try {
 +        for (;;) {
 +          // bail out if the system starts closing
 +          this.getAdvisee().getCancelCriterion().checkCancelInProgress(null);
 +          final GemFireCacheImpl cache = (GemFireCacheImpl)getBucket().getCache();
 +          if (cache != null && cache.isCacheAtShutdownAll()) {
 +            throw new CacheClosedException("Cache is shutting down");
 +          }
 +
 +          if (getBucketRedundancy() == -1 ) {
 +            // there are no real buckets in other vms... no reason to wait
 +            return null;
 +          }
 +          getProxyBucketRegion().getPartitionedRegion().checkReadiness();
 +          if (isClosed()) {
 +            break;
 +          }
 +          long elapsed = timer.elapsedTimeMillis();
 +          long timeLeft = timeout - elapsed;
 +          if (timeLeft <= 0) {
 +            break;
 +          }
 +          if (getBucketRedundancy() == -1 || isClosed() ) {
 +            break; // early out... all bucket regions are gone or we closed
 +          }
 +          InternalDistributedMember primary = basicGetPrimaryMember();
 +          if (primary != null) {
 +            return primary;
 +          }
 +  
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Waiting for bucket {}. Time left :{} ms", this, timeLeft);
 +          }
 +          
 +          //Log a warning if we have waited for the ack wait threshold time.
 +          if(!loggedWarning) {
 +            long timeUntilWarning = warnTime - elapsed;
 +            if(timeUntilWarning <= 0 ) {
 +              logger.warn(LocalizedMessage.create(LocalizedStrings.BucketAdvisor_WAITING_FOR_PRIMARY,
 +                  new Object[] {warnTime / 1000L, this, this.adviseInitialized()}));
 +              //log a warning;
 +              loggedWarning=true;
 +            } else {
 +              timeLeft = timeLeft > timeUntilWarning ? timeUntilWarning : timeLeft;
 +            }
 +          }
 +          this.wait(timeLeft); // spurious wakeup ok
 +        }
 +      }
 +      catch (InterruptedException e) {
 +        // abort and return null
 +        Thread.currentThread().interrupt();
 +      } finally {
 +        if(loggedWarning) {
 +          logger.info(LocalizedMessage.create(LocalizedStrings.BucketAdvisor_WAITING_FOR_PRIMARY_DONE));
 +        }
 +      }
 +      return null;
 +    }
 +  }
 +
 +  /**
 +   * How long to wait, in millisecs, for redundant buckets to exist
 +   */
 +  private final static long BUCKET_REDUNDANCY_WAIT = 15000L; // 15 seconds
 +
 +  /** 
 +   * Wait the desired redundancy to be met.
 +   * @param minRedundancy the amount of desired redundancy.
 +   * @return true if desired redundancy is detected
 +   */
 +  public boolean waitForRedundancy(int minRedundancy) {
 +    synchronized (this) {
 +      // let's park this thread and wait for redundancy!
 +      StopWatch timer = new StopWatch(true);
 +      try {
 +        for (;;) {
 +          if (getBucketRedundancy() >= minRedundancy) {
 +            return true;
 +          }
 +          getProxyBucketRegion().getPartitionedRegion().checkReadiness();
 +          if (isClosed()) {
 +            return false;
 +          }
 +          long timeLeft = BUCKET_REDUNDANCY_WAIT - timer.elapsedTimeMillis();
 +          if (timeLeft <= 0) {
 +            return false;
 +          }
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Waiting for bucket {}", this);
 +          }
 +          this.wait(timeLeft); // spurious wakeup ok
 +        }
 +      }
 +      catch (InterruptedException e) {
 +        // abort and return null
 +        Thread.currentThread().interrupt();
 +      }
 +      return false;
 +    }
 +  }
 +
 +  private final static long BUCKET_STORAGE_WAIT = Long.getLong("gemfire.BUCKET_STORAGE_WAIT", 15000).longValue(); // 15 seconds
 +  
 +  public boolean waitForStorage() {
 +    synchronized (this) {
 +      // let's park this thread and wait for storage!
 +      StopWatch timer = new StopWatch(true);
 +      try {
 +        for (;;) {
 +          if (this.regionAdvisor.isBucketLocal(getBucket().getId())) {
 +            return true;
 +          }
 +          getProxyBucketRegion().getPartitionedRegion().checkReadiness();
 +          if (isClosed()) {
 +            return false;
 +          }
 +          long timeLeft = BUCKET_STORAGE_WAIT - timer.elapsedTimeMillis();
 +          if (timeLeft <= 0) {
 +            return false;
 +          }
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Waiting for bucket storage" + this);
 +          }
 +          this.wait(timeLeft); // spurious wakeup ok
 +        }
 +      }
 +      catch (InterruptedException e) {
 +        // abort and return null
 +        Thread.currentThread().interrupt();
 +      }
 +      return false;
 +    }
 +  }
 +  public void clearPrimaryElector() {
 +    synchronized(this) {
 +      primaryElector = null;
 +    }
 +  }
 +  
 +  public void setPrimaryElector(InternalDistributedMember newPrimaryElector) {
 +    synchronized(this) {
 +      //Only set the new primary elector if we have not yet seen
 +      //a primary for this bucket.
 +      if(primaryElector != null) {
 +        this.primaryElector = newPrimaryElector;
 +      }
 +    }
 +  }
 +  
 +  
 +  public synchronized void initializePrimaryElector(InternalDistributedMember primaryElector) {
 +    //For child buckets, we want the parent bucket to take care'
 +    //of finishing an incomplete bucket creation, so only set the elector for
 +    //the leader region.
 +    if(parentAdvisor == null) {
 +      this.primaryElector = primaryElector;
 +    }
 +  }
 +  
 +  /** 
 +   * Invoked when real bucket is created for hosting in this VM.
 +   * 
 +   * @param value true to begin hosting; false to end hosting
 +   */
 +  protected void setHosting(boolean value) {
 +    //boolean needToNotPrimarySelf = false;
 +    boolean needToVolunteerForPrimary = false;
 +    boolean wasPrimary = false;
 +    synchronized(this) {
 +      wasPrimary = isPrimary();
 +      if (isClosed()) {
 +        return;
 +      }     
 +      if (value) { // setting to HOSTING...
 +        if (hasPrimary()) {
 +          requestPrimaryState(OTHER_PRIMARY_HOSTING);
 +        }
 +        else {
 +          requestPrimaryState(NO_PRIMARY_HOSTING);
 +          needToVolunteerForPrimary = true;
 +        }
 +      }
 +
 +      else { // setting to NOT_HOSTING...
 +        if (hasPrimary()) { // has primary...
 +          if (isPrimary()) {
 +            requestPrimaryState(NO_PRIMARY_NOT_HOSTING);
 +            this.primaryMember.set(null);
 +            findAndSetPrimaryMember();
 +          }
 +          else {
 +            requestPrimaryState(OTHER_PRIMARY_NOT_HOSTING);
 +          }
 +        }
 +        else { // no primary...
 +          // acquiredPrimaryLock will check isHosting and release if not hosting
 +          requestPrimaryState(NO_PRIMARY_NOT_HOSTING);
 +        }
 +      }
 +      this.volunteeringDelegate = null;
 +
 +      //Note - checkRedundancy has the side effect that it updates the stats.
 +      //We need to invoke checkRedundancy here, regardless of whether we
 +      //need this notify.
 +      if (updateRedundancy() > 0 && isHosting()) {
 +        // wake up any threads in waitForRedundancy or waitForPrimary
 +        this.notifyAll(); 
 +      }
 +    }
 +    if(wasPrimary) {
 +      releasePrimaryLock();
 +    }
 +
 +    if (logger.isTraceEnabled()) {
 +      logger.trace("setHosting: {} needToVolunteerForPrimary={} primaryElector: {}", this, needToVolunteerForPrimary, primaryElector);
 +    }
 +    /*if (needToNotPrimarySelf) {
 +      notPrimary(getAdvisee().getDistributionManager().getId());
 +    }*/
 +    if (needToVolunteerForPrimary) {
 +      if(this.primaryElector == null) {
 +        volunteerForPrimary();
 +      }
 +    }
 +    
 +    sendProfileUpdate();
 +  }
 +  
 +  /**
 +   * Sends updated profile for this member to every member with the 
 +   * <code>PartitionedRegion</code>.
 +   * <p>
 +   * Never call this method while synchronized on this BucketAdvisor. This will
 +   * result in distributed deadlocks.
 +   */
 +  private void sendProfileUpdate() {
 +    if (this.getDistributionManager().getSystem().isLoner()) { 
 +      // no one to send the profile update... return to prevent bug 39760 
 +      return; 
 +    } 
 +    // make sure caller is not synchronized or we'll deadlock
 +    Assert.assertTrue( ! Thread.holdsLock(this), 
 +        "Attempting to sendProfileUpdate while synchronized may result in deadlock");
 +    // NOTE: if this assert fails, you COULD use the WaitingThreadPool in DM
 +
 +    final int partitionedRegionId = this.pRegion.getPRId();
 +    final int bucketId = ((ProxyBucketRegion) getAdvisee()).getBucketId();
 +    
 +    BucketProfile bp = (BucketProfile) createProfile();
 +    updateServerBucketProfile(bp);
 +    InternalDistributedMember primary = basicGetPrimaryMember();
 +    HashSet hostsAndProxyMembers = new HashSet();
 +    if (primary != null && !primary.equals(getDistributionManager().getId())) {
 +      hostsAndProxyMembers.add(primary); // Add the primary
 +    }
 +    hostsAndProxyMembers.addAll(adviseGeneric()); // Add all members hosting the bucket
 +    hostsAndProxyMembers.addAll(adviseProfileUpdate()); // Add all proxy instances that could use the bucket
 +    ReplyProcessor21 reply = BucketProfileUpdateMessage.send(hostsAndProxyMembers, getDistributionManager(),
 +        partitionedRegionId, bucketId, bp, true);
 +    if(reply != null) {
 +      reply.waitForRepliesUninterruptibly();
 +    }
 +  }
 +  
 +  /** 
 +   * Returns true if the a primary is known. 
 +   */
 +  private boolean hasPrimary() {
 +    synchronized(this) {
 +      return this.primaryState == OTHER_PRIMARY_NOT_HOSTING || 
 +      this.primaryState == OTHER_PRIMARY_HOSTING ||
 +      this.primaryState ==IS_PRIMARY_HOSTING;
 +    }
 +  }
 +
 +  @Override
 +  protected Profile instantiateProfile(InternalDistributedMember memberId,
 +      int version) {
 +    if (!this.pRegion.isShadowPR()) {
 +      GemFireCacheImpl c = getProxyBucketRegion().getCache();
 +      List servers = null;
 +      servers = c.getCacheServers();
 +
 +      HashSet<BucketServerLocation66> serverLocations = new HashSet<BucketServerLocation66>();
 +      for (Object object : servers) {
 +        CacheServerImpl server = (CacheServerImpl)object;
 +        if (server.isRunning() && (server.getExternalAddress() != null)) {
 +          BucketServerLocation66 location = new BucketServerLocation66(
 +              getBucket().getId(), server.getPort(), server
 +                  .getExternalAddress()
 +              /* .getExternalAddress(false/ checkServerRunning ) */,
 +              getBucket().isPrimary(), Integer.valueOf(version).byteValue(),
 +              server.getCombinedGroups());
 +          serverLocations.add(location);
 +        }
 +      }
 +      if (serverLocations.size() > 0) {
 +        return new ServerBucketProfile(memberId, version, getBucket(),
 +            serverLocations);
 +      }
 +    }
 +    return new BucketProfile(memberId, version, getBucket());
 +  }
 +  
 +  /** 
 +   * Sets primaryMember and notifies all. Caller must be synced on this.
 +   * 
 +   * @param id the member to use as primary for this bucket
 +   */
 +  void setPrimaryMember(InternalDistributedMember id) {
 +    if (!getDistributionManager().getId().equals(id)) {
 +      // volunteerForPrimary handles primary state change if its our id
 +      if (isHosting()) {
 +        requestPrimaryState(OTHER_PRIMARY_HOSTING);
 +      }
 +      else {
 +        requestPrimaryState(OTHER_PRIMARY_NOT_HOSTING);
 +      }
 +    }
 +    this.primaryMember.set(id);
 +    this.everHadPrimary = true;
 +    
 +    if(id != null && id.equals(primaryElector)) {
 +      primaryElector = null;
 +    }
 +    this.notifyAll(); // wake up any threads in waitForPrimaryMember
 +  }
 +  
 +  public void setHadPrimary() {
 +    this.everHadPrimary = true;
 +  }
 +  
 +  public boolean getHadPrimary() {
 +    return this.everHadPrimary;
 +  }
 +  
 +  public InternalDistributedMember getPrimaryElector() {
 +    return primaryElector;
 +  }
 +
 +  /**
 +   * Determine if there has been a change in redundancy and alter the
 +   * lowRedundancyBucketCount stat as needed.
 +   * 
 +   * Also updates a counter used to track the redundancy of this member
 +   * 
 +   * @return current number of hosts for this bucket 
 +   * @see #redundancySatisfied
 +   * @see PartitionedRegionStats#incLowRedundancyBucketCount(int)
 +   * @guarded.By this
 +   */
 +  private int updateRedundancy() {
 +    int desiredRedundancy = 
 +        this.pRegion.getRedundantCopies();
 +    int numBucketHosts = getNumInitializedBuckets();
 +    if (isClosed()) {
 +      return numBucketHosts;
 +    }
 +    int actualRedundancy = numBucketHosts - 1;
 +    this.redundancy = actualRedundancy;
 +    if (this.redundancySatisfied && 
 +        numBucketHosts > 0 &&
 +        actualRedundancy < desiredRedundancy) {
 +      incLowRedundancyBucketCount(1);
 +      this.redundancySatisfied = false;
 +    }
 +    else if (!this.redundancySatisfied &&
 +             numBucketHosts > 0 &&
 +             actualRedundancy >= desiredRedundancy){
 +      incLowRedundancyBucketCount(-1);
 +      this.redundancySatisfied = true;
 +      this.redundancyEverSatisfied = true;
 +    }
 +    return numBucketHosts;
 +  }
 +  
 +  /**
 +   * Returns all {@link InternalDistributedMember}s currently
 +   * flagged as primary.
 +   * <p>
 +   * Since profile messages may arrive out of order from different members,
 +   * more than one member may temporarily be flagged as primary.
 +   * <p>
 +   * The user of this BucketAdvisor should simply assume that the first
 +   * profile is primary until the dust settles, leaving only one primary
 +   * profile.
 +   * 
 +   * @return zero or greater array of primary members
 +   */
 +  private InternalDistributedMember[] findPrimaryMembers() {
 +    Set primaryMembers = adviseFilter(new Filter() {
 +      public boolean include(Profile profile) {
 +        assert profile instanceof BucketProfile;
 +        BucketProfile srp = (BucketProfile) profile;
 +        return srp.isPrimary;
 +      }
 +    });
 +    if (primaryMembers.size() > 1 && logger.isDebugEnabled()) {
 +      logger.debug("[findPrimaryProfiles] found the following primary members for {}: {}", getAdvisee().getName(), primaryMembers);
 +    }
 +    return (InternalDistributedMember[]) primaryMembers.toArray(
 +        new InternalDistributedMember[primaryMembers.size()]);
 +  }
 +
 +  /**
 +   * Searches through profiles to find first profile that is flagged as 
 +   * primary and sets {@link #primaryMember} to it. Caller must synchronize
 +   * on this BucketAdvisor.
 +   * 
 +   * @return true if a primary member was found and used
 +   * @see #findAndSetPrimaryMember()
 +   */
 +  boolean findAndSetPrimaryMember() {
 +    if(isPrimary()) {
 +      setPrimaryMember(this.getDistributionManager().getDistributionManagerId());
 +      return true;
 +    }
 +    InternalDistributedMember[] primaryMembers = findPrimaryMembers();
 +    if (primaryMembers.length > 0) {
 +      setPrimaryMember(primaryMembers[0]);
 +      return true;
 +    }
 +    else {
 +      return false;
 +    }
 +  }
 +  
 +  /**
 +   * Returns the current redundancy of the this bucket, including the locally
 +   * hosted bucket if it exists.
 +   * 
 +   * @return current number of hosts of this bucket ; -1 if there are no hosts
 +   */
 +  public final int getBucketRedundancy() {
 +    return redundancy;
 +  }
 +  
 +  public Set<InternalDistributedMember> adviseInitialized() {
 +    return adviseFilter(new Filter() {
 +      public boolean include(Profile profile) {
 +        assert profile instanceof BucketProfile;
 +        BucketProfile bucketProfile = (BucketProfile) profile;
 +        return bucketProfile.isHosting;
 +      }
 +    });
 +    
 +  }
 +  
 +  public Set<InternalDistributedMember> adviseRecoveredFromDisk() {
 +    return regionAdvisor.adviseInitializedDataStore();
 +  }
 +  
 +  /**
 +   * Get the number of members that are hosting the bucket, and have
 +   * finished initialization.
 +   * 
 +   * This method is currently only used to check the bucket
 +   * redundancy just before creating the bucket. If it is used
 +   * more frequently, it might be better to cache this count.
 +   */
 +  private int getNumInitializedBuckets() {
 +    Profile[] locProfiles = this.profiles; // grab current profiles
 +    int count = 0;
 +    for(Profile profile: locProfiles) {
 +      BucketProfile bucketProfile = (BucketProfile) profile;
 +      if(bucketProfile.isHosting) {
 +        count++;
 +      }
 +    }
 +    if(isHosting()) {
 +      count++;
 +    }
 +    return count;
 +  }
 +  
 +  private Bucket getBucket() {
 +    return (Bucket)getAdvisee();
 +  }
 +  
 +  /**
 +   * Releases the primary lock for this bucket.
 +   */
 +  protected void releasePrimaryLock() {
 +    //We don't have a lock if we have a parent advisor
 +    if(parentAdvisor != null) {
 +      return;
 +    }
 +    if (startingBucketAdvisor == null) {
 +      assignStartingBucketAdvisor();
 +      if (startingBucketAdvisor != null) {
 +        return;
 +      }
 +    } else {
 +      return;
 +    }
 +    // TODO fix this method to not release any locks if the  
 +    // redundancy is zero, since no locks are grabbed. 
 +    try {
 +      DistributedMemberLock thePrimaryLock = getPrimaryLock(false);
 +      if (thePrimaryLock != null) {
 +        thePrimaryLock.unlock();
 +      }
 +      else {
 +        // InternalDistributedSystem.isDisconnecting probably prevented us from
 +        // creating the DLS... hope there's a thread closing this advisor but
 +        // it's probably not safe to assert that it already happened
 +      }
 +    } 
 +    catch (LockNotHeldException e) {      
 +      Assert.assertTrue(!isHosting(), 
 +          "Got LockNotHeldException for Bucket = " + this);
 +    }
 +    catch (LockServiceDestroyedException e) {
 +      Assert.assertTrue(isClosed(), 
 +          "BucketAdvisor was not closed before destroying PR lock service");
 +    }
 +  }
 +  
 +  private String primaryStateToString() {
 +    return primaryStateToString(this.primaryState);
 +  }
 +
 +  /**
 +   * Returns string representation of the primary state value.
 +   * @param value the primary state to return string for
 +   * @return string representation of primaryState
 +   */
 +  private String primaryStateToString(byte value) {
 +    switch (value) {
 +      case NO_PRIMARY_NOT_HOSTING:
 +        return "NO_PRIMARY_NOT_HOSTING";
 +      case NO_PRIMARY_HOSTING:
 +        return "NO_PRIMARY_HOSTING";
 +      case OTHER_PRIMARY_NOT_HOSTING:
 +        return "OTHER_PRIMARY_NOT_HOSTING";
 +      case OTHER_PRIMARY_HOSTING:
 +        return "OTHER_PRIMARY_HOSTING";
 +      case VOLUNTEERING_HOSTING:
 +        return "VOLUNTEERING_HOSTING";
 +      case BECOMING_HOSTING:
 +        return "BECOMING_HOSTING";
 +      case IS_PRIMARY_HOSTING:
 +        return "IS_PRIMARY_HOSTING";
 +      case CLOSED:
 +        return "CLOSED";
 +      default:
 +        return "<unhandled primaryState " + value + " >";
 +    }
 +  }
 +  
 +  /**
 +   * Requests change to the requested primary state. Controls all state
 +   * changes pertaining to primary state. Caller must be synchronized on this.
 +   * 
 +   * @param requestedState primaryState to change to
 +   * @return true if the requestedState change was completed
 +   * @throws IllegalStateException if an illegal state change was attempted
 +   */
 +  private boolean requestPrimaryState(byte requestedState) {
 +    final byte fromState = this.primaryState;
 +    switch (fromState) {
 +      case NO_PRIMARY_NOT_HOSTING:
 +        switch (requestedState) {
 +          case NO_PRIMARY_NOT_HOSTING:
 +            // race condition ok, return false
 +            return false;
 +          case NO_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case OTHER_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case BECOMING_HOSTING:
 +            // race condition during close is ok, return false
 +            return false;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition during close is ok, return false
 +            return false;
 +          case CLOSED:
 +            this.primaryState = requestedState;
 +            break;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState)}));
 +        }
 +        break;
 +      case NO_PRIMARY_HOSTING:
 +        switch (requestedState) {
 +          case NO_PRIMARY_NOT_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +//          case OTHER_PRIMARY_NOT_HOSTING: -- enable for bucket migration
 +//            this.primaryState = requestedState;
 +//            break;
 +          case NO_PRIMARY_HOSTING:
 +            // race condition ok, return false
 +            return false;
 +          case VOLUNTEERING_HOSTING:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.putStartTime(this, stats.startVolunteering());
 +            }
 +            break;
 +          case BECOMING_HOSTING:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.putStartTime(this, stats.startVolunteering());
 +            }
 +            break;
 +          case OTHER_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case CLOSED:
 +            this.primaryState = requestedState;
 +            break;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState)}));
 +        }
 +        break;
 +      case OTHER_PRIMARY_NOT_HOSTING:
 +        switch (requestedState) {
 +          case NO_PRIMARY_NOT_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            // race condition ok, return false
 +            return false;
 +          case OTHER_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case BECOMING_HOSTING:
 +            // race condition during close is ok, return false
 +            return false;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition during close is ok, return false
 +            return false;
 +          case CLOSED:
 +            this.primaryState = requestedState;
 +            break;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState)}));
 +        }
 +        break;
 +      case OTHER_PRIMARY_HOSTING:
 +        switch (requestedState) {
 +//          case NO_PRIMARY_NOT_HOSTING: -- enable for bucket migration
 +//            this.primaryState = requestedState;
 +//            break;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            // May occur when setHosting(false) is called
 +            this.primaryState = requestedState;
 +            break;
 +          case OTHER_PRIMARY_HOSTING:
 +            // race condition ok, return false
 +            return false;
 +          case NO_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            break;
 +          case CLOSED:
 +            this.primaryState = requestedState;
 +            break;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case BECOMING_HOSTING:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.putStartTime(this, stats.startVolunteering());
 +            }
 +            break;
 +          case IS_PRIMARY_HOSTING:
 +            // race condition ok, probably race in HA where other becomes 
 +            // primary and immediately leaves while we have try-lock message
 +            // enroute to grantor
 +            this.primaryState = requestedState;
 +            break;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState)}));
 +        }
 +        break;
 +      case VOLUNTEERING_HOSTING:
 +        switch (requestedState) {
 +          case NO_PRIMARY_NOT_HOSTING:
 +            // May occur when setHosting(false) is called
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringClosed(stats.removeStartTime(this));
 +            }
 +            break;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            // May occur when setHosting(false) is called
 +            // Profile update for other primary may have slipped in
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringClosed(stats.removeStartTime(this));
 +            }
 +            break;
 +          case NO_PRIMARY_HOSTING:
 +            // race condition occurred, return false and stay in volunteering
 +            return false;
 +          case IS_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.incPrimaryBucketCount(1);
 +              stats.endVolunteeringBecamePrimary(stats.removeStartTime(this));
 +            }
 +            break;
 +          case OTHER_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringOtherPrimary(stats.removeStartTime(this));
 +            }
 +            break;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case BECOMING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case CLOSED:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringClosed(stats.removeStartTime(this));
 +            }
 +            break;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState)}));
 +        }
 +        break;
 +      case BECOMING_HOSTING:
 +        switch (requestedState) {
 +          case NO_PRIMARY_NOT_HOSTING:
 +            // May occur when setHosting(false) is called
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringClosed(stats.removeStartTime(this));
 +            }
 +            break;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            // May occur when setHosting(false) is called
 +            // Profile update for other primary may have slipped in
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringClosed(stats.removeStartTime(this));
 +            }
 +            break;
 +          case NO_PRIMARY_HOSTING:
 +            // race condition occurred, return false and stay in volunteering
 +            return false;
 +          case IS_PRIMARY_HOSTING:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.incPrimaryBucketCount(1);
 +              stats.endVolunteeringBecamePrimary(stats.removeStartTime(this));
 +            }
 +            break;
 +          case OTHER_PRIMARY_HOSTING:
 +            return false;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case BECOMING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case CLOSED:
 +            this.primaryState = requestedState;
 +            {
 +              PartitionedRegionStats stats = getPartitionedRegionStats();
 +              stats.endVolunteeringClosed(stats.removeStartTime(this));
 +            }
 +            break;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState)}));
 +        }
 +        break;
 +      case IS_PRIMARY_HOSTING:
 +        switch (requestedState) {
 +          case NO_PRIMARY_HOSTING:
 +            // rebalancing must have moved the primary
 +            changeFromPrimaryTo(requestedState);
 +            break;
 +//          case OTHER_PRIMARY_HOSTING: -- enable for bucket migration
 +//            // rebalancing must have moved the primary
 +//            changeFromPrimaryTo(requestedState);
 +//            break;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            // rebalancing must have moved the primary and primary
 +            changeFromPrimaryTo(requestedState);
 +            break;
 +          case NO_PRIMARY_NOT_HOSTING:
 +            // May occur when setHosting(false) is called due to closing
 +            changeFromPrimaryTo(requestedState);
 +            break;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case BECOMING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case CLOSED:
 +            changeFromPrimaryTo(requestedState);
 +            break;
 +          default:
 +            throw new IllegalStateException(
 +                "Cannot change from " + this.primaryStateToString() + 
 +                " to " + this.primaryStateToString(requestedState));
 +        }
 +        break;
 +      case CLOSED:
 +        switch (requestedState) {
 +          case CLOSED:
 +            Exception e = new Exception(LocalizedStrings.BucketAdvisor_ATTEMPTED_TO_CLOSE_BUCKETADVISOR_THAT_IS_ALREADY_CLOSED.toLocalizedString());
 +            logger.warn(LocalizedMessage.create(LocalizedStrings.BucketAdvisor_ATTEMPTED_TO_CLOSE_BUCKETADVISOR_THAT_IS_ALREADY_CLOSED), e);
 +            break;
 +          case VOLUNTEERING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case BECOMING_HOSTING:
 +            // race condition ok, return false to abort volunteering
 +            return false;
 +          case IS_PRIMARY_HOSTING:
 +            // Commonly occurs when closing and volunteering thread is still running
 +            return false;
 +          case OTHER_PRIMARY_NOT_HOSTING:
 +            // Commonly occurs when a putProfile occurs during closure
 +            return false;
 +          default:
 +            throw new IllegalStateException(LocalizedStrings.BucketAdvisor_CANNOT_CHANGE_FROM_0_TO_1_FOR_BUCKET_2.toLocalizedString(new Object[] {this.primaryStateToString(), this.primaryStateToString(requestedState), getAdvisee().getName()}));
 +        }
 +    }
 +    return this.primaryState == requestedState;
 +  }
 +
 +  private void changeFromPrimaryTo(byte requestedState) {
 +    try {
 +      this.primaryState = requestedState;
 +    }
 +    finally {
 +      getPartitionedRegionStats().incPrimaryBucketCount(-1);
 +    }
 +  }
 +  
 +  @Override
 +  public Set adviseDestroyRegion() {
 +    // fix for bug 37604 - tell all owners of the pr that the bucket is being
 +    // destroyed.  This is needed when bucket cleanup is performed
 +    return this.regionAdvisor.adviseAllPRNodes();
 +  }
 +  
 +  /**
 +   * returns the set of all the members in the system which require both
 +   * DistributedCacheOperation messages and notification-only partition
 +   * messages
 +

<TRUNCATED>


[032/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
index 9cf2f13,0000000..c731721
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
@@@ -1,3135 -1,0 +1,3142 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.DataInput;
 +import java.io.DataInputStream;
 +import java.io.DataOutput;
 +import java.io.IOException;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CopyHelper;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.DeltaSerializationException;
 +import com.gemstone.gemfire.GemFireIOException;
 +import com.gemstone.gemfire.InvalidDeltaException;
 +import com.gemstone.gemfire.SerializationException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.EntryNotFoundException;
 +import com.gemstone.gemfire.cache.EntryOperation;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.SerializedCacheValue;
 +import com.gemstone.gemfire.cache.TransactionId;
 +import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
 +import com.gemstone.gemfire.cache.query.QueryException;
 +import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexProtocol;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexUtils;
 +import com.gemstone.gemfire.cache.util.TimestampedEntryEvent;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.DistributionMessage;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.ByteArrayDataInput;
 +import com.gemstone.gemfire.internal.DSFIDFactory;
 +import com.gemstone.gemfire.internal.DataSerializableFixedID;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.InternalDataSerializer;
 +import com.gemstone.gemfire.internal.Sendable;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.FilterRoutingInfo.FilterInfo;
 +import com.gemstone.gemfire.internal.cache.delta.Delta;
 +import com.gemstone.gemfire.internal.cache.lru.Sizeable;
 +import com.gemstone.gemfire.internal.cache.partitioned.PartitionMessage;
 +import com.gemstone.gemfire.internal.cache.partitioned.PutMessage;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerHelper;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
 +import com.gemstone.gemfire.internal.cache.tx.DistTxKeyInfo;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventCallbackArgument;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.lang.StringUtils;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +import com.gemstone.gemfire.internal.offheap.Chunk;
 +import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 +import com.gemstone.gemfire.internal.offheap.OffHeapRegionEntryHelper;
 +import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
 +import com.gemstone.gemfire.internal.offheap.Releasable;
 +import com.gemstone.gemfire.internal.offheap.StoredObject;
 +import com.gemstone.gemfire.internal.offheap.annotations.Released;
 +import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 +import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 +
 +import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ENTRY_EVENT_NEW_VALUE;
 +import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ENTRY_EVENT_OLD_VALUE;
 +
 +import com.gemstone.gemfire.internal.util.ArrayUtils;
 +import com.gemstone.gemfire.internal.util.BlobHelper;
 +import com.gemstone.gemfire.pdx.internal.PeerTypeRegistration;
 +
 +/**
 + * Implementation of an entry event
 + */
 +// must be public for DataSerializableFixedID
 +public class EntryEventImpl
 +  implements EntryEvent, InternalCacheEvent, DataSerializableFixedID, EntryOperation
 +             , Releasable
 +{
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  // PACKAGE FIELDS //
 +  public transient LocalRegion region;
 +  private transient RegionEntry re;
 +
 +  protected KeyInfo keyInfo;
 +
 +  //private long eventId;
 +  /** the event's id. Scoped by distributedMember. */
 +  protected EventID eventID;
 +
 +  private Object newValue = null;
 +  /**
 +   * If we ever serialize the new value then it should be
 +   * stored in this field in case we need the serialized form
 +   * again later. This was added to fix bug 43781.
 +   * Note that we also have the "newValueBytes" field.
 +   * But it is only non-null if setSerializedNewValue was called.
 +   */
 +  private byte[] cachedSerializedNewValue = null;
 +  @Retained(ENTRY_EVENT_OLD_VALUE)
 +  private Object oldValue = null;
 +  protected Delta delta = null;
 + 
 +  protected short eventFlags = 0x0000;
 +
 +  protected TXId txId = null;
 +
 +  protected Operation op;
 +
 +  /* To store the operation/modification type */
 +  private transient EnumListenerEvent eventType;
 +
 +  /**
 +   * This field will be null unless this event is used for a putAll operation.
 +   *
 +   * @since 5.0
 +   */
 +  protected transient DistributedPutAllOperation putAllOp;
 +
 +  /**
 +   * This field will be null unless this event is used for a removeAll operation.
 +   *
 +   * @since 8.1
 +   */
 +  protected transient DistributedRemoveAllOperation removeAllOp;
 +
 +  /**
 +   * The member that originated this event
 +   *
 +   * @since 5.0
 +   */
 +  protected DistributedMember distributedMember;
 +
 +  
 +  /**
 +   * transient storage for the message that caused the event
 +   */
 +  transient DistributionMessage causedByMessage;
 +  
 +  
 +  //private static long eventID = 0;
 +
 +  /**
 +   * The originating membershipId of this event.
 +   *
 +   * @since 5.1
 +   */
 +  protected ClientProxyMembershipID context = null;
 +  
 +  /**
 +   * A custom context object that can be used for any other contextual
 +   * information. Currently used by SQL Fabric to pass around evaluated rows
 +   * from raw byte arrays and routing object.
 +   */
 +  private transient Object contextObj = null;
 +
 +  /**
 +   * this holds the bytes representing the change in value effected by this
 +   * event.  It is used when the value implements the Delta interface.
 +   */
 +  private byte[] deltaBytes = null;
 +
 +  
 +  /** routing information for cache clients for this event */
 +  private FilterInfo filterInfo;
 +  
 +  /**new value stored in serialized form*/
 +  protected byte[] newValueBytes;
 +  /**old value stored in serialized form*/
 +  private byte[] oldValueBytes;
 +  
 +  /** version tag for concurrency checks */
 +  protected VersionTag versionTag;
 +
 +  /** boolean to indicate that this operation should be optimized by not fetching from HDFS*/
 +  private transient boolean fetchFromHDFS = true;
 +  
 +  private transient boolean isPutDML = false;
 +
 +  /** boolean to indicate that the RegionEntry for this event was loaded from HDFS*/
 +  private transient boolean loadedFromHDFS= false;
 +  
 +  private transient boolean isCustomEviction = false;
 +  
 +  /** boolean to indicate that the RegionEntry for this event has been evicted*/
 +  private transient boolean isEvicted = false;
 +  
 +  private transient boolean isPendingSecondaryExpireDestroy = false;
 +  
 +  public final static Object SUSPECT_TOKEN = new Object();
 +  
 +  public EntryEventImpl() {
 +  }
 +  
 +  /**
 +   * create a new entry event that will be used for conveying version information
 +   * and anything else of use while processing another event
 +   * @return the empty event object
 +   */
 +  @Retained
 +  public static EntryEventImpl createVersionTagHolder() {
 +    return createVersionTagHolder(null);
 +  }
 +  
 +  /**
 +   * create a new entry event that will be used for conveying version information
 +   * and anything else of use while processing another event
 +   * @return the empty event object
 +   */
 +  @Retained
 +  public static EntryEventImpl createVersionTagHolder(VersionTag tag) {
 +    EntryEventImpl result = new EntryEventImpl();
 +    result.setVersionTag(tag);
 +    result.disallowOffHeapValues();
 +    return result;
 +  }
 +
 +  /**
 +   * Reads the contents of this message from the given input.
 +   */
 +  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
 +    this.eventID = (EventID)DataSerializer.readObject(in);
 +    Object key = DataSerializer.readObject(in);
 +    Object value = DataSerializer.readObject(in);
 +    this.keyInfo = new KeyInfo(key, value, null);
 +    this.op = Operation.fromOrdinal(in.readByte());
 +    this.eventFlags = in.readShort();
 +    this.keyInfo.setCallbackArg(DataSerializer.readObject(in));
 +    this.txId = (TXId)DataSerializer.readObject(in);
 +
 +    if (in.readBoolean()) {     // isDelta
 +      this.delta = (Delta)DataSerializer.readObject(in);
 +    }
 +    else {
 +      // OFFHEAP Currently values are never deserialized to off heap memory. If that changes then this code needs to change.
 +      if (in.readBoolean()) {     // newValueSerialized
 +        this.newValueBytes = DataSerializer.readByteArray(in);
 +        this.cachedSerializedNewValue = this.newValueBytes;
 +        this.newValue = CachedDeserializableFactory.create(this.newValueBytes);
 +      }
 +      else {
 +        this.newValue = DataSerializer.readObject(in);
 +      }
 +    }
 +
 +    // OFFHEAP Currently values are never deserialized to off heap memory. If that changes then this code needs to change.
 +    if (in.readBoolean()) {     // oldValueSerialized
 +      this.oldValueBytes = DataSerializer.readByteArray(in);
 +      this.oldValue = CachedDeserializableFactory.create(this.oldValueBytes);
 +    }
 +    else {
 +      this.oldValue = DataSerializer.readObject(in);
 +    }
 +    this.distributedMember = DSFIDFactory.readInternalDistributedMember(in);
 +    this.context = ClientProxyMembershipID.readCanonicalized(in);
 +    this.tailKey = DataSerializer.readLong(in);
 +  }
 +
 +  @Retained
 +  protected EntryEventImpl(LocalRegion region, Operation op, Object key,
 +      boolean originRemote, DistributedMember distributedMember,
 +      boolean generateCallbacks, boolean fromRILocalDestroy) {
 +    this.region = region;
 +    this.op = op;
 +    this.keyInfo = this.region.getKeyInfo(key);
 +    setOriginRemote(originRemote);
 +    setGenerateCallbacks(generateCallbacks);
 +    this.distributedMember = distributedMember;
 +    setFromRILocalDestroy(fromRILocalDestroy);
 +  }
 +
 +  /**
 +   * Doesn't specify oldValue as this will be filled in later as part of an
 +   * operation on the region, or lets it default to null.
 +   */
 +  @Retained
 +  protected EntryEventImpl(
 +      final LocalRegion region,
 +      Operation op, Object key, @Retained(ENTRY_EVENT_NEW_VALUE) Object newVal,
 +      Object callbackArgument,
 +      boolean originRemote, DistributedMember distributedMember,
 +      boolean generateCallbacks, boolean initializeId) {
 +
 +    this.region = region;
 +    this.op = op;
 +    this.keyInfo = this.region.getKeyInfo(key, newVal, callbackArgument);
 +
 +    if (newVal instanceof Delta) {
 +      this.delta = (Delta)newVal;
 +    }
 +    else if (!Token.isInvalid(newVal)) {
 +      basicSetNewValue(newVal);
 +    }
 +
 +    this.txId = this.region.getTXId();
 +    /**
 +     * this might set txId for events done from a thread that has a tx even
 +     * though the op is non-tx. For example region ops.
 +     */
 +    if (newVal == Token.LOCAL_INVALID) {
 +      setLocalInvalid(true);
 +    }
 +    setOriginRemote(originRemote);
 +    setGenerateCallbacks(generateCallbacks);
 +    this.distributedMember = distributedMember;
 +  }
 +
 +  /**
 +   * Called by BridgeEntryEventImpl to use existing EventID
 +   */
 +  @Retained
 +  protected EntryEventImpl(LocalRegion region, Operation op, Object key,
 +      @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue, Object callbackArgument, boolean originRemote,
 +      DistributedMember distributedMember, boolean generateCallbacks,
 +      EventID eventID) {
 +    this(region, op, key, newValue,
 +        callbackArgument, originRemote, distributedMember, generateCallbacks,
 +        true /* initializeId */);
 +    Assert.assertTrue(eventID != null || !(region instanceof PartitionedRegion));
 +    this.setEventId(eventID);
 +  }
 +
 +  /**
 +   * create an entry event from another entry event
 +   */
 +  @Retained
 +  public EntryEventImpl(@Retained({ENTRY_EVENT_NEW_VALUE, ENTRY_EVENT_OLD_VALUE}) EntryEventImpl other) {
 +    this(other, true);
 +  }
 +  
 +  @Retained
 +  public EntryEventImpl(@Retained({ENTRY_EVENT_NEW_VALUE, ENTRY_EVENT_OLD_VALUE}) EntryEventImpl other, boolean setOldValue) {
 +    region = other.region;
 +
 +    this.eventID = other.eventID;
 +    basicSetNewValue(other.basicGetNewValue());
 +    this.newValueBytes = other.newValueBytes;
 +    this.cachedSerializedNewValue = other.cachedSerializedNewValue;
 +    this.re = other.re;
 +    this.delta = other.delta;
 +    if (setOldValue) {
 +      retainAndSetOldValue(other.basicGetOldValue());
 +      this.oldValueBytes = other.oldValueBytes;
 +    }
 +    this.eventFlags = other.eventFlags;
 +    setEventFlag(EventFlags.FLAG_CALLBACKS_INVOKED, false);
 +    txId = other.txId;
 +    op = other.op;
 +    distributedMember = other.distributedMember;
 +    this.filterInfo = other.filterInfo;
 +    this.keyInfo = other.keyInfo.isDistKeyInfo() ? new DistTxKeyInfo(
 +        (DistTxKeyInfo) other.keyInfo) : new KeyInfo(other.keyInfo);
 +    if (other.getRawCallbackArgument() instanceof GatewaySenderEventCallbackArgument) {
 +      this.keyInfo
 +          .setCallbackArg((new GatewaySenderEventCallbackArgument(
 +              (GatewaySenderEventCallbackArgument) other
 +                  .getRawCallbackArgument())));
 +    }
 +    this.context = other.context;
 +    this.deltaBytes = other.deltaBytes;
 +    this.tailKey = other.tailKey;
 +    this.versionTag = other.versionTag;
 +    //set possible duplicate 
 +    this.setPossibleDuplicate(other.isPossibleDuplicate()); 
 +  }
 +
 +  @Retained
 +  public EntryEventImpl(Object key2) {
 +    this.keyInfo = new KeyInfo(key2, null, null);
 +  }
 +  
 +  /**
 +   * This constructor is used to create a bridge event in server-side
 +   * command classes.  Events created with this are not intended to be
 +   * used in cache operations.
 +   * @param id the identity of the client's event
 +   */
 +  @Retained
 +  public EntryEventImpl(EventID id) {
 +    this.eventID = id;
 +    this.offHeapOk = false;
 +  }
 +
 +  /**
 +   * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
 +   * EntryEventImpl if the region parameter is a PartitionedRegion.
 +   */  
 +  @Retained
 +  public static EntryEventImpl create(LocalRegion region,
 +      Operation op,
 +      Object key, @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue, Object callbackArgument,
 +      boolean originRemote, DistributedMember distributedMember) {
 +    return create(region,op,key,newValue,callbackArgument,originRemote,distributedMember,true,true);
 +  }
 +  
 +  /**
 +   * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
 +   * EntryEventImpl if the region parameter is a PartitionedRegion.
 +   */
 +  @Retained
 +  public static EntryEventImpl create(LocalRegion region,
 +      Operation op,
 +      Object key,
 +      @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue,
 +      Object callbackArgument,
 +      boolean originRemote,
 +      DistributedMember distributedMember,
 +      boolean generateCallbacks) {
 +    return create(region, op, key, newValue, callbackArgument, originRemote,
 +        distributedMember, generateCallbacks,true);
 +  }
 +  
 +  /**
 +   * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
 +   * EntryEventImpl if the region parameter is a PartitionedRegion.
 +   *  
 +   * Called by BridgeEntryEventImpl to use existing EventID
 +   * 
 +   * {@link EntryEventImpl#EntryEventImpl(LocalRegion, Operation, Object, Object, Object, boolean, DistributedMember, boolean, EventID)}
 +   */ 
 +  @Retained
 +  public static EntryEventImpl create(LocalRegion region, Operation op, Object key,
 +      @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue, Object callbackArgument, boolean originRemote,
 +      DistributedMember distributedMember, boolean generateCallbacks,
 +      EventID eventID) {
 +    EntryEventImpl entryEvent = new EntryEventImpl(region,op,key,newValue,callbackArgument,originRemote,distributedMember,generateCallbacks,eventID);
 +    return entryEvent;
 +  }
 +  
 +  /**
 +   * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
 +   * EntryEventImpl if the region parameter is a PartitionedRegion.
 +   * 
 +   * {@link EntryEventImpl#EntryEventImpl(LocalRegion, Operation, Object, boolean, DistributedMember, boolean, boolean)}
 +   */
 +  @Retained
 +  public static EntryEventImpl create(LocalRegion region, Operation op, Object key,
 +      boolean originRemote, DistributedMember distributedMember,
 +      boolean generateCallbacks, boolean fromRILocalDestroy) {
 +    EntryEventImpl entryEvent = new EntryEventImpl(region,op,key,originRemote,distributedMember,generateCallbacks,fromRILocalDestroy);
 +    return entryEvent;
 +  }  
 +  
 +  /**
 +   * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
 +   * EntryEventImpl if the region parameter is a PartitionedRegion.
 +   * 
 +   * This creator does not specify the oldValue as this will be filled in later as part of an
 +   * operation on the region, or lets it default to null.
 +   * 
 +   * {@link EntryEventImpl#EntryEventImpl(LocalRegion, Operation, Object, Object, Object, boolean, DistributedMember, boolean, boolean)}
 +   */
 +  @Retained
 +  public static EntryEventImpl create(final LocalRegion region,
 +      Operation op, Object key, @Retained(ENTRY_EVENT_NEW_VALUE) Object newVal,
 +      Object callbackArgument,
 +      boolean originRemote, DistributedMember distributedMember,
 +      boolean generateCallbacks, boolean initializeId)  {
 +    EntryEventImpl entryEvent = new EntryEventImpl(region,op,key,newVal,callbackArgument,
 +        originRemote,distributedMember,generateCallbacks,initializeId);
 +    return entryEvent;
 +  }
 +  
 +  /**
 +   * Creates a PutAllEvent given the distributed operation, the region, and the
 +   * entry data.
 +   *
 +   * @since 5.0
 +   */
 +  @Retained
 +  static EntryEventImpl createPutAllEvent(
 +      DistributedPutAllOperation putAllOp, LocalRegion region,
 +      Operation entryOp, Object entryKey, @Retained(ENTRY_EVENT_NEW_VALUE) Object entryNewValue)
 +  {
 +    EntryEventImpl e;
 +    if (putAllOp != null) {
 +      EntryEventImpl event = putAllOp.getBaseEvent();
 +      if (event.isBridgeEvent()) {
 +        e = EntryEventImpl.create(region, entryOp, entryKey, entryNewValue,
 +            event.getRawCallbackArgument(), false, event.distributedMember,
 +            event.isGenerateCallbacks());
 +        e.setContext(event.getContext());
 +      } else {
 +        e = EntryEventImpl.create(region, entryOp, entryKey, entryNewValue, event.getCallbackArgument(),
 +            false, region.getMyId(), event.isGenerateCallbacks());
 +      }
 +      
 +    } else {
 +      e = EntryEventImpl.create(region, entryOp, entryKey, entryNewValue, null,
 +          false, region.getMyId(), true);
 +    }
 +    
 +    e.putAllOp = putAllOp;
 +    return e;
 +  }
 +  
 +  protected static EntryEventImpl createRemoveAllEvent(
 +      DistributedRemoveAllOperation op, 
 +      LocalRegion region,
 +      Object entryKey) {
 +    EntryEventImpl e;
 +    final Operation entryOp = Operation.REMOVEALL_DESTROY;
 +    if (op != null) {
 +      EntryEventImpl event = op.getBaseEvent();
 +      if (event.isBridgeEvent()) {
 +        e = EntryEventImpl.create(region, entryOp, entryKey, null,
 +            event.getRawCallbackArgument(), false, event.distributedMember,
 +            event.isGenerateCallbacks());
 +        e.setContext(event.getContext());
 +      } else {
 +        e = EntryEventImpl.create(region, entryOp, entryKey, null, event.getCallbackArgument(),
 +            false, region.getMyId(), event.isGenerateCallbacks());
 +      }
 +      
 +    } else {
 +      e = EntryEventImpl.create(region, entryOp, entryKey, null, null,
 +          false, region.getMyId(), true);
 +    }
 +    
 +    e.removeAllOp = op;
 +    return e;
 +  }
 +  public boolean isBulkOpInProgress() {
 +    return getPutAllOperation() != null || getRemoveAllOperation() != null;
 +  }
 +  
 +  /** return the putAll operation for this event, if any */
 +  public DistributedPutAllOperation getPutAllOperation() {
 +    return this.putAllOp;
 +  }
 +  public DistributedPutAllOperation setPutAllOperation(DistributedPutAllOperation nv) {
 +    DistributedPutAllOperation result = this.putAllOp;
 +    if (nv != null && nv.getBaseEvent() != null) {
 +      setCallbackArgument(nv.getBaseEvent().getCallbackArgument());
 +    }
 +    this.putAllOp = nv;
 +    return result;
 +  }
 +  public DistributedRemoveAllOperation getRemoveAllOperation() {
 +    return this.removeAllOp;
 +  }
 +  public DistributedRemoveAllOperation setRemoveAllOperation(DistributedRemoveAllOperation nv) {
 +    DistributedRemoveAllOperation result = this.removeAllOp;
 +    if (nv != null && nv.getBaseEvent() != null) {
 +      setCallbackArgument(nv.getBaseEvent().getCallbackArgument());
 +    }
 +    this.removeAllOp = nv;
 +    return result;
 +  }
 +
 +  private final boolean testEventFlag(short mask)
 +  {
 +    return EventFlags.isSet(this.eventFlags, mask);
 +  }
 +
 +  private final void setEventFlag(short mask, boolean on)
 +  {
 +    this.eventFlags = EventFlags.set(this.eventFlags, mask, on);
 +  }
 +
 +  public DistributedMember getDistributedMember()
 +  {
 +    return this.distributedMember;
 +  }
 +
 +  /////////////////////// INTERNAL BOOLEAN SETTERS
 +  public void setOriginRemote(boolean b)
 +  {
 +    setEventFlag(EventFlags.FLAG_ORIGIN_REMOTE, b);
 +  }
 +
 +  public void setLocalInvalid(boolean b)
 +  {
 +    setEventFlag(EventFlags.FLAG_LOCAL_INVALID, b);
 +  }
 +
 +  void setGenerateCallbacks(boolean b)
 +  {
 +    setEventFlag(EventFlags.FLAG_GENERATE_CALLBACKS, b);
 +  }
 +
 +  /** set the the flag telling whether callbacks should be invoked for a partitioned region */
 +  public void setInvokePRCallbacks(boolean b) {
 +    setEventFlag(EventFlags.FLAG_INVOKE_PR_CALLBACKS, b);
 +  }
 +
 +  /** get the flag telling whether callbacks should be invoked for a partitioned region */
 +  public boolean getInvokePRCallbacks() {
 +    return testEventFlag(EventFlags.FLAG_INVOKE_PR_CALLBACKS);
 +  }
 +  
 +  public boolean getInhibitDistribution() {
 +    return testEventFlag(EventFlags.FLAG_INHIBIT_DISTRIBUTION);
 +  }
 +  
 +  public void setInhibitDistribution(boolean b) {
 +    setEventFlag(EventFlags.FLAG_INHIBIT_DISTRIBUTION, b);
 +  }
 +  
 +  /** was the entry destroyed or missing and allowed to be destroyed again? */
 +  public boolean getIsRedestroyedEntry() {
 +    return testEventFlag(EventFlags.FLAG_REDESTROYED_TOMBSTONE);
 +  }
 +  
 +  public void setIsRedestroyedEntry(boolean b) {
 +    setEventFlag(EventFlags.FLAG_REDESTROYED_TOMBSTONE, b);
 +  }
 +  
 +  public void isConcurrencyConflict(boolean b) {
 +    setEventFlag(EventFlags.FLAG_CONCURRENCY_CONFLICT, b);
 +  }
 +  
 +  public boolean isConcurrencyConflict() {
 +    return testEventFlag(EventFlags.FLAG_CONCURRENCY_CONFLICT);
 +  }
 +
 +  /** set the DistributionMessage that caused this event */
 +  public void setCausedByMessage(DistributionMessage msg) {
 +    this.causedByMessage = msg;
 +  }
 +
 +  /**
 +   * get the PartitionMessage that caused this event, or null if
 +   * the event was not caused by a PartitionMessage
 +   */
 +  public PartitionMessage getPartitionMessage() {
 +    if (this.causedByMessage != null && this.causedByMessage instanceof PartitionMessage) {
 +      return (PartitionMessage)this.causedByMessage;
 +  }
 +    return null;
 +  }
 +
 +  /**
 +   * get the RemoteOperationMessage that caused this event, or null if
 +   * the event was not caused by a RemoteOperationMessage
 +   */
 +  public RemoteOperationMessage getRemoteOperationMessage() {
 +    if (this.causedByMessage != null && this.causedByMessage instanceof RemoteOperationMessage) {
 +      return (RemoteOperationMessage)this.causedByMessage;
 +    }
 +    return null;
 +  }
 +
 +  /////////////// BOOLEAN GETTERS
 +  public boolean isLocalLoad()
 +  {
 +    return this.op.isLocalLoad();
 +  }
 +
 +  public boolean isNetSearch()
 +  {
 +    return this.op.isNetSearch();
 +  }
 +
 +  public boolean isNetLoad()
 +  {
 +    return this.op.isNetLoad();
 +  }
 +
 +  public boolean isDistributed()
 +  {
 +    return this.op.isDistributed();
 +  }
 +
 +  public boolean isExpiration()
 +  {
 +    return this.op.isExpiration();
 +  }
 +  
 +  public boolean isEviction() {
 +    return this.op.isEviction();
 +  }
 +
 +  public final boolean isCustomEviction() {
 +    return this.isCustomEviction;
 +  }
 +  
 +  public final void setCustomEviction(boolean customEvict) {
 +    this.isCustomEviction = customEvict;
 +  }
 +  
 +  public final void setEvicted() {
 +    this.isEvicted = true;
 +  }
 +  
 +  public final boolean isEvicted() {
 +    return this.isEvicted;
 +  }
 +  
 +  public final boolean isPendingSecondaryExpireDestroy() {
 +    return this.isPendingSecondaryExpireDestroy;
 +  }
 +  
 +  public final void setPendingSecondaryExpireDestroy (boolean value) {
 +    this.isPendingSecondaryExpireDestroy = value;
 +  }
 +  // Note that isOriginRemote is sometimes set to false even though the event
 +  // was received from a peer.  This is done to force distribution of the
 +  // message to peers and to cause concurrency version stamping to be performed.
 +  // This is done by all one-hop operations, like RemoteInvalidateMessage.
 +  public boolean isOriginRemote()
 +  {
 +    return testEventFlag(EventFlags.FLAG_ORIGIN_REMOTE);
 +  }
 +
 +  /* return whether this event originated from a WAN gateway and carries a WAN version tag */
 +  public boolean isFromWANAndVersioned() {
 +    return (this.versionTag != null && this.versionTag.isGatewayTag());
 +  }
 +  
 +  /* return whether this event originated in a client and carries a version tag */
 +  public boolean isFromBridgeAndVersioned() {
 +    return (this.context != null) && (this.versionTag != null);
 +  }
 +
 +  public boolean isGenerateCallbacks()
 +  {
 +    return testEventFlag(EventFlags.FLAG_GENERATE_CALLBACKS);
 +  }
 +
 +  public void setNewEventId(DistributedSystem sys) {
 +    Assert.assertTrue(this.eventID == null, "Double setting event id");
 +    EventID newID = new EventID(sys);
 +    if (this.eventID != null) {
 +      if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
 +        logger.trace(LogMarker.BRIDGE_SERVER, "Replacing event ID with {} in event {}", newID, this);
 +      }
 +    }
 +    this.eventID = newID;
 +  }
 +  
 +  public void reserveNewEventId(DistributedSystem sys, int count) {
 +    Assert.assertTrue(this.eventID == null, "Double setting event id");
 +    this.eventID = new EventID(sys);
 +    if (count > 1) {
 +      this.eventID.reserveSequenceId(count-1);
 +    }
 +  }
 +
 +  public void setEventId(EventID id)
 +  {
 +    this.eventID = id;
 +  }
 +
 +  /**
 +   * Return the event id, if any
 +   * @return null if no event id has been set
 +   */
 +  public final EventID getEventId() {
 +    return this.eventID;
 +  }
 +
 +  public boolean isBridgeEvent() {
 +    return hasClientOrigin();
 +  }
 +  public boolean hasClientOrigin() {
 +    return getContext() != null;
 +  }
 +
 +  /**
 +   * sets the ID of the client that initiated this event
 +   */
 +  public void setContext(ClientProxyMembershipID contx) {
 +    Assert.assertTrue(contx != null);
 +    this.context = contx;
 +  }
 +
 +  /**
 +   * gets the ID of the client that initiated this event.  Null if a server-initiated event
 +   */
 +  public ClientProxyMembershipID getContext()
 +  {
 +    return this.context;
 +  }
 +
 +  // INTERNAL
 +  boolean isLocalInvalid()
 +  {
 +    return testEventFlag(EventFlags.FLAG_LOCAL_INVALID);
 +  }
 +
 +  /////////////////////////////////////////////////
 +
 +  /**
 +   * Returns the key.
 +   *
 +   * @return the key.
 +   */
 +  public Object getKey()
 +  {
 +    return keyInfo.getKey();
 +  }
 +
 +  /**
 +   * Returns the value in the cache prior to this event. When passed to an event
 +   * handler after an event occurs, this value reflects the value that was in
 +   * the cache in this VM, not necessarily the value that was in the cache VM
 +   * that initiated the operation.
 +   *
 +   * @return the value in the cache prior to this event.
 +   */
 +  public final Object getOldValue() {
 +    try {
 +      if (isOriginRemote() && this.region.isProxy()) {
 +        return null;
 +      }
 +      @Unretained Object ov = basicGetOldValue();
 +      if (ov == null) {
 +        return null;
 +      } else if (ov == Token.NOT_AVAILABLE) {
 +        return AbstractRegion.handleNotAvailable(ov);
 +      }
 +      boolean doCopyOnRead = getRegion().isCopyOnRead();
 +      if (ov != null) {
 +        if (ov instanceof StoredObject) {
 +          // TODO OFFHEAP: returns off-heap PdxInstance
 +          return ((StoredObject) ov).getValueAsDeserializedHeapObject();
 +        } else
 +        if (ov instanceof CachedDeserializable) {
 +          CachedDeserializable cd = (CachedDeserializable)ov;
 +          if (doCopyOnRead) {
 +            return cd.getDeserializedWritableCopy(this.region, this.re);
 +          } else {
 +            return cd.getDeserializedValue(this.region, this.re);
 +          }
 +        }
 +        else {
 +          if (doCopyOnRead) {
 +            return CopyHelper.copy(ov);
 +          } else {
 +            return ov;
 +          }
 +        }
 +      }
 +      return null;
 +    } catch(IllegalArgumentException i) {
 +      IllegalArgumentException iae = new IllegalArgumentException(LocalizedStrings.DONT_RELEASE.toLocalizedString("Error while deserializing value for key="+getKey()));
 +      iae.initCause(i);
 +      throw iae;
 +    }
 +  }
 +
 +  /**
 +   * Like getRawNewValue except that if the result is an off-heap reference then copy it to the heap.
 +   * ALERT: If there is a Delta, returns that, not the (applied) new value.
 +   * TODO OFFHEAP: to prevent the heap copy use getRawNewValue instead
 +   */
 +  public final Object getRawNewValueAsHeapObject() {
 +    if (this.delta != null) {
 +      return this.delta;
 +    }
 +    return OffHeapHelper.getHeapForm(OffHeapHelper.copyIfNeeded(basicGetNewValue()));
 +  }
 +  
 +  /**
 +   * If new value is a Delta return it.
 +   * Else if new value is off-heap return the StoredObject form (unretained OFF_HEAP_REFERENCE). 
 +   * Its refcount is not inced by this call and the returned object can only be safely used for the lifetime of the EntryEventImpl instance that returned the value.
 +   * Else return the raw form.
 +   */
 +  @Unretained(ENTRY_EVENT_NEW_VALUE)
 +  public final Object getRawNewValue() {
 +    if (this.delta != null) return this.delta;
 +    return basicGetNewValue();
 +  }
 +
 +  @Unretained(ENTRY_EVENT_NEW_VALUE)
 +  public Object getValue() {
 +    return basicGetNewValue();
 +  }
 +  
 +  /**
 +   * Returns the delta that represents the new value; null if no delta.
 +   * @return the delta that represents the new value; null if no delta.
 +   */
 +  public final Delta getDeltaNewValue() {
 +    return this.delta;
 +  }
 +
 +  /**
 +   *  Applies the delta 
 +   */
 +  private Object applyDeltaWithCopyOnRead(boolean doCopyOnRead) {
 +    //try {
 +      if (applyDelta(true)) {
 +        Object applied = basicGetNewValue();
 +        // if applyDelta returns true then newValue should not be off-heap
 +        assert !(applied instanceof StoredObject);
 +        if (applied == this.oldValue && doCopyOnRead) {
 +          applied = CopyHelper.copy(applied);
 +        }
 +        return applied;
 +      }
 +    //} catch (EntryNotFoundException ex) {
 +      // only (broken) product code has the opportunity to call this before
 +      // this.oldValue is set. If oldValue is not set yet, then
 +      // we most likely haven't synchronized on the region entry yet.
 +      // (If we have, then make sure oldValue is set before
 +      // calling this method).
 +      //throw new AssertionError("too early to call getNewValue");
 +    //}
 +    return null;
 +  }
 +
 +  @Released(ENTRY_EVENT_NEW_VALUE)
 +  protected void basicSetNewValue(@Retained(ENTRY_EVENT_NEW_VALUE) Object v) {
 +    if (v == this.newValue) return;
 +    if (this.offHeapOk) {
 +      OffHeapHelper.releaseAndTrackOwner(this.newValue, this);
 +    }
 +    if (v instanceof Chunk) {
 +      ReferenceCountHelper.setReferenceCountOwner(this);
 +      if (!((Chunk) v).retain()) {
 +        ReferenceCountHelper.setReferenceCountOwner(null);
 +        this.newValue = null;
 +        return;
 +      }
 +      ReferenceCountHelper.setReferenceCountOwner(null);
 +    }
 +    this.newValue = v;
 +    this.cachedSerializedNewValue = null;
 +  }
 +  /**
 +   * Returns true if this event has a reference to an off-heap new or old value.
 +   */
 +  public boolean hasOffHeapValue() {
 +    return (this.newValue instanceof Chunk) || (this.oldValue instanceof Chunk);
 +  }
 +  
 +  @Unretained
 +  protected final Object basicGetNewValue() {
 +    Object result = this.newValue;
 +    if (!this.offHeapOk && result instanceof Chunk) {
 +      //this.region.getCache().getLogger().info("DEBUG new value already freed " + System.identityHashCode(result));
 +      throw new IllegalStateException("Attempt to access off heap value after the EntryEvent was released.");
 +    }
 +    return result;
 +  }
 +  
 +  private class OldValueOwner {
 +    private EntryEventImpl getEvent() {
 +      return EntryEventImpl.this;
 +    }
 +    @Override
 +    public int hashCode() {
 +      return getEvent().hashCode();
 +    }
 +
 +    @Override
 +    public boolean equals(Object obj) {
 +      if (obj instanceof OldValueOwner) {
 +        return getEvent().equals(((OldValueOwner) obj).getEvent());
 +      } else {
 +        return false;
 +      }
 +    }
 +    @Override
 +    public String toString() {
 +      return "OldValueOwner " + getEvent().toString();
 +    }
 +  }
 +
 +  /**
 +   * Note if v might be an off-heap reference that you did not retain for this EntryEventImpl
 +   * then call retainsAndSetOldValue instead of this method.
 +   * @param v the caller should have already retained this off-heap reference.
 +   */
 +  @Released(ENTRY_EVENT_OLD_VALUE)
 +  private void basicSetOldValue(@Unretained(ENTRY_EVENT_OLD_VALUE) Object v) {
 +    @Released final Object curOldValue = this.oldValue;
 +    if (v == curOldValue) return;
 +    if (this.offHeapOk) {
 +      if (curOldValue instanceof Chunk) {
 +        if (ReferenceCountHelper.trackReferenceCounts()) {
 +          OffHeapHelper.releaseAndTrackOwner(curOldValue, new OldValueOwner());
 +        } else {
 +          OffHeapHelper.release(curOldValue);
 +        }
 +      }
 +    }
 +    
 +    this.oldValue = v;
 +  }
 +
 +  @Released(ENTRY_EVENT_OLD_VALUE)
 +  private void retainAndSetOldValue(@Retained(ENTRY_EVENT_OLD_VALUE) Object v) {
 +    if (v == this.oldValue) return;
 +    
 +    if (v instanceof Chunk) {
 +      if (ReferenceCountHelper.trackReferenceCounts()) {
 +        ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
 +        boolean couldNotRetain = (!((Chunk) v).retain());
 +        ReferenceCountHelper.setReferenceCountOwner(null);
 +        if (couldNotRetain) {
 +          this.oldValue = null;
 +          return;
 +        }
 +      } else {
 +        if (!((Chunk) v).retain()) {
 +          this.oldValue = null;
 +          return;
 +        }
 +      }
 +    }
 +    basicSetOldValue(v);
 +  }
 +
 +  @Unretained(ENTRY_EVENT_OLD_VALUE)
 +  private Object basicGetOldValue() {
 +    @Unretained(ENTRY_EVENT_OLD_VALUE)
 +    Object result = this.oldValue;
 +    if (!this.offHeapOk && result instanceof Chunk) {
 +      //this.region.getCache().getLogger().info("DEBUG old value already freed " + System.identityHashCode(result));
 +      throw new IllegalStateException("Attempt to access off heap value after the EntryEvent was released.");
 +    }
 +    return result;
 +  }
 +
 +  /**
 +   * Like getRawOldValue except that if the result is an off-heap reference then copy it to the heap.
 +   * To avoid the heap copy use getRawOldValue instead.
 +   */
 +  public final Object getRawOldValueAsHeapObject() {
 +    return OffHeapHelper.getHeapForm(OffHeapHelper.copyIfNeeded(basicGetOldValue()));
 +  }
 +  /*
 +   * If the old value is off-heap return the StoredObject form (unretained OFF_HEAP_REFERENCE). 
 +   * Its refcount is not inced by this call and the returned object can only be safely used for the lifetime of the EntryEventImpl instance that returned the value.
 +   * Else return the raw form.
 +   */
 +  @Unretained
 +  public final Object getRawOldValue() {
 +    return basicGetOldValue();
 +  }
 +  /**
 +   * Just like getRawOldValue except if the raw old value is off-heap deserialize it.
 +   * Note that in some cases sqlf ignores the request to deserialize.
 +   */
 +  @Unretained(ENTRY_EVENT_OLD_VALUE)
 +  public final Object getOldValueAsOffHeapDeserializedOrRaw() {
 +    Object result = basicGetOldValue();
 +    if (result instanceof StoredObject) {
 +      result = ((StoredObject) result).getDeserializedForReading();
 +    }
 +    return AbstractRegion.handleNotAvailable(result); // fixes 49499
 +  }
 +
 +  /**
 +   * Added this function to expose isCopyOnRead function to the
 +   * child classes of EntryEventImpl  
 +   * 
 +   */
 +  protected boolean isRegionCopyOnRead() {
 +    return getRegion().isCopyOnRead();
 +  }
 + 
 +  /**
 +   * Returns the value in the cache after this event.
 +   *
 +   * @return the value in the cache after this event.
 +   */
 +  public final Object getNewValue() {
 +    
 +    boolean doCopyOnRead = getRegion().isCopyOnRead();
 +    try {
 +      if (applyDelta(true)) {
 +        @Unretained(ENTRY_EVENT_NEW_VALUE)
 +        Object applied = basicGetNewValue();
 +        if (applied == this.oldValue && doCopyOnRead) {
 +          applied = CopyHelper.copy(applied);
 +        }
 +        return applied;
 +      }
 +    } catch (EntryNotFoundException ex) {
 +      // only (broken) product code has the opportunity to call this before
 +      // this.oldValue is set. If oldValue is not set yet, then
 +      // we most likely haven't synchronized on the region entry yet.
 +      // (If we have, then make sure oldValue is set before
 +      // calling this method).
 +      throw new AssertionError("too early to call getNewValue");
 +    }
 +    Object nv = basicGetNewValue();
 +    if (nv != null) {
 +      if (nv == Token.NOT_AVAILABLE) {
 +        // I'm not sure this can even happen
 +        return AbstractRegion.handleNotAvailable(nv);
 +      }
 +      if (nv instanceof StoredObject) {
 +        // TODO OFFHEAP currently we copy offheap new value to the heap here. Check callers of this method to see if they can be optimized to use offheap values.
 +        // TODO OFFHEAP: returns off-heap PdxInstance
 +        return ((StoredObject) nv).getValueAsDeserializedHeapObject();
 +      } else
 +      if (nv instanceof CachedDeserializable) {
 +        CachedDeserializable cd = (CachedDeserializable)nv;
 +        Object v = null;
 +        if (doCopyOnRead) {
 +          v = cd.getDeserializedWritableCopy(this.region, this.re);
 +        } else {
 +          v = cd.getDeserializedValue(this.region, this.re);
 +        }
 +        assert !(v instanceof CachedDeserializable) : "for key "+this.getKey()+" found nested CachedDeserializable";
 +        return v;
 +      }
 +      else {
 +        if (doCopyOnRead) {
 +          return CopyHelper.copy(nv);
 +        } else {
 +          return nv;
 +        }
 +      }
 +    }
 +    return null;
 +  }
 +
 +  public final String getNewValueStringForm() {
 +    return StringUtils.forceToString(basicGetNewValue());
 +  }
 +  public final String getOldValueStringForm() {
 +    return StringUtils.forceToString(basicGetOldValue());
 +  }
 +  
 +  protected boolean applyDelta(boolean throwOnNullOldValue)
 +      throws EntryNotFoundException {
 +    if (this.newValue != null || this.delta == null) {
 +      return false;
 +    }
 +    if (this.oldValue == null) {
 +      if (throwOnNullOldValue) {
 +        // !!!:ezoerner:20080611 It would be nice if the client got this
 +        // exception
 +        throw new EntryNotFoundException(
 +            "Cannot apply a delta without an existing value");
 +      }
 +      return false;
 +    }
 +    // swizzle BucketRegion in event for Delta.
 +    // !!!:ezoerner:20090602 this is way ugly; this whole class severely
 +    // needs refactoring
 +    LocalRegion originalRegion = this.region;
 +    try {
 +      if (originalRegion instanceof BucketRegion) {
 +        this.region = ((BucketRegion)this.region).getPartitionedRegion();
 +      }
 +      basicSetNewValue(this.delta.apply(this));
 +    } finally {
 +      this.region = originalRegion;
 +    }
 +    return true;
 +  }
 +
 +  /** Set a deserialized value */
 +  public final void setNewValue(@Retained(ENTRY_EVENT_NEW_VALUE) Object obj) {
 +    if (obj instanceof Delta) {
 +      this.delta = (Delta)obj;
 +      basicSetNewValue(null);
 +    }
 +    else {
 +      basicSetNewValue(obj);
 +    }
 +  }
 +
 +  public TransactionId getTransactionId()
 +  {
 +    return this.txId;
 +  }
 +
 +  public void setTransactionId(TransactionId txId)
 +  {
 +    this.txId = (TXId)txId;
 +  }
 +
 +  /**
 +   * Answer true if this event resulted from a loader.
 +   *
 +   * @return true if isLocalLoad or isNetLoad
 +   */
 +  public boolean isLoad()
 +  {
 +    return this.op.isLoad();
 +  }
 +
 +  public void setRegion(LocalRegion r)
 +  {
 +    this.region = r;
 +  }
 +
 +  /**
 +   * @see com.gemstone.gemfire.cache.CacheEvent#getRegion()
 +   */
 +  public final LocalRegion getRegion() {
 +    return region;
 +  }
 +
 +  public Operation getOperation()
 +  {
 +    return this.op;
 +  }
 +
 +  public void setOperation(Operation op)
 +  {
 +    this.op = op;
 +    PartitionMessage prm = getPartitionMessage();
 +    if (prm != null) {
 +      prm.setOperation(this.op);
 +    }
 +  }
 +
 +  /**
 +   * @see com.gemstone.gemfire.cache.CacheEvent#getCallbackArgument()
 +   */
 +  public Object getCallbackArgument()
 +  {
 +    Object result = this.keyInfo.getCallbackArg();
 +    while (result instanceof WrappedCallbackArgument) {
 +      WrappedCallbackArgument wca = (WrappedCallbackArgument)result;
 +      result = wca.getOriginalCallbackArg();
 +    }
 +    if (result == Token.NOT_AVAILABLE) {
 +      result = AbstractRegion.handleNotAvailable(result);
 +    }
 +    return result;
 +  }
 +  public boolean isCallbackArgumentAvailable() {
 +    return this.getRawCallbackArgument() != Token.NOT_AVAILABLE;
 +  }
 +
 +  /**
 +   * Returns the value of the EntryEventImpl field.
 +   * This is for internal use only. Customers should always call
 +   * {@link #getCallbackArgument}
 +   * @since 5.5 
 +   */
 +  public Object getRawCallbackArgument() {
 +    return this.keyInfo.getCallbackArg();
 +  }
 +  
 +  /**
 +   * Sets the value of raw callback argument field.
 +   */
 +  public void setRawCallbackArgument(Object newCallbackArgument) {
 +    this.keyInfo.setCallbackArg(newCallbackArgument);
 +  }
 +
 +  public void setCallbackArgument(Object newCallbackArgument) {
 +    if (this.keyInfo.getCallbackArg() instanceof WrappedCallbackArgument) {
 +      ((WrappedCallbackArgument)this.keyInfo.getCallbackArg())
 +          .setOriginalCallbackArgument(newCallbackArgument);
 +    }
 +    else {
 +      this.keyInfo.setCallbackArg(newCallbackArgument);
 +    }
 +  }
 +
 +  /**
 +   * @return null if new value is not serialized; otherwise returns a SerializedCacheValueImpl containing the new value.
 +   */
 +  public SerializedCacheValue<?> getSerializedNewValue() {
 +    // In the case where there is a delta that has not been applied yet,
 +    // do not apply it here since it would not produce a serialized new
 +    // value (return null instead to indicate the new value is not
 +    // in serialized form).
 +    @Unretained(ENTRY_EVENT_NEW_VALUE)
 +    final Object tmp = basicGetNewValue();
 +    if (tmp instanceof CachedDeserializable) {
 +      if (tmp instanceof StoredObject) {
 +        if (!((StoredObject) tmp).isSerialized()) {
 +          // TODO OFFHEAP can we handle offheap byte[] better?
 +          return null;
 +        }
 +      }
 +      byte[] bytes = this.newValueBytes;
 +      if (bytes == null) {
 +        bytes = this.cachedSerializedNewValue;
 +      }
 +      return new SerializedCacheValueImpl(this, getRegion(), this.re,
 +          (CachedDeserializable)tmp, bytes);
 +    } else {
 +      // Note we return null even if cachedSerializedNewValue is not null.
 +      // This is because some callers of this method use it to indicate
 +      // that a CacheDeserializable should be created during deserialization.
 +      return null;
 +    }
 +  }
 +  
 +  /**
 +   * Implement this interface if you want to call {@link #exportNewValue}.
 +   * 
 +   * @author darrel
 +   *
 +   */
 +  public interface NewValueImporter {
 +    /**
 +     * @return true if the importer prefers the value to be in serialized form.
 +     */
 +    boolean prefersNewSerialized();
 +
 +    /**
 +     * Only return true if the importer can use the value before the event that exported it is released.
 +     * If false is returned then off-heap values will be copied to the heap for the importer.
 +     * @return true if the importer can deal with the value being an unretained OFF_HEAP_REFERENCE.
 +     */
 +    boolean isUnretainedNewReferenceOk();
 +
 +    /**
 +     * Import a new value that is currently in object form.
 +     * @param nv the new value to import; unretained if isUnretainedNewReferenceOk returns true
 +     * @param isSerialized true if the imported new value represents data that needs to be serialized; false if the imported new value is a simple sequence of bytes.
 +     */
 +    void importNewObject(@Unretained(ENTRY_EVENT_NEW_VALUE) Object nv, boolean isSerialized);
 +
 +    /**
 +     * Import a new value that is currently in byte array form.
 +     * @param nv the new value to import
 +     * @param isSerialized true if the imported new value represents data that needs to be serialized; false if the imported new value is a simple sequence of bytes.
 +     */
 +    void importNewBytes(byte[] nv, boolean isSerialized);
 +  }
 +  
 +  /**
 +   * Export the event's new value to the given importer.
 +   */
 +  public final void exportNewValue(NewValueImporter importer) {
 +    final boolean prefersSerialized = importer.prefersNewSerialized();
 +    if (prefersSerialized) {
 +      if (getCachedSerializedNewValue() != null) {
 +        importer.importNewBytes(getCachedSerializedNewValue(), true);
 +        return;
 +      } else {
 +      if (this.newValueBytes != null && this.newValue instanceof CachedDeserializable) {
 +        importer.importNewBytes(this.newValueBytes, true);
 +        return;
 +      }
 +      }
 +    }
 +    @Unretained(ENTRY_EVENT_NEW_VALUE) 
 +    final Object nv = getRawNewValue();
 +    if (nv instanceof StoredObject) {
 +      @Unretained(ENTRY_EVENT_NEW_VALUE)
 +      final StoredObject so = (StoredObject) nv;
 +      final boolean isSerialized = so.isSerialized();
 +      if (nv instanceof Chunk) {
 +        if (importer.isUnretainedNewReferenceOk()) {
 +          importer.importNewObject(nv, isSerialized);
 +        } else {
 +          if (!isSerialized || prefersSerialized) {
 +            byte[] bytes = so.getValueAsHeapByteArray();
 +            importer.importNewBytes(bytes, isSerialized);
 +            if (isSerialized) {
 +              setCachedSerializedNewValue(bytes);
 +            }
 +          } else {
 +            // TODO OFFHEAP: returns off-heap PdxInstance which is not ok since isUnretainedNewReferenceOk returned false
 +            importer.importNewObject(so.getValueAsDeserializedHeapObject(), true);
 +          }
 +        }
 +      } else {
 +        importer.importNewObject(nv, isSerialized);
 +      }
 +    } else if (nv instanceof byte[]) {
 +      importer.importNewBytes((byte[])nv, false);
 +    } else if (nv instanceof CachedDeserializable) {
 +      CachedDeserializable cd = (CachedDeserializable) nv;
 +      Object cdV = cd.getValue();
 +      if (cdV instanceof byte[]) {
 +        importer.importNewBytes((byte[]) cdV, true);
 +        setCachedSerializedNewValue((byte[]) cdV);
 +      } else {
 +        importer.importNewObject(cdV, true);
 +      }
 +    } else {
 +      importer.importNewObject(nv, true);
 +    }
 +  }
 +  /**
 +   * Implement this interface if you want to call {@link #exportOldValue}.
 +   * 
 +   * @author darrel
 +   *
 +   */
 +  public interface OldValueImporter {
 +    /**
 +     * @return true if the importer prefers the value to be in serialized form.
 +     */
 +    boolean prefersOldSerialized();
 +
 +    /**
 +     * Only return true if the importer can use the value before the event that exported it is released.
 +     * @return true if the importer can deal with the value being an unretained OFF_HEAP_REFERENCE.
 +     */
 +    boolean isUnretainedOldReferenceOk();
 +    
 +    /**
 +     * @return return true if you want the old value to possibly be an instanceof CachedDeserializable; false if you want the value contained in a CachedDeserializable.
 +     */
 +    boolean isCachedDeserializableValueOk();
 +
 +    /**
 +     * Import an old value that is currently in object form.
 +     * @param ov the old value to import; unretained if isUnretainedOldReferenceOk returns true
 +     * @param isSerialized true if the imported old value represents data that needs to be serialized; false if the imported old value is a simple sequence of bytes.
 +     */
 +    void importOldObject(@Unretained(ENTRY_EVENT_OLD_VALUE) Object ov, boolean isSerialized);
 +
 +    /**
 +     * Import an old value that is currently in byte array form.
 +     * @param ov the old value to import
 +     * @param isSerialized true if the imported old value represents data that needs to be serialized; false if the imported old value is a simple sequence of bytes.
 +     */
 +    void importOldBytes(byte[] ov, boolean isSerialized);
 +  }
 +  
 +  /**
 +   * Export the event's old value to the given importer.
 +   */
 +  public final void exportOldValue(OldValueImporter importer) {
 +    final boolean prefersSerialized = importer.prefersOldSerialized();
 +    if (prefersSerialized) {
 +      if (this.oldValueBytes != null && this.oldValue instanceof CachedDeserializable) {
 +        importer.importOldBytes(this.oldValueBytes, true);
 +        return;
 +      }
 +    }
 +    @Unretained(ENTRY_EVENT_OLD_VALUE)
 +    final Object ov = getRawOldValue();
 +    if (ov instanceof StoredObject) {
 +      final StoredObject so = (StoredObject) ov;
 +      final boolean isSerialized = so.isSerialized();
 +      if (ov instanceof Chunk) {
 +        if (importer.isUnretainedOldReferenceOk()) {
 +          importer.importOldObject(ov, isSerialized);
 +        } else {
 +          if (!isSerialized || prefersSerialized) {
 +            importer.importOldBytes(so.getValueAsHeapByteArray(), isSerialized);
 +          } else {
 +            // TODO OFFHEAP: returns off-heap PdxInstance which is not ok since isUnretainedNewReferenceOk returned false
 +           importer.importOldObject(so.getValueAsDeserializedHeapObject(), true);
 +          }
 +        }
 +      } else {
 +        importer.importOldObject(ov, isSerialized);
 +      }
 +    } else if (ov instanceof byte[]) {
 +      importer.importOldBytes((byte[])ov, false);
 +    } else if (!importer.isCachedDeserializableValueOk() && ov instanceof CachedDeserializable) {
 +      CachedDeserializable cd = (CachedDeserializable) ov;
 +      Object cdV = cd.getValue();
 +      if (cdV instanceof byte[]) {
 +        importer.importOldBytes((byte[]) cdV, true);
 +      } else {
 +        importer.importOldObject(cdV, true);
 +      }
 +    } else {
 +      importer.importOldObject(ov, true);
 +    }
 +  }
 +
 +  /**
 +   * If applyDelta is true then first attempt to apply a delta (if we have one) and return the value.
 +   * Else if new value is a Delta return it.
 +   * Else if new value is off-heap return the StoredObject form (unretained OFF_HEAP_REFERENCE). 
 +   * Its refcount is not inced by this call and the returned object can only be safely used for the lifetime of the EntryEventImpl instance that returned the value.
 +   * Else return the raw form.
 +   */
 +  @Unretained(ENTRY_EVENT_NEW_VALUE)
 +  public final Object getRawNewValue(boolean applyDelta) {
 +    if (applyDelta) {
 +      boolean doCopyOnRead = getRegion().isCopyOnRead();
 +      Object newValueWithDelta = applyDeltaWithCopyOnRead(doCopyOnRead);
 +      if (newValueWithDelta != null) {
 +        return newValueWithDelta;
 +      }
 +      // if applyDelta is true and we have already applied the delta then
 +      // just return the applied value instead of the delta object.
 +      @Unretained(ENTRY_EVENT_NEW_VALUE)
 +      Object newValue = basicGetNewValue();
 +      if (newValue != null) return newValue;
 +    }
 +    return getRawNewValue();
 +  }
 +  /**
 +   * Just like getRawNewValue(true) except if the raw new value is off-heap deserialize it.
 +   * Note that in some cases sqlf ignores the request to deserialize.
 +   */
 +  @Unretained(ENTRY_EVENT_NEW_VALUE)
 +  public final Object getNewValueAsOffHeapDeserializedOrRaw() {
 +    Object result = getRawNewValue(true);
 +    if (result instanceof StoredObject) {
 +      result = ((StoredObject) result).getDeserializedForReading();
 +    }
 +    return AbstractRegion.handleNotAvailable(result); // fixes 49499
 +  }
 +
 +  /**
 +   * If the new value is stored off-heap return a retained OFF_HEAP_REFERENCE (caller must release).
 +   * @return a retained OFF_HEAP_REFERENCE if the new value is off-heap; otherwise returns null
 +   */
 +  @Retained(ENTRY_EVENT_NEW_VALUE)
 +  public StoredObject getOffHeapNewValue() {
 +    final Object tmp = basicGetNewValue();
 +    if (tmp instanceof StoredObject) {
 +      StoredObject result = (StoredObject) tmp;
 +      if (!result.retain()) {
 +        return null;
 +      }
 +      return result;
 +    } else {
 +      return null;
 +    }
 +  }
 +  
 +  /**
 +   * If the old value is stored off-heap return a retained OFF_HEAP_REFERENCE (caller must release).
 +   * @return a retained OFF_HEAP_REFERENCE if the old value is off-heap; otherwise returns null
 +   */
 +  @Retained(ENTRY_EVENT_OLD_VALUE)
 +  public StoredObject getOffHeapOldValue() {
 +    final Object tmp = basicGetOldValue();
 +    if (tmp instanceof StoredObject) {
 +      StoredObject result = (StoredObject) tmp;
 +      if (!result.retain()) {
 +        return null;
 +      }
 +      return result;
 +    } else {
 +      return null;
 +    }
 +  }
 +
 +  /**
 +   * Result may be unretained because sqlf getDeserializedForReading returns unretained.
 +   */
 +  public final Object getDeserializedValue() {
 +    if (this.delta == null) {
 +      final Object val = basicGetNewValue();
 +      if (val instanceof StoredObject) {
 +        // TODO OFFHEAP: returns off-heap PdxInstance
 +        return ((StoredObject) val).getValueAsDeserializedHeapObject();
 +      } else 
 +      if (val instanceof CachedDeserializable) {
 +        return ((CachedDeserializable)val).getDeserializedForReading();
 +      }
 +      else {
 +        return val;
 +      }
 +    }
 +    else {
 +      return this.delta;
 +    }
 +  }
 +
 +  public final byte[] getSerializedValue() {
 +    if (this.newValueBytes == null) {
 +      final Object val;
 +      if (this.delta == null) {
 +        val = basicGetNewValue();
 +        if (val instanceof byte[]) {
 +          return (byte[])val;
 +        }
 +        else if (val instanceof CachedDeserializable) {
 +          return ((CachedDeserializable)val).getSerializedValue();
 +        }
 +      }
 +      else {
 +        val = this.delta;
 +      }
 +      try {
 +        return CacheServerHelper.serialize(val);
 +      } catch (IOException ioe) {
 +        throw new GemFireIOException("unexpected exception", ioe);
 +      }
 +    }
 +    else {
 +      return this.newValueBytes;
 +    }
 +  }
 +
 +  /**
 +   * Forces this entry's new value to be in serialized form.
 +   * @since 5.0.2
 +   */
 +  public void makeSerializedNewValue() {
 +    makeSerializedNewValue(false);
 +  }
 +
 +  /**
 +   * @param isSynced true if RegionEntry currently under synchronization
 +   */
 +  private final void makeSerializedNewValue(boolean isSynced) {
 +    Object obj = basicGetNewValue();
 +
 +    // ezoerner:20080611 In the case where there is an unapplied
 +    // delta, do not apply the delta or serialize yet unless entry is
 +    // under synchronization (isSynced is true) 
 +    if (isSynced) {
 +      this.setSerializationDeferred(false);
 +    }
 +    else if (obj == null && this.delta != null) {
 +      // defer serialization until setNewValueInRegion
 +      this.setSerializationDeferred(true);
 +      return;
 +    }
 +    basicSetNewValue(getCachedDeserializable(obj, this));
 +  }
 +
 +  public static Object getCachedDeserializable(Object obj) {
 +    return getCachedDeserializable(obj, null);
 +  }
 +
 +  public static Object getCachedDeserializable(Object obj, EntryEventImpl ev) {
 +    if (obj instanceof byte[]
 +                            || obj == null
 +                            || obj instanceof CachedDeserializable
 +                            || obj == Token.NOT_AVAILABLE
 +                            || Token.isInvalidOrRemoved(obj)
 +                            // don't serialize delta object already serialized
 +                            || obj instanceof com.gemstone.gemfire.Delta
 +                            || obj instanceof Delta) { // internal delta
 +      return obj;
 +    }
 +    final CachedDeserializable cd;
 +    // avoid unneeded serialization of byte[][] used by SQLFabric that
 +    // will end up being deserialized in any case (serialization is cheap
 +    //   for byte[][] anyways)
 +    if (obj instanceof byte[][]) {
 +      int objSize = Sizeable.PER_OBJECT_OVERHEAD + 4;
 +      for (byte[] bytes : (byte[][])obj) {
 +        if (bytes != null) {
 +          objSize += CachedDeserializableFactory.getByteSize(bytes);
 +        }
 +        else {
 +          objSize += Sizeable.PER_OBJECT_OVERHEAD;
 +        }
 +      }
 +      cd = CachedDeserializableFactory.create(obj, objSize);
 +    }
 +    else {
 +      final byte[] b = serialize(obj);
 +      cd = CachedDeserializableFactory.create(b);
 +      if (ev != null) {
 +        ev.newValueBytes = b;
 +        ev.cachedSerializedNewValue = b;
 +      }
 +    }
 +    return cd;
 +  }
 +  public void setCachedSerializedNewValue(byte[] v) {
 +    this.cachedSerializedNewValue = v;
 +  }
 +  public byte[] getCachedSerializedNewValue() {
 +    return this.cachedSerializedNewValue;
 +  }
 +
 +  public final void setSerializedNewValue(byte[] serializedValue) {
 +    Object newVal = null;
 +    if (serializedValue != null) {
 +      if (CachedDeserializableFactory.preferObject()) {
 +        newVal = deserialize(serializedValue);
 +      } else {
 +        newVal = CachedDeserializableFactory.create(serializedValue);
 +      }
 +      if (newVal instanceof Delta) {
 +        this.delta = (Delta)newVal;
 +        newVal = null;
 +        // We need the newValueBytes field and the newValue field to be in sync.
 +        // In the case of non-null delta set both fields to null.
 +        serializedValue = null;
 +      }
 +    }
 +    this.newValueBytes = serializedValue;
 +    basicSetNewValue(newVal);
 +    this.cachedSerializedNewValue = serializedValue;
 +  }
 +
 +  public void setSerializedOldValue(byte[] serializedOldValue){
 +    this.oldValueBytes = serializedOldValue;
 +    final Object ov;
 +    if (CachedDeserializableFactory.preferObject()) {
 +      ov = deserialize(serializedOldValue);
 +    }
 +    else if (serializedOldValue != null) {
 +      ov = CachedDeserializableFactory.create(serializedOldValue);
 +    }
 +    else {
 +      ov = null;
 +    }
 +    retainAndSetOldValue(ov);
 +  }
 +
 +  /**
 +   * If true (the default) then preserve old values in events.
 +   * If false then mark non-null values as being NOT_AVAILABLE.
 +   */
 +  private static final boolean EVENT_OLD_VALUE = !Boolean.getBoolean("gemfire.disable-event-old-value");
 +
 +  
 +  void putExistingEntry(final LocalRegion owner, RegionEntry entry) throws RegionClearedException {
 +    putExistingEntry(owner, entry, false, null);
 +  }
 +  
 +  /**
 +   * Put a newValue into the given, write synced, existing, region entry.
 +   * Sets oldValue in event if hasn't been set yet.
 +   * @param oldValueForDelta Used by Delta Propagation feature
 +   * 
 +   * @throws RegionClearedException
 +   */
 +  void putExistingEntry(final LocalRegion owner, final RegionEntry reentry,
 +     boolean requireOldValue, Object oldValueForDelta) throws RegionClearedException {
 +    makeUpdate();
 +    // only set oldValue if it hasn't already been set to something
 +    if (this.oldValue == null) {
 +      if (!reentry.isInvalidOrRemoved()) {
 +        if (requireOldValue ||
 +            EVENT_OLD_VALUE
 +            || this.region instanceof HARegion // fix for bug 37909
 +            || GemFireCacheImpl.sqlfSystem()
 +            ) {
 +          @Retained Object ov;
 +          if (ReferenceCountHelper.trackReferenceCounts()) {
 +            ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
 +            if (GemFireCacheImpl.sqlfSystem()) {
 +              ov = reentry.getValueOffHeapOrDiskWithoutFaultIn(this.region);
 +            } else {
 +              ov = reentry._getValueRetain(owner, true);
 +            }
 +            ReferenceCountHelper.setReferenceCountOwner(null);
 +          } else {
 +            if (GemFireCacheImpl.sqlfSystem()) {
 +              ov = reentry.getValueOffHeapOrDiskWithoutFaultIn(this.region);
 +            } else {
 +              ov = reentry._getValueRetain(owner, true);
 +            }
 +          }
 +          if (ov == null) ov = Token.NOT_AVAILABLE;
 +          // ov has already been retained so call basicSetOldValue instead of retainAndSetOldValue
 +          basicSetOldValue(ov);
 +        } else {
 +          basicSetOldValue(Token.NOT_AVAILABLE);
 +        }
 +      }
 +    }
 +    if (this.oldValue == Token.NOT_AVAILABLE) {
 +      FilterProfile fp = this.region.getFilterProfile();
 +      if (this.op.guaranteesOldValue() || 
 +          (fp != null /* #41532 */&& fp.entryRequiresOldValue(this.getKey()))) {
 +        setOldValueForQueryProcessing();
 +      }
 +    }
 +
 +    //setNewValueInRegion(null);
 +    setNewValueInRegion(owner, reentry, oldValueForDelta);
 +  }
 +
 +  /**
 +   * If we are currently a create op then turn us into an update
 +   *
 +   * @since 5.0
 +   */
 +  void makeUpdate()
 +  {
 +    setOperation(this.op.getCorrespondingUpdateOp());
 +  }
 +
 +  /**
 +   * If we are currently an update op then turn us into a create
 +   *
 +   * @since 5.0
 +   */
 +  void makeCreate()
 +  {
 +    setOperation(this.op.getCorrespondingCreateOp());
 +  }
 +
 +  /**
 +   * Put a newValue into the given, write synced, new, region entry.
 +   * @throws RegionClearedException
 +   */
 +  void putNewEntry(final LocalRegion owner, final RegionEntry reentry)
 +      throws RegionClearedException {
 +    if (!this.op.guaranteesOldValue()) {  // preserves oldValue for CM ops in clients
 +      basicSetOldValue(null);
 +    }
 +    makeCreate();
 +    setNewValueInRegion(owner, reentry, null);
 +  }
 +
 +  void setRegionEntry(RegionEntry re) {
 +    this.re = re;
 +  }
 +
 +  RegionEntry getRegionEntry() {
 +    return this.re;
 +  }
 +
 +  @Retained(ENTRY_EVENT_NEW_VALUE)
 +  private void setNewValueInRegion(final LocalRegion owner,
 +      final RegionEntry reentry, Object oldValueForDelta) throws RegionClearedException {
 +    
 +    boolean wasTombstone = reentry.isTombstone();
 +    
 +    // put in newValue
 +
 +    if (applyDelta(this.op.isCreate())) {
 +      if (this.isSerializationDeferred()) {
 +        makeSerializedNewValue(true);
 +      }
 +    }
 +
 +    // If event contains new value, then it may mean that the delta bytes should
 +    // not be applied. This is possible if the event originated locally.
 +    if (this.deltaBytes != null && this.newValue == null) {
 +      processDeltaBytes(oldValueForDelta);
 +    }
 +
 +    if (owner!=null) {
 +      owner.generateAndSetVersionTag(this, reentry);
 +    } else {
 +      this.region.generateAndSetVersionTag(this, reentry);
 +    }
 +    
 +    Object v = this.newValue;
 +    if (v == null) {
 +      v = isLocalInvalid() ? Token.LOCAL_INVALID : Token.INVALID;
 +    }
 +    else {
 +      this.region.regionInvalid = false;
 +    }
 +
 +    reentry.setValueResultOfSearch(this.op.isNetSearch());
 +
 +    //dsmith:20090524
 +    //This is a horrible hack, but we need to get the size of the object
 +    //When we store an entry. This code is only used when we do a put
 +    //in the primary.
 +    if(v instanceof com.gemstone.gemfire.Delta && region.isUsedForPartitionedRegionBucket()) {
 +      int vSize;
 +      Object ov = basicGetOldValue();
 +      if(ov instanceof CachedDeserializable && !GemFireCacheImpl.DELTAS_RECALCULATE_SIZE) {
 +        vSize = ((CachedDeserializable) ov).getValueSizeInBytes();
 +      } else {
 +        vSize = CachedDeserializableFactory.calcMemSize(v, region.getObjectSizer(), false);
 +      }
 +      v = CachedDeserializableFactory.create(v, vSize);
 +      basicSetNewValue(v);
 +    }
 +
 +    Object preparedV = reentry.prepareValueForCache(this.region, v, this, this.hasDelta());
 +    if (preparedV != v) {
 +      v = preparedV;
 +      if (v instanceof Chunk) {
 +        if (!((Chunk) v).isCompressed()) { // fix bug 52109
 +          // If we put it off heap and it is not compressed then remember that value.
 +          // Otherwise we want to remember the decompressed value in the event.
 +          basicSetNewValue(v);
 +        }
 +      }
 +    }
 +    boolean isTombstone = (v == Token.TOMBSTONE);
 +    boolean success = false;
 +    boolean calledSetValue = false;
 +    try {
 +    setNewValueBucketSize(owner, v);
 +    
 +    // ezoerner:20081030 
 +    // last possible moment to do index maintenance with old value in
 +    // RegionEntry before new value is set.
 +    // As part of an update, this is a remove operation as prelude to an add that
 +    // will come after the new value is set.
 +    // If this is an "update" from INVALID state, treat this as a create instead
 +    // for the purpose of index maintenance since invalid entries are not
 +    // indexed.
 +    
 +    if ((this.op.isUpdate() && !reentry.isInvalid()) || this.op.isInvalidate()) {
 +      IndexManager idxManager = IndexUtils.getIndexManager(this.region, false);
 +      if (idxManager != null) {
 +        try {
 +          idxManager.updateIndexes(reentry,
 +                                   IndexManager.REMOVE_ENTRY,
 +                                   this.op.isUpdate() ?
 +                                     IndexProtocol.BEFORE_UPDATE_OP :
 +                                     IndexProtocol.OTHER_OP);
 +        }
 +        catch (QueryException e) {
 +          throw new IndexMaintenanceException(e);
 +        }
 +      }
 +    }
 +    final IndexUpdater indexUpdater = this.region.getIndexUpdater();
 +    if (indexUpdater != null) {
 +      final LocalRegion indexRegion;
 +      if (owner != null) {
 +        indexRegion = owner;
 +      }
 +      else {
 +        indexRegion = this.region;
 +      }
 +      try {
 +        indexUpdater.onEvent(indexRegion, this, reentry);
 +        calledSetValue = true;
 +        reentry.setValueWithTombstoneCheck(v, this); // already called prepareValueForCache
 +        success = true;
 +      } finally {
 +        indexUpdater.postEvent(indexRegion, this, reentry, success);
 +      }
 +    }
 +    else {
 +      calledSetValue = true;
 +      reentry.setValueWithTombstoneCheck(v, this); // already called prepareValueForCache
 +      success = true;
 +    }
 +    } finally {
 +      if (!success && reentry instanceof OffHeapRegionEntry && v instanceof Chunk) {
 +        OffHeapRegionEntryHelper.releaseEntry((OffHeapRegionEntry)reentry, (Chunk)v);
 +      }      
 +    }
 +    if (logger.isTraceEnabled()) {
 +      if (v instanceof CachedDeserializable) {
 +        logger.trace("EntryEventImpl.setNewValueInRegion: put CachedDeserializable({},{})",
 +            this.getKey(), ((CachedDeserializable)v).getStringForm());
 +      }
 +      else {
 +        logger.trace("EntryEventImpl.setNewValueInRegion: put({},{})",
 +            this.getKey(), StringUtils.forceToString(v));
 +      }
 +    }
 +
 +    if (!isTombstone  &&  wasTombstone) {
 +      owner.unscheduleTombstone(reentry);
 +    }
 +  }
 +
 +  /**
 +   * The size the new value contributes to a pr bucket.
 +   * Note if this event is not on a pr then this value will be 0.
 +   */
 +  private transient int newValueBucketSize;
 +  public int getNewValueBucketSize() {
 +    return this.newValueBucketSize;
 +  }
 +  private void setNewValueBucketSize(LocalRegion lr, Object v) {
 +    if (lr == null) {
 +      lr = this.region;
 +    }
 +    this.newValueBucketSize = lr.calculateValueSize(v);
 +  }
 +
 +  private void processDeltaBytes(Object oldValueInVM) {
 +    if (!this.region.hasSeenEvent(this)) {
 +      if (oldValueInVM == null || Token.isInvalidOrRemoved(oldValueInVM)) {
 +        this.region.getCachePerfStats().incDeltaFailedUpdates();
 +        throw new InvalidDeltaException("Old value not found for key "
 +            + this.keyInfo.getKey());
 +      }
 +      FilterProfile fp = this.region.getFilterProfile();
 +      // If compression is enabled then we've already gotten a new copy due to the
 +      // serializaion and deserialization that occurs.
 +      boolean copy = this.region.getCompressor() == null &&
 +          (this.region.isCopyOnRead()
 +          || this.region.getCloningEnabled()
 +          || (fp != null && fp.getCqCount() > 0));
 +      Object value = oldValueInVM;
 +      boolean wasCD = false;
 +      if (value instanceof CachedDeserializable) {
 +        wasCD = true;
 +        if (copy) {
 +          value = ((CachedDeserializable)value).getDeserializedWritableCopy(this.region, re);
 +        } else {
 +          value = ((CachedDeserializable)value).getDeserializedValue(
 +              this.region, re);
 +        }
 +      } else {
 +        if (copy) {
 +          value = CopyHelper.copy(value);
 +        }
 +      }
 +      boolean deltaBytesApplied = false;
 +      try {
 +        long start = CachePerfStats.getStatTime();
 +        ((com.gemstone.gemfire.Delta)value).fromDelta(new DataInputStream(
 +            new ByteArrayInputStream(getDeltaBytes())));
 +        this.region.getCachePerfStats().endDeltaUpdate(start);
 +        deltaBytesApplied = true;
 +      } catch (RuntimeException rte) {
 +        throw rte;
 +      } catch (VirtualMachineError e) {
 +        SystemFailure.initiateFailure(e);
 +        throw e;
 +      } catch (Throwable t) {
 +        SystemFailure.checkFailure();
 +        throw new DeltaSerializationException(
 +            "Exception while deserializing delta bytes.", t);
 +      } finally {
 +        if (!deltaBytesApplied) {
 +          this.region.getCachePerfStats().incDeltaFailedUpdates();
 +        }
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Delta has been applied for key {}", getKey());
 +      }
 +      // assert event.getNewValue() == null;
 +      if (wasCD) {
 +        CachedDeserializable old = (CachedDeserializable)oldValueInVM;
 +        int valueSize;
 +        if (GemFireCacheImpl.DELTAS_RECALCULATE_SIZE) {
 +          valueSize = CachedDeserializableFactory.calcMemSize(value, region
 +              .getObjectSizer(), false);
 +        } else {
 +          valueSize = old.getValueSizeInBytes();
 +        }
 +        value = CachedDeserializableFactory.create(value, valueSize);
 +      }
 +      setNewValue(value);
 +      if (this.causedByMessage != null
 +          && this.causedByMessage instanceof PutMessage) {
 +        ((PutMessage)this.causedByMessage).setDeltaValObj(value);
 +      }
 +    } else {
 +      this.region.getCachePerfStats().incDeltaFailedUpdates();
 +      throw new InvalidDeltaException(
 +          "Cache encountered replay of event containing delta bytes for key "
 +              + this.keyInfo.getKey());
 +    }
 +  }
 +
 +  void setTXEntryOldValue(Object oldVal, boolean mustBeAvailable) {
 +    if (Token.isInvalidOrRemoved(oldVal)) {
 +      oldVal = null;
 +    }
 +    else {
 +      if (mustBeAvailable || oldVal == null || EVENT_OLD_VALUE) {
 +        // set oldValue to oldVal
 +      }
 +      else {
 +        oldVal = Token.NOT_AVAILABLE;
 +      }
 +    }
 +    retainAndSetOldValue(oldVal);
 +  }
 +
 +  void putValueTXEntry(final TXEntryState tx) {
 +    Object v = basicGetNewValue();
 +    if (v == null) {
 +      if (deltaBytes != null) {
 +        // since newValue is null, and we have deltaBytes
 +        // there must be a nearSidePendingValue
 +        processDeltaBytes(tx.getNearSidePendingValue());
 +        v = basicGetNewValue();
 +      } else if (this.delta != null) {
 +        v = this.delta;
 +      } else {
 +        v = isLocalInvalid() ? Token.LOCAL_INVALID : Token.INVALID;
 +      }
 +    }
 +
 +    if (this.op != Operation.LOCAL_INVALIDATE
 +        && this.op != Operation.LOCAL_DESTROY) {
 +      // fix for bug 34387
 +      tx.setPendingValue(OffHeapHelper.copyIfNeeded(v)); // TODO OFFHEAP optimize
 +    }
 +    tx.setCallbackArgument(getCallbackArgument());
 +  }
 +
 +  /** @return false if entry doesn't exist */
 +  public boolean setOldValueFromRegion()
 +  {
 +    try {
 +      RegionEntry re = this.region.getRegionEntry(getKey());
 +      if (re == null) return false;
 +      ReferenceCountHelper.skipRefCountTracking();
 +      Object v = re._getValueRetain(this.region, true);
 +      ReferenceCountHelper.unskipRefCountTracking();
 +      try {
 +        return setOldValue(v);
 +      } finally {
 +        OffHeapHelper.releaseWithNoTracking(v);
 +      }
 +    }
 +    catch (EntryNotFoundException ex) {
 +      return false;
 +    }
 +  }
 +
 +  /** Return true if old value is the DESTROYED token */
 +  boolean oldValueIsDestroyedToken()
 +  {
 +    return this.oldValue == Token.DESTROYED || this.oldValue == Token.TOMBSTONE;
 +  }
 +
 +  void setOldValueDestroyedToken()
 +  {
 +    basicSetOldValue(Token.DESTROYED);
 +  }
 +
 +  /**
 +   * @return false if value 'v' indicates that entry does not exist
 +   */
 +  public boolean setOldValue(Object v) {
 +    return setOldValue(v, false);
 +  }
 +  
 +  
 +  /**
 +   * @param force true if the old value should be forcibly set, used
 +   * for HARegions, methods like putIfAbsent, etc.,
 +   * where the old value must be available.
 +   * @return false if value 'v' indicates that entry does not exist
 +   */
 +  public boolean setOldValue(Object v, boolean force) {
 +    if (v == null || Token.isRemoved(v)) {
 +      return false;
 +    }
 +    else {
 +      if (Token.isInvalid(v)) {
 +        v = null;
 +      }
 +      else {
 +        if (force ||
 +            (this.region instanceof HARegion) // fix for bug 37909
 +            ) {
 +          // set oldValue to "v".
 +        } else if (EVENT_OLD_VALUE) {
 +          // TODO Rusty add compression support here
 +          // set oldValue to "v".
 +        } else {
 +          v = Token.NOT_AVAILABLE;
 +        }
 +      }
 +      retainAndSetOldValue(v);
 +      return true;
 +    }
 +  }
 +
 +  /**
 +   * sets the old value for concurrent map operation results received
 +   * from a server.
 +   */
 +  public void setConcurrentMapOldValue(Object v) {
 +    if (Token.isRemoved(v)) {
 +      return;
 +    } else {
 +      if (Token.isInvalid(v)) {
 +        v = null;
 +      }   
 +      retainAndSetOldValue(v);
 +    }
 +  }
 +
 +  /** Return true if new value available */
 +  public boolean hasNewValue() {
 +    Object tmp = this.newValue;
 +    if (tmp == null && hasDelta()) {
 +      // ???:ezoerner:20080611 what if applying the delta would produce
 +      // null or (strangely) NOT_AVAILABLE.. do we need to apply it here to
 +      // find out?
 +      return true;
 +    }
 +    return  tmp != null && tmp != Token.NOT_AVAILABLE;
 +  }
 +
 +  public final boolean hasOldValue() {
 +    return this.oldValue != null && this.oldValue != Token.NOT_AVAILABLE;
 +  }
 +  public final boolean isOldValueAToken() {
 +    return this.oldValue instanceof Token;
 +  }
 +
 +  /**
 +   * This should only be used in case of internal delta and <B>not for Delta of
 +   * Delta Propagation feature</B>.
 +   * 
 +   * @return boolean
 +   */
 +  public boolean hasDelta() {
 +    return (this.delta != null);
 +  }
 +
 +  public boolean isOldValueAvailable() {
 +    if (isOriginRemote() && this.region.isProxy()) {
 +      return false;
 +    } else {
 +      return basicGetOldValue() != Token.NOT_AVAILABLE;
 +    }
 +  }
 +  
 +  public void oldValueNotAvailable() {
 +    basicSetOldValue(Token.NOT_AVAILABLE);
 +  }
 +
 +  public static Object deserialize(byte[] bytes) {
 +    return deserialize(bytes, null, null);
 +  }
 +
 +  public static Object deserialize(byte[] bytes, Version version,
 +      ByteArrayDataInput in) {
 +    if (bytes == null)
 +      return null;
 +    try {
 +      return BlobHelper.deserializeBlob(bytes, version, in);
 +    }
 +    catch (IOException e) {
 +      throw new SerializationException(LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_DESERIALIZING.toLocalizedString(), e);
 +    }
 +    catch (ClassNotFoundException e) {
 +      // fix for bug 43602
 +      throw new SerializationException(LocalizedStrings.EntryEventImpl_A_CLASSNOTFOUNDEXCEPTION_WAS_THROWN_WHILE_TRYING_TO_DESERIALIZE_CACHED_VALUE.toLocalizedString(), e);
 +    }
 +  }
 +
 +  /**
 +   * If a PdxInstance is returned then it will have an unretained reference
 +   * to Chunk's off-heap address.
 +   */
 +  public static @Unretained Object deserializeChunk(Chunk bytes) {
 +    if (bytes == null)
 +      return null;
 +    try {
 +      return BlobHelper.deserializeOffHeapBlob(bytes);
 +    }
 +    catch (IOException e) {
 +      throw new SerializationException(LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_DESERIALIZING.toLocalizedString(), e);
 +    }
 +    catch (ClassNotFoundException e) {
 +      // fix for bug 43602
 +      throw new SerializationException(LocalizedStrings.EntryEventImpl_A_CLASSNOTFOUNDEXCEPTION_WAS_THROWN_WHILE_TRYING_TO_DESERIALIZE_CACHED_VALUE.toLocalizedString(), e);
 +    }
 +  }
 +
 +  /**
 +   * Serialize an object into a <code>byte[]</code>
 +   *
 +   * @throws IllegalArgumentException
 +   *           If <code>obj</code> should not be serialized
 +   */
 +  public static byte[] serialize(Object obj) {
 +    return serialize(obj, null);
 +  }
 +
 +   /**
 +     * Serialize an object into a <code>byte[]</code>
 +     *
 +     * @throws IllegalArgumentException
 +     *           If <code>obj</code> should not be serialized
 +     */
 +  public static byte[] serialize(Object obj, Version version)
 +  {
 +    if (obj == null || obj == Token.NOT_AVAILABLE
 +        || Token.isInvalidOrRemoved(obj))
 +      throw new IllegalArgumentException(LocalizedStrings.EntryEventImpl_MUST_NOT_SERIALIZE_0_IN_THIS_CONTEXT.toLocalizedString(obj));
 +    try {
 +      return BlobHelper.serializeToBlob(obj, version);
 +    }
 +    catch (IOException e) {
 +      throw new SerializationException(LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString(), e);
 +    }
 +  }
 +  
 +  
 +  /**
 +   * Serialize an object into a <code>byte[]</code> . If the byte array
 +   * provided by the wrapper is sufficient to hold the data, it is used
 +   * otherwise a new byte array gets created & its reference is stored in the
 +   * wrapper. The User Bit is also appropriately set as Serialized
 +   * 
 +   * @param wrapper
 +   *                Object of type BytesAndBitsForCompactor which is used to fetch
 +   *                the serialized data. The byte array of the wrapper is used
 +   *                if possible else a the new byte array containing the data is
 +   *                set in the wrapper.
 +   * @throws IllegalArgumentException
 +   *                 If <code>obj</code> should not be serialized
 +   */
 +  public static void fillSerializedValue(BytesAndBitsForCompactor wrapper,
 +                                         Object obj, byte userBits) {
 +    if (obj == null || obj == Token.NOT_AVAILABLE
 +        || Token.isInvalidOrRemoved(obj))
 +      throw new IllegalArgumentException(
 +        LocalizedStrings.EntryEvents_MUST_NOT_SERIALIZE_0_IN_THIS_CONTEXT.toLocalizedString(obj));
 +    try {
 +      HeapDataOutputStream hdos = null;
 +      if (wrapper.getBytes().length < 32) {
 +        hdos = new HeapDataOutputStream(Version.CURRENT);
 +      }
 +      else {
 +        hdos = new HeapDataOutputStream(wrapper.getBytes());
 +      }
 +      DataSerializer.writeObject(obj, hdos);
 +      // return hdos.toByteArray();
 +      hdos.sendTo(wrapper, userBits);
 +    }
 +    catch (IOException e) {
 +      RuntimeException e2 = new IllegalArgumentException(
 +        LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString());
 +      e2.initCause(e);
 +      throw e2;
 +    }
 +  }
 +
 +  protected String getShortClassName() {
 +    String cname = getClass().getName();
 +    return cname.substring(getClass().getPackage().getName().length()+1);
 +  }
 +
 +  @Override
 +  public String toString() {
 +    StringBuilder buf = new StringBuilder();
 +    buf.append(getShortClassName());
 +    buf.append("[");
 +
 +    buf.append("op=");
 +    buf.append(getOperation());
 +    buf.append(";key=");
 +    buf.append(this.getKey());
 +    buf.append(";oldValue=");
 +    try {
 +      ArrayUtils.objectStringNonRecursive(basicGetOldValue(), buf);
 +    } catch (IllegalStateException ex) {
 +      buf.append("OFFHEAP_VALUE_FREED");
 +    }
 +    buf.append(";newValue=");
 +    try {
 +      ArrayUtils.objectStringNonRecursive(basicGetNewValue(), buf);
 +    } catch (IllegalStateException ex) {
 +      buf.append("OFFHEAP_VALUE_FREED");
 +    }
 +    buf.append(";callbackArg=");
 +    buf.append(this.getRawCallbackArgument());
 +    buf.append(";originRemote=");
 +    buf.append(isOriginRemote());
 +    buf.append(";originMember=");
 +    buf.append(getDistributedMember());
 +//    if (this.partitionMessage != null) {
 +//      buf.append("; partitionMessage=");
 +//      buf.append(this.partitionMessage);
 +//    }
 +    if (this.isPossibleDuplicate()) {
 +      buf.append(";posDup");
 +    }
 +    if (callbacksInvoked()) { 
 +      buf.append(";callbacksInvoked");
 +    }
 +    if (this.versionTag != null) {
 +      buf.append(";version=").append(this.versionTag);
 +    }
 +    if (getContext() != null) {
 +      buf.append(";context=");
 +      buf.append(getContext());
 +    }
 +    if (this.eventID != null) {
 +      buf.append(";id=");
 +      buf.append(this.eventID);
 +    }
 +    if (this.deltaBytes != null) {
 +      buf.append(";[" + this.deltaBytes.length + " deltaBytes]");
 +    }
 +//    else {
 +//      buf.append(";[no deltaBytes]");
 +//    }
 +    if (this.filterInfo != null) {
 +      buf.append(";routing=");
 +      buf.append(this.filterInfo);
 +    }
 +    if (this.isFromServer()) {
 +      buf.append(";isFromServer");
 +    }
 +    if (this.isConcurrencyConflict()) {
 +      buf.append(";isInConflict");
 +    }
 +    if (this.getInhibitDistribution()) {
 +      buf.append(";inhibitDistribution");
 +    }
 +    buf.append("]");
 +    return buf.toString();
 +  }
 +
 +  public int getDSFID() {
 +    return ENTRY_EVENT;
 +  }
 +
 +  public void toData(DataOutput out) throws IOException
 +  {
 +    DataSerializer.writeObject(this.eventID, out);    
 +    DataSerializer.writeObject(this.getKey(), out);
 +    DataSerializer.writeObject(this.keyInfo.getValue(), out);
 +    out.writeByte(this.op.ordinal);
 +    out.writeShort(this.eventFlags & EventFlags.FLAG_TRANSIENT_MASK);
 +    DataSerializer.writeObject(this.getRawCallbackArgument(), out);
 +    DataSerializer.writeObject(this.txId, out);
 +
 +    {
 +      boolean isDelta = this.delta != null;
 +      out.writeBoolean(isDelta);
 +      if (isDelta) {
 +        DataSerializer.writeObject(this.delta, out);
 +      }
 +      else {
 +        Object nv = basicGetNewValue();
 +        boolean newValueSerialized = nv instanceof CachedDeserializable;
 +        if (newValueSerialized) {
 +          if (nv instanceof StoredObject) {
 +            newValueSerialized = ((StoredObject) nv).isSerialized();
 +          }
 +        }
 +        out.writeBoolean(newValueSerialized);
 +        if (newValueSerialized) {
 +          if (this.newValueBytes != null) {
 +            DataSerializer.writeByteArray(this.newValueBytes, out);
 +          } else if (this.cachedSerializedNewValue != null) {
 +            DataSerializer.writeByteArray(this.cachedSerializedNewValue, out);
 +          } else {
 +            CachedDeserializable cd = (CachedDeserializable)nv;
 +            DataSerializer.writeObjectAsByteArray(cd.getValue(), out);
 +          }
 +        }
 +        else {
 +          DataSerializer.writeObject(nv, out);
 +        }
 +      }  
 +    }
 +
 +    {
 +      Object ov = basicGetOldValue();
 +      boolean oldValueSerialized = ov instanceof CachedDeserializable;
 +      if (oldValueSerialized) {
 +        if (ov instanceof StoredObject) {
 +          oldValueSerialized = ((StoredObject) ov).isSerialized();
 +        }
 +      }
 +      out.writeBoolean(oldValueSerialized);
 +      if (oldValueSerialized) {
 +        if (this.oldValueBytes != null) {
 +          DataSerializer.writeByteArray(this.oldValueBytes, out);
 +        }
 +        else {
 +          CachedDeserializable cd = (CachedDeserializable)ov;
 +          DataSerializer.writeObjectAsByteArray(cd.getValue(), out);
 +        }
 +      }
 +      else {
 +        DataSerializer.writeObject(ov, out);
 +      }
 +    }
 +    InternalDataSerializer.invokeToData((InternalDistributedMember)this.distributedMember, out);
 +    DataSerializer.writeObject(getContext(), out);
 +    DataSerializer.writeLong(tailKey, out);
 +  }
 +
 +  private static abstract class EventFlags
 +   {
 +    private static final short FLAG_ORIGIN_REMOTE = 0x01;
 +    // localInvalid: true if a null new value should be treated as a local
 + 

<TRUNCATED>


[055/100] [abbrv] incubator-geode git commit: GEODE-831: unit test FreeListManager

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
index daebefa..9c83f5b 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
@@ -43,7 +43,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest {
 
   @Before
   public void setUp() throws Exception {
-    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
   }
 
   @After
@@ -52,7 +52,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest {
   }
   
   private StoredObject createStoredObject(byte[] bytes, boolean isSerialized, boolean isCompressed) {
-    return SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, isCompressed, null);
+    return SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, isCompressed);
   }
   
   private DataInputStream createInput(HeapDataOutputStream hdos) {
@@ -64,7 +64,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest {
   public void testByteArrayChunk() throws IOException, ClassNotFoundException {
     byte[] expected = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
     StoredObject so = createStoredObject(expected, false, false);
-    assertTrue(so instanceof Chunk);
+    assertTrue(so instanceof ObjectChunk);
     HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]);
     DataSerializer.writeObjectAsByteArray(so, hdos);
     DataInputStream in = createInput(hdos);
@@ -88,7 +88,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest {
   public void testStringChunk() throws IOException, ClassNotFoundException {
     byte[] expected = EntryEventImpl.serialize("1234567890");
     StoredObject so = createStoredObject(expected, true, false);
-    assertTrue(so instanceof Chunk);
+    assertTrue(so instanceof ObjectChunk);
     HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]);
     DataSerializer.writeObjectAsByteArray(so, hdos);
     DataInputStream in = createInput(hdos);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
index 6e26b2f..d8c35b8 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
@@ -41,7 +41,7 @@ public class OldFreeListOffHeapRegionJUnitTest extends OffHeapRegionBase {
 
   @Override
   public int perObjectOverhead() {
-    return Chunk.OFF_HEAP_HEADER_SIZE;
+    return ObjectChunk.OFF_HEAP_HEADER_SIZE;
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
index 239cbc8..51f46a1 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
@@ -93,7 +93,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest {
   public void setUp() throws Exception {
     System.setProperty("gemfire.validateOffHeapWithFill", "true");
     this.slab = new UnsafeMemoryChunk(SLAB_SIZE);
-    this.allocator = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
+    this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
   }
 
   /**
@@ -163,7 +163,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest {
         private int totalAllocation = 0;
         
         // List of Chunks allocated by this thread
-        private List<Chunk> chunks = new LinkedList<Chunk>();
+        private List<ObjectChunk> chunks = new LinkedList<ObjectChunk>();
         
         // Time to end thread execution
         private long endTime = System.currentTimeMillis() + RUN_TIME_IN_MILLIS;
@@ -173,7 +173,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest {
          */
         private void allocate() {          
           int allocation = chunkSizer.allocationSize();
-          Chunk chunk = (Chunk) allocator.allocate(allocation, null);
+          ObjectChunk chunk = (ObjectChunk) allocator.allocate(allocation);
           
           // This should always work just after allocation
           chunk.validateFill();
@@ -186,7 +186,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest {
          * Frees a random chunk from the Chunk list.
          */
         private void free() {
-          Chunk chunk = chunks.remove(random.nextInt(chunks.size()));
+          ObjectChunk chunk = chunks.remove(random.nextInt(chunks.size()));
           totalAllocation -= chunk.getSize();
           
           /*
@@ -200,7 +200,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest {
          * Writes canned data to a random Chunk from the Chunk list.
          */
         private void write() {
-          Chunk chunk = chunks.get(random.nextInt(chunks.size()));
+          ObjectChunk chunk = chunks.get(random.nextInt(chunks.size()));
           chunk.writeBytes(0, WRITE_BYTES);
         }
         

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
index 21c9835..7c26f86 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
@@ -66,7 +66,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest {
   public void setUp() throws Exception {
     System.setProperty("gemfire.validateOffHeapWithFill", "true");
     this.slab = new UnsafeMemoryChunk(SLAB_SIZE);
-    this.allocator = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
+    this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
   }
 
   /**
@@ -101,7 +101,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest {
      * Pull a chunk off the fragment.  This will have no fill because
      * it is a "fresh" chunk.
      */
-    Chunk chunk = (Chunk) this.allocator.allocate(chunkSize, null);
+    ObjectChunk chunk = (ObjectChunk) this.allocator.allocate(chunkSize);
 
     /*
      * Chunk should have valid fill from initial fragment allocation.
@@ -109,7 +109,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest {
     chunk.validateFill();
          
     // "Dirty" the chunk so the release has something to fill over
-    chunk.writeBytes(Chunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
+    chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
 
     // This should free the Chunk (ref count == 1)
     chunk.release();
@@ -118,20 +118,20 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest {
      * This chunk should have a fill because it was reused from the
      * free list (assuming no fragmentation at this point...)
      */
-    chunk = (Chunk) this.allocator.allocate(chunkSize, null);
+    chunk = (ObjectChunk) this.allocator.allocate(chunkSize);
     
     // Make sure we have a fill this time
     chunk.validateFill();
     
     // Give the fill code something to write over during the release
-    chunk.writeBytes(Chunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
+    chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
     chunk.release();
 
     // Again, make sure the release implemented the fill
     chunk.validateFill();
 
     // "Dirty up" the free chunk
-    chunk.writeBytes(Chunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
+    chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
     
     catchException(chunk).validateFill();
     assertTrue(caughtException() instanceof IllegalStateException);
@@ -149,14 +149,14 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest {
     /*
      * Stores our allocated memory.
      */
-    Chunk[] allocatedChunks = new Chunk[COMPACTION_CHUNKS];
+    ObjectChunk[] allocatedChunks = new ObjectChunk[COMPACTION_CHUNKS];
     
     /*
      * Use up most of our memory
      * Our memory looks like [      ][      ][      ]
      */
     for(int i =0;i < allocatedChunks.length;++i) {
-      allocatedChunks[i] = (Chunk) this.allocator.allocate(COMPACTION_CHUNK_SIZE, null);
+      allocatedChunks[i] = (ObjectChunk) this.allocator.allocate(COMPACTION_CHUNK_SIZE);
       allocatedChunks[i].validateFill();
     }
 
@@ -173,7 +173,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest {
      * our initial chunks.  This should force a compaction causing our
      * memory to look like [            ][      ].
      */
-    Chunk slightlyLargerChunk = (Chunk) this.allocator.allocate(FORCE_COMPACTION_CHUNK_SIZE, null);
+    ObjectChunk slightlyLargerChunk = (ObjectChunk) this.allocator.allocate(FORCE_COMPACTION_CHUNK_SIZE);
     
     /*
      * Make sure the compacted memory has the fill validation.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
index d9979cc..1f17f9b 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
@@ -32,7 +32,6 @@ import org.junit.experimental.categories.Category;
 import com.gemstone.gemfire.OutOfOffHeapMemoryException;
 import com.gemstone.gemfire.cache.CacheClosedException;
 import com.gemstone.gemfire.internal.logging.NullLogWriter;
-import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk.Factory;
 import com.gemstone.gemfire.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
@@ -54,53 +53,10 @@ public class SimpleMemoryAllocatorJUnitTest {
   @Test
   public void testConstructor() {
     try {
-      SimpleMemoryAllocatorImpl.create(null, null, null);
+      SimpleMemoryAllocatorImpl.createForUnitTest(null, null, null);
       fail("expected IllegalArgumentException");
     } catch (IllegalArgumentException expected) {
     }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, -1, 0, 0, 0);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8"));
-    }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 9, 0, 0, 0);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8"));
-    }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 256+8, 0, 0, 0);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_ALIGNMENT must be <= 256"));
-    }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 0, 0, 0);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE must be >= 1."));
-    }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 1, 0, 0);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1."));
-    }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 1, 1, -1);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("HUGE_MULTIPLE must be >= 0 and <= 256 but it was -1"));
-    }
-    try {
-      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 1, 1, 257);
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-      assertEquals(true, expected.getMessage().contains("HUGE_MULTIPLE must be >= 0 and <= 256 but it was 257"));
-    }
-     
   }
   /**
    * Logger that remembers the last severe message
@@ -140,10 +96,10 @@ public class SimpleMemoryAllocatorJUnitTest {
       NullOffHeapMemoryStats stats = new NullOffHeapMemoryStats();
       LastSevereLogger logger = new LastSevereLogger();
       try {
-        SimpleMemoryAllocatorImpl.create(listener, stats, logger, 10, 950, 100,
-            new UnsafeMemoryChunk.Factory() {
+        SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, logger, 10, 950, 100,
+            new AddressableMemoryChunkFactory() {
           @Override
-          public UnsafeMemoryChunk create(int size) {
+          public AddressableMemoryChunk create(int size) {
             throw new OutOfMemoryError("expected");
           }
         });
@@ -160,10 +116,10 @@ public class SimpleMemoryAllocatorJUnitTest {
       LastSevereLogger logger = new LastSevereLogger();
       int MAX_SLAB_SIZE = 100;
       try {
-        Factory factory = new UnsafeMemoryChunk.Factory() {
+        AddressableMemoryChunkFactory factory = new AddressableMemoryChunkFactory() {
           private int createCount = 0;
           @Override
-          public UnsafeMemoryChunk create(int size) {
+          public AddressableMemoryChunk create(int size) {
             createCount++;
             if (createCount == 1) {
               return new UnsafeMemoryChunk(size);
@@ -172,7 +128,7 @@ public class SimpleMemoryAllocatorJUnitTest {
             }
           }
         };
-        SimpleMemoryAllocatorImpl.create(listener, stats, logger, 10, 950, MAX_SLAB_SIZE, factory);
+        SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, logger, 10, 950, MAX_SLAB_SIZE, factory);
       } catch (OutOfMemoryError expected) {
       }
       assertTrue(listener.isClosed());
@@ -183,14 +139,14 @@ public class SimpleMemoryAllocatorJUnitTest {
     {
       NullOutOfOffHeapMemoryListener listener = new NullOutOfOffHeapMemoryListener();
       NullOffHeapMemoryStats stats = new NullOffHeapMemoryStats();
-      Factory factory = new UnsafeMemoryChunk.Factory() {
+      AddressableMemoryChunkFactory factory = new AddressableMemoryChunkFactory() {
         @Override
-        public UnsafeMemoryChunk create(int size) {
+        public AddressableMemoryChunk create(int size) {
           return new UnsafeMemoryChunk(size);
         }
       };
       MemoryAllocator ma = 
-        SimpleMemoryAllocatorImpl.create(listener, stats, new NullLogWriter(), 10, 950, 100, factory);
+        SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, new NullLogWriter(), 10, 950, 100, factory);
       try {
         assertFalse(listener.isClosed());
         assertFalse(stats.isClosed());
@@ -202,7 +158,7 @@ public class SimpleMemoryAllocatorJUnitTest {
         {
           UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
           try {
-            SimpleMemoryAllocatorImpl.create(listener, stats2, new UnsafeMemoryChunk[]{slab});
+            SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats2, new UnsafeMemoryChunk[]{slab});
           } catch (IllegalStateException expected) {
             assertTrue("unexpected message: " + expected.getMessage(), 
                 expected.getMessage().equals("attempted to reuse existing off-heap memory even though new off-heap memory was allocated"));
@@ -215,7 +171,7 @@ public class SimpleMemoryAllocatorJUnitTest {
         }
         listener = new NullOutOfOffHeapMemoryListener();
         stats2 = new NullOffHeapMemoryStats();
-        MemoryAllocator ma2 = SimpleMemoryAllocatorImpl.create(listener, stats2, new NullLogWriter(), 10, 950, 100, factory);
+        MemoryAllocator ma2 = SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats2, new NullLogWriter(), 10, 950, 100, factory);
         assertSame(ma, ma2);
         assertTrue(stats.isClosed());
         assertFalse(listener.isClosed());
@@ -232,24 +188,24 @@ public class SimpleMemoryAllocatorJUnitTest {
   }
   @Test
   public void testBasics() {
-    int BATCH_SIZE = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.BATCH_SIZE;
-    int TINY_MULTIPLE = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.TINY_MULTIPLE;
-    int HUGE_MULTIPLE = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.HUGE_MULTIPLE;
-    int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
-    int maxTiny = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.MAX_TINY-perObjectOverhead;
+    int BATCH_SIZE = 1;
+    int TINY_MULTIPLE = com.gemstone.gemfire.internal.offheap.FreeListManager.TINY_MULTIPLE;
+    int HUGE_MULTIPLE = com.gemstone.gemfire.internal.offheap.FreeListManager.HUGE_MULTIPLE;
+    int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
+    int maxTiny = com.gemstone.gemfire.internal.offheap.FreeListManager.MAX_TINY-perObjectOverhead;
     int minHuge = maxTiny+1;
     int TOTAL_MEM = (maxTiny+perObjectOverhead)*BATCH_SIZE /*+ (maxBig+perObjectOverhead)*BATCH_SIZE*/ + round(TINY_MULTIPLE, minHuge+1+perObjectOverhead)*BATCH_SIZE + (TINY_MULTIPLE+perObjectOverhead)*BATCH_SIZE /*+ (MIN_BIG_SIZE+perObjectOverhead)*BATCH_SIZE*/ + round(TINY_MULTIPLE, minHuge+perObjectOverhead+1);
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       assertEquals(TOTAL_MEM, ma.getFreeMemory());
       assertEquals(TOTAL_MEM, ma.freeList.getFreeFragmentMemory());
       assertEquals(0, ma.freeList.getFreeTinyMemory());
       assertEquals(0, ma.freeList.getFreeHugeMemory());
-      MemoryChunk tinymc = ma.allocate(maxTiny, null);
+      MemoryChunk tinymc = ma.allocate(maxTiny);
       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeTinyMemory());
-      MemoryChunk hugemc = ma.allocate(minHuge, null);
+      MemoryChunk hugemc = ma.allocate(minHuge);
       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, minHuge+perObjectOverhead)/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
       long freeSlab = ma.freeList.getFreeFragmentMemory();
       long oldFreeHugeMemory = ma.freeList.getFreeHugeMemory();
@@ -263,10 +219,10 @@ public class SimpleMemoryAllocatorJUnitTest {
       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.freeList.getFreeTinyMemory()-oldFreeTinyMemory);
       assertEquals(TOTAL_MEM, ma.getFreeMemory());
       // now lets reallocate from the free lists
-      tinymc = ma.allocate(maxTiny, null);
+      tinymc = ma.allocate(maxTiny);
       assertEquals(oldFreeTinyMemory, ma.freeList.getFreeTinyMemory());
       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
-      hugemc = ma.allocate(minHuge, null);
+      hugemc = ma.allocate(minHuge);
       assertEquals(oldFreeHugeMemory, ma.freeList.getFreeHugeMemory());
       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, minHuge+perObjectOverhead)/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
       hugemc.release();
@@ -278,22 +234,22 @@ public class SimpleMemoryAllocatorJUnitTest {
       assertEquals(TOTAL_MEM, ma.getFreeMemory());
       // None of the reallocates should have come from the slab.
       assertEquals(freeSlab, ma.freeList.getFreeFragmentMemory());
-      tinymc = ma.allocate(1, null);
+      tinymc = ma.allocate(1);
       assertEquals(round(TINY_MULTIPLE, 1+perObjectOverhead), tinymc.getSize());
       assertEquals(freeSlab-(round(TINY_MULTIPLE, 1+perObjectOverhead)*BATCH_SIZE), ma.freeList.getFreeFragmentMemory());
       freeSlab = ma.freeList.getFreeFragmentMemory();
       tinymc.release();
       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead)+(round(TINY_MULTIPLE, 1+perObjectOverhead)*BATCH_SIZE), ma.freeList.getFreeTinyMemory()-oldFreeTinyMemory);
       
-      hugemc = ma.allocate(minHuge+1, null);
+      hugemc = ma.allocate(minHuge+1);
       assertEquals(round(TINY_MULTIPLE, minHuge+1+perObjectOverhead), hugemc.getSize());
       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory());
       hugemc.release();
       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*BATCH_SIZE, ma.freeList.getFreeHugeMemory());
-      hugemc = ma.allocate(minHuge, null);
+      hugemc = ma.allocate(minHuge);
       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory());
       if (BATCH_SIZE > 1) {
-        MemoryChunk hugemc2 = ma.allocate(minHuge, null);
+        MemoryChunk hugemc2 = ma.allocate(minHuge);
         assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-2), ma.freeList.getFreeHugeMemory());
         hugemc2.release();
         assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory());
@@ -301,7 +257,7 @@ public class SimpleMemoryAllocatorJUnitTest {
       hugemc.release();
       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*BATCH_SIZE, ma.freeList.getFreeHugeMemory());
       // now that we do compaction the following allocate works.
-      hugemc = ma.allocate(minHuge + HUGE_MULTIPLE + HUGE_MULTIPLE-1, null);
+      hugemc = ma.allocate(minHuge + HUGE_MULTIPLE + HUGE_MULTIPLE-1);
     } finally {
       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
     }
@@ -311,13 +267,13 @@ public class SimpleMemoryAllocatorJUnitTest {
   public void testChunkCreateDirectByteBuffer() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       ByteBuffer bb = ByteBuffer.allocate(1024);
       for (int i=0; i < 1024; i++) {
         bb.put((byte) i);
       }
       bb.position(0);
-      Chunk c = (Chunk) ma.allocateAndInitialize(bb.array(), false, false, null);
+      ObjectChunk c = (ObjectChunk) ma.allocateAndInitialize(bb.array(), false, false);
       assertEquals(1024, c.getDataSize());
       if (!Arrays.equals(bb.array(), c.getRawBytes())) {
         fail("arrays are not equal. Expected " + Arrays.toString(bb.array()) + " but found: " + Arrays.toString(c.getRawBytes()));
@@ -339,7 +295,7 @@ public class SimpleMemoryAllocatorJUnitTest {
   public void testGetLostChunks() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       assertEquals(Collections.emptyList(), ma.getLostChunks());
     } finally {
       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
@@ -350,7 +306,7 @@ public class SimpleMemoryAllocatorJUnitTest {
     final int SLAB_SIZE = 1024*1024;
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       assertEquals(0, ma.findSlab(slab.getMemoryAddress()));
       assertEquals(0, ma.findSlab(slab.getMemoryAddress()+SLAB_SIZE-1));
       try {
@@ -372,7 +328,7 @@ public class SimpleMemoryAllocatorJUnitTest {
     final int SLAB_SIZE = 1024*1024;
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       try {
         SimpleMemoryAllocatorImpl.validateAddress(0L);
         fail("expected IllegalStateException");
@@ -409,7 +365,7 @@ public class SimpleMemoryAllocatorJUnitTest {
     final int SLAB_SIZE = 1024*1024;
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       MemoryInspector inspector = ma.getMemoryInspector();
       assertNotNull(inspector);
       assertEquals(null, inspector.getFirstBlock());
@@ -449,12 +405,12 @@ public class SimpleMemoryAllocatorJUnitTest {
     boolean freeSlab = true;
     UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[]{slab};
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
       ma.close();
       ma.close();
       System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
       try {
-        ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
+        ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
         ma.close();
         freeSlab = false;
         ma.close();
@@ -471,43 +427,43 @@ public class SimpleMemoryAllocatorJUnitTest {
   
   @Test
   public void testCompaction() {
-    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
+    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
     final int BIG_ALLOC_SIZE = 150000;
     final int SMALL_ALLOC_SIZE = BIG_ALLOC_SIZE/2;
     final int TOTAL_MEM = BIG_ALLOC_SIZE;
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
       try {
-        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
+        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
         fail("Expected out of memory");
       } catch (OutOfOffHeapMemoryException expected) {
       }
       bmc.release();
       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
-      MemoryChunk smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
-      MemoryChunk smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
+      MemoryChunk smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+      MemoryChunk smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
       smc2.release();
       assertEquals(TOTAL_MEM-SMALL_ALLOC_SIZE, ma.freeList.getFreeMemory());
       try {
-        bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
+        bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
         fail("Expected out of memory");
       } catch (OutOfOffHeapMemoryException expected) {
       }
       smc1.release();
       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
-      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
+      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
       bmc.release();
       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
       ArrayList<MemoryChunk> mcs = new ArrayList<MemoryChunk>();
       for (int i=0; i < BIG_ALLOC_SIZE/(8+perObjectOverhead); i++) {
-        mcs.add(ma.allocate(8, null));
+        mcs.add(ma.allocate(8));
       }
       checkMcs(mcs);
       assertEquals(0, ma.freeList.getFreeMemory());
       try {
-        ma.allocate(8, null);
+        ma.allocate(8);
         fail("expected out of memory");
       } catch (OutOfOffHeapMemoryException expected) {
       }
@@ -515,20 +471,20 @@ public class SimpleMemoryAllocatorJUnitTest {
       assertEquals(8+perObjectOverhead, ma.freeList.getFreeMemory());
       mcs.remove(0).release(); // frees 8+perObjectOverhead
       assertEquals((8+perObjectOverhead)*2, ma.freeList.getFreeMemory());
-      ma.allocate(16, null).release(); // allocates and frees 16+perObjectOverhead; still have perObjectOverhead
+      ma.allocate(16).release(); // allocates and frees 16+perObjectOverhead; still have perObjectOverhead
       assertEquals((8+perObjectOverhead)*2, ma.freeList.getFreeMemory());
       mcs.remove(0).release(); // frees 8+perObjectOverhead
       assertEquals((8+perObjectOverhead)*3, ma.freeList.getFreeMemory());
       mcs.remove(0).release(); // frees 8+perObjectOverhead
       assertEquals((8+perObjectOverhead)*4, ma.freeList.getFreeMemory());
       // At this point I should have 8*4 + perObjectOverhead*4 of free memory
-      ma.allocate(8*4+perObjectOverhead*3, null).release();
+      ma.allocate(8*4+perObjectOverhead*3).release();
       assertEquals((8+perObjectOverhead)*4, ma.freeList.getFreeMemory());
       mcs.remove(0).release(); // frees 8+perObjectOverhead
       assertEquals((8+perObjectOverhead)*5, ma.freeList.getFreeMemory());
       // At this point I should have 8*5 + perObjectOverhead*5 of free memory
       try {
-        ma.allocate((8*5+perObjectOverhead*4)+1, null);
+        ma.allocate((8*5+perObjectOverhead*4)+1);
         fail("expected out of memory");
       } catch (OutOfOffHeapMemoryException expected) {
       }
@@ -536,24 +492,24 @@ public class SimpleMemoryAllocatorJUnitTest {
       assertEquals((8+perObjectOverhead)*6, ma.freeList.getFreeMemory());
       checkMcs(mcs);
       // At this point I should have 8*6 + perObjectOverhead*6 of free memory
-      MemoryChunk mc24 = ma.allocate(24, null);
+      MemoryChunk mc24 = ma.allocate(24);
       checkMcs(mcs);
       assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead), ma.freeList.getFreeMemory());
       // At this point I should have 8*3 + perObjectOverhead*5 of free memory
-      MemoryChunk mc16 = ma.allocate(16, null);
+      MemoryChunk mc16 = ma.allocate(16);
       checkMcs(mcs);
       assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead) - (16+perObjectOverhead), ma.freeList.getFreeMemory());
       // At this point I should have 8*1 + perObjectOverhead*4 of free memory
-      mcs.add(ma.allocate(8, null));
+      mcs.add(ma.allocate(8));
       checkMcs(mcs);
       assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead) - (16+perObjectOverhead) - (8+perObjectOverhead), ma.freeList.getFreeMemory());
       // At this point I should have 8*0 + perObjectOverhead*3 of free memory
-      MemoryChunk mcDO = ma.allocate(perObjectOverhead*2, null);
+      MemoryChunk mcDO = ma.allocate(perObjectOverhead*2);
       checkMcs(mcs);
       // At this point I should have 8*0 + perObjectOverhead*0 of free memory
       assertEquals(0, ma.freeList.getFreeMemory());
       try {
-        ma.allocate(1, null);
+        ma.allocate(1);
         fail("expected out of memory");
       } catch (OutOfOffHeapMemoryException expected) {
       }
@@ -576,7 +532,7 @@ public class SimpleMemoryAllocatorJUnitTest {
       }
       mcs.clear();
       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
-      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
+      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
       bmc.release();
     } finally {
       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
@@ -587,11 +543,11 @@ public class SimpleMemoryAllocatorJUnitTest {
   boolean memoryUsageEventReceived;
   @Test
   public void testUsageEventListener() {
-    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
+    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
     final int SMALL_ALLOC_SIZE = 1000;
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(3000);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       MemoryUsageListener listener = new MemoryUsageListener() {
         @Override
         public void updateMemoryUsed(final long bytesUsed) {
@@ -603,12 +559,12 @@ public class SimpleMemoryAllocatorJUnitTest {
       
       this.expectedMemoryUsage = SMALL_ALLOC_SIZE;
       this.memoryUsageEventReceived = false;
-      MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
+      MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
       assertEquals(true, this.memoryUsageEventReceived);
       
       this.expectedMemoryUsage = SMALL_ALLOC_SIZE * 2;
       this.memoryUsageEventReceived = false;
-      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
+      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
       assertEquals(true, this.memoryUsageEventReceived);
       
       MemoryUsageListener unaddedListener = new MemoryUsageListener() {
@@ -625,7 +581,7 @@ public class SimpleMemoryAllocatorJUnitTest {
 
       this.expectedMemoryUsage = SMALL_ALLOC_SIZE * 2;
       this.memoryUsageEventReceived = false;
-      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
+      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
       assertEquals(false, this.memoryUsageEventReceived);
       
     } finally {
@@ -640,7 +596,7 @@ public class SimpleMemoryAllocatorJUnitTest {
   
   @Test
   public void testOutOfOffHeapMemory() {
-    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
+    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
     final int BIG_ALLOC_SIZE = 150000;
     final int SMALL_ALLOC_SIZE = BIG_ALLOC_SIZE/2;
     final int TOTAL_MEM = BIG_ALLOC_SIZE;
@@ -656,13 +612,13 @@ public class SimpleMemoryAllocatorJUnitTest {
       }
     };
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(oooml, new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(oooml, new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
       // make a big allocation
-      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
+      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
       assertNull(ooom.get());
       // drive the ma to ooom with small allocations
       try {
-        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
+        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
         fail("Expected out of memory");
       } catch (OutOfOffHeapMemoryException expected) {
       }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
index d4f9e97..feb5de8 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java
@@ -22,10 +22,9 @@ import org.junit.runners.Suite;
 
 @Suite.SuiteClasses({
 	DataAsAddressJUnitTest.class,
-	GemFireChunkJUnitTest.class,
-	ChunkWithHeapFormJUnitTest.class,
-	GemFireChunkSliceJUnitTest.class,
-	GemFireChunkFactoryJUnitTest.class
+	ObjectChunkJUnitTest.class,
+	ObjectChunkWithHeapFormJUnitTest.class,
+	ObjectChunkSliceJUnitTest.class,
 })
 @RunWith(Suite.class)
 public class StoredObjectTestSuite {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
index aaa2ec8..3ae6159 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java
@@ -106,8 +106,8 @@ public class SyncChunkStackJUnitTest {
   public void stackCreatedWithAddressIsNotEmpty() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
 
       SyncChunkStack stack = new SyncChunkStack(chunk.getMemoryAddress());
       assertEquals(false, stack.isEmpty());
@@ -120,8 +120,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkIsNotEmpty() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
 
       SyncChunkStack stack = new SyncChunkStack();
       stack.offer(chunk.getMemoryAddress());
@@ -135,8 +135,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkTopEqualsAddress() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
 
       long addr = chunk.getMemoryAddress();
       SyncChunkStack stack = new SyncChunkStack();
@@ -162,8 +162,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkClearReturnsAddressAndEmptiesStack() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
 
       long addr = chunk.getMemoryAddress();
       SyncChunkStack stack = new SyncChunkStack();
@@ -180,8 +180,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkPollReturnsAddressAndEmptiesStack() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
 
       long addr = chunk.getMemoryAddress();
       SyncChunkStack stack = new SyncChunkStack();
@@ -198,8 +198,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkTotalSizeIsChunkSize() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
       int chunkSize = chunk.getSize();
 
       long addr = chunk.getMemoryAddress();
@@ -216,8 +216,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkLogShowsMsgAndSize() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
       int chunkSize = chunk.getSize();
 
       long addr = chunk.getMemoryAddress();
@@ -242,7 +242,7 @@ public class SyncChunkStackJUnitTest {
     protected void testHookDoConcurrentModification() {
       if (doConcurrentMod) {
         doConcurrentMod = false;
-        Chunk chunk2 = (Chunk) ma.allocate(50, null);
+        ObjectChunk chunk2 = (ObjectChunk) ma.allocate(50);
         this.chunk2Size = chunk2.getSize();
         this.offer(chunk2.getMemoryAddress());
       }
@@ -252,8 +252,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkTotalSizeIsChunkSizeWithConcurrentMod() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
       int chunkSize = chunk.getSize();
 
       long addr = chunk.getMemoryAddress();
@@ -271,8 +271,8 @@ public class SyncChunkStackJUnitTest {
   public void stackWithChunkLogShowsMsgAndSizeWithConcurrentMod() {
     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
     try {
-      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
-      Chunk chunk = (Chunk) ma.allocate(100, null);
+      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+      ObjectChunk chunk = (ObjectChunk) ma.allocate(100);
       int chunkSize = chunk.getSize();
 
       long addr = chunk.getMemoryAddress();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
index a98fa28..d7168a7 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunkJUnitTest.java
@@ -35,7 +35,7 @@ public class UnsafeMemoryChunkJUnitTest extends MemoryChunkJUnitTestBase {
   public void testGetAddress() {
     MemoryChunk mc = createChunk(1024);
     try {
-      UnsafeMemoryChunk umc = (UnsafeMemoryChunk) mc;
+      AddressableMemoryChunk umc = (AddressableMemoryChunk) mc;
       assertNotEquals(0, umc.getMemoryAddress());
     } finally {
       mc.release();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
index c7c7b7b..0f918cb 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteBufferByteSourceJUnitTest.java
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
 
 import org.junit.experimental.categories.Category;
 
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
 import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream.ByteSource;
@@ -34,9 +34,9 @@ public class OffHeapByteBufferByteSourceJUnitTest extends OffHeapByteSourceJUnit
   
   @Override
   protected ByteSource createByteSource(byte[] bytes) {
-    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false, null);
-    if (so instanceof Chunk) {
-      Chunk c = (Chunk) so;
+    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false);
+    if (so instanceof ObjectChunk) {
+      ObjectChunk c = (ObjectChunk) so;
       ByteBuffer bb = c.createDirectByteBuffer();
       if (bb == null) {
         fail("could not create a direct ByteBuffer for an off-heap Chunk");

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
index 543ef94..6457425 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/pdx/OffHeapByteSourceJUnitTest.java
@@ -20,7 +20,7 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.experimental.categories.Category;
 
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
 import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
@@ -36,7 +36,7 @@ public class OffHeapByteSourceJUnitTest extends ByteSourceJUnitTest {
 
   @Before
   public void setUp() throws Exception {
-    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
   }
 
   @After
@@ -51,10 +51,10 @@ public class OffHeapByteSourceJUnitTest extends ByteSourceJUnitTest {
   
   @Override
   protected ByteSource createByteSource(byte[] bytes) {
-    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false, null);
-    if (so instanceof Chunk) {
+    StoredObject so = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, false, false);
+    if (so instanceof ObjectChunk) {
       // bypass the factory to make sure that OffHeapByteSource is tested
-      return new OffHeapByteSource((Chunk)so);
+      return new OffHeapByteSource((ObjectChunk)so);
     } else {
       // bytes are so small they can be encoded in a long (see DataAsAddress).
       // So for this test just wrap the original bytes.


[017/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsOffHeapDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsOffHeapDUnitTest.java
index 532a239,0000000..3cf7b09
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsOffHeapDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/management/MemoryThresholdsOffHeapDUnitTest.java
@@@ -1,1826 -1,0 +1,1826 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.management;
 +
 +import java.util.ArrayList;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.concurrent.atomic.AtomicInteger;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.AttributesMutator;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.LowMemoryException;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.cache.control.ResourceManager;
 +import com.gemstone.gemfire.cache.management.MemoryThresholdsDUnitTest.Range;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.ClientServerTestCase;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.cache.DistributedRegion;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
 +import com.gemstone.gemfire.internal.cache.ProxyBucketRegion;
 +import com.gemstone.gemfire.internal.cache.control.InternalResourceManager;
 +import com.gemstone.gemfire.internal.cache.control.InternalResourceManager.ResourceType;
 +import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
 +import com.gemstone.gemfire.internal.cache.control.MemoryThresholds.MemoryState;
 +import com.gemstone.gemfire.internal.cache.control.OffHeapMemoryMonitor;
 +import com.gemstone.gemfire.internal.cache.control.OffHeapMemoryMonitor.OffHeapMemoryMonitorObserver;
 +import com.gemstone.gemfire.internal.cache.control.ResourceAdvisor;
 +import com.gemstone.gemfire.internal.cache.control.ResourceListener;
 +import com.gemstone.gemfire.internal.cache.control.TestMemoryThresholdListener;
 +import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * Tests the Off-Heap Memory thresholds of {@link ResourceManager}
 + * 
 + * @author David Hoots
 + * @since 9.0
 + */
 +public class MemoryThresholdsOffHeapDUnitTest extends ClientServerTestCase {
 +  private static final long serialVersionUID = -684231183212051910L;
 +
 +  final String expectedEx = LocalizedStrings.MemoryMonitor_MEMBER_ABOVE_CRITICAL_THRESHOLD.getRawText().replaceAll("\\{[0-9]+\\}",
 +      ".*?");
 +  final String addExpectedExString = "<ExpectedException action=add>" + this.expectedEx + "</ExpectedException>";
 +  final String removeExpectedExString = "<ExpectedException action=remove>" + this.expectedEx + "</ExpectedException>";
 +  final String expectedBelow = LocalizedStrings.MemoryMonitor_MEMBER_BELOW_CRITICAL_THRESHOLD.getRawText().replaceAll(
 +      "\\{[0-9]+\\}", ".*?");
 +  final String addExpectedBelow = "<ExpectedException action=add>" + this.expectedBelow + "</ExpectedException>";
 +  final String removeExpectedBelow = "<ExpectedException action=remove>" + this.expectedBelow + "</ExpectedException>";
 +
 +  public MemoryThresholdsOffHeapDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  
 +
 +  @Override
 +  public void setUp() throws Exception {
 +    IgnoredException.addIgnoredException(expectedEx);
 +    IgnoredException.addIgnoredException(expectedBelow);
 +  }
 +
 +
 +
 +  @Override
 +  protected void preTearDownClientServerTestCase() throws Exception {
 +    Invoke.invokeInEveryVM(this.resetResourceManager);
 +  }
 +
 +  private SerializableCallable resetResourceManager = new SerializableCallable() {
 +    public Object call() throws Exception {
 +      InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +      Set<ResourceListener> listeners = irm.getResourceListeners(ResourceType.OFFHEAP_MEMORY);
 +      Iterator<ResourceListener> it = listeners.iterator();
 +      while (it.hasNext()) {
 +        ResourceListener<MemoryEvent> l = it.next();
 +        if (l instanceof TestMemoryThresholdListener) {
 +          ((TestMemoryThresholdListener)l).resetThresholdCalls();
 +        }
 +      }
 +      return null;
 +    }
 +  };
 +
 +  /**
 +   * Make sure appropriate events are delivered when moving between states.
 +   * 
 +   * @throws Exception
 +   */
 +  public void testEventDelivery() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    
 +    final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
 +    final int port1 = ports[0];
 +    final int port2 = ports[1];
 +    final String regionName = "offHeapEventDelivery";
 +
 +    startCacheServer(server1, port1, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    startCacheServer(server2, port2, 70f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +    
 +    // NORMAL -> EVICTION
 +    setUsageAboveEvictionThreshold(server2, regionName);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 1, true);
 +    
 +    // EVICTION -> CRITICAL
 +    setUsageAboveCriticalThreshold(server2, regionName);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 2, true);
 +    
 +    // CRITICAL -> CRITICAL
 +    server2.invoke(new SerializableCallable() {
 +      private static final long serialVersionUID = 1L;
 +
 +      @Override
 +      public Object call() throws Exception {
 +        getCache().getLogger().fine(MemoryThresholdsOffHeapDUnitTest.this.addExpectedExString);
 +        getRootRegion().getSubregion(regionName).destroy("oh3");
 +        getCache().getLogger().fine(MemoryThresholdsOffHeapDUnitTest.this.removeExpectedExString);
 +        return null;
 +      }
 +    });
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 2, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 2, true);
 +    
 +    // CRITICAL -> EVICTION
 +    server2.invoke(new SerializableCallable() {
 +      private static final long serialVersionUID = 1L;
 +
 +      @Override
 +      public Object call() throws Exception {
 +        getCache().getLogger().fine(MemoryThresholdsOffHeapDUnitTest.this.addExpectedBelow);
 +        getRootRegion().getSubregion(regionName).destroy("oh2");
 +        getCache().getLogger().fine(MemoryThresholdsOffHeapDUnitTest.this.removeExpectedBelow);
 +        return null;
 +      }
 +    });
 +    verifyListenerValue(server1, MemoryState.EVICTION, 3, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 3, true);
 +
 +    // EVICTION -> EVICTION
 +    server2.invoke(new SerializableCallable() {
 +      private static final long serialVersionUID = 1L;
 +
 +      @Override
 +      public Object call() throws Exception {
 +        getRootRegion().getSubregion(regionName).put("oh6", new byte[20480]);
 +        return null;
 +      }
 +    });
 +    verifyListenerValue(server1, MemoryState.EVICTION, 3, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 3, true);
 +
 +    // EVICTION -> NORMAL
 +    server2.invoke(new SerializableCallable() {
 +      private static final long serialVersionUID = 1L;
 +
 +      @Override
 +      public Object call() throws Exception {
 +        getRootRegion().getSubregion(regionName).destroy("oh4");
 +        return null;
 +      }
 +    });
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 3, true);
 +    verifyListenerValue(server1, MemoryState.NORMAL, 1, true);
 +    
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 3, true);
 +    verifyListenerValue(server2, MemoryState.NORMAL, 1, true);
 +  }
 +  
 +  /**
 +   * test that disabling threshold does not cause remote event and
 +   * remote DISABLED events are delivered
 +   * @throws Exception
 +   */
 +  public void testDisabledThresholds() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    
 +    final String regionName = "offHeapDisabledThresholds";
 +
 +    //set port to 0 in-order for system to pickup a random port.
 +    startCacheServer(server1, 0, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    startCacheServer(server2, 0, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +    
 +    setUsageAboveEvictionThreshold(server1, regionName);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 0, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 0, true);
 +
 +    setThresholds(server1, 70f, 0f);
 +    verifyListenerValue(server1, MemoryState.EVICTION, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION, 1, true);
 +
 +    setUsageAboveCriticalThreshold(server1, regionName);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 0, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 0, true);
 +
 +    setThresholds(server1, 0f, 0f);
 +    verifyListenerValue(server1, MemoryState.EVICTION_DISABLED, 1, true);
 +    verifyListenerValue(server2, MemoryState.EVICTION_DISABLED, 1, true);
 +
 +    setThresholds(server1, 0f, 90f);
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +
 +    //verify that stats on server2 are not changed by events on server1
 +    server2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        assertEquals(0, irm.getStats().getOffHeapEvictionStartEvents());
 +        assertEquals(0, irm.getStats().getOffHeapCriticalEvents());
 +        assertEquals(0, irm.getStats().getOffHeapCriticalThreshold());
 +        assertEquals(0, irm.getStats().getOffHeapEvictionThreshold());
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void setUsageAboveCriticalThreshold(final VM vm, final String regionName) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        Region region = getRootRegion().getSubregion(regionName);
 +        if (!region.containsKey("oh1")) {
 +          region.put("oh5", new byte[954204]);
 +        } else {
 +          region.put("oh5", new byte[122880]);
 +        }
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void setUsageAboveEvictionThreshold(final VM vm, final String regionName) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        Region region = getRootRegion().getSubregion(regionName);
 +        region.put("oh1", new byte[245760]);
 +        region.put("oh2", new byte[184320]);
 +        region.put("oh3", new byte[33488]);
 +        region.put("oh4", new byte[378160]);
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void setUsageBelowEviction(final VM vm, final String regionName) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        Region region = getRootRegion().getSubregion(regionName);
 +        region.remove("oh1");
 +        region.remove("oh2");
 +        region.remove("oh3");
 +        region.remove("oh4");
 +        region.remove("oh5");
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void setThresholds(VM server, final float evictionThreshold,
 +      final float criticalThreshold) {
 +    
 +    server.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        ResourceManager irm = getCache().getResourceManager();
 +        irm.setCriticalOffHeapPercentage(criticalThreshold);
 +        irm.setEvictionOffHeapPercentage(evictionThreshold);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  /**
 +   * test that puts in a client are rejected when a remote VM crosses
 +   * critical threshold
 +   * @throws Exception
 +   */
 +  public void testDistributedRegionRemoteClientPutRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    final VM client = host.getVM(2);
 +
 +    final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
 +    final int port1 = ports[0];
 +    final int port2 = ports[1];
 +    final String regionName = "offHeapDRRemoteClientPutReject";
 +
 +    startCacheServer(server1, port1, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    startCacheServer(server2, port2, 0f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    startClient(client, server1, port1, regionName);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +
 +    doPuts(client, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, Range.DEFAULT);
 +
 +    //make server2 critical
 +    setUsageAboveCriticalThreshold(server2, regionName);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +
 +    //make sure that client puts are rejected
 +    doPuts(client, regionName, true/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, true/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, new Range(Range.DEFAULT, Range.DEFAULT.width()+1));
 +    
 +    setUsageBelowEviction(server2, regionName);
 +  }
 +
 +  public void testDistributedRegionRemotePutRejectionLocalDestroy() throws Exception {
 +    doDistributedRegionRemotePutRejection(true, false);
 +  }
 +  
 +  public void testDistributedRegionRemotePutRejectionCacheClose() throws Exception {
 +    doDistributedRegionRemotePutRejection(false, true);
 +  }
 +  
 +  public void testDistributedRegionRemotePutRejectionBelowThreshold() throws Exception {
 +    doDistributedRegionRemotePutRejection(false, false);
 +  }
 +  
 +  public void testGettersAndSetters() {
 +    getSystem(getOffHeapProperties());
 +    ResourceManager rm = getCache().getResourceManager();
 +    assertEquals(0.0f, rm.getCriticalOffHeapPercentage());
 +    assertEquals(0.0f, rm.getEvictionOffHeapPercentage());
 +    
 +    rm.setEvictionOffHeapPercentage(50);
 +    rm.setCriticalOffHeapPercentage(90);
 +    
 +    // verify
 +    assertEquals(50.0f, rm.getEvictionOffHeapPercentage());
 +    assertEquals(90.0f, rm.getCriticalOffHeapPercentage());
 +    
 +    getCache().createRegionFactory(RegionShortcut.REPLICATE_HEAP_LRU).create(getName());
 +    
 +    assertEquals(50.0f, rm.getEvictionOffHeapPercentage());
 +    assertEquals(90.0f, rm.getCriticalOffHeapPercentage());
 +  }
 +  
 +  /**
 +   * test that puts in a server are rejected when a remote VM crosses
 +   * critical threshold
 +   * @throws Exception
 +   */
 +  private void doDistributedRegionRemotePutRejection(boolean localDestroy, boolean cacheClose) throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +
 +    final String regionName = "offHeapDRRemotePutRejection";
 +
 +    //set port to 0 in-order for system to pickup a random port.
 +    startCacheServer(server1, 0, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    startCacheServer(server2, 0, 0f, 90f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    registerTestMemoryThresholdListener(server1);
 +    registerTestMemoryThresholdListener(server2);
 +
 +    doPuts(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, Range.DEFAULT);
 +
 +    //make server2 critical
 +    setUsageAboveCriticalThreshold(server2, regionName);
 +
 +    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);
 +    verifyListenerValue(server2, MemoryState.CRITICAL, 1, true);
 +
 +    //make sure that local server1 puts are rejected
 +    doPuts(server1, regionName, false/*catchRejectedException*/,
 +        true/*catchLowMemoryException*/);
 +    Range r1 = new Range(Range.DEFAULT, Range.DEFAULT.width()+1);
 +    doPutAlls(server1, regionName, false/*catchRejectedException*/,
 +        true/*catchLowMemoryException*/, r1);
 +
 +    if (localDestroy) {
 +    //local destroy the region on sick member
 +    server2.invoke(new SerializableCallable("local destroy") {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion().getSubregion(regionName);
 +        r.localDestroyRegion();
 +        return null;
 +      }
 +    });
 +    } else if (cacheClose) {
 +      server2.invoke(new SerializableCallable() {
 +        public Object call() throws Exception {
 +          getCache().close();
 +          return null;
 +        }
 +      });
 +    } else {
 +      setUsageBelowEviction(server2, regionName);
 +    }
 +    
 +    //wait for remote region destroyed message to be processed
 +    server1.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "remote localRegionDestroyed message not received";
 +          }
 +          public boolean done() {
 +            DistributedRegion dr = (DistributedRegion)getRootRegion().
 +                                                getSubregion(regionName);
 +            return dr.getMemoryThresholdReachedMembers().size() == 0;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 10000, 10, true);
 +        return null;
 +      }
 +    });
 +
 +    //make sure puts succeed
 +    doPuts(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/);
 +    Range r2 = new Range(r1, r1.width()+1);
 +    doPutAlls(server1, regionName, false/*catchRejectedException*/,
 +        false/*catchLowMemoryException*/, r2);
 +  }
 +
 +  /**
 +   * Test that DistributedRegion cacheLoade and netLoad are passed through to the 
 +   * calling thread if the local VM is in a critical state.  Once the VM has moved
 +   * to a safe state then test that they are allowed.
 +   * @throws Exception
 +   */
 +  public void testDRLoadRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM replicate1 = host.getVM(1);
 +    final VM replicate2 = host.getVM(2);
 +    final String rName = getUniqueName();
 +    
 +    // Make sure the desired VMs will have a fresh DS.
-     AsyncInvocation d1 = replicate1.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
-     AsyncInvocation d2 = replicate2.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
++    AsyncInvocation d1 = replicate1.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
++    AsyncInvocation d2 = replicate2.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
 +    d1.join();
 +    assertFalse(d1.exceptionOccurred());
 +    d2.join();
 +    assertFalse(d2.exceptionOccurred());
 +    CacheSerializableRunnable establishConnectivity = new CacheSerializableRunnable("establishcConnectivity") {
 +      @SuppressWarnings("synthetic-access")
 +      @Override
 +      public void run2() throws CacheException {
 +        getSystem(getOffHeapProperties());
 +      }
 +    };
 +    replicate1.invoke(establishConnectivity);
 +    replicate2.invoke(establishConnectivity);
 +    
 +    CacheSerializableRunnable createRegion = new CacheSerializableRunnable("create DistributedRegion") {
 +      @Override
 +      public void run2() throws CacheException {
 +        // Assert some level of connectivity
 +        InternalDistributedSystem ds = getSystem(getOffHeapProperties());
 +        assertTrue(ds.getDistributionManager().getNormalDistributionManagerIds().size() >= 1);
 +
 +        InternalResourceManager irm = (InternalResourceManager)getCache().getResourceManager();
 +        irm.setCriticalOffHeapPercentage(90f);
 +        AttributesFactory af = new AttributesFactory();
 +        af.setScope(Scope.DISTRIBUTED_ACK);
 +        af.setDataPolicy(DataPolicy.REPLICATE);
 +        af.setOffHeap(true);
 +        Region region = getCache().createRegion(rName, af.create());
 +      }
 +    };
 +    replicate1.invoke(createRegion);
 +    replicate2.invoke(createRegion);
 +    
 +    replicate1.invoke(addExpectedException);
 +    replicate2.invoke(addExpectedException);
 +    
 +    final Integer expected = (Integer)replicate1.invoke(new SerializableCallable("test Local DistributedRegion Load") {
 +      public Object call() throws Exception {
 +        final DistributedRegion r = (DistributedRegion) getCache().getRegion(rName);
 +        AttributesMutator<Integer, String> am = r.getAttributesMutator();
 +        am.setCacheLoader(new CacheLoader<Integer, String>() {
 +          final AtomicInteger numLoaderInvocations = new AtomicInteger(0);
 +          public String load(LoaderHelper<Integer, String> helper) throws CacheLoaderException {
 +            Integer expectedInvocations = (Integer)helper.getArgument();
 +            final int actualInvocations = this.numLoaderInvocations.getAndIncrement();
 +            if (expectedInvocations.intValue() != actualInvocations) {
 +              throw new CacheLoaderException("Expected " + expectedInvocations 
 +                  + " invocations, actual is " + actualInvocations);
 +            }
 +            return helper.getKey().toString();
 +          }
 +          public void close() {}
 +        });
 +
 +        int expectedInvocations = 0;
 +        final OffHeapMemoryMonitor ohmm = ((InternalResourceManager)getCache().getResourceManager()).getOffHeapMonitor();
 +        assertFalse(ohmm.getState().isCritical());
 +        {
 +          Integer k = new Integer(1);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +
 +        r.put("oh1", new byte[838860]);
 +        r.put("oh3", new byte[157287]);
 +        
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "expected region " + r + " to set memoryThreshold";
 +          }
 +          public boolean done() {
 +            return r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        {
 +          Integer k = new Integer(2); 
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        
 +        r.destroy("oh3");
 +        wc = new WaitCriterion() {
 +          public String description() {
 +            return "expected region " + r + " to unset memoryThreshold";
 +          }
 +          public boolean done() {
 +            return !r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        {
 +          Integer k = new Integer(3);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        return new Integer(expectedInvocations);
 +      }
 +    });
 +
 +    final CacheSerializableRunnable validateData1 = new CacheSerializableRunnable("Validate data 1") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Region r = getCache().getRegion(rName);
 +        Integer i1 = new Integer(1);
 +        assertTrue(r.containsKey(i1));
 +        assertNotNull(r.getEntry(i1));
 +        Integer i2 = new Integer(2);
 +        assertFalse(r.containsKey(i2));
 +        assertNull(r.getEntry(i2));
 +        Integer i3 = new Integer(3);
 +        assertTrue(r.containsKey(i3));
 +        assertNotNull(r.getEntry(i3));
 +      }
 +    };
 +    replicate1.invoke(validateData1);
 +    replicate2.invoke(validateData1);
 +    
 +    replicate2.invoke(new SerializableCallable("test DistributedRegion netLoad") {
 +      public Object call() throws Exception {
 +        final DistributedRegion r = (DistributedRegion) getCache().getRegion(rName);
 +        final OffHeapMemoryMonitor ohmm = ((InternalResourceManager)getCache().getResourceManager()).getOffHeapMonitor();
 +        assertFalse(ohmm.getState().isCritical());
 +        
 +        int expectedInvocations = expected.intValue();
 +        {
 +          Integer k = new Integer(4);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        
 +        // Place in a critical state for the next test
 +        r.put("oh3", new byte[157287]);
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "expected region " + r + " to set memoryThreshold";
 +          }
 +          public boolean done() {
 +            return r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        {
 +          Integer k = new Integer(5);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +
 +        r.destroy("oh3");
 +        wc = new WaitCriterion() {
 +          public String description() {
 +            return "expected region " + r + " to unset memoryThreshold";
 +          }
 +          public boolean done() {
 +            return !r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        {
 +          Integer k = new Integer(6);
 +          assertEquals(k.toString(), r.get(k, new Integer(expectedInvocations++)));
 +        }
 +        return new Integer(expectedInvocations);
 +      }
 +    });
 +    
 +    replicate1.invoke(removeExpectedException);
 +    replicate2.invoke(removeExpectedException);
 +    
 +    final CacheSerializableRunnable validateData2 = new CacheSerializableRunnable("Validate data 2") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer i4 = new Integer(4);
 +        assertTrue(r.containsKey(i4));
 +        assertNotNull(r.getEntry(i4));
 +        Integer i5 = new Integer(5);
 +        assertFalse(r.containsKey(i5));
 +        assertNull(r.getEntry(i5));
 +        Integer i6 = new Integer(6);
 +        assertTrue(r.containsKey(i6));
 +        assertNotNull(r.getEntry(i6));
 +      }
 +    };
 +    replicate1.invoke(validateData2);
 +    replicate2.invoke(validateData2);
 +  }
 +  
 +
 +  private SerializableRunnable addExpectedException = new SerializableRunnable
 +  ("addExpectedEx") {
 +    public void run() {
 +      getCache().getLoggerI18n().fine(addExpectedExString);
 +      getCache().getLoggerI18n().fine(addExpectedBelow);
 +    };
 +  };
 +  
 +  private SerializableRunnable removeExpectedException = new SerializableRunnable
 +  ("removeExpectedException") {
 +    public void run() {
 +      getCache().getLoggerI18n().fine(removeExpectedExString);
 +      getCache().getLoggerI18n().fine(removeExpectedBelow);
 +    };
 +  };
 +  
 +  public void testPR_RemotePutRejectionLocalDestroy() throws Exception {
 +    prRemotePutRejection(false, true, false);
 +  }
 +
 +  public void testPR_RemotePutRejectionCacheClose() throws Exception {
 +    prRemotePutRejection(true, false, false);
 +  }
 +
 +  public void testPR_RemotePutRejection() throws Exception {
 +    prRemotePutRejection(false, false, false);
 +  }
 +
 +  public void testPR_RemotePutRejectionLocalDestroyWithTx() throws Exception {
 +    prRemotePutRejection(false, true, true);
 +  }
 +
 +  public void testPR_RemotePutRejectionCacheCloseWithTx() throws Exception {
 +    prRemotePutRejection(true, false, true);
 +  }
 +
 +  public void testPR_RemotePutRejectionWithTx() throws Exception {
 +    prRemotePutRejection(false, false, true);
 +  }
 +
 +  private void prRemotePutRejection(boolean cacheClose, boolean localDestroy, final boolean useTx) throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM accessor = host.getVM(0);
 +    final VM servers[] = new VM[3];
 +    servers[0] = host.getVM(1);
 +    servers[1] = host.getVM(2);
 +    servers[2] = host.getVM(3);
 +
 +    final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(3);
 +    final String regionName = "offHeapPRRemotePutRejection";
 +    final int redundancy = 1;
 +
 +    startCacheServer(servers[0], ports[0], 0f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    startCacheServer(servers[1], ports[1], 0f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    startCacheServer(servers[2], ports[2], 0f, 90f,
 +        regionName, true/*createPR*/, false/*notifyBySubscription*/, redundancy);
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getOffHeapProperties());
 +        getCache();
 +        AttributesFactory factory = new AttributesFactory();        
 +        PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +        paf.setRedundantCopies(redundancy);
 +        paf.setLocalMaxMemory(0);
 +        paf.setTotalNumBuckets(11);
 +        factory.setPartitionAttributes(paf.create());
 +        factory.setOffHeap(true);
 +        createRegion(regionName, factory.create());
 +        return null;
 +      }
 +    });
 +    
 +    doPuts(accessor, regionName, false, false);
 +    final Range r1 = Range.DEFAULT;
 +    doPutAlls(accessor, regionName, false, false, r1);
 +
 +    servers[0].invoke(addExpectedException);
 +    servers[1].invoke(addExpectedException);
 +    servers[2].invoke(addExpectedException);
 +    setUsageAboveCriticalThreshold(servers[0], regionName);
 +    
 +    final Set<InternalDistributedMember> criticalMembers = (Set) servers[0].invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        final PartitionedRegion pr = (PartitionedRegion)getRootRegion().getSubregion(regionName);
 +        final int hashKey = PartitionedRegionHelper.getHashKey(pr, null, "oh5", null, null);
 +        return pr.getRegionAdvisor().getBucketOwners(hashKey);
 +      }
 +    });
 +    
 +    accessor.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {     
 +        final PartitionedRegion pr = (PartitionedRegion)getRootRegion().getSubregion(regionName);
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "remote bucket not marked sick";
 +          }
 +          public boolean done() {
 +            boolean keyFoundOnSickMember = false;
 +            boolean caughtException = false;
 +            for (int i=0; i<20; i++) {
 +              Integer key = Integer.valueOf(i);
 +              int hKey = PartitionedRegionHelper.getHashKey(pr, null, key, null, null);
 +              Set<InternalDistributedMember> owners = pr.getRegionAdvisor().getBucketOwners(hKey);
 +              final boolean hasCriticalOwners = owners.removeAll(criticalMembers);
 +              if (hasCriticalOwners) {
 +                keyFoundOnSickMember = true;
 +                try {
 +                  if (useTx) getCache().getCacheTransactionManager().begin();
 +                  pr.getCache().getLogger().fine("SWAP:putting in tx:"+useTx);
 +                  pr.put(key, "value");
 +                  if (useTx) getCache().getCacheTransactionManager().commit();
 +                } catch (LowMemoryException ex) {
 +                  caughtException = true;
 +                  if (useTx) getCache().getCacheTransactionManager().rollback();
 +                }
 +              } else {
 +                //puts on healthy member should continue
 +                pr.put(key, "value");
 +              }
 +            }
 +            return keyFoundOnSickMember && caughtException;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 10000, 10, true);
 +        return null;
 +      }
 +    });
 +
 +    {
 +      Range r2 = new Range(r1, r1.width()+1);
 +      doPutAlls(accessor, regionName, false, true, r2);
 +    }
 +    
 +    // Find all VMs that have a critical region
 +    SerializableCallable getMyId = new SerializableCallable() {
 +      public Object call() throws Exception {        
 +        return ((GemFireCacheImpl)getCache()).getMyId();
 +      }
 +    };
 +    final Set<VM> criticalServers = new HashSet<VM>();
 +    for (final VM server : servers) {
 +      DistributedMember member = (DistributedMember) server.invoke(getMyId);
 +      if (criticalMembers.contains(member)) {
 +        criticalServers.add(server);
 +      }
 +    }
 +    
 +    if (localDestroy) {
 +    //local destroy the region on sick members
 +      for (final VM vm : criticalServers) {
 +        vm.invoke(new SerializableCallable("local destroy sick member") {
 +          public Object call() throws Exception {
 +            Region r = getRootRegion().getSubregion(regionName);
 +            LogWriterUtils.getLogWriter().info("PRLocalDestroy");
 +            r.localDestroyRegion();
 +            return null;
 +          }
 +        });
 +      }
 +    } else if (cacheClose) {
 +      // close cache on sick members
 +      for (final VM vm : criticalServers) {
 +        vm.invoke(new SerializableCallable("close cache sick member") {
 +          public Object call() throws Exception {
 +            getCache().close();
 +            return null;
 +          }
 +        });
 +      }
 +    } else {
 +      setUsageBelowEviction(servers[0], regionName);
 +      servers[0].invoke(removeExpectedException);
 +      servers[1].invoke(removeExpectedException);
 +      servers[2].invoke(removeExpectedException);
 +    }
 +    
 +    //do put all in a loop to allow distribution of message
 +    accessor.invoke(new SerializableCallable("Put in a loop") {
 +      public Object call() throws Exception {
 +        final Region r = getRootRegion().getSubregion(regionName);
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {            
 +            return "pr should have gone un-critical";
 +          }
 +          public boolean done() {
 +            boolean done = true;
 +            for (int i=0; i<20; i++) {
 +              try {
 +                r.put(i,"value");
 +              } catch (LowMemoryException e) {
 +                //expected
 +                done = false;
 +              }
 +            }            
 +            return done;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 10000, 10, true);
 +        return null;
 +      }
 +    });
 +    doPutAlls(accessor, regionName, false, false, r1);
 +  }
 +
 +  /**
 +   * Test that a Partitioned Region loader invocation is rejected
 +   * if the VM with the bucket is in a critical state.
 +   * @throws Exception
 +   */
 +  public void testPRLoadRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM accessor = host.getVM(1);
 +    final VM ds1 = host.getVM(2);
 +    final String rName = getUniqueName();
 +
 +    // Make sure the desired VMs will have a fresh DS.
-     AsyncInvocation d0 = accessor.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
-     AsyncInvocation d1 = ds1.invokeAsync(DistributedTestCase.class, "disconnectFromDS");
++    AsyncInvocation d0 = accessor.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
++    AsyncInvocation d1 = ds1.invokeAsync(() -> DistributedTestCase.disconnectFromDS());
 +    d0.join();
 +    assertFalse(d0.exceptionOccurred());
 +    d1.join();
 +    assertFalse(d1.exceptionOccurred());
 +    CacheSerializableRunnable establishConnectivity = new CacheSerializableRunnable("establishcConnectivity") {
 +      @Override
 +      public void run2() throws CacheException { getSystem();  }
 +    };
 +    ds1.invoke(establishConnectivity);
 +    accessor.invoke(establishConnectivity);
 +
 +    ds1.invoke(createPR(rName, false));
 +    accessor.invoke(createPR(rName, true));
 +    
 +    final AtomicInteger expectedInvocations = new AtomicInteger(0);
 +
 +    Integer ex = (Integer) accessor.invoke(new SerializableCallable("Invoke loader from accessor, non-critical") {
 +      public Object call() throws Exception {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer k = new Integer(1);
 +        Integer expectedInvocations0 = new Integer(expectedInvocations.getAndIncrement());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations0)); // should load for new key
 +        assertTrue(r.containsKey(k));
 +        Integer expectedInvocations1 = new Integer(expectedInvocations.get());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations1)); // no load
 +        assertEquals(k.toString(), r.get(k, expectedInvocations1)); // no load
 +        return expectedInvocations1;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +
 +    ex = (Integer)ds1.invoke(new SerializableCallable("Invoke loader from datastore, non-critical") {
 +      public Object call() throws Exception {
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        Integer k = new Integer(2);
 +        Integer expectedInvocations1 = new Integer(expectedInvocations.getAndIncrement());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations1)); // should load for new key
 +        assertTrue(r.containsKey(k));
 +        Integer expectedInvocations2 = new Integer(expectedInvocations.get());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations2)); // no load
 +        assertEquals(k.toString(), r.get(k, expectedInvocations2)); // no load
 +        String oldVal = r.remove(k);
 +        assertFalse(r.containsKey(k));
 +        assertEquals(k.toString(), oldVal);
 +        return expectedInvocations2;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +
 +    accessor.invoke(addExpectedException);
 +    ds1.invoke(addExpectedException);
 +
 +    ex = (Integer)ds1.invoke(new SerializableCallable("Set critical state, assert local load behavior") {
 +      public Object call() throws Exception {
 +        final OffHeapMemoryMonitor ohmm = ((InternalResourceManager)getCache().getResourceManager()).getOffHeapMonitor();
 +        final PartitionedRegion pr = (PartitionedRegion) getCache().getRegion(rName);
 +        final RegionAdvisor advisor = pr.getRegionAdvisor();
 +        
 +        pr.put("oh1", new byte[838860]);
 +        pr.put("oh3", new byte[157287]);
 +        
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "verify critical state";
 +          }
 +          public boolean done() {
 +            for (final ProxyBucketRegion bucket : advisor.getProxyBucketArray()) {
 +              if (bucket.isBucketSick()) {
 +                return true;
 +              }
 +            }
 +            return false;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        
 +        final Integer k = new Integer(2); // reload with same key again and again
 +        final Integer expectedInvocations3 = new Integer(expectedInvocations.getAndIncrement());
 +        assertEquals(k.toString(), pr.get(k, expectedInvocations3)); // load
 +        assertFalse(pr.containsKey(k));
 +        Integer expectedInvocations4 = new Integer(expectedInvocations.getAndIncrement());
 +        assertEquals(k.toString(), pr.get(k, expectedInvocations4)); // load
 +        assertFalse(pr.containsKey(k));
 +        Integer expectedInvocations5 = new Integer(expectedInvocations.get());
 +        assertEquals(k.toString(), pr.get(k, expectedInvocations5)); // load
 +        assertFalse(pr.containsKey(k));
 +        return expectedInvocations5;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +
 +    ex = (Integer)accessor.invoke(new SerializableCallable("During critical state on datastore, assert accesor load behavior") {
 +      public Object call() throws Exception {
 +        final Integer k = new Integer(2);  // reload with same key again and again
 +        Integer expectedInvocations6 = new Integer(expectedInvocations.incrementAndGet());
 +        Region<Integer, String> r = getCache().getRegion(rName);
 +        assertEquals(k.toString(), r.get(k, expectedInvocations6)); // load
 +        assertFalse(r.containsKey(k));
 +        Integer expectedInvocations7 = new Integer(expectedInvocations.incrementAndGet());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations7)); // load
 +        assertFalse(r.containsKey(k));
 +        return expectedInvocations7;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +    
 +    ex = (Integer)ds1.invoke(new SerializableCallable("Set safe state on datastore, assert local load behavior") {
 +      public Object call() throws Exception {
 +        final PartitionedRegion r = (PartitionedRegion) getCache().getRegion(rName);
 +        
 +        r.destroy("oh3");
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "verify critical state";
 +          }
 +          public boolean done() {
 +            return !r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        
 +        Integer k = new Integer(3); // same key as previously used, this time is should stick
 +        Integer expectedInvocations8 = new Integer(expectedInvocations.incrementAndGet());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations8)); // last load for 3
 +        assertTrue(r.containsKey(k));
 +        return expectedInvocations8;
 +      }
 +    });
 +    expectedInvocations.set(ex.intValue());
 +
 +    accessor.invoke(new SerializableCallable("Data store in safe state, assert load behavior, accessor sets critical state, assert load behavior") {
 +      public Object call() throws Exception {
 +        final OffHeapMemoryMonitor ohmm = ((InternalResourceManager)getCache().getResourceManager()).getOffHeapMonitor();
 +        assertFalse(ohmm.getState().isCritical());
 +        Integer k = new Integer(4);
 +        Integer expectedInvocations9 = new Integer(expectedInvocations.incrementAndGet());
 +        final PartitionedRegion r = (PartitionedRegion) getCache().getRegion(rName);
 +        assertEquals(k.toString(), r.get(k, expectedInvocations9)); // load for 4
 +        assertTrue(r.containsKey(k));
 +        assertEquals(k.toString(), r.get(k, expectedInvocations9)); // no load
 +
 +        // Go critical in accessor
 +        r.put("oh3", new byte[157287]);
 +        
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "verify critical state";
 +          }
 +          public boolean done() {
 +            return r.memoryThresholdReached.get();
 +          }
 +        };
 +
 +        k = new Integer(5);
 +        Integer expectedInvocations10 = new Integer(expectedInvocations.incrementAndGet());
 +        assertEquals(k.toString(), r.get(k, expectedInvocations10)); // load for key 5
 +        assertTrue(r.containsKey(k));
 +        assertEquals(k.toString(), r.get(k, expectedInvocations10)); // no load
 +        
 +        // Clean up critical state
 +        r.destroy("oh3");
 +        wc = new WaitCriterion() {
 +          public String description() {
 +            return "verify critical state";
 +          }
 +          public boolean done() {
 +            return !ohmm.getState().isCritical();
 +          }
 +        };
 +        return expectedInvocations10;
 +      }
 +    });
 +
 +    accessor.invoke(removeExpectedException);
 +    ds1.invoke(removeExpectedException);
 +  }
 +  
 +  private CacheSerializableRunnable createPR(final String rName, final boolean accessor) {
 +    return new CacheSerializableRunnable("create PR accessor") {
 +    @Override
 +    public void run2() throws CacheException {
 +      // Assert some level of connectivity
 +      getSystem(getOffHeapProperties());      
 +      InternalResourceManager irm = (InternalResourceManager)getCache().getResourceManager();
 +      irm.setCriticalOffHeapPercentage(90f);
 +      AttributesFactory<Integer, String> af = new AttributesFactory<Integer, String>();
 +      if (!accessor) {
 +        af.setCacheLoader(new CacheLoader<Integer, String>() {
 +          final AtomicInteger numLoaderInvocations = new AtomicInteger(0);
 +          public String load(LoaderHelper<Integer, String> helper) throws CacheLoaderException {
 +            Integer expectedInvocations = (Integer)helper.getArgument();
 +            final int actualInvocations = this.numLoaderInvocations.getAndIncrement();
 +            if (expectedInvocations.intValue() != actualInvocations) {
 +              throw new CacheLoaderException("Expected " + expectedInvocations 
 +                  + " invocations, actual is " + actualInvocations);
 +            }
 +            return helper.getKey().toString();
 +          }
 +          public void close() {}
 +        });
 +
 +        af.setPartitionAttributes(new PartitionAttributesFactory().create());
 +      } else {
 +        af.setPartitionAttributes(new PartitionAttributesFactory().setLocalMaxMemory(0).create());
 +      }
 +      af.setOffHeap(true);
 +      getCache().createRegion(rName, af.create());
 +    }
 +  };
 +  }
 +  
 +  /**
 +   * Test that LocalRegion cache Loads are not stored in the Region
 +   * if the VM is in a critical state, then test that they are allowed
 +   * once the VM is no longer critical
 +   * @throws Exception
 +   */
 +  public void testLRLoadRejection() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM vm = host.getVM(2);
 +    final String rName = getUniqueName();
 +
-     vm.invoke(DistributedTestCase.class, "disconnectFromDS");
++    vm.invoke(() -> DistributedTestCase.disconnectFromDS());
 +    
 +    vm.invoke(new CacheSerializableRunnable("test LocalRegion load passthrough when critical") {
 +      @Override
 +      public void run2() throws CacheException {
 +        getSystem(getOffHeapProperties());
 +        InternalResourceManager irm = (InternalResourceManager)getCache().getResourceManager();
 +        final OffHeapMemoryMonitor ohmm = irm.getOffHeapMonitor();
 +        irm.setCriticalOffHeapPercentage(90f);
 +        AttributesFactory<Integer, String> af = new AttributesFactory<Integer, String>();
 +        af.setScope(Scope.LOCAL);
 +        af.setOffHeap(true);
 +        final AtomicInteger numLoaderInvocations = new AtomicInteger(0);
 +        af.setCacheLoader(new CacheLoader<Integer, String>() {
 +          public String load(LoaderHelper<Integer, String> helper)
 +          throws CacheLoaderException {
 +            numLoaderInvocations.incrementAndGet();
 +            return helper.getKey().toString();
 +          }
 +          public void close() {}
 +        });
 +        final LocalRegion r = (LocalRegion) getCache().createRegion(rName, af.create());
 +        
 +        assertFalse(ohmm.getState().isCritical());
 +        int expectedInvocations = 0;
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        {
 +          Integer k = new Integer(1);
 +          assertEquals(k.toString(), r.get(k));
 +        }
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        expectedInvocations++; expectedInvocations++;
 +        r.getAll(createRanges(10, 12));
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        r.put("oh1", new byte[838860]);
 +        r.put("oh3", new byte[157287]);
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "expected region " + r + " to set memoryThresholdReached";
 +          }
 +          public boolean done() {
 +            return r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        { 
 +          Integer k = new Integer(2);
 +          assertEquals(k.toString(), r.get(k));
 +        }
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        expectedInvocations++; expectedInvocations++;
 +        r.getAll(createRanges(13, 15));
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        
 +        getCache().getLoggerI18n().fine(addExpectedBelow);
 +        r.destroy("oh3");
 +        getCache().getLoggerI18n().fine(removeExpectedBelow);
 +        wc = new WaitCriterion() {
 +          public String description() {
 +            return "expected region " + r + " to unset memoryThresholdReached";
 +          }
 +          public boolean done() {
 +            return !r.memoryThresholdReached.get();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30*1000, 10, true);
 +        
 +        {
 +          Integer k = new Integer(3);
 +          assertEquals(k.toString(), r.get(k));
 +        }
 +        assertEquals(expectedInvocations++, numLoaderInvocations.get());
 +        expectedInvocations++; expectedInvocations++;
 +        r.getAll(createRanges(16, 18));
 +        assertEquals(expectedInvocations, numLoaderInvocations.get());
 +
 +        // Do extra validation that the entry doesn't exist in the local region
 +        for (Integer i: createRanges(2, 2, 13, 15)) {
 +          if (r.containsKey(i)) {
 +            fail("Expected containsKey return false for key" + i);
 +          }
 +          if (r.getEntry(i) != null) {
 +            fail("Expected getEntry to return null for key" + i);
 +          }
 +        }
 +      }
 +    });
 +  }
 +  
 +  /** Create a list of integers consisting of the ranges defined by the provided
 +  * argument e.g..  createRanges(1, 4, 10, 12) means create ranges 1 through 4 and
 +  * 10 through 12 and should yield the list:
 +  * 1, 2, 3, 4, 10, 11, 12
 +  */ 
 +  public static List<Integer> createRanges(int... startEnds) {
 +    assert startEnds.length % 2 == 0;
 +    ArrayList<Integer> ret = new ArrayList<Integer>();
 +    for (int si=0; si<startEnds.length; si++) { 
 +      final int start = startEnds[si++];
 +      final int end = startEnds[si];
 +      assert end >= start;
 +      ret.ensureCapacity(ret.size() + ((end-start)+1));
 +      for (int i=start; i<=end; i++) {
 +        ret.add(new Integer(i));
 +      }
 +    }
 +    return ret;
 +  }
 +  
 +  public void testCleanAdvisorClose() throws Exception {
 +    final Host host = Host.getHost(0);
 +    final VM server1 = host.getVM(0);
 +    final VM server2 = host.getVM(1);
 +    final VM server3 = host.getVM(2);
 +
 +    final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(3);
 +    final int port1 = ports[0];
 +    final int port2 = ports[1];
 +    final int port3 = ports[2];
 +    final String regionName = "testEventOrder";
 +
 +    startCacheServer(server1, port1, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +    startCacheServer(server2, port2, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    verifyProfiles(server1, 2);
 +    verifyProfiles(server2, 2);
 +
 +    server2.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        closeCache();
 +        return null;
 +      }
 +    });
 +
 +    verifyProfiles(server1, 1);
 +
 +    startCacheServer(server3, port3, 0f, 0f,
 +        regionName, false/*createPR*/, false/*notifyBySubscription*/, 0);
 +
 +    verifyProfiles(server1, 2);
 +    verifyProfiles(server3, 2);
 +  }
 +  
 +  public void testPRClientPutRejection() throws Exception {
 +    doClientServerTest("parRegReject", true/*createPR*/);
 +  }
 +
 +  public void testDistributedRegionClientPutRejection() throws Exception {
 +    doClientServerTest("distrReject", false/*createPR*/);
 +  }
 +  
 +  private void doPuts(VM vm, final String regionName,
 +      final boolean catchServerException, final boolean catchLowMemoryException) {
 +
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion().getSubregion(regionName);
 +        try {
 +          r.put(Integer.valueOf(0), "value-1");
 +          if (catchServerException || catchLowMemoryException) {
 +            fail("An expected ResourceException was not thrown");
 +          }
 +        } catch (ServerOperationException ex) {
 +          if (!catchServerException) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +          if (!(ex.getCause() instanceof LowMemoryException)) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +        } catch (LowMemoryException low) {
 +          if (!catchLowMemoryException) {
 +            Assert.fail("Unexpected exception: ", low);
 +          }
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void doPutAlls(VM vm, final String regionName,
 +      final boolean catchServerException, final boolean catchLowMemoryException, 
 +      final Range rng) {
 +
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        Region r = getRootRegion().getSubregion(regionName);
 +        Map<Integer, String> temp = new HashMap<Integer, String>();
 +        for (int i=rng.start; i<rng.end; i++) {
 +          Integer k = Integer.valueOf(i);
 +          temp.put(k, "value-"+i);
 +        }
 +        try {
 +          r.putAll(temp);
 +          if (catchServerException || catchLowMemoryException) {
 +            fail("An expected ResourceException was not thrown");
 +          }
 +          for (Map.Entry<Integer, String> me: temp.entrySet()) {
 +            assertEquals(me.getValue(), r.get(me.getKey()));
 +          }
 +        } catch (ServerOperationException ex) {
 +          if (!catchServerException) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +          if (!(ex.getCause() instanceof LowMemoryException)) {
 +            Assert.fail("Unexpected exception: ", ex);
 +          }
 +          for(Integer me: temp.keySet()) {
 +            assertFalse("Key " + me + " should not exist", r.containsKey(me));
 +          }
 +        } catch (LowMemoryException low) {
 +          LogWriterUtils.getLogWriter().info("Caught LowMemoryException", low);
 +          if (!catchLowMemoryException) {
 +            Assert.fail("Unexpected exception: ", low);
 +          }
 +          for(Integer me: temp.keySet()) {
 +            assertFalse("Key " + me + " should not exist", r.containsKey(me));
 +          }
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void doClientServerTest(final String regionName, boolean createPR)
 +      throws Exception {
 +    //create region on the server
 +    final Host host = Host.getHost(0);
 +    final VM server = host.getVM(0);
 +    final VM client = host.getVM(1);
 +    final Object bigKey = -1;
 +    final Object smallKey = -2;
 +
 +    final int port = AvailablePortHelper.getRandomAvailableTCPPort();
 +    startCacheServer(server, port, 0f, 90f,
 +        regionName, createPR, false, 0);
 +    startClient(client, server, port, regionName);
 +    doPuts(client, regionName, false/*catchServerException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, false/*catchServerException*/,
 +        false/*catchLowMemoryException*/, Range.DEFAULT);
 +
 +    
 +    //make the region sick in the server
 +    final long bytesUsedAfterSmallKey = (long)server.invoke(new SerializableCallable() {
 +      @Override
 +      public Object call() throws Exception {
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        final OffHeapMemoryMonitor ohm = irm.getOffHeapMonitor();
 +        assertTrue(ohm.getState().isNormal());
 +        getCache().getLoggerI18n().fine(addExpectedExString);
 +        final LocalRegion r = (LocalRegion) getRootRegion().getSubregion(regionName);
 +        final long bytesUsedAfterSmallKey;
 +        {
 +          OffHeapMemoryMonitorObserverImpl _testHook = new OffHeapMemoryMonitorObserverImpl();
 +          ohm.testHook = _testHook;
 +          try {
 +            r.put(smallKey, "1234567890");
 +            bytesUsedAfterSmallKey = _testHook.verifyBeginUpdateMemoryUsed(false);
 +          } finally {
 +            ohm.testHook = null;
 +          }
 +        }
 +        {
 +          final OffHeapMemoryMonitorObserverImpl th = new OffHeapMemoryMonitorObserverImpl();
 +          ohm.testHook = th;
 +          try {
 +            r.put(bigKey, new byte[943720]);
 +            th.verifyBeginUpdateMemoryUsed(bytesUsedAfterSmallKey + 943720 + 8, true);
 +            WaitCriterion waitForCritical = new WaitCriterion() {
 +              public boolean done() {
 +                return th.checkUpdateStateAndSendEventBeforeProcess(bytesUsedAfterSmallKey + 943720 + 8, MemoryState.EVICTION_DISABLED_CRITICAL);
 +              }
 +              @Override
 +              public String description() {
 +                return null;
 +              }
 +            };
 +            Wait.waitForCriterion(waitForCritical, 30*1000, 9, false);
 +            th.validateUpdateStateAndSendEventBeforeProcess(bytesUsedAfterSmallKey + 943720 + 8, MemoryState.EVICTION_DISABLED_CRITICAL);
 +          } finally {
 +            ohm.testHook = null;
 +          }
 +        }
 +        WaitCriterion wc;
 +        if (r instanceof PartitionedRegion) {
 +          final PartitionedRegion pr = (PartitionedRegion) r;
 +          final int bucketId = PartitionedRegionHelper.getHashKey(pr, null, bigKey, null, null);
 +          wc = new WaitCriterion() {
 +            @Override
 +            public String description() {
 +              return "Expected to go critical: isCritical=" + ohm.getState().isCritical();
 +            }
 +
 +            @Override
 +            public boolean done() {
 +              if (!ohm.getState().isCritical()) return false;
 +              // Only done once the bucket has been marked sick
 +              try {
 +                pr.getRegionAdvisor().checkIfBucketSick(bucketId, bigKey);
 +                return false;
 +              } catch (LowMemoryException ignore) {
 +                return true;
 +              }
 +            }
 +          };
 +        } else {
 +          wc = new WaitCriterion() {
 +            @Override
 +            public String description() {
 +              return "Expected to go critical: isCritical=" + ohm.getState().isCritical() + " memoryThresholdReached=" + r.memoryThresholdReached.get();
 +            }
 +
 +            @Override
 +            public boolean done() {
 +              return ohm.getState().isCritical() && r.memoryThresholdReached.get();
 +            }
 +          };
 +        }
 +        Wait.waitForCriterion(wc, 30000, 9, true);
 +        getCache().getLoggerI18n().fine(removeExpectedExString);
 +        return bytesUsedAfterSmallKey;
 +      }
 +    });
 +
 +    //make sure client puts are rejected
 +    doPuts(client, regionName, true/*catchServerException*/,
 +        false/*catchLowMemoryException*/);
 +    doPutAlls(client, regionName, true/*catchServerException*/,
 +        false/*catchLowMemoryException*/, new Range(Range.DEFAULT, Range.DEFAULT.width()+1));
 +    
 +    //make the region healthy in the server
 +    server.invoke(new SerializableRunnable() {
 +      public void run() {
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        final OffHeapMemoryMonitor ohm = irm.getOffHeapMonitor();
 +        assertTrue(ohm.getState().isCritical());
 +        getCache().getLogger().fine(MemoryThresholdsOffHeapDUnitTest.this.addExpectedBelow);
 +        OffHeapMemoryMonitorObserverImpl _testHook = new OffHeapMemoryMonitorObserverImpl();
 +        ohm.testHook = _testHook;
 +        try {
 +          getRootRegion().getSubregion(regionName).destroy(bigKey);
 +          _testHook.verifyBeginUpdateMemoryUsed(bytesUsedAfterSmallKey, true);
 +        } finally {
 +          ohm.testHook = null;
 +        }
 +        WaitCriterion wc = new WaitCriterion() {
 +          @Override
 +          public String description() {
 +            return "Expected to go normal";
 +          }
 +
 +          @Override
 +          public boolean done() {
 +            return ohm.getState().isNormal();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 30000, 9, true);
 +        getCache().getLogger().fine(MemoryThresholdsOffHeapDUnitTest.this.removeExpectedBelow);
 +        return;
 +      }
 +    });
 +  }
 +  
 +  private static class OffHeapMemoryMonitorObserverImpl implements OffHeapMemoryMonitorObserver {
 +    private boolean beginUpdateMemoryUsed;
 +    private long beginUpdateMemoryUsed_bytesUsed;
 +    private boolean beginUpdateMemoryUsed_willSendEvent;
 +    @Override
 +    public synchronized void beginUpdateMemoryUsed(long bytesUsed, boolean willSendEvent) {
 +      beginUpdateMemoryUsed = true;
 +      beginUpdateMemoryUsed_bytesUsed = bytesUsed;
 +      beginUpdateMemoryUsed_willSendEvent = willSendEvent;
 +    }
 +    @Override
 +    public synchronized void afterNotifyUpdateMemoryUsed(long bytesUsed) {
 +    }
 +    @Override
 +    public synchronized void beginUpdateStateAndSendEvent(long bytesUsed, boolean willSendEvent) {
 +    }
 +    private boolean updateStateAndSendEventBeforeProcess;
 +    private long updateStateAndSendEventBeforeProcess_bytesUsed;
 +    private MemoryEvent updateStateAndSendEventBeforeProcess_event;
 +    @Override
 +    public synchronized void updateStateAndSendEventBeforeProcess(long bytesUsed, MemoryEvent event) {
 +      updateStateAndSendEventBeforeProcess = true;
 +      updateStateAndSendEventBeforeProcess_bytesUsed = bytesUsed;
 +      updateStateAndSendEventBeforeProcess_event = event;
 +    }
 +    @Override
 +    public synchronized void updateStateAndSendEventBeforeAbnormalProcess(long bytesUsed, MemoryEvent event) {
 +    }
 +    @Override
 +    public synchronized void updateStateAndSendEventIgnore(long bytesUsed, MemoryState oldState, MemoryState newState, long mostRecentBytesUsed,
 +        boolean deliverNextAbnormalEvent) {
 +    }
 +
 +    public synchronized void verifyBeginUpdateMemoryUsed(long expected_bytesUsed, boolean expected_willSendEvent) {
 +      if (!beginUpdateMemoryUsed) {
 +        fail("beginUpdateMemoryUsed was not called");
 +      }
 +      assertEquals(expected_bytesUsed, beginUpdateMemoryUsed_bytesUsed);
 +      assertEquals(expected_willSendEvent, beginUpdateMemoryUsed_willSendEvent);
 +    }
 +    /**
 +     * Verify that beginUpdateMemoryUsed was called, event will be sent, and return the "bytesUsed" it recorded.
 +     */
 +    public synchronized long verifyBeginUpdateMemoryUsed(boolean expected_willSendEvent) {
 +      if (!beginUpdateMemoryUsed) {
 +        fail("beginUpdateMemoryUsed was not called");
 +      }
 +      assertEquals(expected_willSendEvent, beginUpdateMemoryUsed_willSendEvent);
 +      return beginUpdateMemoryUsed_bytesUsed;
 +    }
 +    public synchronized boolean checkUpdateStateAndSendEventBeforeProcess(long expected_bytesUsed, MemoryState expected_memoryState) {
 +      if (!updateStateAndSendEventBeforeProcess) {
 +        return false;
 +      }
 +      if (expected_bytesUsed != updateStateAndSendEventBeforeProcess_bytesUsed) {
 +        return false;
 +      }
 +      if (!expected_memoryState.equals(updateStateAndSendEventBeforeProcess_event.getState())) {
 +        return false;
 +      }
 +      return true;
 +    }
 +    public synchronized void validateUpdateStateAndSendEventBeforeProcess(long expected_bytesUsed, MemoryState expected_memoryState) {
 +      if (!updateStateAndSendEventBeforeProcess) {
 +        fail("updateStateAndSendEventBeforeProcess was not called");
 +      }
 +      assertEquals(expected_bytesUsed, updateStateAndSendEventBeforeProcess_bytesUsed);
 +      assertEquals(expected_memoryState, updateStateAndSendEventBeforeProcess_event.getState());
 +    }
 +   }
 +  private void registerTestMemoryThresholdListener(VM vm) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        TestMemoryThresholdListener listener = new TestMemoryThresholdListener();
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        irm.addResourceListener(ResourceType.OFFHEAP_MEMORY, listener);
 +        assertTrue(irm.getResourceListeners(ResourceType.OFFHEAP_MEMORY).contains(listener));
 +        return null;
 +      }
 +    });
 +  }
 +
 +  private void startCacheServer(VM server, final int port,
 +      final float evictionThreshold, final float criticalThreshold, final String regionName,
 +      final boolean createPR, final boolean notifyBySubscription, final int prRedundancy) throws Exception {
 +
 +    server.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getOffHeapProperties());
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +
 +        InternalResourceManager irm = cache.getResourceManager();
 +        irm.setEvictionOffHeapPercentage(evictionThreshold);
 +        irm.setCriticalOffHeapPercentage(criticalThreshold);
 +
 +        AttributesFactory factory = new AttributesFactory();
 +        if (createPR) {
 +          PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +          paf.setRedundantCopies(prRedundancy);
 +          paf.setTotalNumBuckets(11);
 +          factory.setPartitionAttributes(paf.create());
 +          factory.setOffHeap(true);
 +        } else {
 +          factory.setScope(Scope.DISTRIBUTED_ACK);
 +          factory.setDataPolicy(DataPolicy.REPLICATE);
 +          factory.setOffHeap(true);
 +        }
 +        Region region = createRegion(regionName, factory.create());
 +        if (createPR) {
 +          assertTrue(region instanceof PartitionedRegion);
 +        } else {
 +          assertTrue(region instanceof DistributedRegion);
 +        }
 +        CacheServer cacheServer = getCache().addCacheServer();
 +        cacheServer.setPort(port);
 +        cacheServer.setNotifyBySubscription(notifyBySubscription);
 +        cacheServer.start();
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void startClient(VM client, final VM server, final int serverPort,
 +      final String regionName) {
 +
 +    client.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        getSystem(getClientProps());
 +        getCache();
 +
 +        PoolFactory pf = PoolManager.createFactory();
 +        pf.addServer(NetworkUtils.getServerHostName(server.getHost()), serverPort);
 +        pf.create("pool1");
 +        
 +        AttributesFactory af = new AttributesFactory();
 +        af.setScope(Scope.LOCAL);
 +        af.setPoolName("pool1");        
 +        createRegion(regionName, af.create());
 +        return null;
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Verifies that the test listener value on the given vm is what is expected
 +   * Note that for remote events useWaitCriterion must be true.
 +   * Note also that since off-heap local events are async local events must also
 +   * set useWaitCriterion to true.
 +   * 
 +   * @param vm
 +   *          the vm where verification should take place
 +   * @param value
 +   *          the expected value
 +   * @param useWaitCriterion
 +   *          must be true for both local and remote events (see GEODE-138)
 +   */
 +  private void verifyListenerValue(VM vm, final MemoryState state, final int value, final boolean useWaitCriterion) {
 +    vm.invoke(new SerializableCallable() {
 +      private static final long serialVersionUID = 1L;
 +
 +      @Override
 +      public Object call() throws Exception {
 +        WaitCriterion wc = null;
 +        Set<ResourceListener> listeners = getGemfireCache().getResourceManager().getResourceListeners(ResourceType.OFFHEAP_MEMORY);
 +        TestMemoryThresholdListener tmp_listener = null;
 +        Iterator<ResourceListener> it = listeners.iterator();
 +        while (it.hasNext()) {
 +          ResourceListener<MemoryEvent> l = it.next();
 +          if (l instanceof TestMemoryThresholdListener) {
 +            tmp_listener = (TestMemoryThresholdListener) l;
 +            break;
 +          }
 +        }
 +        final TestMemoryThresholdListener listener = tmp_listener == null ? null : tmp_listener;
 +        switch (state) {
 +        case CRITICAL:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              @Override
 +              public String description() {
 +                return "Remote CRITICAL assert failed " + listener.toString();
 +              }
 +
 +              @Override
 +              public boolean done() {
 +                return value == listener.getCriticalThresholdCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getCriticalThresholdCalls());
 +          }
 +          break;
 +        case CRITICAL_DISABLED:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              @Override
 +              public String description() {
 +                return "Remote CRITICAL_DISABLED assert failed " + listener.toString();
 +              }
 +
 +              @Override
 +              public boolean done() {
 +                return value == listener.getCriticalDisabledCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getCriticalDisabledCalls());
 +          }
 +          break;
 +        case EVICTION:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              @Override
 +              public String description() {
 +                return "Remote EVICTION assert failed " + listener.toString();
 +              }
 +
 +              @Override
 +              public boolean done() {
 +                return value == listener.getEvictionThresholdCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getEvictionThresholdCalls());
 +          }
 +          break;
 +        case EVICTION_DISABLED:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              @Override
 +              public String description() {
 +                return "Remote EVICTION_DISABLED assert failed " + listener.toString();
 +              }
 +
 +              @Override
 +              public boolean done() {
 +                return value == listener.getEvictionDisabledCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getEvictionDisabledCalls());
 +          }
 +          break;
 +        case NORMAL:
 +          if (useWaitCriterion) {
 +            wc = new WaitCriterion() {
 +              @Override
 +              public String description() {
 +                return "Remote NORMAL assert failed " + listener.toString();
 +              }
 +
 +              @Override
 +              public boolean done() {
 +                return value == listener.getNormalCalls();
 +              }
 +            };
 +          } else {
 +            assertEquals(value, listener.getNormalCalls());
 +          }
 +          break;
 +        default:
 +          throw new IllegalStateException("Unknown memory state");
 +        }
 +        if (useWaitCriterion) {
 +          Wait.waitForCriterion(wc, 5000, 10, true);
 +        }
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private void verifyProfiles(VM vm, final int numberOfProfiles) {
 +    vm.invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        InternalResourceManager irm = ((GemFireCacheImpl)getCache()).getResourceManager();
 +        final ResourceAdvisor ra = irm.getResourceAdvisor();
 +        WaitCriterion wc = new WaitCriterion() {
 +          public String description() {
 +            return "verify profiles failed. Current profiles: " + ra.adviseGeneric();
 +          }
 +          public boolean done() {
 +            return numberOfProfiles == ra.adviseGeneric().size();
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 10000, 10, true);
 +        return null;
 +      }
 +    });
 +  }
 +  
 +  private Properties getOffHeapProperties() {
 +    Properties p = new Properties();
 +    p.setProperty(DistributionConfig.LOCATORS_NAME, "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +    p.setProperty(DistributionConfig.OFF_HEAP_MEMORY_SIZE_NAME, "1m");
 +    return p;
 +  }
 +  
 +  protected Properties getClientProps() {
 +    Properties p = new Properties();
 +    p.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
 +    p.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +    return p;
 +  }
 +}


[093/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
GEODE-917: Merge branch 'feature/GEODE-917' into develop

Renaming subprojects from gemfire- to geode-


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/c741a68f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/c741a68f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/c741a68f

Branch: refs/heads/feature/GEODE-870
Commit: c741a68f31b52d636e061bb56848958636e20b73
Parents: 31a69e4 87586d0
Author: Dan Smith <up...@apache.org>
Authored: Mon Feb 22 10:21:14 2016 -0800
Committer: Dan Smith <up...@apache.org>
Committed: Mon Feb 22 10:23:44 2016 -0800

----------------------------------------------------------------------
 COMPILING.txt                                   |     2 +-
 README.md                                       |     6 +-
 RUNNING.txt                                     |     2 +-
 build.gradle                                    |     2 +-
 docker/Dockerfile                               |     6 +-
 .../gemfire-modules-assembly/build.gradle       |   247 -
 .../release/conf/cache-client.xml               |    40 -
 .../release/conf/cache-peer.xml                 |    48 -
 .../release/conf/cache-server.xml               |    74 -
 .../release/scripts/cacheserver.bat             |   133 -
 .../release/scripts/cacheserver.sh              |    97 -
 .../release/scripts/gemfire.bat                 |    41 -
 .../release/scripts/gemfire.sh                  |    58 -
 .../release/scripts/setenv.properties           |     6 -
 .../release/session/bin/cacheserver.bat         |    56 -
 .../release/session/bin/cacheserver.sh          |    57 -
 .../release/session/bin/gemfire.bat             |    53 -
 .../release/session/bin/gemfire.sh              |    69 -
 .../release/session/bin/modify_war              |   392 -
 .../release/session/bin/setenv.properties       |     6 -
 .../gemfire-cs-tomcat-7/context-fragment.xml    |    15 -
 .../tcserver/gemfire-cs-tomcat-7/modules.env    |     1 -
 .../gemfire-cs-tomcat-8/context-fragment.xml    |    15 -
 .../tcserver/gemfire-cs-tomcat-8/modules.env    |     1 -
 .../gemfire-cs/configuration-prompts.properties |    17 -
 .../tcserver/gemfire-cs/context-fragment.xml    |    13 -
 .../release/tcserver/gemfire-cs/modules.env     |     1 -
 .../tcserver/gemfire-cs/server-fragment.xml     |    12 -
 .../gemfire-p2p-tomcat-7/context-fragment.xml   |    15 -
 .../tcserver/gemfire-p2p-tomcat-7/modules.env   |     1 -
 .../gemfire-p2p-tomcat-8/context-fragment.xml   |    15 -
 .../tcserver/gemfire-p2p-tomcat-8/modules.env   |     1 -
 .../configuration-prompts.properties            |    19 -
 .../tcserver/gemfire-p2p/context-fragment.xml   |    13 -
 .../release/tcserver/gemfire-p2p/modules.env    |     1 -
 .../tcserver/gemfire-p2p/server-fragment.xml    |    14 -
 .../gemfire-modules-hibernate/build.gradle      |    33 -
 .../gemfire/modules/hibernate/EnumType.java     |    58 -
 .../gemfire/modules/hibernate/GemFireCache.java |   238 -
 .../modules/hibernate/GemFireCacheListener.java |    54 -
 .../modules/hibernate/GemFireCacheProvider.java |   200 -
 .../hibernate/GemFireQueryCacheFactory.java     |    39 -
 .../modules/hibernate/GemFireRegionFactory.java |   237 -
 .../modules/hibernate/internal/Access.java      |   257 -
 .../ClientServerRegionFactoryDelegate.java      |   208 -
 .../hibernate/internal/CollectionAccess.java    |   224 -
 .../hibernate/internal/EntityRegionWriter.java  |    87 -
 .../hibernate/internal/EntityVersion.java       |    28 -
 .../hibernate/internal/EntityVersionImpl.java   |    51 -
 .../hibernate/internal/EntityWrapper.java       |    89 -
 .../hibernate/internal/GemFireBaseRegion.java   |   166 -
 .../internal/GemFireCollectionRegion.java       |    59 -
 .../hibernate/internal/GemFireEntityRegion.java |   187 -
 .../internal/GemFireQueryResultsRegion.java     |   113 -
 .../modules/hibernate/internal/KeyWrapper.java  |    93 -
 .../internal/NonStrictReadWriteAccess.java      |    83 -
 .../hibernate/internal/ReadOnlyAccess.java      |    55 -
 .../hibernate/internal/ReadWriteAccess.java     |    36 -
 .../internal/RegionFactoryDelegate.java         |   153 -
 .../hibernate/internal/TransactionalAccess.java |    25 -
 .../com/gemstone/gemfire/modules/Event.java     |    67 -
 .../gemfire/modules/HibernateJUnitTest.java     |   410 -
 .../com/gemstone/gemfire/modules/Owner.java     |   186 -
 .../com/gemstone/gemfire/modules/Person.java    |    72 -
 .../gemstone/gemfire/modules/SecondVMTest.java  |    93 -
 .../com/gemstone/gemfire/modules/Event.hbm.xml  |    32 -
 .../com/gemstone/gemfire/modules/Person.hbm.xml |    36 -
 .../src/test/resources/log4j.properties         |    16 -
 extensions/gemfire-modules-session/build.gradle |    54 -
 .../session/filter/SessionCachingFilter.java    |   652 -
 .../modules/session/filter/SessionListener.java |    51 -
 .../modules/session/installer/Installer.java    |   296 -
 .../session/installer/JarClassLoader.java       |   123 -
 .../session/installer/args/Argument.java        |   275 -
 .../session/installer/args/ArgumentHandler.java |    38 -
 .../installer/args/ArgumentProcessor.java       |   397 -
 .../session/installer/args/ArgumentValues.java  |   222 -
 .../installer/args/URLArgumentHandler.java      |    77 -
 .../installer/args/UnknownArgumentHandler.java  |    36 -
 .../session/installer/args/UsageException.java  |    89 -
 .../internal/common/AbstractSessionCache.java   |   102 -
 .../session/internal/common/CacheProperty.java  |    65 -
 .../common/ClientServerSessionCache.java        |   186 -
 .../internal/common/PeerToPeerSessionCache.java |   184 -
 .../session/internal/common/SessionCache.java   |    68 -
 .../common/SessionExpirationCacheListener.java  |    53 -
 .../session/internal/filter/Constants.java      |    30 -
 .../internal/filter/DummySessionManager.java    |   132 -
 .../internal/filter/GemfireHttpSession.java     |   526 -
 .../filter/GemfireSessionException.java         |    41 -
 .../internal/filter/GemfireSessionManager.java  |   511 -
 .../internal/filter/ListenerEventType.java      |    75 -
 .../session/internal/filter/SessionManager.java |   110 -
 .../AbstractDeltaSessionAttributes.java         |   107 -
 .../attributes/AbstractSessionAttributes.java   |   188 -
 .../internal/filter/attributes/DeltaEvent.java  |   119 -
 .../DeltaQueuedSessionAttributes.java           |    94 -
 .../attributes/DeltaSessionAttributes.java      |    75 -
 .../attributes/ImmediateSessionAttributes.java  |    68 -
 .../attributes/QueuedSessionAttributes.java     |    65 -
 .../filter/attributes/SessionAttributes.java    |   120 -
 .../filter/util/NamedThreadFactory.java         |    68 -
 .../filter/util/ThreadLocalSession.java         |    39 -
 .../internal/filter/util/TypeAwareMap.java      |    50 -
 .../session/internal/jmx/SessionStatistics.java |    78 -
 .../internal/jmx/SessionStatisticsMXBean.java   |    30 -
 .../internal/filter/AbstractListener.java       |    57 -
 .../session/internal/filter/BasicServlet.java   |    52 -
 .../session/internal/filter/Callback.java       |    30 -
 .../internal/filter/CallbackServlet.java        |    91 -
 .../session/internal/filter/CommonTests.java    |   582 -
 .../HttpSessionAttributeListenerImpl.java       |    46 -
 .../filter/HttpSessionBindingListenerImpl.java  |    42 -
 .../filter/HttpSessionListenerImpl.java         |    41 -
 .../filter/HttpSessionListenerImpl2.java        |    43 -
 .../internal/filter/MyServletTester.java        |    38 -
 .../internal/filter/RendezvousManager.java      |    46 -
 .../ServletRequestAttributeListenerImpl.java    |    45 -
 .../filter/ServletRequestListenerImpl.java      |    36 -
 .../SessionReplicationIntegrationJUnitTest.java |  1558 --
 .../filter/SessionReplicationJUnitTest.java     |    53 -
 .../SessionReplicationLocalCacheJUnitTest.java  |    54 -
 .../session/junit/ChildFirstClassLoader.java    |    86 -
 .../modules/session/junit/NamedRunner.java      |   120 -
 .../session/junit/PerTestClassLoaderRunner.java |   283 -
 .../junit/SeparateClassloaderTestRunner.java    |    56 -
 .../src/test/resources/log4j.properties         |    12 -
 extensions/gemfire-modules-tomcat7/build.gradle |    54 -
 .../catalina/Tomcat7DeltaSessionManager.java    |   112 -
 .../session/Tomcat7SessionsJUnitTest.java       |    35 -
 .../test/resources/tomcat/conf/tomcat-users.xml |     3 -
 .../src/test/resources/tomcat/logs/.gitkeep     |     0
 .../src/test/resources/tomcat/temp/.gitkeep     |     0
 extensions/gemfire-modules/build.gradle         |    39 -
 .../gatewaydelta/AbstractGatewayDeltaEvent.java |    64 -
 .../modules/gatewaydelta/GatewayDelta.java      |    26 -
 .../gatewaydelta/GatewayDeltaCreateEvent.java   |    88 -
 .../gatewaydelta/GatewayDeltaDestroyEvent.java  |    82 -
 .../modules/gatewaydelta/GatewayDeltaEvent.java |    24 -
 ...tewayDeltaEventApplicationCacheListener.java |    67 -
 .../GatewayDeltaForwarderCacheListener.java     |   197 -
 .../session/bootstrap/AbstractCache.java        |   398 -
 .../session/bootstrap/ClientServerCache.java    |    74 -
 .../session/bootstrap/LifecycleTypeAdapter.java |    59 -
 .../session/bootstrap/PeerToPeerCache.java      |    85 -
 .../AbstractCacheLifecycleListener.java         |    68 -
 .../session/catalina/AbstractSessionCache.java  |   113 -
 .../ClientServerCacheLifecycleListener.java     |    26 -
 .../catalina/ClientServerSessionCache.java      |   252 -
 .../session/catalina/CommitSessionValve.java    |    68 -
 .../modules/session/catalina/DeltaSession.java  |   597 -
 .../session/catalina/DeltaSessionFacade.java    |    49 -
 .../session/catalina/DeltaSessionManager.java   |   992 -
 .../session/catalina/JvmRouteBinderValve.java   |   108 -
 .../session/catalina/LocalStrings.properties    |    16 -
 .../PeerToPeerCacheLifecycleListener.java       |    29 -
 .../catalina/PeerToPeerSessionCache.java        |   215 -
 .../modules/session/catalina/SessionCache.java  |    64 -
 .../session/catalina/SessionManager.java        |    48 -
 .../catalina/Tomcat6DeltaSessionManager.java    |    98 -
 .../callback/LocalSessionCacheLoader.java       |    45 -
 .../callback/LocalSessionCacheWriter.java       |    59 -
 .../SessionExpirationCacheListener.java         |    77 -
 .../internal/DeltaSessionAttributeEvent.java    |    25 -
 .../DeltaSessionAttributeEventBatch.java        |    88 -
 .../DeltaSessionDestroyAttributeEvent.java      |    73 -
 .../internal/DeltaSessionStatistics.java        |    88 -
 .../DeltaSessionUpdateAttributeEvent.java       |    83 -
 .../gemstone/gemfire/modules/util/Banner.java   |    59 -
 .../modules/util/BootstrappingFunction.java     |   188 -
 .../util/ClassLoaderObjectInputStream.java      |    40 -
 .../gemfire/modules/util/ContextMapper.java     |    53 -
 .../modules/util/CreateRegionFunction.java      |   245 -
 .../modules/util/DebugCacheListener.java        |    72 -
 .../gemfire/modules/util/ModuleStatistics.java  |    91 -
 .../modules/util/RegionConfiguration.java       |   308 -
 .../util/RegionConfigurationCacheListener.java  |   114 -
 .../gemfire/modules/util/RegionHelper.java      |   241 -
 .../modules/util/RegionSizeFunction.java        |    56 -
 .../gemfire/modules/util/RegionStatus.java      |    21 -
 .../modules/util/ResourceManagerValidator.java  |   166 -
 .../modules/util/SessionCustomExpiry.java       |    64 -
 .../TouchPartitionedRegionEntriesFunction.java  |   100 -
 .../TouchReplicatedRegionEntriesFunction.java   |    97 -
 .../main/resources/modules-version.properties   |     1 -
 .../gemfire/modules/session/Callback.java       |    30 -
 .../gemfire/modules/session/CommandServlet.java |    91 -
 .../gemfire/modules/session/EmbeddedTomcat.java |   193 -
 .../gemfire/modules/session/QueryCommand.java   |    34 -
 .../modules/session/TestSessionsBase.java       |   493 -
 .../session/Tomcat6SessionsJUnitTest.java       |    35 -
 .../com/gemstone/gemfire/modules/Event.hbm.xml  |    16 -
 .../com/gemstone/gemfire/modules/Person.hbm.xml |    21 -
 .../src/test/resources/log4j.properties         |    16 -
 .../test/resources/tomcat/conf/tomcat-users.xml |     3 -
 .../src/test/resources/tomcat/logs/.gitkeep     |     0
 .../src/test/resources/tomcat/temp/.gitkeep     |     0
 extensions/geode-modules-assembly/build.gradle  |   247 +
 .../release/conf/cache-client.xml               |    40 +
 .../release/conf/cache-peer.xml                 |    48 +
 .../release/conf/cache-server.xml               |    74 +
 .../release/scripts/cacheserver.bat             |   133 +
 .../release/scripts/cacheserver.sh              |    97 +
 .../release/scripts/gemfire.bat                 |    41 +
 .../release/scripts/gemfire.sh                  |    58 +
 .../release/scripts/setenv.properties           |     6 +
 .../release/session/bin/cacheserver.bat         |    56 +
 .../release/session/bin/cacheserver.sh          |    57 +
 .../release/session/bin/gemfire.bat             |    53 +
 .../release/session/bin/gemfire.sh              |    69 +
 .../release/session/bin/modify_war              |   392 +
 .../release/session/bin/setenv.properties       |     6 +
 .../gemfire-cs-tomcat-7/context-fragment.xml    |    15 +
 .../tcserver/gemfire-cs-tomcat-7/modules.env    |     1 +
 .../gemfire-cs-tomcat-8/context-fragment.xml    |    15 +
 .../tcserver/gemfire-cs-tomcat-8/modules.env    |     1 +
 .../gemfire-cs/configuration-prompts.properties |    17 +
 .../tcserver/gemfire-cs/context-fragment.xml    |    13 +
 .../release/tcserver/gemfire-cs/modules.env     |     1 +
 .../tcserver/gemfire-cs/server-fragment.xml     |    12 +
 .../gemfire-p2p-tomcat-7/context-fragment.xml   |    15 +
 .../tcserver/gemfire-p2p-tomcat-7/modules.env   |     1 +
 .../gemfire-p2p-tomcat-8/context-fragment.xml   |    15 +
 .../tcserver/gemfire-p2p-tomcat-8/modules.env   |     1 +
 .../configuration-prompts.properties            |    19 +
 .../tcserver/gemfire-p2p/context-fragment.xml   |    13 +
 .../release/tcserver/gemfire-p2p/modules.env    |     1 +
 .../tcserver/gemfire-p2p/server-fragment.xml    |    14 +
 extensions/geode-modules-hibernate/build.gradle |    33 +
 .../gemfire/modules/hibernate/EnumType.java     |    58 +
 .../gemfire/modules/hibernate/GemFireCache.java |   238 +
 .../modules/hibernate/GemFireCacheListener.java |    54 +
 .../modules/hibernate/GemFireCacheProvider.java |   200 +
 .../hibernate/GemFireQueryCacheFactory.java     |    39 +
 .../modules/hibernate/GemFireRegionFactory.java |   237 +
 .../modules/hibernate/internal/Access.java      |   257 +
 .../ClientServerRegionFactoryDelegate.java      |   208 +
 .../hibernate/internal/CollectionAccess.java    |   224 +
 .../hibernate/internal/EntityRegionWriter.java  |    87 +
 .../hibernate/internal/EntityVersion.java       |    28 +
 .../hibernate/internal/EntityVersionImpl.java   |    51 +
 .../hibernate/internal/EntityWrapper.java       |    89 +
 .../hibernate/internal/GemFireBaseRegion.java   |   166 +
 .../internal/GemFireCollectionRegion.java       |    59 +
 .../hibernate/internal/GemFireEntityRegion.java |   187 +
 .../internal/GemFireQueryResultsRegion.java     |   113 +
 .../modules/hibernate/internal/KeyWrapper.java  |    93 +
 .../internal/NonStrictReadWriteAccess.java      |    83 +
 .../hibernate/internal/ReadOnlyAccess.java      |    55 +
 .../hibernate/internal/ReadWriteAccess.java     |    36 +
 .../internal/RegionFactoryDelegate.java         |   153 +
 .../hibernate/internal/TransactionalAccess.java |    25 +
 .../com/gemstone/gemfire/modules/Event.java     |    67 +
 .../gemfire/modules/HibernateJUnitTest.java     |   410 +
 .../com/gemstone/gemfire/modules/Owner.java     |   186 +
 .../com/gemstone/gemfire/modules/Person.java    |    72 +
 .../gemstone/gemfire/modules/SecondVMTest.java  |    93 +
 .../com/gemstone/gemfire/modules/Event.hbm.xml  |    32 +
 .../com/gemstone/gemfire/modules/Person.hbm.xml |    36 +
 .../src/test/resources/log4j.properties         |    16 +
 extensions/geode-modules-session/build.gradle   |    54 +
 .../session/filter/SessionCachingFilter.java    |   652 +
 .../modules/session/filter/SessionListener.java |    51 +
 .../modules/session/installer/Installer.java    |   296 +
 .../session/installer/JarClassLoader.java       |   123 +
 .../session/installer/args/Argument.java        |   275 +
 .../session/installer/args/ArgumentHandler.java |    38 +
 .../installer/args/ArgumentProcessor.java       |   397 +
 .../session/installer/args/ArgumentValues.java  |   222 +
 .../installer/args/URLArgumentHandler.java      |    77 +
 .../installer/args/UnknownArgumentHandler.java  |    36 +
 .../session/installer/args/UsageException.java  |    89 +
 .../internal/common/AbstractSessionCache.java   |   102 +
 .../session/internal/common/CacheProperty.java  |    65 +
 .../common/ClientServerSessionCache.java        |   186 +
 .../internal/common/PeerToPeerSessionCache.java |   184 +
 .../session/internal/common/SessionCache.java   |    68 +
 .../common/SessionExpirationCacheListener.java  |    53 +
 .../session/internal/filter/Constants.java      |    30 +
 .../internal/filter/DummySessionManager.java    |   132 +
 .../internal/filter/GemfireHttpSession.java     |   526 +
 .../filter/GemfireSessionException.java         |    41 +
 .../internal/filter/GemfireSessionManager.java  |   511 +
 .../internal/filter/ListenerEventType.java      |    75 +
 .../session/internal/filter/SessionManager.java |   110 +
 .../AbstractDeltaSessionAttributes.java         |   107 +
 .../attributes/AbstractSessionAttributes.java   |   188 +
 .../internal/filter/attributes/DeltaEvent.java  |   119 +
 .../DeltaQueuedSessionAttributes.java           |    94 +
 .../attributes/DeltaSessionAttributes.java      |    75 +
 .../attributes/ImmediateSessionAttributes.java  |    68 +
 .../attributes/QueuedSessionAttributes.java     |    65 +
 .../filter/attributes/SessionAttributes.java    |   120 +
 .../filter/util/NamedThreadFactory.java         |    68 +
 .../filter/util/ThreadLocalSession.java         |    39 +
 .../internal/filter/util/TypeAwareMap.java      |    50 +
 .../session/internal/jmx/SessionStatistics.java |    78 +
 .../internal/jmx/SessionStatisticsMXBean.java   |    30 +
 .../internal/filter/AbstractListener.java       |    57 +
 .../session/internal/filter/BasicServlet.java   |    52 +
 .../session/internal/filter/Callback.java       |    30 +
 .../internal/filter/CallbackServlet.java        |    91 +
 .../session/internal/filter/CommonTests.java    |   582 +
 .../HttpSessionAttributeListenerImpl.java       |    46 +
 .../filter/HttpSessionBindingListenerImpl.java  |    42 +
 .../filter/HttpSessionListenerImpl.java         |    41 +
 .../filter/HttpSessionListenerImpl2.java        |    43 +
 .../internal/filter/MyServletTester.java        |    38 +
 .../internal/filter/RendezvousManager.java      |    46 +
 .../ServletRequestAttributeListenerImpl.java    |    45 +
 .../filter/ServletRequestListenerImpl.java      |    36 +
 .../SessionReplicationIntegrationJUnitTest.java |  1558 ++
 .../filter/SessionReplicationJUnitTest.java     |    53 +
 .../SessionReplicationLocalCacheJUnitTest.java  |    54 +
 .../session/junit/ChildFirstClassLoader.java    |    86 +
 .../modules/session/junit/NamedRunner.java      |   120 +
 .../session/junit/PerTestClassLoaderRunner.java |   283 +
 .../junit/SeparateClassloaderTestRunner.java    |    56 +
 .../src/test/resources/log4j.properties         |    12 +
 extensions/geode-modules-tomcat7/build.gradle   |    54 +
 .../catalina/Tomcat7DeltaSessionManager.java    |   112 +
 .../session/Tomcat7SessionsJUnitTest.java       |    35 +
 .../test/resources/tomcat/conf/tomcat-users.xml |     3 +
 .../src/test/resources/tomcat/logs/.gitkeep     |     0
 .../src/test/resources/tomcat/temp/.gitkeep     |     0
 extensions/geode-modules/build.gradle           |    39 +
 .../gatewaydelta/AbstractGatewayDeltaEvent.java |    64 +
 .../modules/gatewaydelta/GatewayDelta.java      |    26 +
 .../gatewaydelta/GatewayDeltaCreateEvent.java   |    88 +
 .../gatewaydelta/GatewayDeltaDestroyEvent.java  |    82 +
 .../modules/gatewaydelta/GatewayDeltaEvent.java |    24 +
 ...tewayDeltaEventApplicationCacheListener.java |    67 +
 .../GatewayDeltaForwarderCacheListener.java     |   197 +
 .../session/bootstrap/AbstractCache.java        |   398 +
 .../session/bootstrap/ClientServerCache.java    |    74 +
 .../session/bootstrap/LifecycleTypeAdapter.java |    59 +
 .../session/bootstrap/PeerToPeerCache.java      |    85 +
 .../AbstractCacheLifecycleListener.java         |    68 +
 .../session/catalina/AbstractSessionCache.java  |   113 +
 .../ClientServerCacheLifecycleListener.java     |    26 +
 .../catalina/ClientServerSessionCache.java      |   252 +
 .../session/catalina/CommitSessionValve.java    |    68 +
 .../modules/session/catalina/DeltaSession.java  |   597 +
 .../session/catalina/DeltaSessionFacade.java    |    49 +
 .../session/catalina/DeltaSessionManager.java   |   992 +
 .../session/catalina/JvmRouteBinderValve.java   |   108 +
 .../session/catalina/LocalStrings.properties    |    16 +
 .../PeerToPeerCacheLifecycleListener.java       |    29 +
 .../catalina/PeerToPeerSessionCache.java        |   215 +
 .../modules/session/catalina/SessionCache.java  |    64 +
 .../session/catalina/SessionManager.java        |    48 +
 .../catalina/Tomcat6DeltaSessionManager.java    |    98 +
 .../callback/LocalSessionCacheLoader.java       |    45 +
 .../callback/LocalSessionCacheWriter.java       |    59 +
 .../SessionExpirationCacheListener.java         |    77 +
 .../internal/DeltaSessionAttributeEvent.java    |    25 +
 .../DeltaSessionAttributeEventBatch.java        |    88 +
 .../DeltaSessionDestroyAttributeEvent.java      |    73 +
 .../internal/DeltaSessionStatistics.java        |    88 +
 .../DeltaSessionUpdateAttributeEvent.java       |    83 +
 .../gemstone/gemfire/modules/util/Banner.java   |    59 +
 .../modules/util/BootstrappingFunction.java     |   188 +
 .../util/ClassLoaderObjectInputStream.java      |    40 +
 .../gemfire/modules/util/ContextMapper.java     |    53 +
 .../modules/util/CreateRegionFunction.java      |   245 +
 .../modules/util/DebugCacheListener.java        |    72 +
 .../gemfire/modules/util/ModuleStatistics.java  |    91 +
 .../modules/util/RegionConfiguration.java       |   308 +
 .../util/RegionConfigurationCacheListener.java  |   114 +
 .../gemfire/modules/util/RegionHelper.java      |   241 +
 .../modules/util/RegionSizeFunction.java        |    56 +
 .../gemfire/modules/util/RegionStatus.java      |    21 +
 .../modules/util/ResourceManagerValidator.java  |   166 +
 .../modules/util/SessionCustomExpiry.java       |    64 +
 .../TouchPartitionedRegionEntriesFunction.java  |   100 +
 .../TouchReplicatedRegionEntriesFunction.java   |    97 +
 .../main/resources/modules-version.properties   |     1 +
 .../gemfire/modules/session/Callback.java       |    30 +
 .../gemfire/modules/session/CommandServlet.java |    91 +
 .../gemfire/modules/session/EmbeddedTomcat.java |   193 +
 .../gemfire/modules/session/QueryCommand.java   |    34 +
 .../modules/session/TestSessionsBase.java       |   493 +
 .../session/Tomcat6SessionsJUnitTest.java       |    35 +
 .../com/gemstone/gemfire/modules/Event.hbm.xml  |    16 +
 .../com/gemstone/gemfire/modules/Person.hbm.xml |    21 +
 .../src/test/resources/log4j.properties         |    16 +
 .../test/resources/tomcat/conf/tomcat-users.xml |     3 +
 .../src/test/resources/tomcat/logs/.gitkeep     |     0
 .../src/test/resources/tomcat/temp/.gitkeep     |     0
 gemfire-assembly/build.gradle                   |   347 -
 gemfire-assembly/src/main/dist/DISCLAIMER       |     6 -
 gemfire-assembly/src/main/dist/LICENSE          |   434 -
 gemfire-assembly/src/main/dist/NOTICE           |   467 -
 gemfire-assembly/src/main/dist/bin/gfsh         |   152 -
 .../src/main/dist/bin/gfsh-completion.bash      |   103 -
 gemfire-assembly/src/main/dist/bin/gfsh.bat     |    87 -
 gemfire-assembly/src/src/dist/gradlew           |   221 -
 .../LocatorLauncherAssemblyJUnitTest.java       |   157 -
 .../management/internal/AgentUtilJUnitTest.java |    51 -
 .../LauncherLifecycleCommandsDUnitTest.java     |  1007 -
 .../LauncherLifecycleCommandsJUnitTest.java     |   625 -
 .../SharedConfigurationEndToEndDUnitTest.java   |   450 -
 gemfire-common/build.gradle                     |    20 -
 .../gemfire/annotations/Experimental.java       |    56 -
 .../annotations/ExperimentalJUnitTest.java      |   199 -
 .../ClassInExperimentalPackage.java             |    27 -
 .../experimentalpackage/package-info.java       |    27 -
 .../ClassInNonExperimentalPackage.java          |    27 -
 .../nonexperimentalpackage/package-info.java    |    24 -
 gemfire-core/build.gradle                       |   204 -
 .../internal/ra/GFConnectionFactoryImpl.java    |    66 -
 .../gemfire/internal/ra/GFConnectionImpl.java   |    71 -
 .../internal/ra/spi/JCALocalTransaction.java    |   236 -
 .../internal/ra/spi/JCAManagedConnection.java   |   299 -
 .../ra/spi/JCAManagedConnectionFactory.java     |   145 -
 .../ra/spi/JCAManagedConnectionMetaData.java    |    67 -
 gemfire-core/src/jca/ra.xml                     |    52 -
 .../com/gemstone/gemfire/CancelCriterion.java   |   109 -
 .../com/gemstone/gemfire/CancelException.java   |    64 -
 .../gemstone/gemfire/CanonicalInstantiator.java |    86 -
 .../com/gemstone/gemfire/CopyException.java     |    67 -
 .../java/com/gemstone/gemfire/CopyHelper.java   |   268 -
 .../com/gemstone/gemfire/DataSerializable.java  |   140 -
 .../com/gemstone/gemfire/DataSerializer.java    |  3565 ----
 .../main/java/com/gemstone/gemfire/Delta.java   |    66 -
 .../gemfire/DeltaSerializationException.java    |    59 -
 .../gemfire/ForcedDisconnectException.java      |    41 -
 .../gemstone/gemfire/GemFireCacheException.java |    50 -
 .../gemfire/GemFireCheckedException.java        |    90 -
 .../gemfire/GemFireConfigException.java         |    42 -
 .../com/gemstone/gemfire/GemFireException.java  |   149 -
 .../gemstone/gemfire/GemFireIOException.java    |    41 -
 .../gemstone/gemfire/GemFireRethrowable.java    |    47 -
 .../gemfire/IncompatibleSystemException.java    |    38 -
 .../java/com/gemstone/gemfire/Instantiator.java |   315 -
 .../gemstone/gemfire/InternalGemFireError.java  |   154 -
 .../gemfire/InternalGemFireException.java       |    56 -
 .../gemstone/gemfire/InvalidDeltaException.java |    63 -
 .../gemstone/gemfire/InvalidValueException.java |    42 -
 .../gemfire/InvalidVersionException.java        |    25 -
 .../com/gemstone/gemfire/LicenseException.java  |    54 -
 .../java/com/gemstone/gemfire/LogWriter.java    |   301 -
 .../com/gemstone/gemfire/NoSystemException.java |    48 -
 .../gemfire/OutOfOffHeapMemoryException.java    |    45 -
 .../gemfire/SerializationException.java         |    45 -
 .../gemstone/gemfire/StatisticDescriptor.java   |    82 -
 .../java/com/gemstone/gemfire/Statistics.java   |   446 -
 .../com/gemstone/gemfire/StatisticsFactory.java |   154 -
 .../com/gemstone/gemfire/StatisticsType.java    |    72 -
 .../gemstone/gemfire/StatisticsTypeFactory.java |   197 -
 .../gemfire/SystemConnectException.java         |    42 -
 .../com/gemstone/gemfire/SystemFailure.java     |  1239 --
 .../gemfire/SystemIsRunningException.java       |    46 -
 .../gemfire/ThreadInterruptedException.java     |    31 -
 .../com/gemstone/gemfire/ToDataException.java   |    42 -
 .../gemfire/UncreatedSystemException.java       |    48 -
 .../gemstone/gemfire/UnmodifiableException.java |    36 -
 .../gemfire/UnstartedSystemException.java       |    49 -
 .../com/gemstone/gemfire/admin/AdminConfig.java |   157 -
 .../gemfire/admin/AdminDistributedSystem.java   |   478 -
 .../admin/AdminDistributedSystemFactory.java    |   163 -
 .../gemstone/gemfire/admin/AdminException.java  |    90 -
 .../gemfire/admin/AdminXmlException.java        |    48 -
 .../java/com/gemstone/gemfire/admin/Alert.java  |    56 -
 .../com/gemstone/gemfire/admin/AlertLevel.java  |   174 -
 .../gemstone/gemfire/admin/AlertListener.java   |    30 -
 .../gemstone/gemfire/admin/BackupStatus.java    |    49 -
 .../admin/CacheDoesNotExistException.java       |    87 -
 .../gemfire/admin/CacheHealthConfig.java        |   157 -
 .../com/gemstone/gemfire/admin/CacheServer.java |    46 -
 .../gemfire/admin/CacheServerConfig.java        |    55 -
 .../com/gemstone/gemfire/admin/CacheVm.java     |    38 -
 .../gemstone/gemfire/admin/CacheVmConfig.java   |    54 -
 .../gemfire/admin/ConfigurationParameter.java   |    74 -
 .../gemfire/admin/DistributedSystemConfig.java  |   682 -
 .../admin/DistributedSystemHealthConfig.java    |    77 -
 .../gemfire/admin/DistributionLocator.java      |    47 -
 .../admin/DistributionLocatorConfig.java        |    90 -
 .../gemstone/gemfire/admin/GemFireHealth.java   |   234 -
 .../gemfire/admin/GemFireHealthConfig.java      |    58 -
 .../gemfire/admin/GemFireMemberStatus.java      |   709 -
 .../gemstone/gemfire/admin/ManagedEntity.java   |   125 -
 .../gemfire/admin/ManagedEntityConfig.java      |   100 -
 .../gemfire/admin/MemberHealthConfig.java       |   142 -
 .../admin/OperationCancelledException.java      |    48 -
 .../gemfire/admin/RegionNotFoundException.java  |    39 -
 .../gemfire/admin/RegionSubRegionSnapshot.java  |   193 -
 .../gemfire/admin/RuntimeAdminException.java    |    50 -
 .../com/gemstone/gemfire/admin/Statistic.java   |    66 -
 .../gemfire/admin/StatisticResource.java        |    86 -
 .../gemstone/gemfire/admin/SystemMember.java    |   148 -
 .../gemfire/admin/SystemMemberBridgeServer.java |   309 -
 .../gemfire/admin/SystemMemberCache.java        |   205 -
 .../gemfire/admin/SystemMemberCacheEvent.java   |    34 -
 .../admin/SystemMemberCacheListener.java        |    73 -
 .../gemfire/admin/SystemMemberCacheServer.java  |   309 -
 .../gemfire/admin/SystemMemberRegion.java       |   322 -
 .../gemfire/admin/SystemMemberRegionEvent.java  |    33 -
 .../gemfire/admin/SystemMemberType.java         |   146 -
 .../gemfire/admin/SystemMembershipEvent.java    |    41 -
 .../gemfire/admin/SystemMembershipListener.java |    62 -
 .../UnmodifiableConfigurationException.java     |    89 -
 .../admin/internal/AbstractHealthEvaluator.java |   185 -
 .../internal/AdminDistributedSystemImpl.java    |  2510 ---
 .../admin/internal/BackupDataStoreHelper.java   |    76 -
 .../admin/internal/BackupDataStoreResult.java   |    57 -
 .../admin/internal/BackupStatusImpl.java        |    62 -
 .../admin/internal/CacheHealthConfigImpl.java   |    92 -
 .../admin/internal/CacheHealthEvaluator.java    |   324 -
 .../admin/internal/CacheServerConfigImpl.java   |   136 -
 .../gemfire/admin/internal/CacheServerImpl.java |   199 -
 .../internal/ConfigurationParameterImpl.java    |   281 -
 .../ConfigurationParameterListener.java         |    35 -
 .../DisabledManagedEntityController.java        |    92 -
 .../internal/DistributedSystemConfigImpl.java   |  1103 --
 .../DistributedSystemHealthConfigImpl.java      |    59 -
 .../DistributedSystemHealthEvaluator.java       |   172 -
 .../DistributedSystemHealthMonitor.java         |   437 -
 .../internal/DistributionLocatorConfigImpl.java |   192 -
 .../admin/internal/DistributionLocatorImpl.java |   331 -
 .../EnabledManagedEntityController.java         |   412 -
 .../admin/internal/FinishBackupRequest.java     |   172 -
 .../admin/internal/FinishBackupResponse.java    |    79 -
 .../admin/internal/FlushToDiskRequest.java      |    98 -
 .../admin/internal/FlushToDiskResponse.java     |    46 -
 .../admin/internal/GemFireHealthConfigImpl.java |    84 -
 .../admin/internal/GemFireHealthEvaluator.java  |   188 -
 .../admin/internal/GemFireHealthImpl.java       |   536 -
 .../gemfire/admin/internal/InetAddressUtil.java |   209 -
 .../admin/internal/InternalManagedEntity.java   |   106 -
 .../gemfire/admin/internal/LogCollator.java     |   137 -
 .../admin/internal/ManagedEntityConfigImpl.java |   263 -
 .../admin/internal/ManagedEntityConfigXml.java  |   170 -
 .../ManagedEntityConfigXmlGenerator.java        |   386 -
 .../internal/ManagedEntityConfigXmlParser.java  |   623 -
 .../admin/internal/ManagedEntityController.java |    74 -
 .../ManagedEntityControllerFactory.java         |    61 -
 .../admin/internal/ManagedSystemMemberImpl.java |   271 -
 .../admin/internal/MemberHealthConfigImpl.java  |    96 -
 .../admin/internal/MemberHealthEvaluator.java   |   242 -
 .../admin/internal/PrepareBackupRequest.java    |   133 -
 .../admin/internal/PrepareBackupResponse.java   |    82 -
 .../gemfire/admin/internal/StatisticImpl.java   |    97 -
 .../admin/internal/StatisticResourceImpl.java   |   182 -
 .../internal/SystemMemberBridgeServerImpl.java  |   234 -
 .../internal/SystemMemberCacheEventImpl.java    |    61 -
 .../SystemMemberCacheEventProcessor.java        |   148 -
 .../admin/internal/SystemMemberCacheImpl.java   |   313 -
 .../admin/internal/SystemMemberImpl.java        |   520 -
 .../internal/SystemMemberRegionEventImpl.java   |    63 -
 .../admin/internal/SystemMemberRegionImpl.java  |   381 -
 .../internal/SystemMembershipEventImpl.java     |    71 -
 .../internal/doc-files/config-hierarchy.fig     |   156 -
 .../admin/internal/doc-files/health-classes.fig |   233 -
 .../admin/internal/doc-files/health-classes.gif |   Bin 8973 -> 0 bytes
 .../gemfire/admin/internal/package.html         |    53 -
 .../com/gemstone/gemfire/admin/jmx/Agent.java   |   165 -
 .../gemstone/gemfire/admin/jmx/AgentConfig.java |   884 -
 .../gemfire/admin/jmx/AgentFactory.java         |    52 -
 .../internal/AdminDistributedSystemJmxImpl.java |  2341 ---
 .../admin/jmx/internal/AgentConfigImpl.java     |  1847 --
 .../gemfire/admin/jmx/internal/AgentImpl.java   |  1622 --
 .../admin/jmx/internal/AgentLauncher.java       |   889 -
 .../admin/jmx/internal/CacheServerJmxImpl.java  |   642 -
 .../admin/jmx/internal/ConfigAttributeInfo.java |    77 -
 .../internal/ConfigurationParameterJmxImpl.java |   170 -
 .../DistributedSystemHealthConfigJmxImpl.java   |   108 -
 .../internal/DistributionLocatorJmxImpl.java    |   186 -
 .../admin/jmx/internal/DynamicManagedBean.java  |   142 -
 .../internal/GemFireHealthConfigJmxImpl.java    |   223 -
 .../jmx/internal/GemFireHealthJmxImpl.java      |   179 -
 .../admin/jmx/internal/GenerateMBeanHTML.java   |   514 -
 .../gemfire/admin/jmx/internal/MBeanUtil.java   |   769 -
 .../admin/jmx/internal/MX4JModelMBean.java      |  1255 --
 .../jmx/internal/MX4JServerSocketFactory.java   |   160 -
 .../gemfire/admin/jmx/internal/MailManager.java |   333 -
 .../admin/jmx/internal/ManagedResource.java     |    78 -
 .../admin/jmx/internal/ManagedResourceType.java |   210 -
 .../jmx/internal/MemberInfoWithStatsMBean.java  |  1388 --
 .../admin/jmx/internal/RMIRegistryService.java  |   239 -
 .../jmx/internal/RMIRegistryServiceMBean.java   |    85 -
 .../jmx/internal/RefreshNotificationType.java   |   133 -
 .../jmx/internal/StatAlertNotification.java     |   162 -
 .../jmx/internal/StatAlertsAggregator.java      |   125 -
 .../jmx/internal/StatisticAttributeInfo.java    |    79 -
 .../jmx/internal/StatisticResourceJmxImpl.java  |   361 -
 .../SystemMemberBridgeServerJmxImpl.java        |   135 -
 .../jmx/internal/SystemMemberCacheJmxImpl.java  |   475 -
 .../admin/jmx/internal/SystemMemberJmx.java     |   508 -
 .../admin/jmx/internal/SystemMemberJmxImpl.java |   593 -
 .../jmx/internal/SystemMemberRegionJmxImpl.java |   140 -
 .../gemfire/admin/jmx/internal/package.html     |   166 -
 .../com/gemstone/gemfire/admin/jmx/package.html |    28 -
 .../com/gemstone/gemfire/admin/package.html     |    78 -
 .../gemfire/cache/AttributesFactory.java        |  2056 --
 .../gemfire/cache/AttributesMutator.java        |   224 -
 .../java/com/gemstone/gemfire/cache/Cache.java  |   457 -
 .../gemstone/gemfire/cache/CacheCallback.java   |    47 -
 .../gemfire/cache/CacheClosedException.java     |    77 -
 .../com/gemstone/gemfire/cache/CacheEvent.java  |   110 -
 .../gemstone/gemfire/cache/CacheException.java  |    70 -
 .../gemfire/cache/CacheExistsException.java     |    66 -
 .../gemstone/gemfire/cache/CacheFactory.java    |   392 -
 .../gemstone/gemfire/cache/CacheListener.java   |   174 -
 .../com/gemstone/gemfire/cache/CacheLoader.java |    64 -
 .../gemfire/cache/CacheLoaderException.java     |    66 -
 .../gemfire/cache/CacheRuntimeException.java    |    81 -
 .../gemstone/gemfire/cache/CacheStatistics.java |   130 -
 .../gemfire/cache/CacheTransactionManager.java  |   350 -
 .../com/gemstone/gemfire/cache/CacheWriter.java |   151 -
 .../gemfire/cache/CacheWriterException.java     |    70 -
 .../gemfire/cache/CacheXmlException.java        |    50 -
 .../gemstone/gemfire/cache/ClientSession.java   |   198 -
 .../gemfire/cache/CommitConflictException.java  |    57 -
 .../cache/CommitDistributionException.java      |    81 -
 .../cache/CommitIncompleteException.java        |    31 -
 .../gemfire/cache/CustomEvictionAttributes.java |    79 -
 .../gemstone/gemfire/cache/CustomExpiry.java    |    42 -
 .../com/gemstone/gemfire/cache/DataPolicy.java  |   266 -
 .../com/gemstone/gemfire/cache/Declarable.java  |    77 -
 .../gemfire/cache/DiskAccessException.java      |   141 -
 .../com/gemstone/gemfire/cache/DiskStore.java   |   216 -
 .../gemfire/cache/DiskStoreFactory.java         |   243 -
 .../gemfire/cache/DiskWriteAttributes.java      |   108 -
 .../cache/DiskWriteAttributesFactory.java       |   263 -
 .../DuplicatePrimaryPartitionException.java     |    65 -
 .../gemfire/cache/DynamicRegionFactory.java     |  1108 --
 .../gemfire/cache/DynamicRegionListener.java    |    70 -
 .../gemfire/cache/EntryDestroyedException.java  |    61 -
 .../com/gemstone/gemfire/cache/EntryEvent.java  |   167 -
 .../gemfire/cache/EntryExistsException.java     |    62 -
 .../gemfire/cache/EntryNotFoundException.java   |    51 -
 .../gemfire/cache/EntryNotFoundInRegion.java    |    50 -
 .../gemstone/gemfire/cache/EntryOperation.java  |    86 -
 .../gemstone/gemfire/cache/EvictionAction.java  |   115 -
 .../gemfire/cache/EvictionAlgorithm.java        |   151 -
 .../gemfire/cache/EvictionAttributes.java       |   494 -
 .../cache/EvictionAttributesMutator.java        |    40 -
 .../gemfire/cache/EvictionCriteria.java         |    58 -
 .../gemfire/cache/ExpirationAction.java         |   123 -
 .../gemfire/cache/ExpirationAttributes.java     |   144 -
 .../cache/FailedSynchronizationException.java   |    59 -
 .../gemfire/cache/FixedPartitionAttributes.java |   115 -
 .../gemfire/cache/FixedPartitionResolver.java   |    79 -
 .../cache/GatewayConfigurationException.java    |    45 -
 .../gemfire/cache/GatewayException.java         |    68 -
 .../gemstone/gemfire/cache/GemFireCache.java    |   262 -
 .../cache/IncompatibleVersionException.java     |    48 -
 .../gemstone/gemfire/cache/InterestPolicy.java  |   149 -
 .../cache/InterestRegistrationEvent.java        |    92 -
 .../cache/InterestRegistrationListener.java     |    84 -
 .../gemfire/cache/InterestResultPolicy.java     |   122 -
 .../gemstone/gemfire/cache/LoaderHelper.java    |    81 -
 .../com/gemstone/gemfire/cache/LossAction.java  |   149 -
 .../gemfire/cache/LowMemoryException.java       |    67 -
 .../gemfire/cache/MembershipAttributes.java     |   269 -
 .../com/gemstone/gemfire/cache/MirrorType.java  |   136 -
 .../cache/NoQueueServersAvailableException.java |    64 -
 ...NoSubscriptionServersAvailableException.java |    64 -
 .../com/gemstone/gemfire/cache/Operation.java   |  1010 -
 .../cache/OperationAbortedException.java        |    63 -
 .../gemfire/cache/PartitionAttributes.java      |   171 -
 .../cache/PartitionAttributesFactory.java       |   457 -
 .../gemfire/cache/PartitionResolver.java        |    84 -
 .../PartitionedRegionDistributionException.java |    46 -
 .../PartitionedRegionStorageException.java      |    96 -
 .../java/com/gemstone/gemfire/cache/Region.java |  2403 ---
 .../gemfire/cache/RegionAccessException.java    |   118 -
 .../gemfire/cache/RegionAttributes.java         |   490 -
 .../gemfire/cache/RegionDestroyedException.java |    52 -
 .../cache/RegionDistributionException.java      |   123 -
 .../com/gemstone/gemfire/cache/RegionEvent.java |    41 -
 .../gemfire/cache/RegionExistsException.java    |    65 -
 .../gemstone/gemfire/cache/RegionFactory.java   |   934 -
 .../gemfire/cache/RegionMembershipListener.java |    83 -
 .../cache/RegionReinitializedException.java     |    48 -
 .../gemfire/cache/RegionRoleException.java      |    63 -
 .../gemfire/cache/RegionRoleListener.java       |    54 -
 .../gemstone/gemfire/cache/RegionService.java   |   142 -
 .../gemstone/gemfire/cache/RegionShortcut.java  |   238 -
 .../cache/RemoteTransactionException.java       |    42 -
 .../gemstone/gemfire/cache/RequiredRoles.java   |   117 -
 .../gemfire/cache/ResourceException.java        |    61 -
 .../gemfire/cache/ResumptionAction.java         |   114 -
 .../com/gemstone/gemfire/cache/RoleEvent.java   |    39 -
 .../gemstone/gemfire/cache/RoleException.java   |    68 -
 .../java/com/gemstone/gemfire/cache/Scope.java  |   168 -
 .../gemfire/cache/SerializedCacheValue.java     |    53 -
 .../cache/StatisticsDisabledException.java      |    68 -
 .../gemfire/cache/SubscriptionAttributes.java   |   117 -
 .../SynchronizationCommitConflictException.java |    49 -
 .../gemfire/cache/TimeoutException.java         |    73 -
 ...TransactionDataNodeHasDepartedException.java |    42 -
 .../TransactionDataNotColocatedException.java   |    46 -
 .../TransactionDataRebalancedException.java     |    38 -
 .../gemfire/cache/TransactionEvent.java         |   114 -
 .../gemfire/cache/TransactionException.java     |    43 -
 .../gemstone/gemfire/cache/TransactionId.java   |    33 -
 .../cache/TransactionInDoubtException.java      |    42 -
 .../gemfire/cache/TransactionListener.java      |    66 -
 .../gemfire/cache/TransactionWriter.java        |    44 -
 .../cache/TransactionWriterException.java       |    45 -
 ...upportedOperationInTransactionException.java |    37 -
 .../cache/UnsupportedVersionException.java      |    44 -
 .../gemfire/cache/VersionException.java         |    50 -
 .../gemfire/cache/asyncqueue/AsyncEvent.java    |    42 -
 .../cache/asyncqueue/AsyncEventListener.java    |    76 -
 .../cache/asyncqueue/AsyncEventQueue.java       |   151 -
 .../asyncqueue/AsyncEventQueueFactory.java      |   191 -
 .../internal/AsyncEventQueueFactoryImpl.java    |   299 -
 .../internal/AsyncEventQueueImpl.java           |   205 -
 .../internal/AsyncEventQueueStats.java          |   186 -
 .../internal/ParallelAsyncEventQueueImpl.java   |   260 -
 .../internal/SerialAsyncEventQueueImpl.java     |   257 -
 .../client/AllConnectionsInUseException.java    |    61 -
 .../gemfire/cache/client/ClientCache.java       |   168 -
 .../cache/client/ClientCacheFactory.java        |   695 -
 .../cache/client/ClientNotReadyException.java   |    56 -
 .../cache/client/ClientRegionFactory.java       |   346 -
 .../cache/client/ClientRegionShortcut.java      |   108 -
 .../client/NoAvailableLocatorsException.java    |    59 -
 .../client/NoAvailableServersException.java     |    59 -
 .../com/gemstone/gemfire/cache/client/Pool.java |   251 -
 .../gemfire/cache/client/PoolFactory.java       |   477 -
 .../gemfire/cache/client/PoolManager.java       |    98 -
 .../client/ServerConnectivityException.java     |    63 -
 .../cache/client/ServerOperationException.java  |    86 -
 .../ServerRefusedConnectionException.java       |    41 -
 .../client/SubscriptionNotEnabledException.java |    63 -
 .../client/doc-files/example-client-cache.xml   |    46 -
 .../cache/client/internal/AbstractOp.java       |   436 -
 .../cache/client/internal/AddPDXEnumOp.java     |    98 -
 .../cache/client/internal/AddPDXTypeOp.java     |    96 -
 .../client/internal/AuthenticateUserOp.java     |   312 -
 .../internal/AutoConnectionSourceImpl.java      |   387 -
 .../client/internal/CacheServerLoadMessage.java |   108 -
 .../gemfire/cache/client/internal/ClearOp.java  |   106 -
 .../client/internal/ClientMetadataService.java  |   848 -
 .../client/internal/ClientPartitionAdvisor.java |   288 -
 .../internal/ClientRegionFactoryImpl.java       |   271 -
 .../cache/client/internal/ClientUpdater.java    |    36 -
 .../client/internal/CloseConnectionOp.java      |    95 -
 .../gemfire/cache/client/internal/CommitOp.java |   109 -
 .../cache/client/internal/Connection.java       |    85 -
 .../client/internal/ConnectionFactory.java      |    68 -
 .../client/internal/ConnectionFactoryImpl.java  |   334 -
 .../cache/client/internal/ConnectionImpl.java   |   339 -
 .../cache/client/internal/ConnectionSource.java |    77 -
 .../cache/client/internal/ConnectionStats.java  |  3292 ----
 .../cache/client/internal/ContainsKeyOp.java    |   102 -
 .../DataSerializerRecoveryListener.java         |   153 -
 .../cache/client/internal/DestroyOp.java        |   286 -
 .../cache/client/internal/DestroyRegionOp.java  |   104 -
 .../gemfire/cache/client/internal/Endpoint.java |   111 -
 .../cache/client/internal/EndpointManager.java  |   100 -
 .../client/internal/EndpointManagerImpl.java    |   308 -
 .../cache/client/internal/ExecutablePool.java   |   150 -
 .../client/internal/ExecuteFunctionHelper.java  |    30 -
 .../client/internal/ExecuteFunctionNoAckOp.java |   243 -
 .../client/internal/ExecuteFunctionOp.java      |   653 -
 .../internal/ExecuteRegionFunctionNoAckOp.java  |   227 -
 .../internal/ExecuteRegionFunctionOp.java       |   624 -
 .../ExecuteRegionFunctionSingleHopOp.java       |   500 -
 .../internal/ExplicitConnectionSourceImpl.java  |   277 -
 .../gemfire/cache/client/internal/GetAllOp.java |   242 -
 .../client/internal/GetClientPRMetaDataOp.java  |   171 -
 .../GetClientPartitionAttributesOp.java         |   177 -
 .../cache/client/internal/GetEntryOp.java       |    82 -
 .../cache/client/internal/GetEventValueOp.java  |   121 -
 .../client/internal/GetFunctionAttributeOp.java |    84 -
 .../gemfire/cache/client/internal/GetOp.java    |   245 -
 .../cache/client/internal/GetPDXEnumByIdOp.java |    92 -
 .../cache/client/internal/GetPDXEnumsOp.java    |   112 -
 .../client/internal/GetPDXIdForEnumOp.java      |   113 -
 .../client/internal/GetPDXIdForTypeOp.java      |   113 -
 .../cache/client/internal/GetPDXTypeByIdOp.java |    92 -
 .../cache/client/internal/GetPDXTypesOp.java    |   112 -
 .../internal/InstantiatorRecoveryListener.java  |   159 -
 .../cache/client/internal/InternalPool.java     |    43 -
 .../cache/client/internal/InvalidateOp.java     |   121 -
 .../gemfire/cache/client/internal/KeySetOp.java |   130 -
 .../cache/client/internal/LiveServerPinger.java |   117 -
 .../internal/LocatorDiscoveryCallback.java      |    47 -
 .../LocatorDiscoveryCallbackAdapter.java        |    36 -
 .../cache/client/internal/MakePrimaryOp.java    |    91 -
 .../gemfire/cache/client/internal/Op.java       |    43 -
 .../cache/client/internal/OpExecutorImpl.java   |   985 -
 .../internal/PdxRegistryRecoveryListener.java   |    90 -
 .../gemfire/cache/client/internal/PingOp.java   |    97 -
 .../gemfire/cache/client/internal/PoolImpl.java |  1522 --
 .../cache/client/internal/PrimaryAckOp.java     |   101 -
 .../cache/client/internal/ProxyCache.java       |   248 -
 .../client/internal/ProxyCacheCloseOp.java      |   124 -
 .../cache/client/internal/ProxyRegion.java      |   698 -
 .../gemfire/cache/client/internal/PutAllOp.java |   430 -
 .../gemfire/cache/client/internal/PutOp.java    |   553 -
 .../gemfire/cache/client/internal/QueryOp.java  |   203 -
 .../client/internal/QueueConnectionImpl.java    |   226 -
 .../cache/client/internal/QueueManager.java     |    57 -
 .../cache/client/internal/QueueManagerImpl.java |  1487 --
 .../cache/client/internal/QueueState.java       |    33 -
 .../cache/client/internal/QueueStateImpl.java   |   450 -
 .../cache/client/internal/ReadyForEventsOp.java |    91 -
 .../internal/RegisterDataSerializersOp.java     |   138 -
 .../internal/RegisterInstantiatorsOp.java       |   180 -
 .../client/internal/RegisterInterestListOp.java |   147 -
 .../client/internal/RegisterInterestOp.java     |   296 -
 .../internal/RegisterInterestTracker.java       |   419 -
 .../cache/client/internal/RemoveAllOp.java      |   391 -
 .../cache/client/internal/RollbackOp.java       |    99 -
 .../cache/client/internal/ServerBlackList.java  |   188 -
 .../cache/client/internal/ServerProxy.java      |    69 -
 .../client/internal/ServerRegionDataAccess.java |   143 -
 .../client/internal/ServerRegionProxy.java      |   878 -
 .../internal/SingleHopClientExecutor.java       |   415 -
 .../internal/SingleHopOperationCallable.java    |    83 -
 .../gemfire/cache/client/internal/SizeOp.java   |    92 -
 .../cache/client/internal/TXFailoverOp.java     |    93 -
 .../client/internal/TXSynchronizationOp.java    |   163 -
 .../internal/UnregisterInterestListOp.java      |   100 -
 .../client/internal/UnregisterInterestOp.java   |    98 -
 .../cache/client/internal/UserAttributes.java   |    59 -
 .../doc-files/ConnectionManagerImpl.dia         |   Bin 2034 -> 0 bytes
 .../doc-files/ConnectionManagerImpl.png         |   Bin 11825 -> 0 bytes
 .../client/internal/doc-files/PoolImpl.dia      |   Bin 3083 -> 0 bytes
 .../internal/doc-files/QueueManagerImpl.dia     |   Bin 2180 -> 0 bytes
 .../internal/doc-files/QueueManagerImpl.png     |   Bin 15075 -> 0 bytes
 .../doc-files/client_static_diagram.png         |   Bin 29430 -> 0 bytes
 .../locator/ClientConnectionRequest.java        |    68 -
 .../locator/ClientConnectionResponse.java       |    85 -
 .../locator/ClientReplacementRequest.java       |    75 -
 .../internal/locator/GetAllServersRequest.java  |    58 -
 .../internal/locator/GetAllServersResponse.java |    80 -
 .../internal/locator/LocatorListRequest.java    |    36 -
 .../internal/locator/LocatorListResponse.java   |    92 -
 .../internal/locator/LocatorStatusRequest.java  |    37 -
 .../internal/locator/LocatorStatusResponse.java |   321 -
 .../locator/QueueConnectionRequest.java         |    99 -
 .../locator/QueueConnectionResponse.java        |    87 -
 .../internal/locator/SerializationHelper.java   |   123 -
 .../internal/locator/ServerLocationRequest.java |    61 -
 .../locator/ServerLocationResponse.java         |    33 -
 .../locator/wan/LocatorMembershipListener.java  |    57 -
 .../gemfire/cache/client/internal/package.html  |    63 -
 .../pooling/ConnectionDestroyedException.java   |    48 -
 .../internal/pooling/ConnectionManager.java     |   132 -
 .../internal/pooling/ConnectionManagerImpl.java |  1587 --
 .../internal/pooling/PooledConnection.java      |   354 -
 .../gemstone/gemfire/cache/client/package.html  |    67 -
 .../gemfire/cache/control/RebalanceFactory.java |    66 -
 .../cache/control/RebalanceOperation.java       |    75 -
 .../gemfire/cache/control/RebalanceResults.java |   106 -
 .../gemfire/cache/control/ResourceManager.java  |   260 -
 .../gemstone/gemfire/cache/control/package.html |    23 -
 .../gemfire/cache/doc-files/architecture.fig    |   170 -
 .../gemfire/cache/doc-files/architecture.gif    |   Bin 9983 -> 0 bytes
 .../cache/doc-files/entry-life-cycle.fig        |    64 -
 .../cache/doc-files/entry-life-cycle.gif        |   Bin 3357 -> 0 bytes
 .../gemfire/cache/doc-files/example-cache.xml   |    98 -
 .../gemfire/cache/doc-files/example2-cache.xml  |    63 -
 .../gemfire/cache/doc-files/example3-cache.xml  |    60 -
 .../cache/doc-files/partitioned-regions.fig     |   267 -
 .../cache/doc-files/partitioned-regions.gif     |   Bin 9494 -> 0 bytes
 .../execute/EmtpyRegionFunctionException.java   |    64 -
 .../gemfire/cache/execute/Execution.java        |   224 -
 .../gemfire/cache/execute/Function.java         |   112 -
 .../gemfire/cache/execute/FunctionAdapter.java  |   124 -
 .../gemfire/cache/execute/FunctionContext.java  |    80 -
 .../cache/execute/FunctionException.java        |   129 -
 .../FunctionInvocationTargetException.java      |    93 -
 .../gemfire/cache/execute/FunctionService.java  |   371 -
 .../cache/execute/RegionFunctionContext.java    |    72 -
 .../gemfire/cache/execute/ResultCollector.java  |   136 -
 .../gemfire/cache/execute/ResultSender.java     |    93 -
 .../internal/FunctionServiceManager.java        |   460 -
 .../gemstone/gemfire/cache/execute/package.html |   162 -
 .../gemfire/cache/hdfs/HDFSIOException.java     |    53 -
 .../gemstone/gemfire/cache/hdfs/HDFSStore.java  |   343 -
 .../gemfire/cache/hdfs/HDFSStoreFactory.java    |   205 -
 .../gemfire/cache/hdfs/HDFSStoreMutator.java    |   197 -
 .../cache/hdfs/StoreExistsException.java        |    33 -
 .../cache/hdfs/internal/FailureTracker.java     |    97 -
 .../cache/hdfs/internal/FlushObserver.java      |    54 -
 .../hdfs/internal/HDFSBucketRegionQueue.java    |  1233 --
 .../cache/hdfs/internal/HDFSEntriesSet.java     |   329 -
 .../cache/hdfs/internal/HDFSEventListener.java  |   180 -
 .../hdfs/internal/HDFSEventQueueFilter.java     |    74 -
 .../hdfs/internal/HDFSGatewayEventImpl.java     |   181 -
 .../hdfs/internal/HDFSIntegrationUtil.java      |   118 -
 .../HDFSParallelGatewaySenderQueue.java         |   473 -
 .../hdfs/internal/HDFSStoreConfigHolder.java    |   560 -
 .../cache/hdfs/internal/HDFSStoreCreation.java  |   199 -
 .../hdfs/internal/HDFSStoreFactoryImpl.java     |    78 -
 .../cache/hdfs/internal/HDFSStoreImpl.java      |   639 -
 .../hdfs/internal/HDFSStoreMutatorImpl.java     |   200 -
 .../HDFSWriteOnlyStoreEventListener.java        |   185 -
 .../hdfs/internal/HoplogListenerForRegion.java  |    73 -
 .../cache/hdfs/internal/PersistedEventImpl.java |   203 -
 .../hdfs/internal/QueuedPersistentEvent.java    |    27 -
 .../hdfs/internal/SignalledFlushObserver.java   |   123 -
 .../internal/SortedHDFSQueuePersistedEvent.java |    87 -
 .../internal/SortedHoplogPersistedEvent.java    |   115 -
 .../UnsortedHDFSQueuePersistedEvent.java        |    77 -
 .../internal/UnsortedHoplogPersistedEvent.java  |    93 -
 .../hdfs/internal/hoplog/AbstractHoplog.java    |   357 -
 .../hoplog/AbstractHoplogOrganizer.java         |   430 -
 .../cache/hdfs/internal/hoplog/BloomFilter.java |    36 -
 .../hoplog/CloseTmpHoplogsTimerTask.java        |   109 -
 .../hdfs/internal/hoplog/CompactionStatus.java  |    73 -
 .../cache/hdfs/internal/hoplog/FlushStatus.java |    73 -
 .../internal/hoplog/HDFSCompactionManager.java  |   330 -
 .../internal/hoplog/HDFSFlushQueueArgs.java     |    94 -
 .../internal/hoplog/HDFSFlushQueueFunction.java |   287 -
 .../hoplog/HDFSForceCompactionArgs.java         |   108 -
 .../hoplog/HDFSForceCompactionFunction.java     |   130 -
 .../HDFSForceCompactionResultCollector.java     |   132 -
 .../hoplog/HDFSLastCompactionTimeFunction.java  |    57 -
 .../internal/hoplog/HDFSRegionDirector.java     |   480 -
 .../hdfs/internal/hoplog/HDFSStoreDirector.java |    79 -
 .../hoplog/HDFSUnsortedHoplogOrganizer.java     |   448 -
 .../hdfs/internal/hoplog/HFileSortedOplog.java  |   853 -
 .../hoplog/HdfsSortedOplogOrganizer.java        |  2007 --
 .../cache/hdfs/internal/hoplog/Hoplog.java      |   264 -
 .../hdfs/internal/hoplog/HoplogConfig.java      |    75 -
 .../hdfs/internal/hoplog/HoplogListener.java    |    47 -
 .../hdfs/internal/hoplog/HoplogOrganizer.java   |   123 -
 .../hdfs/internal/hoplog/HoplogSetIterator.java |   166 -
 .../hdfs/internal/hoplog/HoplogSetReader.java   |   114 -
 .../internal/hoplog/SequenceFileHoplog.java     |   396 -
 .../hoplog/mapred/AbstractGFRecordReader.java   |   106 -
 .../internal/hoplog/mapred/GFInputFormat.java   |    95 -
 .../internal/hoplog/mapred/GFOutputFormat.java  |    76 -
 .../mapreduce/AbstractGFRecordReader.java       |   140 -
 .../hoplog/mapreduce/GFInputFormat.java         |   124 -
 .../hdfs/internal/hoplog/mapreduce/GFKey.java   |    72 -
 .../hoplog/mapreduce/GFOutputFormat.java        |   199 -
 .../hoplog/mapreduce/HDFSSplitIterator.java     |   198 -
 .../internal/hoplog/mapreduce/HoplogUtil.java   |   464 -
 .../hoplog/mapreduce/RWSplitIterator.java       |    49 -
 .../hoplog/mapreduce/StreamSplitIterator.java   |    47 -
 .../org/apache/hadoop/io/SequenceFile.java      |  3726 ----
 .../operations/CloseCQOperationContext.java     |    65 -
 .../operations/DestroyOperationContext.java     |    63 -
 .../operations/ExecuteCQOperationContext.java   |    68 -
 .../ExecuteFunctionOperationContext.java        |    97 -
 .../GetDurableCQsOperationContext.java          |    60 -
 .../cache/operations/GetOperationContext.java   |    91 -
 .../operations/InterestOperationContext.java    |    84 -
 .../gemfire/cache/operations/InterestType.java  |   152 -
 .../operations/InvalidateOperationContext.java  |    64 -
 .../cache/operations/KeyOperationContext.java   |   125 -
 .../operations/KeySetOperationContext.java      |    97 -
 .../operations/KeyValueOperationContext.java    |   177 -
 .../cache/operations/OperationContext.java      |   521 -
 .../operations/PutAllOperationContext.java      |   407 -
 .../cache/operations/PutOperationContext.java   |   144 -
 .../cache/operations/QueryOperationContext.java |   172 -
 .../operations/RegionClearOperationContext.java |    51 -
 .../RegionCreateOperationContext.java           |    61 -
 .../RegionDestroyOperationContext.java          |    51 -
 .../operations/RegionOperationContext.java      |    87 -
 .../RegisterInterestOperationContext.java       |    72 -
 .../operations/RemoveAllOperationContext.java   |   101 -
 .../operations/StopCQOperationContext.java      |    66 -
 .../UnregisterInterestOperationContext.java     |    54 -
 .../internal/GetOperationContextImpl.java       |   124 -
 .../gemfire/cache/operations/package.html       |   107 -
 .../com/gemstone/gemfire/cache/package.html     |   608 -
 .../cache/partition/PartitionListener.java      |   132 -
 .../partition/PartitionListenerAdapter.java     |    50 -
 .../cache/partition/PartitionMemberInfo.java    |    74 -
 .../PartitionNotAvailableException.java         |    66 -
 .../cache/partition/PartitionRebalanceInfo.java |   150 -
 .../cache/partition/PartitionRegionHelper.java  |   552 -
 .../cache/partition/PartitionRegionInfo.java    |   113 -
 .../gemfire/cache/partition/package.html        |    23 -
 .../ConflictingPersistentDataException.java     |    57 -
 .../persistence/PartitionOfflineException.java  |    77 -
 .../gemfire/cache/persistence/PersistentID.java |    59 -
 .../PersistentReplicatesOfflineException.java   |    44 -
 .../persistence/RevokeFailedException.java      |    51 -
 .../RevokedPersistentDataException.java         |    58 -
 .../gemfire/cache/query/Aggregator.java         |    46 -
 .../cache/query/AmbiguousNameException.java     |    47 -
 .../gemfire/cache/query/CqAttributes.java       |    50 -
 .../cache/query/CqAttributesFactory.java        |   319 -
 .../cache/query/CqAttributesMutator.java        |    57 -
 .../gemfire/cache/query/CqClosedException.java  |    57 -
 .../gemstone/gemfire/cache/query/CqEvent.java   |    93 -
 .../gemfire/cache/query/CqException.java        |    57 -
 .../gemfire/cache/query/CqExistsException.java  |    53 -
 .../gemfire/cache/query/CqListener.java         |    59 -
 .../gemstone/gemfire/cache/query/CqQuery.java   |   155 -
 .../gemstone/gemfire/cache/query/CqResults.java |    51 -
 .../cache/query/CqServiceStatistics.java        |    70 -
 .../gemstone/gemfire/cache/query/CqState.java   |    55 -
 .../gemfire/cache/query/CqStatistics.java       |    53 -
 .../gemfire/cache/query/CqStatusListener.java   |    42 -
 .../cache/query/FunctionDomainException.java    |    36 -
 .../com/gemstone/gemfire/cache/query/Index.java |   112 -
 .../cache/query/IndexCreationException.java     |    46 -
 .../cache/query/IndexExistsException.java       |    52 -
 .../cache/query/IndexInvalidException.java      |    64 -
 .../cache/query/IndexMaintenanceException.java  |    66 -
 .../cache/query/IndexNameConflictException.java |    52 -
 .../gemfire/cache/query/IndexStatistics.java    |    76 -
 .../gemstone/gemfire/cache/query/IndexType.java |   106 -
 .../query/MultiIndexCreationException.java      |    82 -
 .../cache/query/NameNotFoundException.java      |    48 -
 .../cache/query/NameResolutionException.java    |    47 -
 .../query/ParameterCountInvalidException.java   |    38 -
 .../com/gemstone/gemfire/cache/query/Query.java |   328 -
 .../gemfire/cache/query/QueryException.java     |    66 -
 .../query/QueryExecutionLowMemoryException.java |    67 -
 .../query/QueryExecutionTimeoutException.java   |    62 -
 .../cache/query/QueryInvalidException.java      |    48 -
 .../query/QueryInvocationTargetException.java   |    54 -
 .../gemfire/cache/query/QueryService.java       |   852 -
 .../gemfire/cache/query/QueryStatistics.java    |    38 -
 .../cache/query/RegionNotFoundException.java    |    45 -
 .../gemfire/cache/query/SelectResults.java      |   122 -
 .../gemstone/gemfire/cache/query/Struct.java    |    59 -
 .../cache/query/TypeMismatchException.java      |    45 -
 .../query/internal/AbstractCompiledValue.java   |   323 -
 .../internal/AbstractGroupOrRangeJunction.java  |   596 -
 .../cache/query/internal/AllGroupJunction.java  |   276 -
 .../query/internal/AttributeDescriptor.java     |   420 -
 .../gemfire/cache/query/internal/Bag.java       |   726 -
 .../internal/CompiledAggregateFunction.java     |   185 -
 .../query/internal/CompiledBindArgument.java    |   100 -
 .../query/internal/CompiledComparison.java      |   877 -
 .../query/internal/CompiledConstruction.java    |    78 -
 .../cache/query/internal/CompiledFunction.java  |   117 -
 .../query/internal/CompiledGroupBySelect.java   |   522 -
 .../cache/query/internal/CompiledID.java        |    99 -
 .../cache/query/internal/CompiledIn.java        |   965 -
 .../query/internal/CompiledIndexOperation.java  |   183 -
 .../query/internal/CompiledIteratorDef.java     |   379 -
 .../cache/query/internal/CompiledJunction.java  |  1254 --
 .../cache/query/internal/CompiledLike.java      |   548 -
 .../cache/query/internal/CompiledLiteral.java   |    85 -
 .../cache/query/internal/CompiledNegation.java  |    79 -
 .../cache/query/internal/CompiledOperation.java |   331 -
 .../cache/query/internal/CompiledPath.java      |   177 -
 .../cache/query/internal/CompiledRegion.java    |   111 -
 .../cache/query/internal/CompiledSelect.java    |  1590 --
 .../query/internal/CompiledSortCriterion.java   |   320 -
 .../query/internal/CompiledUnaryMinus.java      |   102 -
 .../cache/query/internal/CompiledUndefined.java |   320 -
 .../cache/query/internal/CompiledValue.java     |   143 -
 .../query/internal/CompositeGroupJunction.java  |   555 -
 .../gemfire/cache/query/internal/CqEntry.java   |   112 -
 .../cache/query/internal/CqQueryVsdStats.java   |   342 -
 .../cache/query/internal/CqStateImpl.java       |   104 -
 .../internal/CumulativeNonDistinctResults.java  |   391 -
 .../cache/query/internal/DefaultQuery.java      |  1141 --
 .../query/internal/DefaultQueryService.java     |  1003 -
 .../cache/query/internal/DerivedInfo.java       |   306 -
 .../cache/query/internal/ExecutionContext.java  |   736 -
 .../gemfire/cache/query/internal/Filter.java    |   178 -
 .../gemfire/cache/query/internal/Functions.java |   206 -
 .../cache/query/internal/GroupJunction.java     |   193 -
 .../cache/query/internal/HashingStrategy.java   |    55 -
 .../gemfire/cache/query/internal/IndexInfo.java |    78 -
 .../internal/IndexTrackingQueryObserver.java    |   217 -
 .../cache/query/internal/IndexUpdater.java      |   123 -
 .../gemfire/cache/query/internal/Indexable.java |    55 -
 .../cache/query/internal/LinkedResultSet.java   |   145 -
 .../cache/query/internal/LinkedStructSet.java   |   367 -
 .../cache/query/internal/MapIndexable.java      |    26 -
 .../cache/query/internal/MethodDispatch.java    |   232 -
 .../cache/query/internal/NWayMergeResults.java  |   546 -
 .../gemfire/cache/query/internal/Negatable.java |    26 -
 .../gemfire/cache/query/internal/NullToken.java |    77 -
 .../cache/query/internal/ObjectIntHashMap.java  |  1141 --
 .../cache/query/internal/OrderByComparator.java |   237 -
 .../internal/OrderByComparatorUnmapped.java     |    90 -
 .../gemfire/cache/query/internal/Ordered.java   |    44 -
 .../cache/query/internal/OrganizedOperands.java |    55 -
 .../cache/query/internal/PRQueryTraceInfo.java  |   109 -
 .../gemfire/cache/query/internal/PathUtils.java |   269 -
 .../gemfire/cache/query/internal/PlanInfo.java  |    36 -
 .../cache/query/internal/ProxyQueryService.java |   451 -
 .../gemfire/cache/query/internal/QCompiler.java |   698 -
 .../gemfire/cache/query/internal/QRegion.java   |   539 -
 .../gemfire/cache/query/internal/QScope.java    |    92 -
 .../QueryExecutionCanceledException.java        |    63 -
 .../query/internal/QueryExecutionContext.java   |   242 -
 .../cache/query/internal/QueryExecutor.java     |    40 -
 .../cache/query/internal/QueryMonitor.java      |   361 -
 .../cache/query/internal/QueryObserver.java     |   338 -
 .../query/internal/QueryObserverAdapter.java    |   341 -
 .../query/internal/QueryObserverHolder.java     |    84 -
 .../cache/query/internal/QueryUtils.java        |  2079 --
 .../cache/query/internal/RangeJunction.java     |  1255 --
 .../cache/query/internal/ResultsBag.java        |   276 -
 .../ResultsCollectionCopyOnReadWrapper.java     |   228 -
 ...ResultsCollectionPdxDeserializerWrapper.java |   219 -
 .../internal/ResultsCollectionWrapper.java      |   664 -
 .../cache/query/internal/ResultsSet.java        |   150 -
 .../cache/query/internal/RuntimeIterator.java   |   338 -
 .../query/internal/SelectResultsComparator.java |    61 -
 .../cache/query/internal/SortedResultSet.java   |   134 -
 .../cache/query/internal/SortedResultsBag.java  |   260 -
 .../cache/query/internal/SortedStructBag.java   |   369 -
 .../cache/query/internal/SortedStructSet.java   |   385 -
 .../gemfire/cache/query/internal/StructBag.java |   474 -
 .../cache/query/internal/StructFields.java      |    42 -
 .../cache/query/internal/StructImpl.java        |   183 -
 .../gemfire/cache/query/internal/StructSet.java |   459 -
 .../gemfire/cache/query/internal/Support.java   |    95 -
 .../gemfire/cache/query/internal/Undefined.java |    87 -
 .../internal/aggregate/AbstractAggregator.java  |    47 -
 .../cache/query/internal/aggregate/Avg.java     |    50 -
 .../query/internal/aggregate/AvgBucketNode.java |    49 -
 .../query/internal/aggregate/AvgDistinct.java   |    43 -
 .../aggregate/AvgDistinctPRQueryNode.java       |    35 -
 .../internal/aggregate/AvgPRQueryNode.java      |    47 -
 .../cache/query/internal/aggregate/Count.java   |    49 -
 .../query/internal/aggregate/CountDistinct.java |    33 -
 .../aggregate/CountDistinctPRQueryNode.java     |    44 -
 .../internal/aggregate/CountPRQueryNode.java    |    48 -
 .../internal/aggregate/DistinctAggregator.java  |    56 -
 .../cache/query/internal/aggregate/MaxMin.java  |    68 -
 .../cache/query/internal/aggregate/Sum.java     |    48 -
 .../query/internal/aggregate/SumDistinct.java   |    35 -
 .../aggregate/SumDistinctPRQueryNode.java       |    46 -
 .../cache/query/internal/cq/ClientCQ.java       |    42 -
 .../cache/query/internal/cq/CqService.java      |   263 -
 .../query/internal/cq/CqServiceProvider.java    |    72 -
 .../query/internal/cq/InternalCqQuery.java      |    82 -
 .../query/internal/cq/MissingCqService.java     |   217 -
 .../internal/cq/MissingCqServiceStatistics.java |    52 -
 .../cache/query/internal/cq/ServerCQ.java       |    87 -
 .../query/internal/cq/spi/CqServiceFactory.java |    36 -
 .../query/internal/index/AbstractIndex.java     |  2405 ---
 .../query/internal/index/AbstractMapIndex.java  |   440 -
 .../internal/index/CompactMapRangeIndex.java    |   216 -
 .../query/internal/index/CompactRangeIndex.java |  1799 --
 .../query/internal/index/DummyQRegion.java      |   252 -
 .../index/FunctionalIndexCreationHelper.java    |   721 -
 .../cache/query/internal/index/HashIndex.java   |  1573 --
 .../query/internal/index/HashIndexSet.java      |   818 -
 .../query/internal/index/IMQException.java      |    59 -
 .../internal/index/IndexConcurrentHashSet.java  |    78 -
 .../query/internal/index/IndexCreationData.java |   166 -
 .../internal/index/IndexCreationHelper.java     |   113 -
 .../cache/query/internal/index/IndexData.java   |    72 -
 .../query/internal/index/IndexElemArray.java    |   361 -
 .../query/internal/index/IndexManager.java      |  1721 --
 .../query/internal/index/IndexProtocol.java     |   222 -
 .../cache/query/internal/index/IndexStats.java  |   223 -
 .../cache/query/internal/index/IndexStore.java  |   153 -
 .../cache/query/internal/index/IndexUtils.java  |   135 -
 .../index/IndexedExpressionEvaluator.java       |    52 -
 .../query/internal/index/MapIndexStore.java     |   336 -
 .../query/internal/index/MapRangeIndex.java     |   195 -
 .../query/internal/index/MemoryIndexStore.java  |   822 -
 .../query/internal/index/PartitionedIndex.java  |   656 -
 .../query/internal/index/PrimaryKeyIndex.java   |   392 -
 .../index/PrimaryKeyIndexCreationHelper.java    |   135 -
 .../cache/query/internal/index/RangeIndex.java  |  1686 --
 .../cache/query/internal/index/package.html     |   646 -
 .../gemfire/cache/query/internal/package.html   |    43 -
 .../query/internal/parse/ASTAggregateFunc.java  |    66 -
 .../cache/query/internal/parse/ASTAnd.java      |    39 -
 .../query/internal/parse/ASTCombination.java    |    46 -
 .../query/internal/parse/ASTCompareOp.java      |    38 -
 .../query/internal/parse/ASTConstruction.java   |    45 -
 .../query/internal/parse/ASTConversionExpr.java |    42 -
 .../cache/query/internal/parse/ASTDummy.java    |    39 -
 .../cache/query/internal/parse/ASTGroupBy.java  |    44 -
 .../cache/query/internal/parse/ASTHint.java     |    52 -
 .../query/internal/parse/ASTHintIdentifier.java |    52 -
 .../query/internal/parse/ASTIdentifier.java     |    42 -
 .../cache/query/internal/parse/ASTImport.java   |    57 -
 .../cache/query/internal/parse/ASTIn.java       |    43 -
 .../query/internal/parse/ASTIteratorDef.java    |    79 -
 .../cache/query/internal/parse/ASTLike.java     |    47 -
 .../cache/query/internal/parse/ASTLimit.java    |    41 -
 .../cache/query/internal/parse/ASTLiteral.java  |   232 -
 .../internal/parse/ASTMethodInvocation.java     |    68 -
 .../cache/query/internal/parse/ASTOr.java       |    38 -
 .../cache/query/internal/parse/ASTOrderBy.java  |    44 -
 .../query/internal/parse/ASTParameter.java      |    40 -
 .../cache/query/internal/parse/ASTPostfix.java  |    70 -
 .../query/internal/parse/ASTProjection.java     |    48 -
 .../query/internal/parse/ASTRegionPath.java     |    41 -
 .../cache/query/internal/parse/ASTSelect.java   |    68 -
 .../query/internal/parse/ASTSortCriterion.java  |    44 -
 .../cache/query/internal/parse/ASTTrace.java    |    41 -
 .../cache/query/internal/parse/ASTType.java     |    67 -
 .../cache/query/internal/parse/ASTTypeCast.java |    44 -
 .../cache/query/internal/parse/ASTUnary.java    |    65 -
 .../query/internal/parse/ASTUndefinedExpr.java  |    42 -
 .../query/internal/parse/ASTUnsupported.java    |    45 -
 .../cache/query/internal/parse/GemFireAST.java  |    61 -
 .../cache/query/internal/parse/OQLLexer.java    |  2265 ---
 .../internal/parse/OQLLexerTokenTypes.java      |   155 -
 .../query/internal/parse/OQLLexerTokenTypes.txt |   147 -
 .../cache/query/internal/parse/OQLParser.java   |  3833 ----
 .../cache/query/internal/parse/UtilParser.java  |    92 -
 .../cache/query/internal/parse/fixantlr.sh      |    52 -
 .../gemfire/cache/query/internal/parse/oql.g    |  1195 --
 .../internal/types/CollectionTypeImpl.java      |   126 -
 .../types/ExtendedNumericComparator.java        |    52 -
 .../cache/query/internal/types/MapTypeImpl.java |   100 -
 .../query/internal/types/NumericComparator.java |    96 -
 .../query/internal/types/ObjectTypeImpl.java    |   100 -
 .../query/internal/types/StructTypeImpl.java    |   160 -
 .../internal/types/TemporalComparator.java      |    77 -
 .../cache/query/internal/types/TypeUtils.java   |   476 -
 .../query/internal/utils/LimitIterator.java     |    63 -
 .../cache/query/internal/utils/PDXUtils.java    |    95 -
 .../gemstone/gemfire/cache/query/package.html   |   708 -
 .../cache/query/types/CollectionType.java       |    47 -
 .../gemfire/cache/query/types/MapType.java      |    42 -
 .../gemfire/cache/query/types/ObjectType.java   |    60 -
 .../gemfire/cache/query/types/StructType.java   |    52 -
 .../gemfire/cache/server/CacheServer.java       |   512 -
 .../cache/server/ClientSubscriptionConfig.java  |   148 -
 .../gemfire/cache/server/ServerLoad.java        |   187 -
 .../gemfire/cache/server/ServerLoadProbe.java   |    75 -
 .../cache/server/ServerLoadProbeAdapter.java    |    43 -
 .../gemfire/cache/server/ServerMetrics.java     |    53 -
 .../server/internal/ConnectionCountProbe.java   |    94 -
 .../cache/server/internal/LoadMonitor.java      |   242 -
 .../server/internal/ServerMetricsImpl.java      |    79 -
 .../gemstone/gemfire/cache/server/package.html  |    42 -
 .../cache/snapshot/CacheSnapshotService.java    |   149 -
 .../cache/snapshot/RegionSnapshotService.java   |   140 -
 .../gemfire/cache/snapshot/SnapshotFilter.java  |    45 -
 .../cache/snapshot/SnapshotIterator.java        |    62 -
 .../gemfire/cache/snapshot/SnapshotOptions.java |    62 -
 .../gemfire/cache/snapshot/SnapshotReader.java  |    58 -
 .../gemfire/cache/snapshot/package.html         |    54 -
 .../cache/util/BoundedLinkedHashMap.java        |    88 -
 .../cache/util/CacheListenerAdapter.java        |    67 -
 .../gemfire/cache/util/CacheWriterAdapter.java  |    54 -
 .../gemfire/cache/util/CqListenerAdapter.java   |    66 -
 .../gemstone/gemfire/cache/util/Gateway.java    |    53 -
 .../cache/util/GatewayConflictHelper.java       |    34 -
 .../cache/util/GatewayConflictResolver.java     |    48 -
 .../gemfire/cache/util/GatewayEvent.java        |    91 -
 .../gemfire/cache/util/ObjectSizer.java         |    83 -
 .../gemfire/cache/util/ObjectSizerImpl.java     |    35 -
 .../util/RegionMembershipListenerAdapter.java   |    44 -
 .../cache/util/RegionRoleListenerAdapter.java   |    40 -
 .../cache/util/TimestampedEntryEvent.java       |    40 -
 .../cache/util/TransactionListenerAdapter.java  |    43 -
 .../gemstone/gemfire/cache/util/package.html    |    31 -
 .../gemfire/cache/wan/EventSequenceID.java      |   104 -
 .../gemfire/cache/wan/GatewayEventFilter.java   |    64 -
 .../wan/GatewayEventSubstitutionFilter.java     |    40 -
 .../gemfire/cache/wan/GatewayQueueEvent.java    |    81 -
 .../gemfire/cache/wan/GatewayReceiver.java      |   174 -
 .../cache/wan/GatewayReceiverFactory.java       |   122 -
 .../gemfire/cache/wan/GatewaySender.java        |   415 -
 .../gemfire/cache/wan/GatewaySenderFactory.java |   239 -
 .../cache/wan/GatewayTransportFilter.java       |    27 -
 .../compression/CompressionException.java       |    43 -
 .../gemfire/compression/Compressor.java         |    48 -
 .../gemfire/compression/SnappyCompressor.java   |   110 -
 .../gemfire/distributed/AbstractLauncher.java   |   926 -
 .../distributed/ClientSocketFactory.java        |    47 -
 .../distributed/DistributedLockService.java     |   393 -
 .../gemfire/distributed/DistributedMember.java  |    80 -
 .../gemfire/distributed/DistributedSystem.java  |  2207 ---
 .../DistributedSystemDisconnectedException.java |    47 -
 .../distributed/DurableClientAttributes.java    |   147 -
 .../distributed/FutureCancelledException.java   |    47 -
 .../distributed/GatewayCancelledException.java  |    46 -
 .../distributed/LeaseExpiredException.java      |    38 -
 .../gemstone/gemfire/distributed/Locator.java   |   553 -
 .../gemfire/distributed/LocatorLauncher.java    |  2051 --
 .../distributed/LockNotHeldException.java       |    51 -
 .../LockServiceDestroyedException.java          |    51 -
 .../distributed/OplogCancelledException.java    |    47 -
 .../distributed/PoolCancelledException.java     |    47 -
 .../com/gemstone/gemfire/distributed/Role.java  |    56 -
 .../gemfire/distributed/ServerLauncher.java     |  2613 ---
 .../TXManagerCancelledException.java            |    47 -
 .../internal/AbstractDistributionConfig.java    |  1161 --
 .../distributed/internal/AdminMessageType.java  |    23 -
 .../internal/AtomicLongWithTerminalState.java   |    67 -
 .../internal/CollectingReplyProcessor.java      |    56 -
 .../distributed/internal/ConfigAttribute.java   |    36 -
 .../internal/ConfigAttributeChecker.java        |    31 -
 .../internal/ConfigAttributeDesc.java           |    31 -
 .../internal/ConfigAttributeGetter.java         |    31 -
 .../internal/ConfigAttributeSetter.java         |    31 -
 .../distributed/internal/ConflationKey.java     |    78 -
 .../gemfire/distributed/internal/DM.java        |   467 -
 .../gemfire/distributed/internal/DMStats.java   |   622 -
 .../gemfire/distributed/internal/DSClock.java   |   313 -
 .../internal/DirectReplyProcessor.java          |   172 -
 .../internal/DistributionAdvisee.java           |    93 -
 .../internal/DistributionAdvisor.java           |  1678 --
 .../internal/DistributionChannel.java           |   166 -
 .../internal/DistributionConfig.java            |  3778 ----
 .../internal/DistributionConfigImpl.java        |  3533 ----
 .../internal/DistributionConfigSnapshot.java    |    71 -
 .../internal/DistributionException.java         |    37 -
 .../internal/DistributionManager.java           |  4811 -----
 .../internal/DistributionMessage.java           |   711 -
 .../internal/DistributionMessageObserver.java   |    75 -
 .../distributed/internal/DistributionStats.java |  2065 --
 .../distributed/internal/FlowControlParams.java |   114 -
 .../FunctionExecutionPooledExecutor.java        |   311 -
 .../distributed/internal/HealthMonitor.java     |    46 -
 .../distributed/internal/HealthMonitorImpl.java |   148 -
 .../internal/HighPriorityAckedMessage.java      |   235 -
 .../HighPriorityDistributionMessage.java        |    31 -
 .../distributed/internal/IgnoredByManager.java  |    26 -
 .../internal/InternalDistributedSystem.java     |  3079 ---
 .../distributed/internal/InternalLocator.java   |  1488 --
 .../internal/LocatorLoadSnapshot.java           |   695 -
 .../distributed/internal/LocatorStats.java      |   245 -
 .../internal/LonerDistributionManager.java      |  1001 -
 .../gemfire/distributed/internal/MQueue.java    |    32 -
 .../internal/MembershipListener.java            |    77 -
 .../distributed/internal/MessageFactory.java    |    56 -
 .../distributed/internal/MessageWithReply.java  |    43 -
 .../internal/OverflowQueueWithDMStats.java      |   174 -
 .../distributed/internal/PoolStatHelper.java    |    38 -
 .../internal/PooledDistributionMessage.java     |    34 -
 .../internal/PooledExecutorWithDMStats.java     |   234 -
 .../distributed/internal/ProcessorKeeper21.java |   129 -
 .../distributed/internal/ProductUseLog.java     |   147 -
 .../distributed/internal/ProfileListener.java   |    55 -
 .../distributed/internal/QueueStatHelper.java   |    42 -
 .../internal/ReliableReplyException.java        |    37 -
 .../internal/ReliableReplyProcessor21.java      |   116 -
 .../distributed/internal/ReplyException.java    |   201 -
 .../distributed/internal/ReplyMessage.java      |   364 -
 .../distributed/internal/ReplyProcessor21.java  |  1298 --
 .../distributed/internal/ReplySender.java       |    39 -
 .../distributed/internal/ResourceEvent.java     |    52 -
 .../internal/ResourceEventsListener.java        |    38 -
 .../internal/RuntimeDistributionConfigImpl.java |   138 -
 .../internal/SerialAckedMessage.java            |   159 -
 .../internal/SerialDistributionMessage.java     |    34 -
 .../SerialQueuedExecutorWithDMStats.java        |    51 -
 .../distributed/internal/ServerLocation.java    |   178 -
 .../distributed/internal/ServerLocator.java     |   486 -
 .../internal/SharedConfiguration.java           |   955 -
 .../distributed/internal/ShutdownMessage.java   |   121 -
 .../gemfire/distributed/internal/Sizeable.java  |    28 -
 .../distributed/internal/SizeableRunnable.java  |    39 -
 .../distributed/internal/StartupMessage.java    |   433 -
 .../internal/StartupMessageData.java            |   231 -
 .../internal/StartupMessageReplyProcessor.java  |   118 -
 .../distributed/internal/StartupOperation.java  |   136 -
 .../internal/StartupResponseMessage.java        |   294 -
 .../StartupResponseWithVersionMessage.java      |   108 -
 .../internal/ThrottledMemQueueStatHelper.java   |    49 -
 .../internal/ThrottledQueueStatHelper.java      |    39 -
 .../ThrottlingMemLinkedQueueWithDMStats.java    |   165 -
 .../internal/WaitForViewInstallation.java       |   126 -
 .../internal/WanLocatorDiscoverer.java          |    31 -
 .../deadlock/DLockDependencyMonitor.java        |   147 -
 .../internal/deadlock/DeadlockDetector.java     |   395 -
 .../internal/deadlock/Dependency.java           |    88 -
 .../internal/deadlock/DependencyGraph.java      |   340 -
 .../internal/deadlock/DependencyMonitor.java    |    45 -
 .../deadlock/DependencyMonitorManager.java      |   107 -
 .../deadlock/GemFireDeadlockDetector.java       |   142 -
 .../internal/deadlock/LocalLockInfo.java        |   101 -
 .../internal/deadlock/LocalThread.java          |   120 -
 .../deadlock/MessageDependencyMonitor.java      |   155 -
 .../internal/deadlock/ThreadReference.java      |    28 -
 .../internal/deadlock/UnsafeThreadLocal.java    |    92 -
 .../internal/direct/DirectChannel.java          |   939 -
 .../internal/direct/DirectChannelListener.java  |    38 -
 .../internal/direct/ShunnedMemberException.java |    34 -
 .../internal/distribution-overview.html         |    42 -
 .../internal/doc-files/config-classes.fig       |   138 -
 .../internal/doc-files/config-classes.gif       |   Bin 4205 -> 0 bytes
 .../doc-files/distribution-managers.fig         |    76 -
 .../doc-files/distribution-managers.gif         |   Bin 3267 -> 0 bytes
 .../internal/locks/Collaboration.java           |   454 -
 .../distributed/internal/locks/DLockBatch.java  |    46 -
 .../internal/locks/DLockBatchId.java            |    31 -
 .../internal/locks/DLockGrantor.java            |  3796 ----
 .../locks/DLockLessorDepartureHandler.java      |    35 -
 .../internal/locks/DLockQueryProcessor.java     |   519 -
 .../locks/DLockRecoverGrantorProcessor.java     |   460 -
 .../internal/locks/DLockReleaseProcessor.java   |   450 -
 .../internal/locks/DLockRemoteToken.java        |   235 -
 .../internal/locks/DLockRequestProcessor.java   |  1284 --
 .../internal/locks/DLockService.java            |  3377 ----
 .../distributed/internal/locks/DLockStats.java  |   887 -
 .../distributed/internal/locks/DLockToken.java  |   572 -
 .../internal/locks/DeposeGrantorProcessor.java  |   210 -
 .../internal/locks/DistributedLockStats.java    |   201 -
 .../internal/locks/DistributedMemberLock.java   |   297 -
 .../internal/locks/DummyDLockStats.java         |   180 -
 .../internal/locks/ElderInitProcessor.java      |   314 -
 .../distributed/internal/locks/ElderState.java  |   399 -
 .../distributed/internal/locks/GrantorInfo.java |    87 -
 .../internal/locks/GrantorRequestProcessor.java |   751 -
 .../locks/LockGrantorDestroyedException.java    |    51 -
 .../internal/locks/LockGrantorId.java           |   243 -
 .../locks/NonGrantorDestroyedProcessor.java     |   308 -
 .../internal/locks/RemoteThread.java            |    88 -
 .../internal/locks/doc-files/elder.fig          |    84 -
 .../internal/locks/doc-files/elder.jpg          |   Bin 55182 -> 0 bytes
 .../internal/locks/doc-files/turks.fig          |   128 -
 .../internal/locks/doc-files/turks.jpg          |   Bin 79859 -> 0 bytes
 .../distributed/internal/locks/package.html     |   313 -
 .../DistributedMembershipListener.java          |    86 -
 .../membership/InternalDistributedMember.java   |  1304 --
 .../internal/membership/InternalRole.java       |   169 -
 .../internal/membership/MemberAttributes.java   |   124 -
 .../internal/membership/MemberFactory.java      |   109 -
 .../internal/membership/MemberServices.java     |    90 -
 .../internal/membership/MembershipManager.java  |   326 -
 .../internal/membership/MembershipTestHook.java |    40 -
 .../internal/membership/NetMember.java          |    82 -
 .../internal/membership/NetView.java            |   614 -
 .../internal/membership/QuorumChecker.java      |    63 -
 .../internal/membership/gms/GMSMember.java      |   458 -
 .../membership/gms/GMSMemberFactory.java        |   133 -
 .../internal/membership/gms/GMSUtil.java        |   159 -
 .../internal/membership/gms/NetLocator.java     |    32 -
 .../internal/membership/gms/ServiceConfig.java  |   187 -
 .../internal/membership/gms/Services.java       |   387 -
 .../internal/membership/gms/SuspectMember.java  |    58 -
 .../membership/gms/auth/GMSAuthenticator.java   |   235 -
 .../membership/gms/fd/GMSHealthMonitor.java     |  1380 --
 .../gms/interfaces/Authenticator.java           |    27 -
 .../gms/interfaces/HealthMonitor.java           |    64 -
 .../membership/gms/interfaces/JoinLeave.java    |    73 -
 .../membership/gms/interfaces/Locator.java      |    32 -
 .../membership/gms/interfaces/Manager.java      |   120 -
 .../gms/interfaces/MessageHandler.java          |    30 -
 .../membership/gms/interfaces/Messenger.java    |    81 -
 .../membership/gms/interfaces/Service.java      |    83 -
 .../gms/locator/FindCoordinatorRequest.java     |   148 -
 .../gms/locator/FindCoordinatorResponse.java    |   161 -
 .../membership/gms/locator/GMSLocator.java      |   373 -
 .../membership/gms/locator/GetViewRequest.java  |    49 -
 .../membership/gms/locator/GetViewResponse.java |    64 -
 .../gms/locator/PeerLocatorRequest.java         |    25 -
 .../membership/gms/membership/GMSJoinLeave.java |  2312 ---
 .../membership/gms/messages/HasMemberID.java    |    25 -
 .../gms/messages/HeartbeatMessage.java          |    74 -
 .../gms/messages/HeartbeatRequestMessage.java   |    80 -
 .../gms/messages/InstallViewMessage.java        |   106 -
 .../gms/messages/JoinRequestMessage.java        |    97 -
 .../gms/messages/JoinResponseMessage.java       |   129 -
 .../gms/messages/LeaveRequestMessage.java       |    94 -
 .../gms/messages/NetworkPartitionMessage.java   |    44 -
 .../gms/messages/RemoveMemberMessage.java       |    96 -
 .../gms/messages/SuspectMembersMessage.java     |    91 -
 .../membership/gms/messages/SuspectRequest.java |    72 -
 .../membership/gms/messages/ViewAckMessage.java |   103 -
 .../gms/messenger/AddressManager.java           |   121 -
 .../membership/gms/messenger/GMSPingPonger.java |    65 -
 .../gms/messenger/GMSQuorumChecker.java         |   274 -
 .../membership/gms/messenger/JGAddress.java     |   221 -
 .../gms/messenger/JGroupsMessenger.java         |  1116 --
 .../membership/gms/messenger/StatRecorder.java  |   162 -
 .../membership/gms/messenger/Transport.java     |   163 -
 .../gms/mgr/GMSMembershipManager.java           |  2652 ---
 .../membership/gms/mgr/LocalViewMessage.java    |    85 -
 .../internal/membership/gms/package.html        |    57 -
 .../gemfire/distributed/internal/package.html   |    55 -
 .../internal/streaming/StreamingOperation.java  |   613 -
 .../internal/tcpserver/InfoRequest.java         |    41 -
 .../internal/tcpserver/InfoResponse.java        |    56 -
 .../internal/tcpserver/ShutdownRequest.java     |    39 -
 .../internal/tcpserver/ShutdownResponse.java    |    40 -
 .../internal/tcpserver/TcpClient.java           |   251 -
 .../internal/tcpserver/TcpHandler.java          |    61 -
 .../internal/tcpserver/TcpServer.java           |   546 -
 .../internal/tcpserver/VersionRequest.java      |    41 -
 .../internal/tcpserver/VersionResponse.java     |    54 -
 .../unsafe/RegisterSignalHandlerSupport.java    |    35 -
 .../gemstone/gemfire/distributed/package.html   |    37 -
 .../doc-files/data-serialization-exceptions.fig |   135 -
 .../doc-files/data-serialization-exceptions.gif |   Bin 3666 -> 0 bytes
 .../gemstone/gemfire/i18n/LogWriterI18n.java    |   420 -
 .../com/gemstone/gemfire/i18n/StringId.java     |   161 -
 .../gemfire/internal/AbstractConfig.java        |   403 -
 .../internal/AbstractStatisticsFactory.java     |   340 -
 .../gemfire/internal/ArchiveSplitter.java       |   522 -
 .../com/gemstone/gemfire/internal/Assert.java   |   177 -
 .../gemfire/internal/AvailablePort.java         |   588 -
 .../com/gemstone/gemfire/internal/Banner.java   |   172 -
 .../gemfire/internal/ByteArrayDataInput.java    |   458 -
 .../internal/ByteBufferOutputStream.java        |   102 -
 .../gemfire/internal/ByteBufferWriter.java      |    35 -
 .../gemfire/internal/ClassLoadUtil.java         |   124 -
 .../gemfire/internal/ClassPathLoader.java       |   726 -
 .../com/gemstone/gemfire/internal/Config.java   |   110 -
 .../gemstone/gemfire/internal/ConfigSource.java |   108 -
 .../gemfire/internal/ConnectionWatcher.java     |    41 -
 .../gemfire/internal/CopyOnWriteHashSet.java    |   177 -
 .../com/gemstone/gemfire/internal/DSCODE.java   |   416 -
 .../gemstone/gemfire/internal/DSFIDFactory.java |  1403 --
 .../internal/DSFIDNotFoundException.java        |    52 -
 .../internal/DataSerializableFixedID.java       |   912 -
 .../gemfire/internal/DistributionLocator.java   |   190 -
 .../internal/DummyStatisticsFactory.java        |   134 -
 .../gemfire/internal/DummyStatisticsImpl.java   |   199 -
 .../gemfire/internal/ExternalizableDSFID.java   |    43 -
 .../com/gemstone/gemfire/internal/FileUtil.java |   331 -
 .../gemfire/internal/GemFireStatSampler.java    |   507 -
 .../gemfire/internal/GemFireUtilLauncher.java   |   166 -
 .../gemfire/internal/GemFireVersion.java        |   681 -
 .../internal/GfeConsoleReaderFactory.java       |    87 -
 .../gemfire/internal/HeapDataOutputStream.java  |  1374 --
 .../gemfire/internal/HistogramStats.java        |    82 -
 .../gemfire/internal/HostStatHelper.java        |   289 -
 .../gemfire/internal/HostStatSampler.java       |   546 -
 .../InsufficientDiskSpaceException.java         |    54 -
 .../internal/InternalDataSerializer.java        |  4057 ----
 .../gemfire/internal/InternalEntity.java        |    30 -
 .../gemfire/internal/InternalInstantiator.java  |  1061 -
 .../InternalStatisticsDisabledException.java    |    70 -
 .../gemfire/internal/JarClassLoader.java        |   701 -
 .../gemstone/gemfire/internal/JarDeployer.java  |   639 -
 .../gemfire/internal/LinuxProcFsStatistics.java |   786 -
 .../gemfire/internal/LinuxProcessStats.java     |    79 -
 .../gemfire/internal/LinuxSystemStats.java      |   311 -
 .../gemfire/internal/LocalStatListener.java     |    41 -
 .../internal/LocalStatisticsFactory.java        |   101 -
 .../gemfire/internal/LocalStatisticsImpl.java   |   269 -
 .../gemstone/gemfire/internal/ManagerInfo.java  |   386 -
 .../gemfire/internal/MigrationClient.java       |   260 -
 .../gemfire/internal/MigrationServer.java       |   566 -
 .../gemstone/gemfire/internal/NanoTimer.java    |   186 -
 .../gemfire/internal/NullDataOutputStream.java  |   379 -
 .../gemstone/gemfire/internal/OSProcess.java    |   753 -
 .../gemfire/internal/OSXProcessStats.java       |    83 -
 .../gemfire/internal/OSXSystemStats.java        |   228 -
 .../gemfire/internal/ObjIdConcurrentMap.java    |  1366 --
 .../com/gemstone/gemfire/internal/ObjIdMap.java |   337 -
 .../internal/ObjToByteArraySerializer.java      |    35 -
 .../gemfire/internal/OneTaskOnlyExecutor.java   |   175 -
 .../gemfire/internal/OsStatisticsFactory.java   |    42 -
 .../gemfire/internal/PdxSerializerObject.java   |    33 -
 .../gemfire/internal/ProcessOutputReader.java   |   135 -
 .../gemstone/gemfire/internal/ProcessStats.java |    61 -
 .../gemstone/gemfire/internal/PureJavaMode.java |    80 -
 ...cheduledThreadPoolExecutorWithKeepAlive.java |   313 -
 .../com/gemstone/gemfire/internal/Sendable.java |    42 -
 .../gemfire/internal/SerializationVersions.java |    42 -
 .../com/gemstone/gemfire/internal/SetUtils.java |    68 -
 .../gemfire/internal/SharedLibrary.java         |   226 -
 .../gemfire/internal/SimpleStatSampler.java     |   114 -
 .../com/gemstone/gemfire/internal/SmHelper.java |   183 -
 .../gemstone/gemfire/internal/SocketCloser.java |   257 -
 .../gemfire/internal/SocketCreator.java         |  1364 --
 .../gemfire/internal/SocketIOWithTimeout.java   |   491 -
 .../gemfire/internal/SocketInputStream.java     |   181 -
 .../gemfire/internal/SocketInputWrapper.java    |    93 -
 .../gemfire/internal/SocketOutputStream.java    |   174 -
 .../gemstone/gemfire/internal/SocketUtils.java  |   220 -
 .../gemfire/internal/SolarisProcessStats.java   |   217 -
 .../gemfire/internal/SolarisSystemStats.java    |   428 -
 .../gemfire/internal/StatArchiveFormat.java     |   197 -
 .../gemfire/internal/StatArchiveReader.java     |  3338 ----
 .../gemfire/internal/StatArchiveWriter.java     |   748 -
 .../gemfire/internal/StatSamplerStats.java      |   123 -
 .../internal/StatisticDescriptorImpl.java       |   385 -
 .../gemfire/internal/StatisticsImpl.java        |   454 -
 .../gemfire/internal/StatisticsManager.java     |    79 -
 .../internal/StatisticsTypeFactoryImpl.java     |   141 -
 .../gemfire/internal/StatisticsTypeImpl.java    |   260 -
 .../gemfire/internal/StatisticsTypeXml.java     |   280 -
 .../gemstone/gemfire/internal/SystemAdmin.java  |  2305 ---
 .../gemfire/internal/SystemFailureTestHook.java |    48 -
 .../gemstone/gemfire/internal/SystemTimer.java  |   467 -
 .../gemfire/internal/UniqueIdGenerator.java     |   257 -
 .../com/gemstone/gemfire/internal/VMStats.java  |    87 -
 .../gemfire/internal/VMStatsContract.java       |    36 -
 .../internal/VMStatsContractFactory.java        |    60 -
 .../com/gemstone/gemfire/internal/Version.java  |   636 -
 .../internal/VersionedDataInputStream.java      |    67 -
 .../internal/VersionedDataOutputStream.java     |    57 -
 .../internal/VersionedDataSerializable.java     |    34 -
 .../gemfire/internal/VersionedDataStream.java   |    53 -
 .../gemfire/internal/VersionedObjectInput.java  |   245 -
 .../gemfire/internal/VersionedObjectOutput.java |   199 -
 .../gemfire/internal/WindowsProcessStats.java   |   160 -
 .../gemfire/internal/WindowsSystemStats.java    |   267 -
 .../internal/admin/AdminBridgeServer.java       |    33 -
 .../gemstone/gemfire/internal/admin/Alert.java  |    69 -
 .../gemfire/internal/admin/AlertListener.java   |    29 -
 .../gemfire/internal/admin/ApplicationVM.java   |    36 -
 .../gemfire/internal/admin/CacheCollector.java  |   277 -
 .../gemfire/internal/admin/CacheInfo.java       |   102 -
 .../gemfire/internal/admin/CacheSnapshot.java   |    34 -
 .../admin/ClientHealthMonitoringRegion.java     |   117 -
 .../internal/admin/ClientMembershipMessage.java |   187 -
 .../internal/admin/ClientStatsManager.java      |   263 -
 .../internal/admin/CompoundEntrySnapshot.java   |   201 -
 .../internal/admin/CompoundRegionSnapshot.java  |   387 -
 .../gemfire/internal/admin/DLockInfo.java       |    35 -
 .../gemfire/internal/admin/EntrySnapshot.java   |    29 -
 .../gemfire/internal/admin/EntryValueNode.java  |    53 -
 .../gemfire/internal/admin/GemFireVM.java       |   396 -
 .../gemfire/internal/admin/GfManagerAgent.java  |   112 -
 .../internal/admin/GfManagerAgentConfig.java    |    87 -
 .../internal/admin/GfManagerAgentFactory.java   |    42 -
 .../gemfire/internal/admin/GfObject.java        |    28 -
 .../gemfire/internal/admin/HealthListener.java  |    44 -
 .../internal/admin/JoinLeaveListener.java       |    27 -
 .../gemfire/internal/admin/ListenerIdMap.java   |   318 -
 .../gemfire/internal/admin/RegionSnapshot.java  |    31 -
 .../gemfire/internal/admin/SSLConfig.java       |   131 -
 .../gemfire/internal/admin/SnapshotClient.java  |    38 -
 .../gemstone/gemfire/internal/admin/Stat.java   |    44 -
 .../gemfire/internal/admin/StatAlert.java       |   140 -
 .../internal/admin/StatAlertDefinition.java     |   103 -
 .../internal/admin/StatAlertsManager.java       |   408 -
 .../gemfire/internal/admin/StatListener.java    |    43 -
 .../gemfire/internal/admin/StatResource.java    |    42 -
 .../gemfire/internal/admin/TransportConfig.java |    27 -
 .../admin/doc-files/class-hierarchy.fig         |   224 -
 .../admin/doc-files/class-hierarchy.gif         |   Bin 11971 -> 0 bytes
 .../gemfire/internal/admin/package.html         |    29 -
 .../admin/remote/AddHealthListenerRequest.java  |    89 -
 .../admin/remote/AddHealthListenerResponse.java |    76 -
 .../admin/remote/AddStatListenerRequest.java    |    85 -
 .../admin/remote/AddStatListenerResponse.java   |    79 -
 .../remote/AdminConsoleDisconnectMessage.java   |   125 -
 .../admin/remote/AdminConsoleMessage.java       |    83 -
 .../admin/remote/AdminFailureResponse.java      |    73 -
 .../remote/AdminMultipleReplyProcessor.java     |    91 -
 .../internal/admin/remote/AdminRegion.java      |   581 -
 .../admin/remote/AdminReplyProcessor.java       |   148 -
 .../internal/admin/remote/AdminRequest.java     |   193 -
 .../internal/admin/remote/AdminResponse.java    |    90 -
 .../internal/admin/remote/AdminWaiters.java     |   184 -
 .../admin/remote/AlertLevelChangeMessage.java   |    96 -
 .../admin/remote/AlertListenerMessage.java      |   147 -
 .../admin/remote/AlertsNotificationMessage.java |   110 -
 .../admin/remote/AppCacheSnapshotMessage.java   |   163 -
 .../admin/remote/BridgeServerRequest.java       |   202 -
 .../admin/remote/BridgeServerResponse.java      |   181 -
 .../admin/remote/CacheConfigRequest.java        |    88 -
 .../admin/remote/CacheConfigResponse.java       |   119 -
 .../internal/admin/remote/CacheDisplay.java     |    86 -
 .../internal/admin/remote/CacheInfoRequest.java |    73 -
 .../admin/remote/CacheInfoResponse.java         |    83 -
 .../admin/remote/CancelStatListenerRequest.java |    79 -
 .../remote/CancelStatListenerResponse.java      |    74 -
 .../internal/admin/remote/Cancellable.java      |    27 -
 .../admin/remote/CancellationMessage.java       |    70 -
 .../admin/remote/CancellationRegistry.java      |    95 -
 .../remote/ChangeRefreshIntervalMessage.java    |    98 -
 .../internal/admin/remote/CliLegacyMessage.java |    58 -
 .../admin/remote/ClientHealthStats.java         |   308 -
 .../internal/admin/remote/CompactRequest.java   |   145 -
 .../internal/admin/remote/CompactResponse.java  |    66 -
 .../admin/remote/DestroyEntryMessage.java       |   100 -
 .../admin/remote/DestroyRegionMessage.java      |    96 -
 .../admin/remote/DistributionLocatorId.java     |   394 -
 .../internal/admin/remote/DummyEntry.java       |    77 -
 .../admin/remote/DurableClientInfoRequest.java  |   109 -
 .../admin/remote/DurableClientInfoResponse.java |   108 -
 .../admin/remote/EntryValueNodeImpl.java        |   393 -
 .../admin/remote/FetchDistLockInfoRequest.java  |    68 -
 .../admin/remote/FetchDistLockInfoResponse.java |    93 -
 .../remote/FetchHealthDiagnosisRequest.java     |    91 -
 .../remote/FetchHealthDiagnosisResponse.java    |    92 -
 .../internal/admin/remote/FetchHostRequest.java |    70 -
 .../admin/remote/FetchHostResponse.java         |   173 -
 .../remote/FetchResourceAttributesRequest.java  |    70 -
 .../remote/FetchResourceAttributesResponse.java |    81 -
 .../admin/remote/FetchStatsRequest.java         |    72 -
 .../admin/remote/FetchStatsResponse.java        |   145 -
 .../admin/remote/FetchSysCfgRequest.java        |    76 -
 .../admin/remote/FetchSysCfgResponse.java       |    77 -
 .../remote/FlushAppCacheSnapshotMessage.java    |    69 -
 .../admin/remote/HealthListenerMessage.java     |    89 -
 .../remote/InspectionClasspathManager.java      |    90 -
 .../admin/remote/LicenseInfoRequest.java        |    72 -
 .../admin/remote/LicenseInfoResponse.java       |    79 -
 .../remote/MissingPersistentIDsRequest.java     |   141 -
 .../remote/MissingPersistentIDsResponse.java    |   115 -
 .../admin/remote/ObjectDetailsRequest.java      |   103 -
 .../admin/remote/ObjectDetailsResponse.java     |   155 -
 .../admin/remote/ObjectNamesRequest.java        |    89 -
 .../admin/remote/ObjectNamesResponse.java       |    98 -
 .../PrepareRevokePersistentIDRequest.java       |   127 -
 .../remote/RefreshMemberSnapshotRequest.java    |    74 -
 .../remote/RefreshMemberSnapshotResponse.java   |    95 -
 .../admin/remote/RegionAdminMessage.java        |    66 -
 .../admin/remote/RegionAdminRequest.java        |    74 -
 .../admin/remote/RegionAttributesRequest.java   |    74 -
 .../admin/remote/RegionAttributesResponse.java  |    75 -
 .../internal/admin/remote/RegionRequest.java    |   175 -
 .../internal/admin/remote/RegionResponse.java   |   149 -
 .../admin/remote/RegionSizeRequest.java         |    90 -
 .../admin/remote/RegionSizeResponse.java        |    96 -
 .../admin/remote/RegionStatisticsRequest.java   |    74 -
 .../admin/remote/RegionStatisticsResponse.java  |    75 -
 .../remote/RegionSubRegionSizeRequest.java      |    94 -
 .../remote/RegionSubRegionsSizeResponse.java    |   162 -
 .../internal/admin/remote/RemoteAlert.java      |   205 -
 .../admin/remote/RemoteApplicationVM.java       |    61 -
 .../admin/remote/RemoteBridgeServer.java        |   300 -
 .../internal/admin/remote/RemoteCacheInfo.java  |   192 -
 .../admin/remote/RemoteCacheStatistics.java     |    87 -
 .../internal/admin/remote/RemoteDLockInfo.java  |   115 -
 .../admin/remote/RemoteEntrySnapshot.java       |   131 -
 .../internal/admin/remote/RemoteGemFireVM.java  |   998 -
 .../admin/remote/RemoteGfManagerAgent.java      |  1489 --
 .../internal/admin/remote/RemoteObjectName.java |    95 -
 .../admin/remote/RemoteRegionAttributes.java    |   702 -
 .../admin/remote/RemoteRegionSnapshot.java      |   158 -
 .../internal/admin/remote/RemoteStat.java       |   118 -
 .../admin/remote/RemoteStatResource.java        |   154 -
 .../admin/remote/RemoteTransportConfig.java     |   376 -
 .../remote/RemoveHealthListenerRequest.java     |    80 -
 .../remote/RemoveHealthListenerResponse.java    |    67 -
 .../admin/remote/ResetHealthStatusRequest.java  |    80 -
 .../admin/remote/ResetHealthStatusResponse.java |    72 -
 .../admin/remote/RevokePersistentIDRequest.java |   103 -
 .../remote/RevokePersistentIDResponse.java      |    36 -
 .../admin/remote/RootRegionRequest.java         |    76 -
 .../admin/remote/RootRegionResponse.java        |   115 -
 .../remote/ShutdownAllGatewayHubsRequest.java   |    68 -
 .../admin/remote/ShutdownAllRequest.java        |   301 -
 .../admin/remote/ShutdownAllResponse.java       |    80 -
 .../admin/remote/SnapshotResultMessage.java     |    85 -
 .../remote/StatAlertsManagerAssignMessage.java  |   152 -
 .../admin/remote/StatListenerMessage.java       |   118 -
 .../admin/remote/StoreSysCfgRequest.java        |    81 -
 .../admin/remote/StoreSysCfgResponse.java       |    77 -
 .../internal/admin/remote/SubRegionRequest.java |    74 -
 .../admin/remote/SubRegionResponse.java         |   100 -
 .../internal/admin/remote/TailLogRequest.java   |    62 -
 .../internal/admin/remote/TailLogResponse.java  |   169 -
 .../remote/UpdateAlertDefinitionMessage.java    |   162 -
 .../admin/remote/VersionInfoRequest.java        |    73 -
 .../admin/remote/VersionInfoResponse.java       |    74 -
 .../admin/remote/VersionMismatchAlert.java      |    66 -
 .../gemfire/internal/admin/remote/package.html  |    41 -
 .../admin/statalerts/BaseDecoratorImpl.java     |   224 -
 .../statalerts/DummyStatisticInfoImpl.java      |   146 -
 .../admin/statalerts/FunctionDecoratorImpl.java |   133 -
 .../admin/statalerts/FunctionHelper.java        |   257 -
 .../statalerts/GaugeThresholdDecoratorImpl.java |   156 -
 .../statalerts/MultiAttrDefinitionImpl.java     |   207 -
 .../NumberThresholdDecoratorImpl.java           |   153 -
 .../statalerts/SingleAttrDefinitionImpl.java    |   213 -
 .../admin/statalerts/StatisticInfo.java         |    85 -
 .../admin/statalerts/StatisticInfoImpl.java     |   157 -
 .../cache/AbstractBucketRegionQueue.java        |   563 -
 .../internal/cache/AbstractCacheServer.java     |   407 -
 .../cache/AbstractDiskLRURegionEntry.java       |    42 -
 .../internal/cache/AbstractDiskRegion.java      |   992 -
 .../internal/cache/AbstractDiskRegionEntry.java |    76 -
 .../internal/cache/AbstractLRURegionEntry.java  |    46 -
 .../internal/cache/AbstractLRURegionMap.java    |   861 -
 .../cache/AbstractOplogDiskRegionEntry.java     |   173 -
 .../gemfire/internal/cache/AbstractRegion.java  |  2134 --
 .../internal/cache/AbstractRegionEntry.java     |  2243 ---
 .../internal/cache/AbstractRegionMap.java       |  4164 ----
 .../internal/cache/AbstractUpdateOperation.java |   338 -
 .../gemfire/internal/cache/AcceptHelper.java    |   101 -
 .../cache/AddCacheServerProfileMessage.java     |   161 -
 .../gemfire/internal/cache/BackupLock.java      |    91 -
 .../gemfire/internal/cache/BucketAdvisor.java   |  3002 ---
 .../gemfire/internal/cache/BucketDump.java      |   144 -
 .../internal/cache/BucketNotFoundException.java |    38 -
 .../cache/BucketPersistenceAdvisor.java         |   463 -
 .../gemfire/internal/cache/BucketRegion.java    |  2622 ---
 .../internal/cache/BucketRegionEvictior.java    |    63 -
 .../internal/cache/BucketRegionQueue.java       |   548 -
 .../internal/cache/BucketServerLocation.java    |    88 -
 .../internal/cache/BucketServerLocation66.java  |   113 -
 .../cache/BytesAndBitsForCompactor.java         |    94 -
 .../internal/cache/CacheClientStatus.java       |   101 -
 .../gemfire/internal/cache/CacheConfig.java     |   228 -
 .../cache/CacheDistributionAdvisee.java         |    58 -
 .../cache/CacheDistributionAdvisor.java         |  1260 --
 .../internal/cache/CacheLifecycleListener.java  |    37 -
 .../gemfire/internal/cache/CacheObserver.java   |   190 -
 .../internal/cache/CacheObserverAdapter.java    |   154 -
 .../internal/cache/CacheObserverHolder.java     |    78 -
 .../gemfire/internal/cache/CachePerfStats.java  |  1419 --
 .../internal/cache/CacheServerAdvisor.java      |   173 -
 .../gemfire/internal/cache/CacheServerImpl.java |   832 -
 .../internal/cache/CacheServerLauncher.java     |  1393 --
 .../gemfire/internal/cache/CacheService.java    |    42 -
 .../internal/cache/CacheStatisticsImpl.java     |   111 -
 .../internal/cache/CachedDeserializable.java    |   114 -
 .../cache/CachedDeserializableFactory.java      |   275 -
 .../internal/cache/ClientRegionEventImpl.java   |   117 -
 .../internal/cache/ClientServerObserver.java    |    99 -
 .../cache/ClientServerObserverAdapter.java      |   116 -
 .../cache/ClientServerObserverHolder.java       |    62 -
 .../cache/ClientSubscriptionConfigImpl.java     |   178 -
 .../internal/cache/CloseCacheMessage.java       |   116 -
 .../cache/ClusterConfigurationLoader.java       |   245 -
 .../internal/cache/ColocationHelper.java        |   569 -
 .../internal/cache/CommitReplyException.java    |    73 -
 .../internal/cache/CompactableOplog.java        |    37 -
 .../gemfire/internal/cache/Conflatable.java     |    76 -
 .../internal/cache/ControllerAdvisor.java       |   171 -
 .../internal/cache/CountingDataInputStream.java |   125 -
 .../internal/cache/CreateRegionProcessor.java   |   914 -
 .../internal/cache/CustomEntryExpiryTask.java   |    49 -
 .../cache/CustomEvictionAttributesImpl.java     |    36 -
 .../internal/cache/DataLocationException.java   |    43 -
 .../internal/cache/DestroyOperation.java        |   303 -
 .../cache/DestroyPartitionedRegionMessage.java  |   252 -
 .../internal/cache/DestroyRegionOperation.java  |   547 -
 .../gemfire/internal/cache/DestroyedEntry.java  |    85 -
 .../internal/cache/DirectReplyMessage.java      |    58 -
 .../gemfire/internal/cache/DirectoryHolder.java |   123 -
 .../internal/cache/DiskDirectoryStats.java      |   117 -
 .../gemfire/internal/cache/DiskEntry.java       |  2028 --
 .../gemstone/gemfire/internal/cache/DiskId.java |   730 -
 .../gemfire/internal/cache/DiskInitFile.java    |  2877 ---
 .../gemfire/internal/cache/DiskRegion.java      |   876 -
 .../gemfire/internal/cache/DiskRegionStats.java |   326 -
 .../internal/cache/DiskStoreAttributes.java     |   196 -
 .../gemfire/internal/cache/DiskStoreBackup.java |    98 -
 .../internal/cache/DiskStoreFactoryImpl.java    |   291 -
 .../gemfire/internal/cache/DiskStoreImpl.java   |  4873 -----
 .../internal/cache/DiskStoreMonitor.java        |   413 -
 .../internal/cache/DiskStoreObserver.java       |    63 -
 .../gemfire/internal/cache/DiskStoreStats.java  |   528 -
 .../gemfire/internal/cache/DiskStoreTask.java   |    27 -
 .../internal/cache/DiskWriteAttributesImpl.java |   564 -
 .../internal/cache/DistPeerTXStateStub.java     |   374 -
 .../cache/DistTXAdjunctCommitMessage.java       |    51 -
 .../internal/cache/DistTXCommitMessage.java     |   500 -
 .../cache/DistTXCoordinatorInterface.java       |    73 -
 .../internal/cache/DistTXPrecommitMessage.java  |   548 -
 .../internal/cache/DistTXRollbackMessage.java   |   507 -
 .../gemfire/internal/cache/DistTXState.java     |   746 -
 .../cache/DistTXStateOnCoordinator.java         |   416 -
 .../internal/cache/DistTXStateProxyImpl.java    |    48 -
 .../DistTXStateProxyImplOnCoordinator.java      |  1068 -
 .../cache/DistTXStateProxyImplOnDatanode.java   |   128 -
 .../cache/DistributedCacheOperation.java        |  1615 --
 .../cache/DistributedClearOperation.java        |   356 -
 .../cache/DistributedPutAllOperation.java       |  1384 --
 .../internal/cache/DistributedRegion.java       |  4311 -----
 ...stributedRegionFunctionStreamingMessage.java |   460 -
 .../cache/DistributedRemoveAllOperation.java    |  1097 --
 .../cache/DistributedTombstoneOperation.java    |   227 -
 .../internal/cache/DummyCachePerfStats.java     |   485 -
 .../internal/cache/DynamicRegionAttributes.java |    52 -
 .../cache/DynamicRegionFactoryImpl.java         |    44 -
 .../gemfire/internal/cache/EntriesMap.java      |   155 -
 .../gemfire/internal/cache/EntriesSet.java      |   294 -
 .../gemfire/internal/cache/EntryBits.java       |   128 -
 .../gemfire/internal/cache/EntryEventImpl.java  |  3142 ---
 .../gemfire/internal/cache/EntryExpiryTask.java |   358 -
 .../internal/cache/EntryOperationImpl.java      |   119 -
 .../gemfire/internal/cache/EntrySnapshot.java   |   285 -
 .../internal/cache/EnumListenerEvent.java       |   475 -
 .../gemfire/internal/cache/EventID.java         |   804 -
 .../internal/cache/EventStateHelper.java        |   196 -
 .../gemfire/internal/cache/EventTracker.java    |   812 -
 .../internal/cache/EvictionAttributesImpl.java  |   243 -
 .../gemfire/internal/cache/EvictorService.java  |   285 -
 .../internal/cache/ExpirationScheduler.java     |   106 -
 .../gemfire/internal/cache/ExpiryTask.java      |   540 -
 .../internal/cache/ExportDiskRegion.java        |    84 -
 .../gemfire/internal/cache/FilterProfile.java   |  2218 ---
 .../internal/cache/FilterRoutingInfo.java       |   519 -
 .../cache/FindDurableQueueProcessor.java        |   256 -
 .../internal/cache/FindRemoteTXMessage.java     |   281 -
 .../internal/cache/FindVersionTagOperation.java |   254 -
 .../cache/FixedPartitionAttributesImpl.java     |   156 -
 .../internal/cache/ForceReattemptException.java |   121 -
 .../cache/ForceableLinkedBlockingQueue.java     |   864 -
 .../FunctionStreamingOrderedReplyMessage.java   |    64 -
 .../cache/FunctionStreamingReplyMessage.java    |   145 -
 .../internal/cache/GatewayEventFilter.java      |    27 -
 .../internal/cache/GemFireCacheImpl.java        |  5467 ------
 .../internal/cache/GemfireCacheHelper.java      |    38 -
 .../gemfire/internal/cache/GridAdvisor.java     |   442 -
 .../gemfire/internal/cache/HARegion.java        |   618 -
 .../internal/cache/HDFSLRURegionMap.java        |   112 -
 .../gemfire/internal/cache/HDFSRegionMap.java   |    33 -
 .../internal/cache/HDFSRegionMapDelegate.java   |   541 -
 .../internal/cache/HDFSRegionMapImpl.java       |    75 -
 .../internal/cache/HasCachePerfStats.java       |    22 -
 .../internal/cache/IdentityArrayList.java       |   473 -
 .../gemfire/internal/cache/ImageState.java      |    89 -
 .../cache/InMemoryPersistentMemberView.java     |   136 -
 .../internal/cache/IncomingGatewayStatus.java   |    83 -
 .../internal/cache/InitialImageFlowControl.java |   253 -
 .../internal/cache/InitialImageOperation.java   |  4310 -----
 .../gemfire/internal/cache/InlineKeyHelper.java |    71 -
 .../gemfire/internal/cache/InterestEvent.java   |    68 -
 .../gemfire/internal/cache/InterestFilter.java  |    34 -
 .../cache/InterestRegistrationEventImpl.java    |   152 -
 .../gemfire/internal/cache/InternalCache.java   |    52 -
 .../internal/cache/InternalCacheEvent.java      |    87 -
 .../internal/cache/InternalDataView.java        |   255 -
 .../internal/cache/InternalRegionArguments.java |   337 -
 .../internal/cache/InvalidateOperation.java     |   236 -
 .../InvalidatePartitionedRegionMessage.java     |   102 -
 .../cache/InvalidateRegionOperation.java        |   108 -
 .../cache/JtaAfterCompletionMessage.java        |   128 -
 .../cache/JtaBeforeCompletionMessage.java       |    82 -
 .../gemfire/internal/cache/KeyInfo.java         |   129 -
 .../internal/cache/KeyWithRegionContext.java    |    71 -
 .../gemfire/internal/cache/ListOfDeltas.java    |   101 -
 .../internal/cache/LoaderHelperFactory.java     |    40 -
 .../internal/cache/LoaderHelperImpl.java        |   169 -
 .../gemfire/internal/cache/LocalDataSet.java    |   750 -
 .../gemfire/internal/cache/LocalRegion.java     | 12975 -------------
 .../internal/cache/LocalRegionDataView.java     |   273 -
 .../cache/MemberFunctionStreamingMessage.java   |   416 -
 .../cache/MinimumSystemRequirements.java        |    92 -
 .../cache/NetSearchExpirationCalculator.java    |    49 -
 .../gemstone/gemfire/internal/cache/Node.java   |   187 -
 .../internal/cache/NonLocalRegionEntry.java     |   579 -
 .../cache/NonLocalRegionEntryWithStats.java     |    86 -
 .../internal/cache/OffHeapRegionEntry.java      |    42 -
 .../cache/OfflineCompactionDiskRegion.java      |   124 -
 .../gemstone/gemfire/internal/cache/OpType.java |    59 -
 .../gemstone/gemfire/internal/cache/Oplog.java  |  7969 --------
 .../gemfire/internal/cache/OplogSet.java        |    34 -
 .../internal/cache/OrderedTombstoneMap.java     |   123 -
 .../gemfire/internal/cache/OverflowOplog.java   |  1613 --
 .../internal/cache/OverflowOplogSet.java        |   328 -
 .../internal/cache/PRContainsValueFunction.java |    60 -
 .../internal/cache/PRHARedundancyProvider.java  |  2384 ---
 .../internal/cache/PRQueryProcessor.java        |   658 -
 .../internal/cache/PRSystemPropertyGetter.java  |    70 -
 .../internal/cache/PartitionAttributesImpl.java |   828 -
 .../internal/cache/PartitionRegionConfig.java   |   477 -
 .../cache/PartitionRegionConfigValidator.java   |   511 -
 .../internal/cache/PartitionedRegion.java       | 11398 -----------
 .../PartitionedRegionBucketMgmtHelper.java      |    54 -
 .../cache/PartitionedRegionDataStore.java       |  3284 ----
 .../cache/PartitionedRegionDataView.java        |   142 -
 .../cache/PartitionedRegionException.java       |    48 -
 .../internal/cache/PartitionedRegionHelper.java |  1132 --
 .../cache/PartitionedRegionQueryEvaluator.java  |  1486 --
 .../internal/cache/PartitionedRegionStats.java  |  1267 --
 .../internal/cache/PartitionedRegionStatus.java |    86 -
 .../gemfire/internal/cache/PeerTXStateStub.java |   257 -
 .../internal/cache/PersistentOplogSet.java      |  1184 --
 .../internal/cache/PlaceHolderDiskRegion.java   |   207 -
 .../gemfire/internal/cache/PoolFactoryImpl.java |   529 -
 .../gemfire/internal/cache/PoolManagerImpl.java |   336 -
 .../gemfire/internal/cache/PoolStats.java       |   319 -
 .../cache/PreferBytesCachedDeserializable.java  |   157 -
 .../internal/cache/PrimaryBucketException.java  |    49 -
 .../cache/ProfileExchangeProcessor.java         |    41 -
 .../internal/cache/ProxyBucketRegion.java       |   657 -
 .../gemfire/internal/cache/ProxyRegionMap.java  |   794 -
 .../cache/PutAllPartialResultException.java     |   229 -
 .../gemfire/internal/cache/QueuedOperation.java |   196 -
 .../internal/cache/RegionClearedException.java  |    62 -
 .../gemfire/internal/cache/RegionEntry.java     |   519 -
 .../internal/cache/RegionEntryContext.java      |    41 -
 .../internal/cache/RegionEntryFactory.java      |    50 -
 .../gemfire/internal/cache/RegionEventImpl.java |   352 -
 .../internal/cache/RegionEvictorTask.java       |   144 -
 .../internal/cache/RegionExpiryTask.java        |   162 -
 .../internal/cache/RegionFactoryImpl.java       |    50 -
 .../internal/cache/RegionIdleExpiryTask.java    |    73 -
 .../gemfire/internal/cache/RegionListener.java  |    46 -
 .../gemfire/internal/cache/RegionMap.java       |   404 -
 .../internal/cache/RegionMapFactory.java        |    76 -
 .../gemfire/internal/cache/RegionQueue.java     |   158 -
 .../internal/cache/RegionQueueException.java    |    49 -
 .../gemfire/internal/cache/RegionStatus.java    |    88 -
 .../internal/cache/RegionTTLExpiryTask.java     |    75 -
 .../internal/cache/ReleaseClearLockMessage.java |   113 -
 .../cache/ReliableDistributionData.java         |    43 -
 .../internal/cache/ReliableMessageQueue.java    |    66 -
 .../cache/ReliableMessageQueueFactory.java      |    43 -
 .../cache/ReliableMessageQueueFactoryImpl.java  |   230 -
 .../cache/RemoteContainsKeyValueMessage.java    |   342 -
 .../internal/cache/RemoteDestroyMessage.java    |   745 -
 .../internal/cache/RemoteFetchEntryMessage.java |   386 -
 .../cache/RemoteFetchVersionMessage.java        |   261 -
 .../internal/cache/RemoteGetMessage.java        |   462 -
 .../internal/cache/RemoteInvalidateMessage.java |   439 -
 .../cache/RemoteOperationException.java         |   119 -
 .../internal/cache/RemoteOperationMessage.java  |   656 -
 .../RemoteOperationMessageWithDirectReply.java  |    85 -
 .../internal/cache/RemotePutAllMessage.java     |   549 -
 .../internal/cache/RemotePutMessage.java        |  1236 --
 .../internal/cache/RemoteRegionOperation.java   |   224 -
 .../internal/cache/RemoteRemoveAllMessage.java  |   531 -
 .../gemfire/internal/cache/RoleEventImpl.java   |    96 -
 .../cache/SearchLoadAndWriteProcessor.java      |  2802 ---
 .../internal/cache/SendQueueOperation.java      |   191 -
 .../internal/cache/SerializationHelper.java     |    24 -
 .../internal/cache/ServerPingMessage.java       |   136 -
 .../internal/cache/StateFlushOperation.java     |   783 -
 .../cache/StoreAllCachedDeserializable.java     |   159 -
 .../internal/cache/TXBucketRegionState.java     |    37 -
 .../gemfire/internal/cache/TXCommitMessage.java |  2478 ---
 .../gemfire/internal/cache/TXEntry.java         |   274 -
 .../gemfire/internal/cache/TXEntryState.java    |  2270 ---
 .../internal/cache/TXEntryStateFactory.java     |    38 -
 .../internal/cache/TXEntryUserAttrState.java    |    67 -
 .../gemfire/internal/cache/TXEvent.java         |   148 -
 .../internal/cache/TXFarSideCMTracker.java      |   360 -
 .../gemstone/gemfire/internal/cache/TXId.java   |   130 -
 .../gemfire/internal/cache/TXLockRequest.java   |   144 -
 .../gemfire/internal/cache/TXManagerImpl.java   |  1511 --
 .../gemfire/internal/cache/TXMessage.java       |   215 -
 .../internal/cache/TXRegionLockRequestImpl.java |   209 -
 .../gemfire/internal/cache/TXRegionState.java   |   629 -
 .../internal/cache/TXRemoteCommitMessage.java   |   320 -
 .../internal/cache/TXRemoteRollbackMessage.java |    88 -
 .../internal/cache/TXReservationMgr.java        |   154 -
 .../gemfire/internal/cache/TXRmtEvent.java      |   243 -
 .../gemfire/internal/cache/TXState.java         |  1839 --
 .../internal/cache/TXStateInterface.java        |   224 -
 .../gemfire/internal/cache/TXStateProxy.java    |    96 -
 .../internal/cache/TXStateProxyImpl.java        |  1036 -
 .../gemfire/internal/cache/TXStateStub.java     |   577 -
 .../cache/TXSynchronizationRunnable.java        |   160 -
 .../cache/TestHeapThresholdObserver.java        |    62 -
 .../cache/TimestampedEntryEventImpl.java        |    73 -
 .../gemstone/gemfire/internal/cache/Token.java  |   301 -
 .../internal/cache/TombstoneService.java        |  1007 -
 .../internal/cache/TransactionMessage.java      |    75 -
 .../gemfire/internal/cache/TxEntryFactory.java  |    35 -
 .../internal/cache/UnsharedImageState.java      |   293 -
 .../cache/UpdateAttributesProcessor.java        |   553 -
 .../cache/UpdateEntryVersionOperation.java      |   195 -
 .../gemfire/internal/cache/UpdateOperation.java |   629 -
 .../cache/UserSpecifiedDiskStoreAttributes.java |   191 -
 .../cache/UserSpecifiedRegionAttributes.java    |   624 -
 .../internal/cache/VMCachedDeserializable.java  |   263 -
 .../gemfire/internal/cache/VMLRURegionMap.java  |    65 -
 .../gemfire/internal/cache/VMRegionMap.java     |    39 -
 .../cache/VMStatsDiskLRURegionEntry.java        |    40 -
 .../cache/VMStatsDiskLRURegionEntryHeap.java    |    69 -
 .../VMStatsDiskLRURegionEntryHeapIntKey.java    |   345 -
 .../VMStatsDiskLRURegionEntryHeapLongKey.java   |   345 -
 .../VMStatsDiskLRURegionEntryHeapObjectKey.java |   338 -
 ...VMStatsDiskLRURegionEntryHeapStringKey1.java |   407 -
 ...VMStatsDiskLRURegionEntryHeapStringKey2.java |   448 -
 .../VMStatsDiskLRURegionEntryHeapUUIDKey.java   |   349 -
 .../cache/VMStatsDiskLRURegionEntryOffHeap.java |    69 -
 .../VMStatsDiskLRURegionEntryOffHeapIntKey.java |   394 -
 ...VMStatsDiskLRURegionEntryOffHeapLongKey.java |   394 -
 ...StatsDiskLRURegionEntryOffHeapObjectKey.java |   387 -
 ...tatsDiskLRURegionEntryOffHeapStringKey1.java |   456 -
 ...tatsDiskLRURegionEntryOffHeapStringKey2.java |   497 -
 ...VMStatsDiskLRURegionEntryOffHeapUUIDKey.java |   398 -
 .../internal/cache/VMStatsDiskRegionEntry.java  |    39 -
 .../cache/VMStatsDiskRegionEntryHeap.java       |    69 -
 .../cache/VMStatsDiskRegionEntryHeapIntKey.java |   248 -
 .../VMStatsDiskRegionEntryHeapLongKey.java      |   248 -
 .../VMStatsDiskRegionEntryHeapObjectKey.java    |   241 -
 .../VMStatsDiskRegionEntryHeapStringKey1.java   |   310 -
 .../VMStatsDiskRegionEntryHeapStringKey2.java   |   351 -
 .../VMStatsDiskRegionEntryHeapUUIDKey.java      |   252 -
 .../cache/VMStatsDiskRegionEntryOffHeap.java    |    69 -
 .../VMStatsDiskRegionEntryOffHeapIntKey.java    |   297 -
 .../VMStatsDiskRegionEntryOffHeapLongKey.java   |   297 -
 .../VMStatsDiskRegionEntryOffHeapObjectKey.java |   290 -
 ...VMStatsDiskRegionEntryOffHeapStringKey1.java |   359 -
 ...VMStatsDiskRegionEntryOffHeapStringKey2.java |   400 -
 .../VMStatsDiskRegionEntryOffHeapUUIDKey.java   |   301 -
 .../internal/cache/VMStatsLRURegionEntry.java   |    43 -
 .../cache/VMStatsLRURegionEntryHeap.java        |    69 -
 .../cache/VMStatsLRURegionEntryHeapIntKey.java  |   256 -
 .../cache/VMStatsLRURegionEntryHeapLongKey.java |   256 -
 .../VMStatsLRURegionEntryHeapObjectKey.java     |   249 -
 .../VMStatsLRURegionEntryHeapStringKey1.java    |   318 -
 .../VMStatsLRURegionEntryHeapStringKey2.java    |   359 -
 .../cache/VMStatsLRURegionEntryHeapUUIDKey.java |   260 -
 .../cache/VMStatsLRURegionEntryOffHeap.java     |    69 -
 .../VMStatsLRURegionEntryOffHeapIntKey.java     |   305 -
 .../VMStatsLRURegionEntryOffHeapLongKey.java    |   305 -
 .../VMStatsLRURegionEntryOffHeapObjectKey.java  |   298 -
 .../VMStatsLRURegionEntryOffHeapStringKey1.java |   367 -
 .../VMStatsLRURegionEntryOffHeapStringKey2.java |   408 -
 .../VMStatsLRURegionEntryOffHeapUUIDKey.java    |   309 -
 .../internal/cache/VMStatsRegionEntry.java      |    39 -
 .../internal/cache/VMStatsRegionEntryHeap.java  |    69 -
 .../cache/VMStatsRegionEntryHeapIntKey.java     |   175 -
 .../cache/VMStatsRegionEntryHeapLongKey.java    |   175 -
 .../cache/VMStatsRegionEntryHeapObjectKey.java  |   168 -
 .../cache/VMStatsRegionEntryHeapStringKey1.java |   237 -
 .../cache/VMStatsRegionEntryHeapStringKey2.java |   278 -
 .../cache/VMStatsRegionEntryHeapUUIDKey.java    |   179 -
 .../cache/VMStatsRegionEntryOffHeap.java        |    69 -
 .../cache/VMStatsRegionEntryOffHeapIntKey.java  |   224 -
 .../cache/VMStatsRegionEntryOffHeapLongKey.java |   224 -
 .../VMStatsRegionEntryOffHeapObjectKey.java     |   217 -
 .../VMStatsRegionEntryOffHeapStringKey1.java    |   286 -
 .../VMStatsRegionEntryOffHeapStringKey2.java    |   327 -
 .../cache/VMStatsRegionEntryOffHeapUUIDKey.java |   228 -
 .../cache/VMThinDiskLRURegionEntry.java         |    39 -
 .../cache/VMThinDiskLRURegionEntryHeap.java     |    69 -
 .../VMThinDiskLRURegionEntryHeapIntKey.java     |   280 -
 .../VMThinDiskLRURegionEntryHeapLongKey.java    |   280 -
 .../VMThinDiskLRURegionEntryHeapObjectKey.java  |   273 -
 .../VMThinDiskLRURegionEntryHeapStringKey1.java |   342 -
 .../VMThinDiskLRURegionEntryHeapStringKey2.java |   383 -
 .../VMThinDiskLRURegionEntryHeapUUIDKey.java    |   284 -
 .../cache/VMThinDiskLRURegionEntryOffHeap.java  |    69 -
 .../VMThinDiskLRURegionEntryOffHeapIntKey.java  |   329 -
 .../VMThinDiskLRURegionEntryOffHeapLongKey.java |   329 -
 ...MThinDiskLRURegionEntryOffHeapObjectKey.java |   322 -
 ...ThinDiskLRURegionEntryOffHeapStringKey1.java |   391 -
 ...ThinDiskLRURegionEntryOffHeapStringKey2.java |   432 -
 .../VMThinDiskLRURegionEntryOffHeapUUIDKey.java |   333 -
 .../internal/cache/VMThinDiskRegionEntry.java   |    41 -
 .../cache/VMThinDiskRegionEntryHeap.java        |    69 -
 .../cache/VMThinDiskRegionEntryHeapIntKey.java  |   182 -
 .../cache/VMThinDiskRegionEntryHeapLongKey.java |   182 -
 .../VMThinDiskRegionEntryHeapObjectKey.java     |   175 -
 .../VMThinDiskRegionEntryHeapStringKey1.java    |   244 -
 .../VMThinDiskRegionEntryHeapStringKey2.java    |   285 -
 .../cache/VMThinDiskRegionEntryHeapUUIDKey.java |   186 -
 .../cache/VMThinDiskRegionEntryOffHeap.java     |    69 -
 .../VMThinDiskRegionEntryOffHeapIntKey.java     |   231 -
 .../VMThinDiskRegionEntryOffHeapLongKey.java    |   231 -
 .../VMThinDiskRegionEntryOffHeapObjectKey.java  |   224 -
 .../VMThinDiskRegionEntryOffHeapStringKey1.java |   293 -
 .../VMThinDiskRegionEntryOffHeapStringKey2.java |   334 -
 .../VMThinDiskRegionEntryOffHeapUUIDKey.java    |   235 -
 .../internal/cache/VMThinLRURegionEntry.java    |    37 -
 .../cache/VMThinLRURegionEntryHeap.java         |    69 -
 .../cache/VMThinLRURegionEntryHeapIntKey.java   |   191 -
 .../cache/VMThinLRURegionEntryHeapLongKey.java  |   191 -
 .../VMThinLRURegionEntryHeapObjectKey.java      |   184 -
 .../VMThinLRURegionEntryHeapStringKey1.java     |   253 -
 .../VMThinLRURegionEntryHeapStringKey2.java     |   294 -
 .../cache/VMThinLRURegionEntryHeapUUIDKey.java  |   195 -
 .../cache/VMThinLRURegionEntryOffHeap.java      |    69 -
 .../VMThinLRURegionEntryOffHeapIntKey.java      |   240 -
 .../VMThinLRURegionEntryOffHeapLongKey.java     |   240 -
 .../VMThinLRURegionEntryOffHeapObjectKey.java   |   233 -
 .../VMThinLRURegionEntryOffHeapStringKey1.java  |   302 -
 .../VMThinLRURegionEntryOffHeapStringKey2.java  |   343 -
 .../VMThinLRURegionEntryOffHeapUUIDKey.java     |   244 -
 .../internal/cache/VMThinRegionEntry.java       |    35 -
 .../internal/cache/VMThinRegionEntryHeap.java   |    71 -
 .../cache/VMThinRegionEntryHeapIntKey.java      |   109 -
 .../cache/VMThinRegionEntryHeapLongKey.java     |   109 -
 .../cache/VMThinRegionEntryHeapObjectKey.java   |   102 -
 .../cache/VMThinRegionEntryHeapStringKey1.java  |   171 -
 .../cache/VMThinRegionEntryHeapStringKey2.java  |   212 -
 .../cache/VMThinRegionEntryHeapUUIDKey.java     |   113 -
 .../cache/VMThinRegionEntryOffHeap.java         |    71 -
 .../cache/VMThinRegionEntryOffHeapIntKey.java   |   158 -
 .../cache/VMThinRegionEntryOffHeapLongKey.java  |   158 -
 .../VMThinRegionEntryOffHeapObjectKey.java      |   151 -
 .../VMThinRegionEntryOffHeapStringKey1.java     |   220 -
 .../VMThinRegionEntryOffHeapStringKey2.java     |   261 -
 .../cache/VMThinRegionEntryOffHeapUUIDKey.java  |   162 -
 .../internal/cache/ValidatingDiskRegion.java    |   519 -
 .../internal/cache/ValueByteWrapper.java        |    70 -
 .../internal/cache/VersionTimestamp.java        |    47 -
 .../cache/VersionedStatsDiskLRURegionEntry.java |    33 -
 .../VersionedStatsDiskLRURegionEntryHeap.java   |    70 -
 ...sionedStatsDiskLRURegionEntryHeapIntKey.java |   430 -
 ...ionedStatsDiskLRURegionEntryHeapLongKey.java |   430 -
 ...nedStatsDiskLRURegionEntryHeapObjectKey.java |   423 -
 ...edStatsDiskLRURegionEntryHeapStringKey1.java |   492 -
 ...edStatsDiskLRURegionEntryHeapStringKey2.java |   533 -
 ...ionedStatsDiskLRURegionEntryHeapUUIDKey.java |   434 -
 ...VersionedStatsDiskLRURegionEntryOffHeap.java |    70 -
 ...nedStatsDiskLRURegionEntryOffHeapIntKey.java |   479 -
 ...edStatsDiskLRURegionEntryOffHeapLongKey.java |   479 -
 ...StatsDiskLRURegionEntryOffHeapObjectKey.java |   472 -
 ...tatsDiskLRURegionEntryOffHeapStringKey1.java |   541 -
 ...tatsDiskLRURegionEntryOffHeapStringKey2.java |   582 -
 ...edStatsDiskLRURegionEntryOffHeapUUIDKey.java |   483 -
 .../cache/VersionedStatsDiskRegionEntry.java    |    33 -
 .../VersionedStatsDiskRegionEntryHeap.java      |    70 -
 ...VersionedStatsDiskRegionEntryHeapIntKey.java |   333 -
 ...ersionedStatsDiskRegionEntryHeapLongKey.java |   333 -
 ...sionedStatsDiskRegionEntryHeapObjectKey.java |   326 -
 ...ionedStatsDiskRegionEntryHeapStringKey1.java |   395 -
 ...ionedStatsDiskRegionEntryHeapStringKey2.java |   436 -
 ...ersionedStatsDiskRegionEntryHeapUUIDKey.java |   337 -
 .../VersionedStatsDiskRegionEntryOffHeap.java   |    70 -
 ...sionedStatsDiskRegionEntryOffHeapIntKey.java |   382 -
 ...ionedStatsDiskRegionEntryOffHeapLongKey.java |   382 -
 ...nedStatsDiskRegionEntryOffHeapObjectKey.java |   375 -
 ...edStatsDiskRegionEntryOffHeapStringKey1.java |   444 -
 ...edStatsDiskRegionEntryOffHeapStringKey2.java |   485 -
 ...ionedStatsDiskRegionEntryOffHeapUUIDKey.java |   386 -
 .../cache/VersionedStatsLRURegionEntry.java     |    34 -
 .../cache/VersionedStatsLRURegionEntryHeap.java |    70 -
 .../VersionedStatsLRURegionEntryHeapIntKey.java |   341 -
 ...VersionedStatsLRURegionEntryHeapLongKey.java |   341 -
 ...rsionedStatsLRURegionEntryHeapObjectKey.java |   334 -
 ...sionedStatsLRURegionEntryHeapStringKey1.java |   403 -
 ...sionedStatsLRURegionEntryHeapStringKey2.java |   444 -
 ...VersionedStatsLRURegionEntryHeapUUIDKey.java |   345 -
 .../VersionedStatsLRURegionEntryOffHeap.java    |    70 -
 ...rsionedStatsLRURegionEntryOffHeapIntKey.java |   390 -
 ...sionedStatsLRURegionEntryOffHeapLongKey.java |   390 -
 ...onedStatsLRURegionEntryOffHeapObjectKey.java |   383 -
 ...nedStatsLRURegionEntryOffHeapStringKey1.java |   452 -
 ...nedStatsLRURegionEntryOffHeapStringKey2.java |   493 -
 ...sionedStatsLRURegionEntryOffHeapUUIDKey.java |   394 -
 .../cache/VersionedStatsRegionEntry.java        |    34 -
 .../cache/VersionedStatsRegionEntryHeap.java    |    69 -
 .../VersionedStatsRegionEntryHeapIntKey.java    |   260 -
 .../VersionedStatsRegionEntryHeapLongKey.java   |   260 -
 .../VersionedStatsRegionEntryHeapObjectKey.java |   253 -
 ...VersionedStatsRegionEntryHeapStringKey1.java |   322 -
 ...VersionedStatsRegionEntryHeapStringKey2.java |   363 -
 .../VersionedStatsRegionEntryHeapUUIDKey.java   |   264 -
 .../cache/VersionedStatsRegionEntryOffHeap.java |    69 -
 .../VersionedStatsRegionEntryOffHeapIntKey.java |   309 -
 ...VersionedStatsRegionEntryOffHeapLongKey.java |   309 -
 ...rsionedStatsRegionEntryOffHeapObjectKey.java |   302 -
 ...sionedStatsRegionEntryOffHeapStringKey1.java |   371 -
 ...sionedStatsRegionEntryOffHeapStringKey2.java |   412 -
 ...VersionedStatsRegionEntryOffHeapUUIDKey.java |   313 -
 .../cache/VersionedThinDiskLRURegionEntry.java  |    33 -
 .../VersionedThinDiskLRURegionEntryHeap.java    |    70 -
 ...rsionedThinDiskLRURegionEntryHeapIntKey.java |   365 -
 ...sionedThinDiskLRURegionEntryHeapLongKey.java |   365 -
 ...onedThinDiskLRURegionEntryHeapObjectKey.java |   358 -
 ...nedThinDiskLRURegionEntryHeapStringKey1.java |   427 -
 ...nedThinDiskLRURegionEntryHeapStringKey2.java |   468 -
 ...sionedThinDiskLRURegionEntryHeapUUIDKey.java |   369 -
 .../VersionedThinDiskLRURegionEntryOffHeap.java |    70 -
 ...onedThinDiskLRURegionEntryOffHeapIntKey.java |   414 -
 ...nedThinDiskLRURegionEntryOffHeapLongKey.java |   414 -
 ...dThinDiskLRURegionEntryOffHeapObjectKey.java |   407 -
 ...ThinDiskLRURegionEntryOffHeapStringKey1.java |   476 -
 ...ThinDiskLRURegionEntryOffHeapStringKey2.java |   517 -
 ...nedThinDiskLRURegionEntryOffHeapUUIDKey.java |   418 -
 .../cache/VersionedThinDiskRegionEntry.java     |    33 -
 .../cache/VersionedThinDiskRegionEntryHeap.java |    70 -
 .../VersionedThinDiskRegionEntryHeapIntKey.java |   267 -
 ...VersionedThinDiskRegionEntryHeapLongKey.java |   267 -
 ...rsionedThinDiskRegionEntryHeapObjectKey.java |   260 -
 ...sionedThinDiskRegionEntryHeapStringKey1.java |   329 -
 ...sionedThinDiskRegionEntryHeapStringKey2.java |   370 -
 ...VersionedThinDiskRegionEntryHeapUUIDKey.java |   271 -
 .../VersionedThinDiskRegionEntryOffHeap.java    |    70 -
 ...rsionedThinDiskRegionEntryOffHeapIntKey.java |   316 -
 ...sionedThinDiskRegionEntryOffHeapLongKey.java |   316 -
 ...onedThinDiskRegionEntryOffHeapObjectKey.java |   309 -
 ...nedThinDiskRegionEntryOffHeapStringKey1.java |   378 -
 ...nedThinDiskRegionEntryOffHeapStringKey2.java |   419 -
 ...sionedThinDiskRegionEntryOffHeapUUIDKey.java |   320 -
 .../cache/VersionedThinLRURegionEntry.java      |    38 -
 .../cache/VersionedThinLRURegionEntryHeap.java  |    69 -
 .../VersionedThinLRURegionEntryHeapIntKey.java  |   276 -
 .../VersionedThinLRURegionEntryHeapLongKey.java |   276 -
 ...ersionedThinLRURegionEntryHeapObjectKey.java |   269 -
 ...rsionedThinLRURegionEntryHeapStringKey1.java |   338 -
 ...rsionedThinLRURegionEntryHeapStringKey2.java |   379 -
 .../VersionedThinLRURegionEntryHeapUUIDKey.java |   280 -
 .../VersionedThinLRURegionEntryOffHeap.java     |    69 -
 ...ersionedThinLRURegionEntryOffHeapIntKey.java |   325 -
 ...rsionedThinLRURegionEntryOffHeapLongKey.java |   325 -
 ...ionedThinLRURegionEntryOffHeapObjectKey.java |   318 -
 ...onedThinLRURegionEntryOffHeapStringKey1.java |   387 -
 ...onedThinLRURegionEntryOffHeapStringKey2.java |   428 -
 ...rsionedThinLRURegionEntryOffHeapUUIDKey.java |   329 -
 .../cache/VersionedThinRegionEntry.java         |    33 -
 .../cache/VersionedThinRegionEntryHeap.java     |    69 -
 .../VersionedThinRegionEntryHeapIntKey.java     |   194 -
 .../VersionedThinRegionEntryHeapLongKey.java    |   194 -
 .../VersionedThinRegionEntryHeapObjectKey.java  |   187 -
 .../VersionedThinRegionEntryHeapStringKey1.java |   256 -
 .../VersionedThinRegionEntryHeapStringKey2.java |   297 -
 .../VersionedThinRegionEntryHeapUUIDKey.java    |   198 -
 .../cache/VersionedThinRegionEntryOffHeap.java  |    69 -
 .../VersionedThinRegionEntryOffHeapIntKey.java  |   243 -
 .../VersionedThinRegionEntryOffHeapLongKey.java |   243 -
 ...ersionedThinRegionEntryOffHeapObjectKey.java |   236 -
 ...rsionedThinRegionEntryOffHeapStringKey1.java |   305 -
 ...rsionedThinRegionEntryOffHeapStringKey2.java |   346 -
 .../VersionedThinRegionEntryOffHeapUUIDKey.java |   247 -
 .../internal/cache/WrappedCallbackArgument.java |   105 -
 .../cache/WrappedRegionMembershipListener.java  |   200 -
 .../CompressedCachedDeserializable.java         |   197 -
 .../SnappyCompressedCachedDeserializable.java   |    83 -
 .../internal/cache/control/FilterByPath.java    |    66 -
 .../cache/control/HeapMemoryMonitor.java        |   881 -
 .../cache/control/InternalResourceManager.java  |   620 -
 .../internal/cache/control/MemoryEvent.java     |    93 -
 .../cache/control/MemoryThresholds.java         |   282 -
 .../cache/control/OffHeapMemoryMonitor.java     |   562 -
 .../control/PartitionRebalanceDetailsImpl.java  |   159 -
 .../cache/control/RebalanceOperationImpl.java   |   263 -
 .../cache/control/RebalanceResultsImpl.java     |   104 -
 .../internal/cache/control/RegionFilter.java    |    27 -
 .../internal/cache/control/ResourceAdvisor.java |   475 -
 .../internal/cache/control/ResourceEvent.java   |    33 -
 .../cache/control/ResourceListener.java         |    33 -
 .../cache/control/ResourceManagerStats.java     |   607 -
 .../internal/cache/control/ResourceMonitor.java |    54 -
 .../gemfire/internal/cache/delta/Delta.java     |    57 -
 .../cache/doc-files/BucketAdvisor-state.png     |   Bin 39148 -> 0 bytes
 .../internal/cache/doc-files/eventmatrix.xls    |   Bin 24576 -> 0 bytes
 .../cache/doc-files/extensible-hashing.fig      |   159 -
 .../cache/doc-files/extensible-hashing.gif      |   Bin 6605 -> 0 bytes
 .../cache/doc-files/jcache-get-flow.fig         |   349 -
 .../cache/doc-files/jcache-get-flow.pdf         |   Bin 7519 -> 0 bytes
 .../cache/doc-files/jcache-put-flow.fig         |   359 -
 .../cache/doc-files/jcache-put-flow.pdf         |   Bin 7667 -> 0 bytes
 .../doc-files/jcache-update-message-flow.fig    |   334 -
 .../doc-files/jcache-update-message-flow.pdf    |   Bin 5937 -> 0 bytes
 .../cache/doc-files/partitioned-regions.fig     |   255 -
 .../cache/doc-files/partitioned-regions.gif     |   Bin 9273 -> 0 bytes
 .../internal/cache/doc-files/properties.html    |  3937 ----
 .../cache/doc-files/region-implementation.fig   |   262 -
 .../cache/execute/AbstractExecution.java        |   635 -
 .../cache/execute/BucketMovedException.java     |    57 -
 .../cache/execute/DefaultResultCollector.java   |   108 -
 .../DistributedRegionFunctionExecutor.java      |   444 -
 .../DistributedRegionFunctionResultSender.java  |   263 -
 .../DistributedRegionFunctionResultWaiter.java  |    60 -
 .../cache/execute/FunctionContextImpl.java      |   107 -
 .../execute/FunctionExecutionNodePruner.java    |   260 -
 .../cache/execute/FunctionRemoteContext.java    |   131 -
 .../cache/execute/FunctionServiceStats.java     |   440 -
 .../internal/cache/execute/FunctionStats.java   |   536 -
 .../FunctionStreamingResultCollector.java       |   636 -
 .../cache/execute/InternalExecution.java        |   112 -
 .../execute/InternalFunctionException.java      |    78 -
 ...ternalFunctionInvocationTargetException.java |    96 -
 .../cache/execute/InternalFunctionService.java  |   199 -
 .../execute/InternalRegionFunctionContext.java  |    84 -
 .../cache/execute/InternalResultSender.java     |    35 -
 .../cache/execute/LocalResultCollector.java     |    43 -
 .../cache/execute/LocalResultCollectorImpl.java |   212 -
 .../cache/execute/MemberFunctionExecutor.java   |   283 -
 .../execute/MemberFunctionResultSender.java     |   278 -
 .../execute/MemberFunctionResultWaiter.java     |    51 -
 .../cache/execute/MemberMappedArgument.java     |    74 -
 .../execute/MultiRegionFunctionContext.java     |    50 -
 .../execute/MultiRegionFunctionContextImpl.java |    56 -
 .../execute/MultiRegionFunctionExecutor.java    |   416 -
 .../MultiRegionFunctionResultWaiter.java        |    61 -
 .../internal/cache/execute/NoResult.java        |    79 -
 .../PartitionedRegionFunctionExecutor.java      |   378 -
 .../PartitionedRegionFunctionResultSender.java  |   340 -
 .../PartitionedRegionFunctionResultWaiter.java  |   125 -
 .../execute/RegionFunctionContextImpl.java      |   160 -
 .../cache/execute/ServerFunctionExecutor.java   |   428 -
 .../execute/ServerRegionFunctionExecutor.java   |   501 -
 .../ServerToClientFunctionResultSender.java     |   319 -
 .../ServerToClientFunctionResultSender65.java   |   289 -
 .../execute/StreamingFunctionOperation.java     |   127 -
 .../cache/execute/util/CommitFunction.java      |   142 -
 .../util/FindRestEnabledServersFunction.java    |    83 -
 .../execute/util/NestedTransactionFunction.java |   117 -
 .../cache/execute/util/RollbackFunction.java    |   137 -
 .../internal/cache/extension/Extensible.java    |    43 -
 .../internal/cache/extension/Extension.java     |    53 -
 .../cache/extension/ExtensionPoint.java         |    65 -
 .../cache/extension/SimpleExtensionPoint.java   |    85 -
 .../internal/cache/ha/HAContainerMap.java       |   203 -
 .../internal/cache/ha/HAContainerRegion.java    |   170 -
 .../internal/cache/ha/HAContainerWrapper.java   |    47 -
 .../internal/cache/ha/HARegionQueue.java        |  4226 ----
 .../cache/ha/HARegionQueueAttributes.java       |   109 -
 .../internal/cache/ha/HARegionQueueStats.java   |   411 -
 .../internal/cache/ha/QueueRemovalMessage.java  |   240 -
 .../internal/cache/ha/ThreadIdentifier.java     |   330 -
 .../cache/locks/TXLessorDepartureHandler.java   |   102 -
 .../internal/cache/locks/TXLockBatch.java       |   148 -
 .../gemfire/internal/cache/locks/TXLockId.java  |    35 -
 .../internal/cache/locks/TXLockIdImpl.java      |   140 -
 .../internal/cache/locks/TXLockService.java     |   161 -
 .../internal/cache/locks/TXLockServiceImpl.java |   278 -
 .../internal/cache/locks/TXLockToken.java       |    95 -
 .../locks/TXLockUpdateParticipantsMessage.java  |   186 -
 .../locks/TXOriginatorRecoveryProcessor.java    |   312 -
 .../locks/TXRecoverGrantorMessageProcessor.java |   157 -
 .../cache/locks/TXRegionLockRequest.java        |    39 -
 .../gemfire/internal/cache/lru/EnableLRU.java   |   122 -
 .../gemfire/internal/cache/lru/HeapEvictor.java |   492 -
 .../cache/lru/HeapLRUCapacityController.java    |   335 -
 .../internal/cache/lru/HeapLRUStatistics.java   |    68 -
 .../internal/cache/lru/LRUAlgorithm.java        |   352 -
 .../cache/lru/LRUCapacityController.java        |   356 -
 .../internal/cache/lru/LRUClockNode.java        |    45 -
 .../gemfire/internal/cache/lru/LRUEntry.java    |    32 -
 .../internal/cache/lru/LRUMapCallbacks.java     |    61 -
 .../internal/cache/lru/LRUStatistics.java       |   210 -
 .../cache/lru/MemLRUCapacityController.java     |   545 -
 .../internal/cache/lru/NewLIFOClockHand.java    |    98 -
 .../internal/cache/lru/NewLRUClockHand.java     |   468 -
 .../internal/cache/lru/OffHeapEvictor.java      |    97 -
 .../gemfire/internal/cache/lru/Sizeable.java    |    63 -
 .../operations/ContainsKeyOperationContext.java |    52 -
 .../gemfire/internal/cache/package.html         |   241 -
 .../AllBucketProfilesUpdateMessage.java         |   170 -
 .../partitioned/BecomePrimaryBucketMessage.java |   332 -
 .../internal/cache/partitioned/Bucket.java      |    80 -
 .../cache/partitioned/BucketBackupMessage.java  |   137 -
 .../cache/partitioned/BucketCountLoadProbe.java |    75 -
 .../partitioned/BucketProfileUpdateMessage.java |   192 -
 .../cache/partitioned/BucketSizeMessage.java    |   286 -
 .../partitioned/ContainsKeyValueMessage.java    |   348 -
 .../cache/partitioned/CreateBucketMessage.java  |   371 -
 .../partitioned/CreateMissingBucketsTask.java   |    70 -
 .../partitioned/DeposePrimaryBucketMessage.java |   285 -
 .../cache/partitioned/DestroyMessage.java       |   621 -
 .../DestroyRegionOnDataStoreMessage.java        |   118 -
 .../partitioned/DumpAllPRConfigMessage.java     |    77 -
 .../cache/partitioned/DumpB2NRegion.java        |   343 -
 .../cache/partitioned/DumpBucketsMessage.java   |   111 -
 .../partitioned/EndBucketCreationMessage.java   |   149 -
 .../partitioned/FetchBulkEntriesMessage.java    |   670 -
 .../cache/partitioned/FetchEntriesMessage.java  |   659 -
 .../cache/partitioned/FetchEntryMessage.java    |   431 -
 .../cache/partitioned/FetchKeysMessage.java     |   574 -
 .../FetchPartitionDetailsMessage.java           |   397 -
 .../cache/partitioned/FlushMessage.java         |   154 -
 .../internal/cache/partitioned/GetMessage.java  |   669 -
 .../partitioned/IdentityRequestMessage.java     |   342 -
 .../partitioned/IdentityUpdateMessage.java      |   167 -
 .../cache/partitioned/IndexCreationMsg.java     |   687 -
 .../cache/partitioned/InterestEventMessage.java |   284 -
 .../cache/partitioned/InternalPRInfo.java       |    44 -
 .../partitioned/InternalPartitionDetails.java   |    45 -
 .../cache/partitioned/InvalidateMessage.java    |   409 -
 .../internal/cache/partitioned/LoadProbe.java   |    33 -
 .../internal/cache/partitioned/LockObject.java  |    42 -
 .../partitioned/ManageBackupBucketMessage.java  |   437 -
 .../cache/partitioned/ManageBucketMessage.java  |   419 -
 .../cache/partitioned/MoveBucketMessage.java    |   324 -
 .../cache/partitioned/OfflineMemberDetails.java |    48 -
 .../partitioned/OfflineMemberDetailsImpl.java   |    79 -
 .../cache/partitioned/PREntriesIterator.java    |    44 -
 .../PRFunctionStreamingResultCollector.java     |   436 -
 .../internal/cache/partitioned/PRLoad.java      |   154 -
 .../PRLocallyDestroyedException.java            |    40 -
 .../cache/partitioned/PRSanityCheckMessage.java |   164 -
 .../cache/partitioned/PRTombstoneMessage.java   |   182 -
 .../PRUpdateEntryVersionMessage.java            |   295 -
 .../partitioned/PartitionMemberInfoImpl.java    |   167 -
 .../cache/partitioned/PartitionMessage.java     |   849 -
 .../PartitionMessageWithDirectReply.java        |   141 -
 .../partitioned/PartitionRegionInfoImpl.java    |   139 -
 ...rtitionedRegionFunctionStreamingMessage.java |   205 -
 .../partitioned/PartitionedRegionObserver.java  |    44 -
 .../PartitionedRegionObserverAdapter.java       |    47 -
 .../PartitionedRegionObserverHolder.java        |    63 -
 .../PartitionedRegionRebalanceOp.java           |   913 -
 .../partitioned/PrimaryRequestMessage.java      |   238 -
 .../cache/partitioned/PutAllPRMessage.java      |   912 -
 .../internal/cache/partitioned/PutMessage.java  |  1380 --
 .../cache/partitioned/QueryMessage.java         |   326 -
 .../cache/partitioned/RecoveryRunnable.java     |    86 -
 .../RedundancyAlreadyMetException.java          |    42 -
 .../cache/partitioned/RedundancyLogger.java     |   395 -
 .../cache/partitioned/RegionAdvisor.java        |  1965 --
 .../partitioned/RemoteFetchKeysMessage.java     |   489 -
 .../cache/partitioned/RemoteSizeMessage.java    |   363 -
 .../cache/partitioned/RemoveAllPRMessage.java   |   823 -
 .../cache/partitioned/RemoveBucketMessage.java  |   323 -
 .../cache/partitioned/RemoveIndexesMessage.java |   545 -
 .../internal/cache/partitioned/SizeMessage.java |   379 -
 .../cache/partitioned/SizedBasedLoadProbe.java  |    83 -
 .../StreamingPartitionOperation.java            |   471 -
 .../partitioned/rebalance/BucketOperator.java   |   101 -
 .../rebalance/CompositeDirector.java            |   127 -
 .../rebalance/ExplicitMoveDirector.java         |    99 -
 .../partitioned/rebalance/FPRDirector.java      |    79 -
 .../partitioned/rebalance/MoveBuckets.java      |    63 -
 .../partitioned/rebalance/MovePrimaries.java    |    63 -
 .../partitioned/rebalance/MovePrimariesFPR.java |   105 -
 .../rebalance/ParallelBucketOperator.java       |   167 -
 .../rebalance/PartitionedRegionLoadModel.java   |  1640 --
 .../rebalance/PercentageMoveDirector.java       |   165 -
 .../rebalance/RebalanceDirector.java            |    79 -
 .../rebalance/RebalanceDirectorAdapter.java     |    39 -
 .../rebalance/RemoveOverRedundancy.java         |    82 -
 .../rebalance/SatisfyRedundancy.java            |    92 -
 .../rebalance/SatisfyRedundancyFPR.java         |    90 -
 .../rebalance/SimulatedBucketOperator.java      |    55 -
 .../cache/persistence/BackupInspector.java      |   345 -
 .../cache/persistence/BackupManager.java        |   377 -
 .../cache/persistence/BytesAndBits.java         |    51 -
 .../cache/persistence/CanonicalIdHolder.java    |   101 -
 .../CreatePersistentRegionProcessor.java        |    58 -
 .../cache/persistence/DiskExceptionHandler.java |    38 -
 .../persistence/DiskInitFileInterpreter.java    |   148 -
 .../cache/persistence/DiskInitFileParser.java   |   652 -
 .../cache/persistence/DiskRecoveryStore.java    |    64 -
 .../cache/persistence/DiskRegionView.java       |   109 -
 .../cache/persistence/DiskStoreFilter.java      |    57 -
 .../internal/cache/persistence/DiskStoreID.java |   167 -
 .../persistence/MembershipFlushRequest.java     |   141 -
 .../persistence/MembershipViewRequest.java      |   254 -
 .../internal/cache/persistence/OplogType.java   |    32 -
 .../cache/persistence/PRPersistentConfig.java   |    74 -
 .../cache/persistence/PersistenceAdvisor.java   |   190 -
 .../persistence/PersistenceAdvisorImpl.java     |  1300 --
 .../persistence/PersistenceObserverHolder.java  |   102 -
 .../cache/persistence/PersistentMemberID.java   |   171 -
 .../persistence/PersistentMemberManager.java    |   270 -
 .../persistence/PersistentMemberPattern.java    |   229 -
 .../persistence/PersistentMemberState.java      |    41 -
 .../cache/persistence/PersistentMemberView.java |   150 -
 .../persistence/PersistentMembershipView.java   |   112 -
 .../persistence/PersistentStateListener.java    |    38 -
 .../PersistentStateQueryMessage.java            |   308 -
 .../PersistentStateQueryResults.java            |    57 -
 .../PrepareNewPersistentMemberMessage.java      |   168 -
 .../RemovePersistentMemberMessage.java          |   182 -
 .../cache/persistence/RestoreScript.java        |   223 -
 .../persistence/UninterruptibleFileChannel.java |    29 -
 .../UninterruptibleRandomAccessFile.java        |   251 -
 .../persistence/query/CloseableIterator.java    |    33 -
 .../persistence/query/IdentityExtractor.java    |    26 -
 .../cache/persistence/query/IndexMap.java       |   187 -
 .../cache/persistence/query/ResultBag.java      |    60 -
 .../cache/persistence/query/ResultList.java     |    58 -
 .../cache/persistence/query/ResultMap.java      |   124 -
 .../cache/persistence/query/ResultSet.java      |    60 -
 .../persistence/query/SortKeyExtractor.java     |    21 -
 .../query/TemporaryResultSetFactory.java        |    79 -
 .../persistence/query/mock/ByteComparator.java  |    86 -
 .../mock/CachedDeserializableComparator.java    |    54 -
 .../persistence/query/mock/IndexMapImpl.java    |   278 -
 .../persistence/query/mock/ItrAdapter.java      |    62 -
 .../query/mock/NaturalComparator.java           |    33 -
 .../cache/persistence/query/mock/Pair.java      |    72 -
 .../persistence/query/mock/PairComparator.java  |    46 -
 .../persistence/query/mock/ResultListImpl.java  |    55 -
 .../query/mock/ReverseComparator.java           |    40 -
 .../query/mock/SortedResultBagImpl.java         |    64 -
 .../query/mock/SortedResultMapImpl.java         |   184 -
 .../query/mock/SortedResultSetImpl.java         |    52 -
 .../persistence/soplog/ByteComparator.java      |    56 -
 .../persistence/soplog/CursorIterator.java      |    82 -
 .../soplog/DelegatingSerializedComparator.java  |    38 -
 .../soplog/HFileStoreStatistics.java            |   205 -
 .../persistence/soplog/KeyValueIterator.java    |    43 -
 .../soplog/SortedOplogStatistics.java           |   505 -
 .../cache/persistence/soplog/SortedReader.java  |   256 -
 .../persistence/soplog/TrackedReference.java    |   154 -
 .../region/entry/RegionEntryFactoryBuilder.java |   103 -
 .../snapshot/CacheSnapshotServiceImpl.java      |   130 -
 .../internal/cache/snapshot/ClientExporter.java |   229 -
 .../cache/snapshot/ExportedRegistry.java        |   104 -
 .../internal/cache/snapshot/FlowController.java |   350 -
 .../internal/cache/snapshot/GFSnapshot.java     |   417 -
 .../internal/cache/snapshot/LocalExporter.java  |    58 -
 .../snapshot/RegionSnapshotServiceImpl.java     |   565 -
 .../cache/snapshot/SnapshotFileMapper.java      |    93 -
 .../cache/snapshot/SnapshotOptionsImpl.java     |   124 -
 .../internal/cache/snapshot/SnapshotPacket.java |   270 -
 .../cache/snapshot/WindowedExporter.java        |   401 -
 .../gemfire/internal/cache/tier/Acceptor.java   |   115 -
 .../internal/cache/tier/BatchException.java     |    72 -
 .../internal/cache/tier/CachedRegionHelper.java |   109 -
 .../internal/cache/tier/ClientHandShake.java    |    46 -
 .../gemfire/internal/cache/tier/Command.java    |    36 -
 .../internal/cache/tier/ConnectionProxy.java    |    35 -
 .../internal/cache/tier/InterestType.java       |    64 -
 .../cache/tier/InternalClientMembership.java    |   626 -
 .../internal/cache/tier/MessageType.java        |   569 -
 .../gemfire/internal/cache/tier/package.html    |    23 -
 .../cache/tier/sockets/AcceptorImpl.java        |  1872 --
 .../cache/tier/sockets/BaseCommand.java         |  1611 --
 .../cache/tier/sockets/BaseCommandQuery.java    |   578 -
 .../cache/tier/sockets/CacheClientNotifier.java |  2743 ---
 .../tier/sockets/CacheClientNotifierStats.java  |   295 -
 .../cache/tier/sockets/CacheClientProxy.java    |  3116 ---
 .../tier/sockets/CacheClientProxyStats.java     |   405 -
 .../cache/tier/sockets/CacheClientUpdater.java  |  2007 --
 .../cache/tier/sockets/CacheServerHelper.java   |   193 -
 .../cache/tier/sockets/CacheServerStats.java    |  1148 --
 .../cache/tier/sockets/ChunkedMessage.java      |   376 -
 .../tier/sockets/ClientBlacklistProcessor.java  |   174 -
 .../sockets/ClientDataSerializerMessage.java    |   256 -
 .../cache/tier/sockets/ClientHealthMonitor.java |   972 -
 .../tier/sockets/ClientInstantiatorMessage.java |   230 -
 .../tier/sockets/ClientInterestMessageImpl.java |   274 -
 .../tier/sockets/ClientMarkerMessageImpl.java   |   127 -
 .../cache/tier/sockets/ClientMessage.java       |    46 -
 .../tier/sockets/ClientPingMessageImpl.java     |   111 -
 .../tier/sockets/ClientProxyMembershipID.java   |   623 -
 .../tier/sockets/ClientTombstoneMessage.java    |   188 -
 .../cache/tier/sockets/ClientUpdateMessage.java |   188 -
 .../tier/sockets/ClientUpdateMessageImpl.java   |  1725 --
 .../cache/tier/sockets/ClientUserAuths.java     |   201 -
 .../cache/tier/sockets/CommandInitializer.java  |   342 -
 .../cache/tier/sockets/ConnectionListener.java  |    55 -
 .../tier/sockets/ConnectionListenerAdapter.java |    38 -
 .../cache/tier/sockets/HAEventWrapper.java      |   435 -
 .../internal/cache/tier/sockets/HandShake.java  |  1934 --
 .../tier/sockets/InterestResultPolicyImpl.java  |    59 -
 .../internal/cache/tier/sockets/Message.java    |  1116 --
 .../cache/tier/sockets/MessageStats.java        |    29 -
 .../tier/sockets/MessageTooLargeException.java  |    29 -
 .../cache/tier/sockets/ObjectPartList.java      |   273 -
 .../cache/tier/sockets/ObjectPartList651.java   |   166 -
 .../internal/cache/tier/sockets/Part.java       |   452 -
 .../RemoveClientFromBlacklistMessage.java       |   114 -
 .../tier/sockets/SerializedObjectPartList.java  |   132 -
 .../cache/tier/sockets/ServerConnection.java    |  2077 --
 .../tier/sockets/ServerHandShakeProcessor.java  |   464 -
 .../cache/tier/sockets/ServerQueueStatus.java   |   132 -
 .../tier/sockets/ServerResponseMatrix.java      |   141 -
 .../tier/sockets/UnregisterAllInterest.java     |    50 -
 .../cache/tier/sockets/UserAuthAttributes.java  |    81 -
 .../cache/tier/sockets/VersionedObjectList.java |   753 -
 .../cache/tier/sockets/command/AddPdxEnum.java  |    73 -
 .../cache/tier/sockets/command/AddPdxType.java  |    78 -
 .../cache/tier/sockets/command/ClearRegion.java |   150 -
 .../cache/tier/sockets/command/ClientReady.java |    76 -
 .../tier/sockets/command/CloseConnection.java   |    77 -
 .../tier/sockets/command/CommitCommand.java     |   142 -
 .../cache/tier/sockets/command/ContainsKey.java |   145 -
 .../tier/sockets/command/ContainsKey66.java     |   162 -
 .../tier/sockets/command/CreateRegion.java      |   137 -
 .../cache/tier/sockets/command/Default.java     |    52 -
 .../cache/tier/sockets/command/Destroy.java     |   219 -
 .../cache/tier/sockets/command/Destroy65.java   |   340 -
 .../cache/tier/sockets/command/Destroy70.java   |   118 -
 .../tier/sockets/command/DestroyRegion.java     |   175 -
 .../tier/sockets/command/ExecuteFunction.java   |   242 -
 .../tier/sockets/command/ExecuteFunction65.java |   273 -
 .../tier/sockets/command/ExecuteFunction66.java |   431 -
 .../tier/sockets/command/ExecuteFunction70.java |   144 -
 .../sockets/command/ExecuteRegionFunction.java  |   270 -
 .../command/ExecuteRegionFunction61.java        |   292 -
 .../command/ExecuteRegionFunction65.java        |   400 -
 .../command/ExecuteRegionFunction66.java        |   435 -
 .../command/ExecuteRegionFunctionSingleHop.java |   420 -
 .../sockets/command/GatewayReceiverCommand.java |   805 -
 .../cache/tier/sockets/command/Get70.java       |   531 -
 .../cache/tier/sockets/command/GetAll.java      |   260 -
 .../cache/tier/sockets/command/GetAll651.java   |   284 -
 .../cache/tier/sockets/command/GetAll70.java    |   293 -
 .../cache/tier/sockets/command/GetAllForRI.java |    52 -
 .../sockets/command/GetAllWithCallback.java     |   285 -
 .../command/GetClientPRMetadataCommand.java     |   114 -
 .../command/GetClientPRMetadataCommand66.java   |   105 -
 .../GetClientPartitionAttributesCommand.java    |   141 -
 .../GetClientPartitionAttributesCommand66.java  |   158 -
 .../cache/tier/sockets/command/GetEntry70.java  |    77 -
 .../tier/sockets/command/GetEntryCommand.java   |    64 -
 .../sockets/command/GetFunctionAttribute.java   |    81 -
 .../tier/sockets/command/GetPDXEnumById.java    |    73 -
 .../tier/sockets/command/GetPDXIdForEnum.java   |    74 -
 .../tier/sockets/command/GetPDXIdForType.java   |    75 -
 .../tier/sockets/command/GetPDXTypeById.java    |    73 -
 .../tier/sockets/command/GetPdxEnums70.java     |    68 -
 .../tier/sockets/command/GetPdxTypes70.java     |    67 -
 .../cache/tier/sockets/command/Invalid.java     |    49 -
 .../cache/tier/sockets/command/Invalidate.java  |   249 -
 .../tier/sockets/command/Invalidate70.java      |   107 -
 .../cache/tier/sockets/command/KeySet.java      |   193 -
 .../cache/tier/sockets/command/MakePrimary.java |    66 -
 .../tier/sockets/command/ManagementCommand.java |    39 -
 .../cache/tier/sockets/command/PeriodicAck.java |    79 -
 .../cache/tier/sockets/command/Ping.java        |    93 -
 .../cache/tier/sockets/command/Put.java         |   261 -
 .../cache/tier/sockets/command/Put61.java       |   319 -
 .../cache/tier/sockets/command/Put65.java       |   539 -
 .../cache/tier/sockets/command/Put70.java       |   126 -
 .../cache/tier/sockets/command/PutAll.java      |   268 -
 .../cache/tier/sockets/command/PutAll70.java    |   380 -
 .../cache/tier/sockets/command/PutAll80.java    |   469 -
 .../sockets/command/PutAllWithCallback.java     |    53 -
 .../sockets/command/PutUserCredentials.java     |    81 -
 .../cache/tier/sockets/command/Query.java       |   107 -
 .../cache/tier/sockets/command/Query651.java    |   137 -
 .../command/RegisterDataSerializers.java        |   114 -
 .../sockets/command/RegisterInstantiators.java  |   148 -
 .../tier/sockets/command/RegisterInterest.java  |   245 -
 .../sockets/command/RegisterInterest61.java     |   282 -
 .../sockets/command/RegisterInterestList.java   |   253 -
 .../sockets/command/RegisterInterestList61.java |   265 -
 .../sockets/command/RegisterInterestList66.java |   267 -
 .../cache/tier/sockets/command/RemoveAll.java   |   404 -
 .../tier/sockets/command/RemoveUserAuth.java    |    84 -
 .../cache/tier/sockets/command/Request.java     |   278 -
 .../tier/sockets/command/RequestEventValue.java |   176 -
 .../tier/sockets/command/RollbackCommand.java   |    90 -
 .../cache/tier/sockets/command/Size.java        |   167 -
 .../tier/sockets/command/TXFailoverCommand.java |   132 -
 .../command/TXSynchronizationCommand.java       |   210 -
 .../sockets/command/UnregisterInterest.java     |   152 -
 .../sockets/command/UnregisterInterestList.java |   171 -
 .../command/UpdateClientNotification.java       |    79 -
 .../doc-files/communication-architecture.fig    |   158 -
 .../doc-files/communication-architecture.gif    |   Bin 5485 -> 0 bytes
 .../internal/cache/tier/sockets/package.html    |    23 -
 .../cache/tx/AbstractPeerTXRegionStub.java      |    56 -
 .../internal/cache/tx/ClientTXRegionStub.java   |   158 -
 .../internal/cache/tx/ClientTXStateStub.java    |   292 -
 .../cache/tx/DistClientTXStateStub.java         |   140 -
 .../internal/cache/tx/DistTxEntryEvent.java     |   288 -
 .../internal/cache/tx/DistTxKeyInfo.java        |    54 -
 .../cache/tx/DistributedTXRegionStub.java       |   255 -
 .../cache/tx/PartitionedTXRegionStub.java       |   535 -
 .../gemfire/internal/cache/tx/TXRegionStub.java |    65 -
 .../cache/tx/TransactionalOperation.java        |   111 -
 .../cache/versions/CompactVersionHolder.java    |   105 -
 .../ConcurrentCacheModificationException.java   |    41 -
 .../cache/versions/DiskRegionVersionVector.java |   103 -
 .../internal/cache/versions/DiskVersionTag.java |    83 -
 .../internal/cache/versions/RVVException.java   |   207 -
 .../internal/cache/versions/RVVExceptionB.java  |   296 -
 .../internal/cache/versions/RVVExceptionT.java  |   283 -
 .../cache/versions/RegionVersionHolder.java     |   789 -
 .../cache/versions/RegionVersionVector.java     |  1531 --
 .../cache/versions/VMRegionVersionVector.java   |   101 -
 .../internal/cache/versions/VMVersionTag.java   |    74 -
 .../internal/cache/versions/VersionHolder.java  |    57 -
 .../internal/cache/versions/VersionSource.java  |    43 -
 .../internal/cache/versions/VersionStamp.java   |    93 -
 .../internal/cache/versions/VersionTag.java     |   548 -
 .../internal/cache/vmotion/VMotionObserver.java |    44 -
 .../cache/vmotion/VMotionObserverAdapter.java   |    49 -
 .../cache/vmotion/VMotionObserverHolder.java    |    57 -
 .../cache/wan/AbstractGatewaySender.java        |  1331 --
 .../AbstractGatewaySenderEventProcessor.java    |  1353 --
 .../AsyncEventQueueConfigurationException.java  |    73 -
 .../internal/cache/wan/BatchException70.java    |   108 -
 .../cache/wan/DistributedSystemListener.java    |    32 -
 .../cache/wan/GatewayEventFilterImpl.java       |    45 -
 .../cache/wan/GatewayReceiverException.java     |    69 -
 .../cache/wan/GatewayReceiverStats.java         |   278 -
 .../cache/wan/GatewaySenderAdvisor.java         |   747 -
 .../cache/wan/GatewaySenderAttributes.java      |   200 -
 .../GatewaySenderConfigurationException.java    |    49 -
 .../wan/GatewaySenderEventCallbackArgument.java |   201 -
 .../GatewaySenderEventCallbackDispatcher.java   |   203 -
 .../cache/wan/GatewaySenderEventDispatcher.java |    35 -
 .../cache/wan/GatewaySenderEventImpl.java       |  1286 --
 .../cache/wan/GatewaySenderException.java       |    63 -
 .../internal/cache/wan/GatewaySenderStats.java  |   744 -
 .../cache/wan/InternalGatewaySenderFactory.java |    38 -
 .../cache/wan/TransportFilterServerSocket.java  |    40 -
 .../cache/wan/TransportFilterSocket.java        |    78 -
 .../cache/wan/TransportFilterSocketFactory.java |    41 -
 .../internal/cache/wan/WANServiceProvider.java  |    76 -
 .../BucketRegionQueueUnavailableException.java  |    35 -
 ...rentParallelGatewaySenderEventProcessor.java |   376 -
 .../ConcurrentParallelGatewaySenderQueue.java   |   229 -
 .../ParallelGatewaySenderEventProcessor.java    |   245 -
 .../parallel/ParallelGatewaySenderQueue.java    |  1886 --
 .../ParallelQueueBatchRemovalMessage.java       |   279 -
 .../parallel/ParallelQueueRemovalMessage.java   |   282 -
 .../cache/wan/parallel/RREventIDResolver.java   |    54 -
 .../cache/wan/serial/BatchDestroyOperation.java |   243 -
 ...urrentSerialGatewaySenderEventProcessor.java |   386 -
 .../SerialGatewaySenderEventProcessor.java      |   848 -
 .../wan/serial/SerialGatewaySenderQueue.java    |  1300 --
 .../serial/SerialSecondaryGatewayListener.java  |   100 -
 .../internal/cache/wan/spi/WANFactory.java      |    37 -
 .../cache/xmlcache/AbstractXmlParser.java       |    95 -
 .../cache/xmlcache/AsyncEventQueueCreation.java |   223 -
 .../cache/xmlcache/BindingCreation.java         |    61 -
 .../internal/cache/xmlcache/CacheCreation.java  |  1695 --
 .../cache/xmlcache/CacheServerCreation.java     |   257 -
 .../CacheTransactionManagerCreation.java        |   145 -
 .../internal/cache/xmlcache/CacheXml.java       |  1056 -
 .../cache/xmlcache/CacheXmlGenerator.java       |  2877 ---
 .../internal/cache/xmlcache/CacheXmlParser.java |  3795 ----
 .../xmlcache/CacheXmlPropertyResolver.java      |   147 -
 .../CacheXmlPropertyResolverHelper.java         |   152 -
 .../cache/xmlcache/CacheXmlVersion.java         |   132 -
 .../cache/xmlcache/ClientCacheCreation.java     |   306 -
 .../cache/xmlcache/ClientHaQueueCreation.java   |   100 -
 .../internal/cache/xmlcache/Declarable2.java    |    39 -
 .../cache/xmlcache/DefaultEntityResolver2.java  |    75 -
 .../xmlcache/DiskStoreAttributesCreation.java   |   314 -
 .../cache/xmlcache/FunctionServiceCreation.java |    53 -
 .../cache/xmlcache/GatewayReceiverCreation.java |   190 -
 .../cache/xmlcache/GeodeEntityResolver.java     |    58 -
 .../cache/xmlcache/IndexCreationData.java       |   144 -
 .../ParallelAsyncEventQueueCreation.java        |   119 -
 .../xmlcache/ParallelGatewaySenderCreation.java |   123 -
 .../cache/xmlcache/PivotalEntityResolver.java   |    58 -
 .../cache/xmlcache/PropertyResolver.java        |    57 -
 .../xmlcache/RegionAttributesCreation.java      |  1671 --
 .../internal/cache/xmlcache/RegionCreation.java |   969 -
 .../cache/xmlcache/ResourceManagerCreation.java |   215 -
 .../xmlcache/SerialAsyncEventQueueCreation.java |   115 -
 .../xmlcache/SerialGatewaySenderCreation.java   |   115 -
 .../cache/xmlcache/SerializerCreation.java      |   108 -
 .../internal/cache/xmlcache/XmlGenerator.java   |    62 -
 .../cache/xmlcache/XmlGeneratorUtils.java       |   151 -
 .../internal/cache/xmlcache/XmlParser.java      |    58 -
 .../internal/cache/xmlcache/package.html        |    32 -
 .../gemfire/internal/concurrent/AL.java         |   127 -
 .../internal/concurrent/AtomicLong5.java        |    48 -
 .../gemfire/internal/concurrent/Atomics.java    |    67 -
 .../concurrent/CompactConcurrentHashSet2.java   |  2514 ---
 .../internal/concurrent/ConcurrentHashSet.java  |    89 -
 .../gemfire/internal/concurrent/LI.java         |    95 -
 .../internal/concurrent/MapCallback.java        |   269 -
 .../internal/concurrent/MapCallbackAdapter.java |   140 -
 .../gemfire/internal/concurrent/MapResult.java  |    43 -
 .../internal/datasource/AbstractDataSource.java |   241 -
 .../internal/datasource/AbstractPoolCache.java  |   553 -
 .../ClientConnectionFactoryWrapper.java         |    54 -
 .../internal/datasource/ConfigProperty.java     |    65 -
 .../ConfiguredDataSourceProperties.java         |   288 -
 .../ConnectionEventListenerAdaptor.java         |    76 -
 .../datasource/ConnectionPoolCache.java         |    52 -
 .../datasource/ConnectionPoolCacheImpl.java     |   104 -
 .../internal/datasource/ConnectionProvider.java |    50 -
 .../datasource/ConnectionProviderException.java |    67 -
 .../datasource/DataSourceCreateException.java   |    62 -
 .../internal/datasource/DataSourceFactory.java  |   374 -
 .../datasource/DataSourceResources.java         |    49 -
 .../FacetsJCAConnectionManagerImpl.java         |   269 -
 .../datasource/GemFireBasicDataSource.java      |   150 -
 .../datasource/GemFireConnPooledDataSource.java |   225 -
 .../GemFireConnectionPoolManager.java           |   108 -
 .../GemFireTransactionDataSource.java           |   264 -
 .../datasource/JCAConnectionManagerImpl.java    |   220 -
 .../datasource/ManagedPoolCacheImpl.java        |   104 -
 .../internal/datasource/PoolException.java      |    55 -
 .../internal/datasource/TranxPoolCacheImpl.java |   102 -
 .../gemfire/internal/doc-files/cs-maps.fig      |   150 -
 .../gemfire/internal/doc-files/cs-maps.gif      |   Bin 5951 -> 0 bytes
 .../gemfire/internal/doc-files/ds-map.fig       |   105 -
 .../gemfire/internal/doc-files/ds-map.gif       |   Bin 4867 -> 0 bytes
 .../internal/doc-files/merge-log-files.fig      |   153 -
 .../internal/doc-files/merge-log-files.gif      |   Bin 2646 -> 0 bytes
 .../com/gemstone/gemfire/internal/hll/Bits.java |    48 -
 .../internal/hll/CardinalityMergeException.java |    26 -
 .../gemfire/internal/hll/HyperLogLog.java       |   345 -
 .../gemfire/internal/hll/HyperLogLogPlus.java   |  1053 -
 .../gemstone/gemfire/internal/hll/IBuilder.java |    24 -
 .../gemfire/internal/hll/ICardinality.java      |    72 -
 .../gemfire/internal/hll/MurmurHash.java        |   245 -
 .../gemfire/internal/hll/RegisterSet.java       |   110 -
 .../i18n/AbstractStringIdResourceBundle.java    |   156 -
 .../gemfire/internal/i18n/LocalizedStrings.java |  2161 ---
 .../internal/i18n/ParentLocalizedStrings.java   |  2399 ---
 .../gemfire/internal/i18n/StringId.java         |    58 -
 .../internal/io/CompositeOutputStream.java      |   176 -
 .../internal/io/CompositePrintStream.java       |    79 -
 .../gemfire/internal/io/TeeOutputStream.java    |    93 -
 .../gemfire/internal/io/TeePrintStream.java     |    45 -
 .../gemfire/internal/jndi/ContextImpl.java      |   779 -
 .../jndi/InitialContextFactoryImpl.java         |   102 -
 .../gemfire/internal/jndi/JNDIInvoker.java      |   401 -
 .../gemfire/internal/jndi/NameParserImpl.java   |    55 -
 .../gemfire/internal/jta/GlobalTransaction.java |   732 -
 .../gemfire/internal/jta/TransactionImpl.java   |   270 -
 .../internal/jta/TransactionManagerImpl.java    |   867 -
 .../gemfire/internal/jta/TransactionUtils.java  |    59 -
 .../internal/jta/UserTransactionImpl.java       |   145 -
 .../gemstone/gemfire/internal/jta/XidImpl.java  |    94 -
 .../gemfire/internal/lang/ClassUtils.java       |   131 -
 .../gemstone/gemfire/internal/lang/Filter.java  |    30 -
 .../gemfire/internal/lang/InOutParameter.java   |   102 -
 .../gemfire/internal/lang/Initable.java         |    36 -
 .../gemfire/internal/lang/Initializer.java      |    46 -
 .../internal/lang/MutableIdentifiable.java      |    39 -
 .../gemfire/internal/lang/ObjectUtils.java      |   192 -
 .../gemfire/internal/lang/Orderable.java        |    41 -
 .../gemstone/gemfire/internal/lang/Ordered.java |    44 -
 .../gemfire/internal/lang/StringUtils.java      |   716 -
 .../gemfire/internal/lang/SystemUtils.java      |   244 -
 .../gemfire/internal/lang/ThreadUtils.java      |   131 -
 .../gemfire/internal/logging/DateFormatter.java |    94 -
 .../internal/logging/DebugLogWriter.java        |   126 -
 .../internal/logging/GemFireFormatter.java      |   104 -
 .../internal/logging/GemFireHandler.java        |    81 -
 .../gemfire/internal/logging/GemFireLevel.java  |    78 -
 .../internal/logging/InternalLogWriter.java     |   134 -
 .../internal/logging/LocalLogWriter.java        |    95 -
 .../gemfire/internal/logging/LogConfig.java     |    63 -
 .../gemfire/internal/logging/LogFileParser.java |   513 -
 .../gemfire/internal/logging/LogService.java    |   279 -
 .../internal/logging/LogWriterFactory.java      |   109 -
 .../gemfire/internal/logging/LogWriterImpl.java |  1051 -
 .../internal/logging/LoggingThreadGroup.java    |   347 -
 .../internal/logging/ManagerLogWriter.java      |   692 -
 .../gemfire/internal/logging/MergeLogFiles.java |  1008 -
 .../gemfire/internal/logging/PureLogWriter.java |   283 -
 .../logging/SecurityLocalLogWriter.java         |    87 -
 .../internal/logging/SecurityLogConfig.java     |    66 -
 .../internal/logging/SecurityLogWriter.java     |    80 -
 .../logging/SecurityManagerLogWriter.java       |    73 -
 .../gemfire/internal/logging/SortLogFile.java   |   149 -
 .../internal/logging/StandardErrorPrinter.java  |    43 -
 .../internal/logging/StandardOutputPrinter.java |    43 -
 .../internal/logging/log4j/AlertAppender.java   |   351 -
 .../internal/logging/log4j/AppenderContext.java |    80 -
 .../internal/logging/log4j/ConfigLocator.java   |    85 -
 .../internal/logging/log4j/Configurator.java    |   205 -
 .../internal/logging/log4j/FastLogger.java      |    79 -
 .../internal/logging/log4j/GemFireLogger.java   |   923 -
 .../logging/log4j/LocalizedMessage.java         |    81 -
 .../internal/logging/log4j/LogMarker.java       |    98 -
 .../logging/log4j/LogWriterAppender.java        |   212 -
 .../logging/log4j/LogWriterAppenders.java       |   299 -
 .../internal/logging/log4j/LogWriterLogger.java |  2035 --
 .../logging/log4j/ThreadIdPatternConverter.java |    61 -
 .../gemfire/internal/memcached/Command.java     |   501 -
 .../internal/memcached/CommandProcessor.java    |    42 -
 .../internal/memcached/ConnectionHandler.java   |    93 -
 .../gemfire/internal/memcached/KeyWrapper.java  |    95 -
 .../gemfire/internal/memcached/Reply.java       |   121 -
 .../internal/memcached/RequestReader.java       |   291 -
 .../internal/memcached/ResponseStatus.java      |    64 -
 .../internal/memcached/ValueWrapper.java        |   146 -
 .../memcached/commands/AbstractCommand.java     |   223 -
 .../internal/memcached/commands/AddCommand.java |    90 -
 .../memcached/commands/AddQCommand.java         |    30 -
 .../memcached/commands/AppendCommand.java       |    92 -
 .../memcached/commands/AppendQCommand.java      |    29 -
 .../internal/memcached/commands/CASCommand.java |    76 -
 .../memcached/commands/ClientError.java         |    39 -
 .../memcached/commands/DecrementCommand.java    |   173 -
 .../memcached/commands/DecrementQCommand.java   |    29 -
 .../memcached/commands/DeleteCommand.java       |   101 -
 .../memcached/commands/DeleteQCommand.java      |    29 -
 .../memcached/commands/FlushAllCommand.java     |   119 -
 .../memcached/commands/FlushAllQCommand.java    |    29 -
 .../internal/memcached/commands/GATCommand.java |    29 -
 .../memcached/commands/GATQCommand.java         |    29 -
 .../internal/memcached/commands/GetCommand.java |   224 -
 .../memcached/commands/GetKCommand.java         |    30 -
 .../memcached/commands/GetKQCommand.java        |    30 -
 .../memcached/commands/GetQCommand.java         |    38 -
 .../memcached/commands/IncrementCommand.java    |   170 -
 .../memcached/commands/IncrementQCommand.java   |    29 -
 .../memcached/commands/NoOpCommand.java         |    40 -
 .../memcached/commands/NotSupportedCommand.java |    41 -
 .../memcached/commands/PrependCommand.java      |    88 -
 .../memcached/commands/PrependQCommand.java     |    29 -
 .../memcached/commands/QuitCommand.java         |    56 -
 .../memcached/commands/QuitQCommand.java        |    29 -
 .../memcached/commands/ReplaceCommand.java      |   102 -
 .../memcached/commands/ReplaceQCommand.java     |    29 -
 .../internal/memcached/commands/SetCommand.java |    90 -
 .../memcached/commands/SetQCommand.java         |    30 -
 .../memcached/commands/StatsCommand.java        |    50 -
 .../memcached/commands/StorageCommand.java      |   218 -
 .../memcached/commands/TouchCommand.java        |   104 -
 .../memcached/commands/VerbosityCommand.java    |    48 -
 .../memcached/commands/VersionCommand.java      |    49 -
 .../modules/util/RegionConfiguration.java       |   293 -
 .../gemfire/internal/net/SocketUtils.java       |    76 -
 .../internal/offheap/AbstractStoredObject.java  |   107 -
 .../offheap/AddressableMemoryChunk.java         |    29 -
 .../offheap/AddressableMemoryChunkFactory.java  |    27 -
 .../internal/offheap/ByteArrayMemoryChunk.java  |    77 -
 .../internal/offheap/ByteBufferMemoryChunk.java |    90 -
 .../gemfire/internal/offheap/DataAsAddress.java |   131 -
 .../gemfire/internal/offheap/DataType.java      |   269 -
 ...DisconnectingOutOfOffHeapMemoryListener.java |    77 -
 .../gemfire/internal/offheap/Fragment.java      |   139 -
 .../internal/offheap/FreeListManager.java       |   920 -
 .../internal/offheap/LifecycleListener.java     |    98 -
 .../internal/offheap/MemoryAllocator.java       |    62 -
 .../gemfire/internal/offheap/MemoryBlock.java   |    70 -
 .../internal/offheap/MemoryBlockNode.java       |   162 -
 .../gemfire/internal/offheap/MemoryChunk.java   |    47 -
 .../offheap/MemoryChunkWithRefCount.java        |    34 -
 .../internal/offheap/MemoryInspector.java       |    43 -
 .../internal/offheap/MemoryInspectorImpl.java   |    99 -
 .../internal/offheap/MemoryUsageListener.java   |    27 -
 .../gemfire/internal/offheap/ObjectChunk.java   |   737 -
 .../internal/offheap/ObjectChunkSlice.java      |    44 -
 .../offheap/ObjectChunkWithHeapForm.java        |    40 -
 .../offheap/OffHeapCachedDeserializable.java    |   142 -
 .../gemfire/internal/offheap/OffHeapHelper.java |   133 -
 .../internal/offheap/OffHeapMemoryStats.java    |    54 -
 .../offheap/OffHeapRegionEntryHelper.java       |   406 -
 .../internal/offheap/OffHeapStorage.java        |   394 -
 .../offheap/OutOfOffHeapMemoryListener.java     |    44 -
 .../internal/offheap/RefCountChangeInfo.java    |   130 -
 .../internal/offheap/ReferenceCountHelper.java  |   254 -
 .../gemfire/internal/offheap/Releasable.java    |    31 -
 .../offheap/SimpleMemoryAllocatorImpl.java      |   511 -
 .../gemfire/internal/offheap/StoredObject.java  |    95 -
 .../internal/offheap/SyncChunkStack.java        |   141 -
 .../internal/offheap/UnsafeMemoryChunk.java     |   217 -
 .../offheap/annotations/OffHeapIdentifier.java  |    69 -
 .../internal/offheap/annotations/Released.java  |    49 -
 .../internal/offheap/annotations/Retained.java  |    51 -
 .../offheap/annotations/Unretained.java         |    51 -
 .../com/gemstone/gemfire/internal/package.html  |    45 -
 .../internal/process/AttachProcessUtils.java    |    57 -
 .../process/BlockingProcessStreamReader.java    |    73 -
 ...usterConfigurationNotAvailableException.java |    31 -
 .../process/ConnectionFailedException.java      |    50 -
 .../internal/process/ControlFileWatchdog.java   |   158 -
 .../process/ControlNotificationHandler.java     |    32 -
 .../internal/process/ControllableProcess.java   |   132 -
 .../process/FileAlreadyExistsException.java     |    52 -
 .../process/FileControllerParameters.java       |    33 -
 .../internal/process/FileProcessController.java |   162 -
 .../process/LocalProcessController.java         |   478 -
 .../internal/process/LocalProcessLauncher.java  |   128 -
 .../process/MBeanControllerParameters.java      |    37 -
 .../process/MBeanInvocationFailedException.java |    50 -
 .../process/MBeanProcessController.java         |   391 -
 .../internal/process/NativeProcessUtils.java    |    53 -
 .../process/NonBlockingProcessStreamReader.java |   101 -
 .../gemfire/internal/process/PidFile.java       |   169 -
 .../process/PidUnavailableException.java        |    51 -
 .../internal/process/ProcessController.java     |    61 -
 .../process/ProcessControllerFactory.java       |   102 -
 .../process/ProcessControllerParameters.java    |    30 -
 .../process/ProcessLauncherContext.java         |   176 -
 .../internal/process/ProcessStreamReader.java   |   265 -
 .../ProcessTerminatedAbnormallyException.java   |    90 -
 .../gemfire/internal/process/ProcessType.java   |    69 -
 .../gemfire/internal/process/ProcessUtils.java  |   195 -
 .../gemfire/internal/process/StartupStatus.java |    63 -
 .../internal/process/StartupStatusListener.java |    30 -
 .../UnableToControlProcessException.java        |    51 -
 .../AbstractSignalNotificationHandler.java      |   179 -
 .../gemfire/internal/process/signal/Signal.java |   128 -
 .../internal/process/signal/SignalEvent.java    |    53 -
 .../internal/process/signal/SignalListener.java |    34 -
 .../internal/process/signal/SignalType.java     |    44 -
 .../internal/redis/ByteArrayWrapper.java        |   181 -
 .../internal/redis/ByteToCommandDecoder.java    |   189 -
 .../gemstone/gemfire/internal/redis/Coder.java  |   517 -
 .../gemfire/internal/redis/Command.java         |   150 -
 .../gemfire/internal/redis/DoubleWrapper.java   |    79 -
 .../internal/redis/ExecutionHandlerContext.java |   380 -
 .../gemfire/internal/redis/Executor.java        |    38 -
 .../gemfire/internal/redis/Extendable.java      |    33 -
 .../redis/RedisCommandParserException.java      |    45 -
 .../internal/redis/RedisCommandType.java        |  2345 ---
 .../gemfire/internal/redis/RedisConstants.java  |   202 -
 .../gemfire/internal/redis/RedisDataType.java   |   118 -
 .../redis/RedisDataTypeMismatchException.java   |    39 -
 .../internal/redis/RegionCreationException.java |    39 -
 .../gemfire/internal/redis/RegionProvider.java  |   553 -
 .../redis/executor/AbstractExecutor.java        |   139 -
 .../redis/executor/AbstractScanExecutor.java    |    47 -
 .../internal/redis/executor/AuthExecutor.java   |    54 -
 .../internal/redis/executor/DBSizeExecutor.java |    31 -
 .../internal/redis/executor/DelExecutor.java    |    55 -
 .../internal/redis/executor/EchoExecutor.java   |    40 -
 .../internal/redis/executor/ExistsExecutor.java |    49 -
 .../redis/executor/ExpirationExecutor.java      |    41 -
 .../redis/executor/ExpireAtExecutor.java        |    93 -
 .../internal/redis/executor/ExpireExecutor.java |    93 -
 .../redis/executor/FlushAllExecutor.java        |    49 -
 .../internal/redis/executor/KeysExecutor.java   |    70 -
 .../internal/redis/executor/ListQuery.java      |    53 -
 .../redis/executor/PExpireAtExecutor.java       |    32 -
 .../redis/executor/PExpireExecutor.java         |    32 -
 .../internal/redis/executor/PTTLExecutor.java   |    33 -
 .../redis/executor/PersistExecutor.java         |    52 -
 .../internal/redis/executor/PingExecutor.java   |    31 -
 .../internal/redis/executor/QuitExecutor.java   |    31 -
 .../internal/redis/executor/ScanExecutor.java   |   144 -
 .../redis/executor/ShutDownExecutor.java        |    28 -
 .../internal/redis/executor/SortedSetQuery.java |   204 -
 .../internal/redis/executor/TTLExecutor.java    |    77 -
 .../internal/redis/executor/TimeExecutor.java   |    51 -
 .../internal/redis/executor/TypeExecutor.java   |    48 -
 .../internal/redis/executor/UnkownExecutor.java |    31 -
 .../redis/executor/hash/HDelExecutor.java       |    67 -
 .../redis/executor/hash/HExistsExecutor.java    |    66 -
 .../redis/executor/hash/HGetAllExecutor.java    |    63 -
 .../redis/executor/hash/HGetExecutor.java       |    62 -
 .../redis/executor/hash/HIncrByExecutor.java    |   109 -
 .../executor/hash/HIncrByFloatExecutor.java     |    99 -
 .../redis/executor/hash/HKeysExecutor.java      |    63 -
 .../redis/executor/hash/HLenExecutor.java       |    57 -
 .../redis/executor/hash/HMGetExecutor.java      |    72 -
 .../redis/executor/hash/HMSetExecutor.java      |    62 -
 .../redis/executor/hash/HScanExecutor.java      |   163 -
 .../redis/executor/hash/HSetExecutor.java       |    78 -
 .../redis/executor/hash/HSetNXExecutor.java     |    33 -
 .../redis/executor/hash/HValsExecutor.java      |    62 -
 .../redis/executor/hash/HashExecutor.java       |    39 -
 .../redis/executor/hll/HllExecutor.java         |    38 -
 .../redis/executor/hll/PFAddExecutor.java       |    66 -
 .../redis/executor/hll/PFCountExecutor.java     |    70 -
 .../redis/executor/hll/PFMergeExecutor.java     |    74 -
 .../internal/redis/executor/hll/Varint.java     |   241 -
 .../redis/executor/list/LIndexExecutor.java     |   118 -
 .../redis/executor/list/LInsertExecutor.java    |    29 -
 .../redis/executor/list/LLenExecutor.java       |    58 -
 .../redis/executor/list/LPopExecutor.java       |    34 -
 .../redis/executor/list/LPushExecutor.java      |    34 -
 .../redis/executor/list/LPushXExecutor.java     |    34 -
 .../redis/executor/list/LRangeExecutor.java     |   113 -
 .../redis/executor/list/LRemExecutor.java       |   116 -
 .../redis/executor/list/LSetExecutor.java       |   108 -
 .../redis/executor/list/LTrimExecutor.java      |   124 -
 .../redis/executor/list/ListExecutor.java       |   150 -
 .../redis/executor/list/PopExecutor.java        |   150 -
 .../redis/executor/list/PushExecutor.java       |    54 -
 .../redis/executor/list/PushXExecutor.java      |    59 -
 .../redis/executor/list/RPopExecutor.java       |    34 -
 .../redis/executor/list/RPushExecutor.java      |    34 -
 .../redis/executor/list/RPushXExecutor.java     |    34 -
 .../redis/executor/set/SAddExecutor.java        |    60 -
 .../redis/executor/set/SCardExecutor.java       |    55 -
 .../redis/executor/set/SDiffExecutor.java       |    46 -
 .../redis/executor/set/SDiffStoreExecutor.java  |    33 -
 .../redis/executor/set/SInterExecutor.java      |    49 -
 .../redis/executor/set/SInterStoreExecutor.java |    34 -
 .../redis/executor/set/SIsMemberExecutor.java   |    62 -
 .../redis/executor/set/SMembersExecutor.java    |    56 -
 .../redis/executor/set/SMoveExecutor.java       |    72 -
 .../redis/executor/set/SPopExecutor.java        |    61 -
 .../redis/executor/set/SRandMemberExecutor.java |    96 -
 .../redis/executor/set/SRemExecutor.java        |    63 -
 .../redis/executor/set/SScanExecutor.java       |   154 -
 .../redis/executor/set/SUnionExecutor.java      |    51 -
 .../redis/executor/set/SUnionStoreExecutor.java |    34 -
 .../redis/executor/set/SetExecutor.java         |    23 -
 .../redis/executor/set/SetOpExecutor.java       |   109 -
 .../executor/sortedset/SortedSetExecutor.java   |    41 -
 .../redis/executor/sortedset/ZAddExecutor.java  |    88 -
 .../redis/executor/sortedset/ZCardExecutor.java |    54 -
 .../executor/sortedset/ZCountExecutor.java      |   145 -
 .../executor/sortedset/ZIncrByExecutor.java     |    77 -
 .../executor/sortedset/ZLexCountExecutor.java   |   143 -
 .../executor/sortedset/ZRangeByLexExecutor.java |   209 -
 .../sortedset/ZRangeByScoreExecutor.java        |   209 -
 .../executor/sortedset/ZRangeExecutor.java      |   125 -
 .../redis/executor/sortedset/ZRankExecutor.java |    98 -
 .../redis/executor/sortedset/ZRemExecutor.java  |    64 -
 .../sortedset/ZRemRangeByLexExecutor.java       |   153 -
 .../sortedset/ZRemRangeByRankExecutor.java      |   121 -
 .../sortedset/ZRemRangeByScoreExecutor.java     |   143 -
 .../sortedset/ZRevRangeByScoreExecutor.java     |    33 -
 .../executor/sortedset/ZRevRangeExecutor.java   |    34 -
 .../executor/sortedset/ZRevRankExecutor.java    |    32 -
 .../redis/executor/sortedset/ZScanExecutor.java |   161 -
 .../executor/sortedset/ZScoreExecutor.java      |    59 -
 .../redis/executor/string/AppendExecutor.java   |    69 -
 .../redis/executor/string/BitCountExecutor.java |    97 -
 .../redis/executor/string/BitOpExecutor.java    |   153 -
 .../redis/executor/string/BitPosExecutor.java   |   134 -
 .../redis/executor/string/DecrByExecutor.java   |   110 -
 .../redis/executor/string/DecrExecutor.java     |    95 -
 .../redis/executor/string/GetBitExecutor.java   |    82 -
 .../redis/executor/string/GetExecutor.java      |    51 -
 .../redis/executor/string/GetRangeExecutor.java |    98 -
 .../redis/executor/string/GetSetExecutor.java   |    59 -
 .../redis/executor/string/IncrByExecutor.java   |   107 -
 .../executor/string/IncrByFloatExecutor.java    |   122 -
 .../redis/executor/string/IncrExecutor.java     |    91 -
 .../redis/executor/string/MGetExecutor.java     |    73 -
 .../redis/executor/string/MSetExecutor.java     |    64 -
 .../redis/executor/string/MSetNXExecutor.java   |    88 -
 .../redis/executor/string/PSetEXExecutor.java   |    34 -
 .../redis/executor/string/SetBitExecutor.java   |   106 -
 .../redis/executor/string/SetEXExecutor.java    |    88 -
 .../redis/executor/string/SetExecutor.java      |   154 -
 .../redis/executor/string/SetNXExecutor.java    |    60 -
 .../redis/executor/string/SetRangeExecutor.java |    96 -
 .../redis/executor/string/StringExecutor.java   |    45 -
 .../redis/executor/string/StrlenExecutor.java   |    56 -
 .../executor/transactions/DiscardExecutor.java  |    42 -
 .../executor/transactions/ExecExecutor.java     |    88 -
 .../executor/transactions/MultiExecutor.java    |    47 -
 .../transactions/TransactionExecutor.java       |    23 -
 .../executor/transactions/UnwatchExecutor.java  |    31 -
 .../executor/transactions/WatchExecutor.java    |    31 -
 .../redis/org/apache/hadoop/fs/GlobPattern.java |   164 -
 .../internal/security/AuthorizeRequest.java     |   757 -
 .../internal/security/AuthorizeRequestPP.java   |   250 -
 .../security/FilterPostAuthorization.java       |   235 -
 .../security/FilterPreAuthorization.java        |   160 -
 .../internal/security/ObjectWithAuthz.java      |    69 -
 .../gemfire/internal/security/package.html      |    25 -
 .../internal/sequencelog/EntryLogger.java       |   210 -
 .../gemfire/internal/sequencelog/GraphType.java |    60 -
 .../internal/sequencelog/MembershipLogger.java  |    47 -
 .../internal/sequencelog/MessageLogger.java     |    40 -
 .../internal/sequencelog/RegionLogger.java      |    88 -
 .../internal/sequencelog/SequenceLogger.java    |    63 -
 .../sequencelog/SequenceLoggerImpl.java         |   149 -
 .../internal/sequencelog/Transition.java        |    88 -
 .../gemfire/internal/sequencelog/io/Filter.java |    32 -
 .../sequencelog/io/GemfireLogConverter.java     |   251 -
 .../internal/sequencelog/io/GraphReader.java    |    90 -
 .../sequencelog/io/InputStreamReader.java       |   103 -
 .../sequencelog/io/OutputStreamAppender.java    |   117 -
 .../internal/sequencelog/model/Edge.java        |   111 -
 .../internal/sequencelog/model/Graph.java       |   105 -
 .../internal/sequencelog/model/GraphID.java     |    95 -
 .../sequencelog/model/GraphReaderCallback.java  |    37 -
 .../internal/sequencelog/model/GraphSet.java    |   165 -
 .../internal/sequencelog/model/Vertex.java      |   124 -
 .../visualization/text/TextDisplay.java         |    85 -
 .../gemfire/internal/shared/NativeCalls.java    |   633 -
 .../internal/shared/NativeCallsJNAImpl.java     |  1217 --
 .../internal/shared/NativeErrorException.java   |    43 -
 .../gemfire/internal/shared/OSType.java         |    93 -
 .../internal/shared/StringPrintWriter.java      |   236 -
 .../internal/shared/TCPSocketOptions.java       |    48 -
 .../internal/size/CachingSingleObjectSizer.java |    51 -
 .../size/InstrumentationSingleObjectSizer.java  |    42 -
 .../gemfire/internal/size/ObjectGraphSizer.java |   252 -
 .../gemfire/internal/size/ObjectTraverser.java  |   205 -
 .../internal/size/ReflectionObjectSizer.java    |    94 -
 .../size/ReflectionSingleObjectSizer.java       |   183 -
 .../internal/size/SingleObjectSizer.java        |    28 -
 .../internal/size/SizeClassOnceObjectSizer.java |    96 -
 .../gemfire/internal/size/SizeOfUtil0.java      |    33 -
 .../internal/size/WellKnownClassSizer.java      |    60 -
 .../internal/statistics/CounterMonitor.java     |    58 -
 .../internal/statistics/GaugeMonitor.java       |    53 -
 .../statistics/IgnoreResourceException.java     |    65 -
 .../MapBasedStatisticsNotification.java         |    88 -
 .../internal/statistics/ResourceInstance.java   |   120 -
 .../internal/statistics/ResourceType.java       |    70 -
 .../internal/statistics/SampleCollector.java    |   786 -
 .../internal/statistics/SampleHandler.java      |    72 -
 .../internal/statistics/SimpleStatisticId.java  |    67 -
 .../statistics/StatArchiveDescriptor.java       |   134 -
 .../internal/statistics/StatArchiveHandler.java |   676 -
 .../statistics/StatArchiveHandlerConfig.java    |    67 -
 .../internal/statistics/StatMonitorHandler.java |   336 -
 .../internal/statistics/StatisticId.java        |    39 -
 .../statistics/StatisticNotFoundException.java  |    62 -
 .../internal/statistics/StatisticsListener.java |    27 -
 .../internal/statistics/StatisticsMonitor.java  |   166 -
 .../statistics/StatisticsNotification.java      |    66 -
 .../internal/statistics/StatisticsSampler.java  |    57 -
 .../internal/statistics/ValueMonitor.java       |   133 -
 .../gemfire/internal/statistics/package.html    |    31 -
 .../stats50/Atomic50StatisticsImpl.java         |   497 -
 .../gemfire/internal/stats50/VMStats50.java     |   703 -
 .../gemfire/internal/tcp/BaseMsgStreamer.java   |    65 -
 .../gemstone/gemfire/internal/tcp/Buffers.java  |   170 -
 .../internal/tcp/ByteBufferInputStream.java     |  1022 -
 .../gemfire/internal/tcp/ConnectExceptions.java |    93 -
 .../gemfire/internal/tcp/Connection.java        |  4154 ----
 .../internal/tcp/ConnectionException.java       |    38 -
 .../gemfire/internal/tcp/ConnectionTable.java   |  1428 --
 .../gemfire/internal/tcp/DirectReplySender.java |   105 -
 .../tcp/ImmutableByteBufferInputStream.java     |    85 -
 .../internal/tcp/MemberShunnedException.java    |    50 -
 .../gemfire/internal/tcp/MsgDestreamer.java     |   536 -
 .../gemfire/internal/tcp/MsgIdGenerator.java    |    54 -
 .../gemfire/internal/tcp/MsgOutputStream.java   |   427 -
 .../gemfire/internal/tcp/MsgReader.java         |   129 -
 .../gemfire/internal/tcp/MsgStreamer.java       |  1004 -
 .../gemfire/internal/tcp/MsgStreamerList.java   |   169 -
 .../gemfire/internal/tcp/NIOMsgReader.java      |   113 -
 .../gemfire/internal/tcp/OioMsgReader.java      |    43 -
 .../internal/tcp/ReenteredConnectException.java |    51 -
 .../gemfire/internal/tcp/ServerDelegate.java    |    47 -
 .../gemfire/internal/tcp/TCPConduit.java        |  1207 --
 .../tcp/VersionedByteBufferInputStream.java     |    79 -
 .../internal/tcp/VersionedMsgStreamer.java      |    60 -
 .../gemstone/gemfire/internal/tcp/package.html  |   138 -
 .../internal/util/AbortableTaskService.java     |   174 -
 .../gemfire/internal/util/ArrayUtils.java       |   369 -
 .../gemfire/internal/util/BlobHelper.java       |   195 -
 .../gemfire/internal/util/Breadcrumbs.java      |   265 -
 .../gemstone/gemfire/internal/util/Bytes.java   |   259 -
 .../gemfire/internal/util/Callable.java         |    48 -
 .../gemfire/internal/util/CollectionUtils.java  |   282 -
 .../gemfire/internal/util/DebuggerSupport.java  |    65 -
 .../gemfire/internal/util/DelayedAction.java    |    65 -
 .../com/gemstone/gemfire/internal/util/Hex.java |    57 -
 .../gemstone/gemfire/internal/util/IOUtils.java |   347 -
 .../internal/util/JavaCommandBuilder.java       |   123 -
 .../gemfire/internal/util/LogFileUtils.java     |   178 -
 .../internal/util/ObjectIntProcedure.java       |    30 -
 .../gemfire/internal/util/PasswordUtil.java     |   132 -
 .../gemfire/internal/util/PluckStacks.java      |   523 -
 .../internal/util/SingletonCallable.java        |    87 -
 .../gemfire/internal/util/SingletonValue.java   |   318 -
 .../internal/util/StackTraceCollector.java      |   169 -
 .../gemfire/internal/util/StopWatch.java        |    80 -
 .../internal/util/SunAPINotFoundException.java  |    46 -
 .../gemfire/internal/util/TransformUtils.java   |   132 -
 .../gemfire/internal/util/Transformer.java      |    33 -
 .../gemfire/internal/util/Versionable.java      |    37 -
 .../internal/util/VersionedArrayList.java       |   346 -
 .../util/concurrent/CopyOnWriteHashMap.java     |   209 -
 .../util/concurrent/CopyOnWriteWeakHashMap.java |    98 -
 .../CustomEntryConcurrentHashMap.java           |  2679 ---
 .../internal/util/concurrent/FutureResult.java  |    93 -
 .../util/concurrent/ReentrantSemaphore.java     |   161 -
 .../util/concurrent/SemaphoreReadWriteLock.java |   217 -
 .../util/concurrent/StoppableCondition.java     |   113 -
 .../concurrent/StoppableCountDownLatch.java     |    98 -
 .../concurrent/StoppableCountDownOrUpLatch.java |   211 -
 .../concurrent/StoppableNonReentrantLock.java   |    92 -
 .../util/concurrent/StoppableReadWriteLock.java |    35 -
 .../util/concurrent/StoppableReentrantLock.java |   131 -
 .../StoppableReentrantReadWriteLock.java        |   244 -
 .../internal/util/doc-files/call-stack.fig      |    34 -
 .../internal/util/doc-files/class-loaders.fig   |    49 -
 .../lang/AttachAPINotFoundException.java        |    67 -
 .../com/gemstone/gemfire/lang/Identifiable.java |    40 -
 .../management/AlreadyRunningException.java     |    46 -
 .../management/AsyncEventQueueMXBean.java       |   118 -
 .../gemfire/management/CacheServerMXBean.java   |   397 -
 .../gemfire/management/ClientHealthStatus.java  |   346 -
 .../gemfire/management/ClientQueueDetail.java   |   165 -
 .../DependenciesNotFoundException.java          |    58 -
 .../gemfire/management/DiskBackupResult.java    |    68 -
 .../gemfire/management/DiskBackupStatus.java    |    73 -
 .../gemfire/management/DiskMetrics.java         |   124 -
 .../gemfire/management/DiskStoreMXBean.java     |   212 -
 .../DistributedLockServiceMXBean.java           |    66 -
 .../management/DistributedRegionMXBean.java     |   317 -
 .../management/DistributedSystemMXBean.java     |   696 -
 .../management/EvictionAttributesData.java      |   112 -
 .../FixedPartitionAttributesData.java           |    95 -
 .../management/GatewayReceiverMXBean.java       |   211 -
 .../gemfire/management/GatewaySenderMXBean.java |   249 -
 .../gemfire/management/GemFireProperties.java   |  1589 --
 .../gemfire/management/JMXNotificationType.java |   208 -
 .../management/JMXNotificationUserData.java     |    46 -
 .../gemstone/gemfire/management/JVMMetrics.java |   151 -
 .../gemfire/management/LocatorMXBean.java       |    76 -
 .../gemfire/management/LockServiceMXBean.java   |    85 -
 .../gemfire/management/ManagementException.java |    88 -
 .../gemfire/management/ManagementService.java   |   427 -
 .../gemfire/management/ManagerMXBean.java       |    83 -
 .../gemfire/management/MemberMXBean.java        |   855 -
 .../management/MembershipAttributesData.java    |   113 -
 .../gemfire/management/NetworkMetrics.java      |    59 -
 .../gemstone/gemfire/management/OSMetrics.java  |   231 -
 .../management/PartitionAttributesData.java     |   146 -
 .../management/PersistentMemberDetails.java     |    68 -
 .../management/RegionAttributesData.java        |   438 -
 .../gemfire/management/RegionMXBean.java        |   360 -
 .../gemfire/management/ServerLoadData.java      |    93 -
 .../gemfire/management/cli/CliMetaData.java     |   104 -
 .../cli/CommandProcessingException.java         |   125 -
 .../gemfire/management/cli/CommandService.java  |   205 -
 .../management/cli/CommandServiceException.java |    68 -
 .../management/cli/CommandStatement.java        |    58 -
 .../gemfire/management/cli/ConverterHint.java   |    52 -
 .../gemstone/gemfire/management/cli/Result.java |   130 -
 .../gemfire/management/cli/package.html         |    23 -
 .../gemfire/management/internal/AgentUtil.java  |   134 -
 .../management/internal/AlertDetails.java       |   162 -
 .../management/internal/ArrayConverter.java     |    82 -
 .../internal/BaseManagementService.java         |   185 -
 .../internal/CollectionConverter.java           |   110 -
 .../management/internal/CompositeConverter.java |   146 -
 .../management/internal/EnumConverter.java      |    50 -
 .../management/internal/FederatingManager.java  |   626 -
 .../internal/FederationComponent.java           |   306 -
 .../management/internal/FilterChain.java        |    59 -
 .../management/internal/FilterParam.java        |    71 -
 .../management/internal/IdentityConverter.java  |    47 -
 .../management/internal/JettyHelper.java        |   228 -
 .../management/internal/JmxManagerAdvisee.java  |   149 -
 .../management/internal/JmxManagerAdvisor.java  |   384 -
 .../management/internal/JmxManagerLocator.java  |   241 -
 .../internal/JmxManagerLocatorRequest.java      |   118 -
 .../internal/JmxManagerLocatorResponse.java     |   104 -
 .../management/internal/LocalFilterChain.java   |    63 -
 .../management/internal/LocalManager.java       |   466 -
 .../management/internal/MBeanJMXAdapter.java    |   621 -
 .../management/internal/MBeanProxyFactory.java  |   355 -
 .../internal/MBeanProxyInfoRepository.java      |   171 -
 .../internal/MBeanProxyInvocationHandler.java   |   546 -
 .../internal/MXBeanProxyInvocationHandler.java  |   260 -
 .../management/internal/ManagementAgent.java    |   516 -
 .../internal/ManagementCacheListener.java       |   122 -
 .../internal/ManagementConstants.java           |   187 -
 .../management/internal/ManagementFunction.java |   173 -
 .../internal/ManagementMembershipListener.java  |    94 -
 .../internal/ManagementResourceRepo.java        |   262 -
 .../management/internal/ManagementStrings.java  |   153 -
 .../gemfire/management/internal/Manager.java    |    90 -
 .../internal/ManagerStartupMessage.java         |    76 -
 .../management/internal/MemberMessenger.java    |   105 -
 .../internal/MonitoringRegionCacheListener.java |   116 -
 .../internal/NotificationBroadCasterProxy.java  |    38 -
 .../internal/NotificationCacheListener.java     |   120 -
 .../management/internal/NotificationHub.java    |   206 -
 .../internal/NotificationHubClient.java         |    77 -
 .../management/internal/NotificationKey.java    |    66 -
 .../gemfire/management/internal/OpenMethod.java |   190 -
 .../management/internal/OpenTypeConverter.java  |  1018 -
 .../management/internal/OpenTypeUtil.java       |   117 -
 .../gemfire/management/internal/ProxyInfo.java  |    83 -
 .../management/internal/ProxyInterface.java     |    40 -
 .../management/internal/ProxyListener.java      |   137 -
 .../management/internal/RemoteFilterChain.java  |    95 -
 .../gemfire/management/internal/RestAgent.java  |   217 -
 .../gemfire/management/internal/SSLUtil.java    |    82 -
 .../management/internal/StringBasedFilter.java  |   122 -
 .../internal/SystemManagementService.java       |   837 -
 .../management/internal/TableConverter.java     |   102 -
 .../internal/beans/AggregateHandler.java        |    92 -
 .../internal/beans/AsyncEventQueueMBean.java    |   113 -
 .../beans/AsyncEventQueueMBeanBridge.java       |   121 -
 .../internal/beans/BeanUtilFuncs.java           |   393 -
 .../internal/beans/CacheServerBridge.java       |   772 -
 .../internal/beans/CacheServerMBean.java        |   317 -
 .../internal/beans/DiskRegionBridge.java        |   138 -
 .../internal/beans/DiskStoreMBean.java          |   182 -
 .../internal/beans/DiskStoreMBeanBridge.java    |   288 -
 .../beans/DistributedLockServiceBridge.java     |   227 -
 .../beans/DistributedLockServiceMBean.java      |    68 -
 .../internal/beans/DistributedRegionBridge.java |   683 -
 .../internal/beans/DistributedRegionMBean.java  |   330 -
 .../internal/beans/DistributedSystemBridge.java |  1888 --
 .../internal/beans/DistributedSystemMBean.java  |   461 -
 .../internal/beans/GatewayReceiverMBean.java    |   220 -
 .../beans/GatewayReceiverMBeanBridge.java       |   224 -
 .../internal/beans/GatewaySenderMBean.java      |   226 -
 .../beans/GatewaySenderMBeanBridge.java         |   293 -
 .../internal/beans/HDFSRegionBridge.java        |   174 -
 .../management/internal/beans/LocatorMBean.java |    79 -
 .../internal/beans/LocatorMBeanBridge.java      |   157 -
 .../internal/beans/LockServiceMBean.java        |    94 -
 .../internal/beans/LockServiceMBeanBridge.java  |   129 -
 .../internal/beans/MBeanAggregator.java         |   435 -
 .../internal/beans/ManagementAdapter.java       |  1134 --
 .../internal/beans/ManagementListener.java      |   215 -
 .../management/internal/beans/ManagerMBean.java |    71 -
 .../internal/beans/ManagerMBeanBridge.java      |    80 -
 .../management/internal/beans/MemberMBean.java  |   685 -
 .../internal/beans/MemberMBeanBridge.java       |  1999 --
 .../internal/beans/MetricsCalculator.java       |   138 -
 .../internal/beans/PartitionedRegionBridge.java |   317 -
 .../internal/beans/QueryDataFunction.java       |   613 -
 .../management/internal/beans/RegionMBean.java  |   323 -
 .../internal/beans/RegionMBeanBridge.java       |   599 -
 .../beans/RegionMBeanCompositeDataFactory.java  |   229 -
 .../internal/beans/SequenceNumber.java          |    50 -
 .../management/internal/beans/ServerBridge.java |   184 -
 .../stats/AggregateRegionStatsMonitor.java      |   298 -
 .../internal/beans/stats/GCStatsMonitor.java    |    94 -
 .../GatewayReceiverClusterStatsMonitor.java     |    80 -
 .../stats/GatewaySenderClusterStatsMonitor.java |    93 -
 .../stats/IntegerStatsDeltaAggregator.java      |    93 -
 .../beans/stats/LongStatsDeltaAggregator.java   |    92 -
 .../internal/beans/stats/MBeanStatsMonitor.java |   120 -
 .../beans/stats/MemberClusterStatsMonitor.java  |   255 -
 .../beans/stats/MemberLevelDiskMonitor.java     |   311 -
 .../beans/stats/RegionClusterStatsMonitor.java  |   475 -
 .../beans/stats/ServerClusterStatsMonitor.java  |    86 -
 .../internal/beans/stats/StatType.java          |    29 -
 .../internal/beans/stats/StatsAggregator.java   |   305 -
 .../beans/stats/StatsAverageLatency.java        |    55 -
 .../internal/beans/stats/StatsKey.java          |   355 -
 .../internal/beans/stats/StatsLatency.java      |    70 -
 .../internal/beans/stats/StatsRate.java         |    92 -
 .../internal/beans/stats/VMStatsMonitor.java    |   129 -
 .../cli/AbstractCliAroundInterceptor.java       |   133 -
 .../internal/cli/CliAroundInterceptor.java      |    36 -
 .../management/internal/cli/CliUtil.java        |   758 -
 .../management/internal/cli/CommandManager.java |   632 -
 .../management/internal/cli/CommandRequest.java |   134 -
 .../internal/cli/CommandResponse.java           |   350 -
 .../internal/cli/CommandResponseBuilder.java    |    88 -
 .../internal/cli/CommandResponseWriter.java     |    66 -
 .../internal/cli/GfshParseResult.java           |   102 -
 .../management/internal/cli/GfshParser.java     |  1520 --
 .../management/internal/cli/Launcher.java       |   315 -
 .../management/internal/cli/LogWrapper.java     |   440 -
 .../internal/cli/MultipleValueAdapter.java      |    39 -
 .../internal/cli/MultipleValueConverter.java    |    60 -
 .../internal/cli/annotation/CliArgument.java    |    88 -
 .../cli/commands/AbstractCommandsSupport.java   |   197 -
 .../internal/cli/commands/ClientCommands.java   |   328 -
 .../internal/cli/commands/ConfigCommands.java   |   484 -
 .../CreateAlterDestroyRegionCommands.java       |  1200 --
 .../internal/cli/commands/DataCommands.java     |  1402 --
 .../internal/cli/commands/DeployCommands.java   |   345 -
 .../cli/commands/DiskStoreCommands.java         |  1450 --
 .../cli/commands/DurableClientCommands.java     |   430 -
 ...ExportImportSharedConfigurationCommands.java |   292 -
 .../internal/cli/commands/FunctionCommands.java |   642 -
 .../internal/cli/commands/GfshHelpCommands.java |   106 -
 .../internal/cli/commands/IndexCommands.java    |   674 -
 .../cli/commands/LauncherLifecycleCommands.java |  2803 ---
 .../internal/cli/commands/MemberCommands.java   |   204 -
 .../cli/commands/MiscellaneousCommands.java     |  2128 --
 .../internal/cli/commands/PDXCommands.java      |   286 -
 .../internal/cli/commands/QueueCommands.java    |   281 -
 .../internal/cli/commands/RegionCommands.java   |   493 -
 .../internal/cli/commands/ShellCommands.java    |  1081 --
 .../internal/cli/commands/StatusCommands.java   |    92 -
 .../internal/cli/commands/WanCommands.java      |  1281 --
 .../cli/commands/dto/RegionAttributesInfo.java  |   164 -
 .../cli/commands/dto/RegionDetails.java         |   231 -
 .../cli/commands/dto/RegionMemberDetails.java   |   199 -
 .../cli/converters/BooleanConverter.java        |    54 -
 .../ClusterMemberIdNameConverter.java           |    80 -
 .../converters/ConnectionEndpointConverter.java |   145 -
 .../internal/cli/converters/DirConverter.java   |   174 -
 .../cli/converters/DirPathConverter.java        |   143 -
 .../cli/converters/DiskStoreNameConverter.java  |    93 -
 .../internal/cli/converters/EnumConverter.java  |    67 -
 .../cli/converters/FilePathConverter.java       |   136 -
 .../cli/converters/FilePathStringConverter.java |   132 -
 .../converters/GatewayReceiverIdsConverter.java |    73 -
 .../converters/GatewaySenderIdConverter.java    |    81 -
 .../internal/cli/converters/HelpConverter.java  |    73 -
 .../cli/converters/HintTopicConverter.java      |    74 -
 .../cli/converters/IndexTypeConverter.java      |    57 -
 .../LocatorDiscoveryConfigConverter.java        |    80 -
 .../cli/converters/LocatorIdNameConverter.java  |    79 -
 .../cli/converters/LogLevelConverter.java       |    64 -
 .../cli/converters/MemberGroupConverter.java    |    83 -
 .../cli/converters/MemberIdNameConverter.java   |    82 -
 .../cli/converters/RegionPathConverter.java     |   100 -
 .../cli/converters/StringArrayConverter.java    |    59 -
 .../cli/converters/StringListConverter.java     |    60 -
 .../cli/domain/AsyncEventQueueDetails.java      |    77 -
 .../internal/cli/domain/CacheServerInfo.java    |    72 -
 .../cli/domain/ConnectToLocatorResult.java      |    56 -
 .../internal/cli/domain/DataCommandRequest.java |   214 -
 .../internal/cli/domain/DataCommandResult.java  |   904 -
 .../internal/cli/domain/DiskStoreDetails.java   |   692 -
 .../cli/domain/DurableCqNamesResult.java        |    64 -
 .../cli/domain/EvictionAttributesInfo.java      |   100 -
 .../domain/FixedPartitionAttributesInfo.java    |    70 -
 .../internal/cli/domain/IndexDetails.java       |   330 -
 .../internal/cli/domain/IndexInfo.java          |   103 -
 .../cli/domain/MemberConfigurationInfo.java     |   118 -
 .../internal/cli/domain/MemberInformation.java  |   202 -
 .../internal/cli/domain/MemberResult.java       |   114 -
 .../cli/domain/PartitionAttributesInfo.java     |   171 -
 .../cli/domain/RegionAttributesInfo.java        |   492 -
 .../internal/cli/domain/RegionDescription.java  |   247 -
 .../cli/domain/RegionDescriptionPerMember.java  |   137 -
 .../internal/cli/domain/RegionInformation.java  |   157 -
 .../cli/domain/StackTracesPerMember.java        |    39 -
 .../cli/domain/SubscriptionQueueSizeResult.java |    51 -
 .../cli/exceptions/CliCommandException.java     |    65 -
 .../exceptions/CliCommandInvalidException.java  |    33 -
 .../CliCommandMultiModeOptionException.java     |    48 -
 .../CliCommandNotAvailableException.java        |    33 -
 .../exceptions/CliCommandOptionException.java   |    53 -
 ...CommandOptionHasMultipleValuesException.java |    33 -
 .../CliCommandOptionInvalidException.java       |    34 -
 .../CliCommandOptionMissingException.java       |    35 -
 .../CliCommandOptionNotApplicableException.java |    36 -
 ...liCommandOptionValueConversionException.java |    36 -
 .../CliCommandOptionValueException.java         |    42 -
 .../CliCommandOptionValueMissingException.java  |    36 -
 .../internal/cli/exceptions/CliException.java   |    21 -
 .../exceptions/CreateSubregionException.java    |    41 -
 .../cli/exceptions/ExceptionGenerator.java      |    46 -
 .../cli/exceptions/ExceptionHandler.java        |   106 -
 .../cli/exceptions/IndexNotFoundException.java  |    35 -
 .../functions/AlterRuntimeConfigFunction.java   |    96 -
 .../cli/functions/ChangeLogLevelFunction.java   |    96 -
 .../cli/functions/CliFunctionResult.java        |   248 -
 .../functions/CloseDurableClientFunction.java   |    77 -
 .../cli/functions/CloseDurableCqFunction.java   |    79 -
 .../cli/functions/ContunuousQueryFunction.java  |   152 -
 .../CreateAsyncEventQueueFunction.java          |   183 -
 .../functions/CreateDefinedIndexesFunction.java |    91 -
 .../cli/functions/CreateDiskStoreFunction.java  |    91 -
 .../cli/functions/CreateIndexFunction.java      |   100 -
 .../cli/functions/DataCommandFunction.java      |  1048 -
 .../internal/cli/functions/DeployFunction.java  |   115 -
 .../functions/DescribeDiskStoreFunction.java    |   259 -
 .../functions/DescribeHDFSStoreFunction.java    |    87 -
 .../cli/functions/DestroyDiskStoreFunction.java |   103 -
 .../cli/functions/DestroyIndexFunction.java     |   122 -
 .../cli/functions/ExportConfigFunction.java     |   132 -
 .../cli/functions/ExportDataFunction.java       |    74 -
 .../ExportSharedConfigurationFunction.java      |    72 -
 .../FetchRegionAttributesFunction.java          |   144 -
 .../FetchSharedConfigurationStatusFunction.java |    54 -
 .../functions/GarbageCollectionFunction.java    |    93 -
 .../GatewayReceiverCreateFunction.java          |   226 -
 .../functions/GatewayReceiverFunctionArgs.java  |    80 -
 .../functions/GatewaySenderCreateFunction.java  |   219 -
 .../functions/GatewaySenderFunctionArgs.java    |   144 -
 .../GetMemberConfigInformationFunction.java     |   213 -
 .../functions/GetMemberInformationFunction.java |   150 -
 .../functions/GetRegionDescriptionFunction.java |    62 -
 .../cli/functions/GetRegionsFunction.java       |    75 -
 .../cli/functions/GetStackTracesFunction.java   |    54 -
 .../GetSubscriptionQueueSizeFunction.java       |   101 -
 .../cli/functions/ImportDataFunction.java       |    70 -
 ...ortSharedConfigurationArtifactsFunction.java |    77 -
 .../functions/ListAsyncEventQueuesFunction.java |   109 -
 .../cli/functions/ListDeployedFunction.java     |   106 -
 .../cli/functions/ListDiskStoresFunction.java   |    85 -
 .../functions/ListDurableCqNamesFunction.java   |    99 -
 .../cli/functions/ListFunctionFunction.java     |   115 -
 .../cli/functions/ListIndexFunction.java        |    74 -
 .../LoadSharedConfigurationFunction.java        |    65 -
 .../internal/cli/functions/LogFileFunction.java |   298 -
 .../cli/functions/MemberRegionFunction.java     |    85 -
 .../cli/functions/MembersForRegionFunction.java |    96 -
 .../internal/cli/functions/NetstatFunction.java |   272 -
 .../cli/functions/RebalanceFunction.java        |   124 -
 .../cli/functions/RegionAlterFunction.java      |   344 -
 .../cli/functions/RegionCreateFunction.java     |   415 -
 .../cli/functions/RegionDestroyFunction.java    |    85 -
 .../cli/functions/RegionFunctionArgs.java       |   764 -
 .../cli/functions/ShutDownFunction.java         |    87 -
 .../cli/functions/UndeployFunction.java         |   133 -
 .../cli/functions/UnregisterFunction.java       |    76 -
 .../cli/functions/UserFunctionExecution.java    |   227 -
 .../management/internal/cli/help/CliTopic.java  |   131 -
 .../internal/cli/help/format/Block.java         |    45 -
 .../internal/cli/help/format/DataNode.java      |    51 -
 .../internal/cli/help/format/Help.java          |    47 -
 .../internal/cli/help/format/NewHelp.java       |    55 -
 .../internal/cli/help/format/Row.java           |    30 -
 .../internal/cli/help/utils/FormatOutput.java   |    35 -
 .../internal/cli/help/utils/HelpUtils.java      |   418 -
 .../internal/cli/i18n/CliStrings.java           |  2231 ---
 .../internal/cli/json/GfJsonArray.java          |   242 -
 .../internal/cli/json/GfJsonException.java      |    37 -
 .../internal/cli/json/GfJsonObject.java         |   393 -
 .../management/internal/cli/json/TypedJson.java |   820 -
 .../internal/cli/modes/CommandModes.java        |   155 -
 .../cli/multistep/CLIMultiStepHelper.java       |   400 -
 .../internal/cli/multistep/CLIRemoteStep.java   |    35 -
 .../internal/cli/multistep/CLIStep.java         |    34 -
 .../cli/multistep/CLIStepExecption.java         |    38 -
 .../cli/multistep/MultiStepCommand.java         |    34 -
 .../internal/cli/parser/Argument.java           |    76 -
 .../internal/cli/parser/AvailabilityTarget.java |   107 -
 .../internal/cli/parser/CommandTarget.java      |   188 -
 .../internal/cli/parser/GfshMethodTarget.java   |   134 -
 .../internal/cli/parser/GfshOptionParser.java   |    40 -
 .../internal/cli/parser/MethodParameter.java    |    42 -
 .../management/internal/cli/parser/Option.java  |   223 -
 .../internal/cli/parser/OptionSet.java          |   132 -
 .../internal/cli/parser/Parameter.java          |   119 -
 .../internal/cli/parser/ParserUtils.java        |   190 -
 .../internal/cli/parser/SyntaxConstants.java    |    37 -
 .../cli/parser/jopt/JoptOptionParser.java       |   300 -
 .../preprocessor/EnclosingCharacters.java       |    35 -
 .../cli/parser/preprocessor/Preprocessor.java   |   140 -
 .../parser/preprocessor/PreprocessorUtils.java  |   338 -
 .../internal/cli/parser/preprocessor/Stack.java |    55 -
 .../cli/parser/preprocessor/TrimmedInput.java   |    47 -
 .../cli/remote/CommandExecutionContext.java     |   127 -
 .../internal/cli/remote/CommandProcessor.java   |   166 -
 .../cli/remote/CommandStatementImpl.java        |   100 -
 .../cli/remote/MemberCommandService.java        |    84 -
 .../cli/remote/RemoteExecutionStrategy.java     |   169 -
 .../internal/cli/remote/WrapperThreadLocal.java |    42 -
 .../internal/cli/result/AbstractResultData.java |   340 -
 .../cli/result/CliJsonSerializable.java         |    45 -
 .../cli/result/CliJsonSerializableFactory.java  |    48 -
 .../cli/result/CliJsonSerializableIds.java      |    34 -
 .../internal/cli/result/CommandResult.java      |   661 -
 .../cli/result/CommandResultException.java      |    39 -
 .../cli/result/CompositeResultData.java         |   361 -
 .../internal/cli/result/ErrorResultData.java    |   104 -
 .../internal/cli/result/FileResult.java         |   117 -
 .../internal/cli/result/InfoResultData.java     |    91 -
 .../internal/cli/result/ObjectResultData.java   |    88 -
 .../internal/cli/result/ResultBuilder.java      |   475 -
 .../internal/cli/result/ResultData.java         |    53 -
 .../cli/result/ResultDataException.java         |    35 -
 .../internal/cli/result/TableBuilder.java       |   475 -
 .../internal/cli/result/TableBuilderHelper.java |   176 -
 .../internal/cli/result/TabularResultData.java  |   174 -
 .../management/internal/cli/shell/Gfsh.java     |  1259 --
 .../internal/cli/shell/GfshConfig.java          |   253 -
 .../cli/shell/GfshExecutionStrategy.java        |   294 -
 .../cli/shell/JMXConnectionException.java       |    56 -
 .../cli/shell/JMXInvocationException.java       |    42 -
 .../internal/cli/shell/JmxOperationInvoker.java |   416 -
 .../internal/cli/shell/MultiCommandHelper.java  |    70 -
 .../internal/cli/shell/OperationInvoker.java    |   135 -
 .../internal/cli/shell/jline/ANSIBuffer.java    |   433 -
 .../internal/cli/shell/jline/ANSIHandler.java   |   113 -
 .../cli/shell/jline/CygwinMinttyTerminal.java   |    56 -
 .../internal/cli/shell/jline/GfshHistory.java   |    63 -
 .../shell/jline/GfshUnsupportedTerminal.java    |    33 -
 .../cli/shell/unsafe/GfshSignalHandler.java     |    85 -
 .../internal/cli/util/CLIConsoleBufferUtil.java |    37 -
 .../internal/cli/util/CauseFinder.java          |   214 -
 .../cli/util/ClasspathScanLoadHelper.java       |   258 -
 .../internal/cli/util/CommandStringBuilder.java |   105 -
 .../internal/cli/util/CommentSkipHelper.java    |    78 -
 .../internal/cli/util/ConnectionEndpoint.java   |    73 -
 .../internal/cli/util/DiskStoreCompacter.java   |   134 -
 .../cli/util/DiskStoreNotFoundException.java    |    49 -
 .../internal/cli/util/DiskStoreUpgrader.java    |   130 -
 .../internal/cli/util/DiskStoreValidater.java   |    60 -
 .../cli/util/EvictionAttributesInfo.java        |    63 -
 .../cli/util/FixedPartitionAttributesInfo.java  |    65 -
 .../internal/cli/util/GfshConsoleReader.java    |    90 -
 .../cli/util/HDFSStoreNotFoundException.java    |    47 -
 .../cli/util/JConsoleNotFoundException.java     |    47 -
 .../management/internal/cli/util/JsonUtil.java  |   606 -
 .../internal/cli/util/MemberInformation.java    |   157 -
 .../cli/util/MemberNotFoundException.java       |    49 -
 .../management/internal/cli/util/MergeLogs.java |    87 -
 .../internal/cli/util/ReadWriteFile.java        |   232 -
 .../cli/util/RegionAttributesDefault.java       |    90 -
 .../cli/util/RegionAttributesNames.java         |    89 -
 .../internal/cli/util/RegionPath.java           |   128 -
 .../cli/util/VisualVmNotFoundException.java     |    48 -
 .../SharedConfigurationWriter.java              |   180 -
 .../callbacks/ConfigurationChangeListener.java  |    59 -
 .../configuration/domain/CacheElement.java      |   253 -
 .../configuration/domain/Configuration.java     |   207 -
 .../domain/ConfigurationChangeResult.java       |   126 -
 .../domain/SharedConfigurationStatus.java       |    26 -
 .../configuration/domain/XmlEntity.java         |   551 -
 .../configuration/functions/AddJarFunction.java |    67 -
 .../functions/AddXmlEntityFunction.java         |    60 -
 .../functions/DeleteJarFunction.java            |    68 -
 .../functions/DeleteXmlEntityFunction.java      |    65 -
 .../functions/GetAllJarsFunction.java           |    67 -
 .../functions/ModifyPropertiesFunction.java     |    65 -
 .../handlers/ConfigurationRequestHandler.java   |    85 -
 ...SharedConfigurationStatusRequestHandler.java |    65 -
 .../messages/ConfigurationRequest.java          |   128 -
 .../messages/ConfigurationResponse.java         |   174 -
 .../SharedConfigurationStatusRequest.java       |    44 -
 .../SharedConfigurationStatusResponse.java      |    78 -
 .../configuration/utils/DtdResolver.java        |    92 -
 .../configuration/utils/XmlConstants.java       |    56 -
 .../internal/configuration/utils/XmlUtils.java  |   685 -
 .../internal/configuration/utils/ZipUtils.java  |   122 -
 .../internal/messages/CompactRequest.java       |   174 -
 .../internal/messages/CompactResponse.java      |    70 -
 .../internal/security/AccessControl.java        |    51 -
 .../internal/security/AccessControlContext.java |    37 -
 .../internal/security/AccessControlMXBean.java  |    23 -
 .../internal/security/CLIOperationContext.java  |   138 -
 .../internal/security/JMXOperationContext.java  |   177 -
 .../internal/security/JSONAuthorization.java    |   308 -
 .../internal/security/MBeanServerWrapper.java   |   286 -
 .../security/ManagementInterceptor.java         |   271 -
 .../management/internal/security/Resource.java  |    26 -
 .../internal/security/ResourceConstants.java    |   115 -
 .../internal/security/ResourceOperation.java    |    34 -
 .../security/ResourceOperationContext.java      |   203 -
 .../unsafe/ReadOpFileAccessController.java      |    63 -
 .../controllers/AbstractCommandsController.java |   618 -
 .../AbstractMultiPartCommandsController.java    |    78 -
 .../controllers/ClientCommandsController.java   |    60 -
 .../controllers/ClusterCommandsController.java  |    49 -
 .../controllers/ConfigCommandsController.java   |   214 -
 .../web/controllers/DataCommandsController.java |   241 -
 .../controllers/DeployCommandsController.java   |   110 -
 .../DiskStoreCommandsController.java            |   177 -
 .../DurableClientCommandsController.java        |   158 -
 .../controllers/FunctionCommandsController.java |   142 -
 .../controllers/IndexCommandsController.java    |   172 -
 .../LauncherLifecycleCommandsController.java    |    55 -
 .../controllers/MemberCommandsController.java   |    78 -
 .../MiscellaneousCommandsController.java        |   271 -
 .../web/controllers/PdxCommandsController.java  |   122 -
 .../controllers/QueueCommandsController.java    |   133 -
 .../controllers/RegionCommandsController.java   |   332 -
 .../controllers/ShellCommandsController.java    |   286 -
 .../web/controllers/WanCommandsController.java  |   403 -
 .../EnvironmentVariablesHandlerInterceptor.java |    93 -
 .../support/MemberMXBeanAdapter.java            |   660 -
 .../management/internal/web/domain/Link.java    |   161 -
 .../internal/web/domain/LinkIndex.java          |   140 -
 .../web/domain/QueryParameterSource.java        |    63 -
 .../internal/web/http/ClientHttpRequest.java    |   451 -
 .../internal/web/http/HttpHeader.java           |   100 -
 .../internal/web/http/HttpMethod.java           |    36 -
 .../SerializableObjectHttpMessageConverter.java |   103 -
 .../web/http/support/SimpleHttpRequester.java   |   140 -
 .../internal/web/io/MultipartFileAdapter.java   |    68 -
 .../web/io/MultipartFileResourceAdapter.java    |    68 -
 .../web/shell/AbstractHttpOperationInvoker.java |   801 -
 .../web/shell/HttpOperationInvoker.java         |    31 -
 .../web/shell/MBeanAccessException.java         |    45 -
 .../RestApiCallForCommandNotFoundException.java |    44 -
 .../web/shell/RestHttpOperationInvoker.java     |   424 -
 .../web/shell/SimpleHttpOperationInvoker.java   |   161 -
 .../shell/support/HttpInvocationHandler.java    |    95 -
 .../shell/support/HttpMBeanProxyFactory.java    |    41 -
 .../internal/web/util/ConvertUtils.java         |   132 -
 .../management/internal/web/util/UriUtils.java  |   257 -
 .../management/membership/ClientMembership.java |    67 -
 .../membership/ClientMembershipEvent.java       |    51 -
 .../membership/ClientMembershipListener.java    |    48 -
 .../ClientMembershipListenerAdapter.java        |    52 -
 .../management/membership/MembershipEvent.java  |    42 -
 .../membership/MembershipListener.java          |    53 -
 .../UniversalMembershipListenerAdapter.java     |   384 -
 .../gemstone/gemfire/management/package.html    |    24 -
 .../memcached/GemFireMemcachedServer.java       |   284 -
 .../main/java/com/gemstone/gemfire/package.html |    86 -
 .../com/gemstone/gemfire/pdx/FieldType.java     |   158 -
 .../com/gemstone/gemfire/pdx/JSONFormatter.java |   630 -
 .../gemfire/pdx/JSONFormatterException.java     |    47 -
 .../gemfire/pdx/NonPortableClassException.java  |    34 -
 .../gemfire/pdx/PdxConfigurationException.java  |    41 -
 .../pdx/PdxFieldAlreadyExistsException.java     |    46 -
 .../pdx/PdxFieldDoesNotExistException.java      |    42 -
 .../pdx/PdxFieldTypeMismatchException.java      |    46 -
 .../gemfire/pdx/PdxInitializationException.java |    51 -
 .../com/gemstone/gemfire/pdx/PdxInstance.java   |   202 -
 .../gemfire/pdx/PdxInstanceFactory.java         |   472 -
 .../com/gemstone/gemfire/pdx/PdxReader.java     |   265 -
 .../pdx/PdxRegistryMismatchException.java       |    37 -
 .../gemstone/gemfire/pdx/PdxSerializable.java   |    71 -
 .../gemfire/pdx/PdxSerializationException.java  |    53 -
 .../com/gemstone/gemfire/pdx/PdxSerializer.java |    94 -
 .../gemstone/gemfire/pdx/PdxUnreadFields.java   |    42 -
 .../com/gemstone/gemfire/pdx/PdxWriter.java     |   479 -
 .../pdx/ReflectionBasedAutoSerializer.java      |   561 -
 .../gemfire/pdx/WritablePdxInstance.java        |    44 -
 .../pdx/internal/AutoSerializableManager.java   |  2304 ---
 .../pdx/internal/CheckTypeRegistryState.java    |   110 -
 .../pdx/internal/ClientTypeRegistration.java    |   418 -
 .../gemfire/pdx/internal/ComparableEnum.java    |    24 -
 .../pdx/internal/ConvertableToBytes.java        |    23 -
 .../gemstone/gemfire/pdx/internal/DataSize.java |    49 -
 .../gemfire/pdx/internal/DefaultPdxField.java   |    40 -
 .../gemstone/gemfire/pdx/internal/EnumId.java   |    96 -
 .../gemstone/gemfire/pdx/internal/EnumInfo.java |   333 -
 .../pdx/internal/FieldNotFoundInPdxVersion.java |    27 -
 .../gemfire/pdx/internal/InternalPdxReader.java |    85 -
 .../pdx/internal/LonerTypeRegistration.java     |   186 -
 .../pdx/internal/NullTypeRegistration.java      |   120 -
 .../gemstone/gemfire/pdx/internal/PdxField.java |   259 -
 .../gemfire/pdx/internal/PdxInputStream.java    |   439 -
 .../gemfire/pdx/internal/PdxInstanceEnum.java   |   183 -
 .../pdx/internal/PdxInstanceFactoryImpl.java    |   270 -
 .../gemfire/pdx/internal/PdxInstanceImpl.java   |   646 -
 .../pdx/internal/PdxInstanceInputStream.java    |   115 -
 .../gemfire/pdx/internal/PdxOutputStream.java   |   242 -
 .../gemfire/pdx/internal/PdxReaderImpl.java     |   904 -
 .../gemfire/pdx/internal/PdxString.java         |   210 -
 .../gemstone/gemfire/pdx/internal/PdxType.java  |   495 -
 .../gemfire/pdx/internal/PdxUnreadData.java     |   118 -
 .../gemfire/pdx/internal/PdxWriterImpl.java     |   910 -
 .../pdx/internal/PeerTypeRegistration.java      |   776 -
 .../pdx/internal/TrackingPdxReaderImpl.java     |   354 -
 .../gemfire/pdx/internal/TypeRegistration.java  |   102 -
 .../gemfire/pdx/internal/TypeRegistry.java      |   525 -
 .../gemfire/pdx/internal/UnreadPdxType.java     |    73 -
 .../internal/WeakConcurrentIdentityHashMap.java |   137 -
 .../pdx/internal/WritablePdxInstanceImpl.java   |   288 -
 .../gemfire/pdx/internal/json/JsonHelper.java   |   182 -
 .../pdx/internal/json/PdxInstanceHelper.java    |   195 -
 .../pdx/internal/json/PdxListHelper.java        |   190 -
 .../gemfire/pdx/internal/json/PdxToJSON.java    |   322 -
 .../pdx/internal/unsafe/UnsafeWrapper.java      |   188 -
 .../java/com/gemstone/gemfire/pdx/package.html  |   112 -
 .../com/gemstone/gemfire/ra/GFConnection.java   |    27 -
 .../gemfire/ra/GFConnectionFactory.java         |    29 -
 .../gemfire/redis/GemFireRedisServer.java       |   717 -
 .../gemfire/security/AccessControl.java         |    95 -
 .../gemfire/security/AuthInitialize.java        |    88 -
 .../security/AuthenticationFailedException.java |    54 -
 .../AuthenticationRequiredException.java        |    54 -
 .../gemfire/security/Authenticator.java         |    87 -
 .../security/GemFireSecurityException.java      |    55 -
 .../security/NotAuthorizedException.java        |    63 -
 .../com/gemstone/gemfire/security/package.html  |    39 -
 .../message/GemFireParameterizedMessage.java    |   554 -
 .../GemFireParameterizedMessageFactory.java     |    54 -
 .../src/main/java/external-overview.html        |    43 -
 .../src/main/java/internal-overview.html        |    26 -
 .../gemfire/cache/cache-8.1.xsd                 |  1512 --
 .../gemfire/cache/cache-9.0.xsd                 |  1519 --
 .../services/org.xml.sax.ext.EntityResolver2    |     2 -
 .../gemstone/gemfire/admin/doc-files/ds4_0.dtd  |   176 -
 .../gemstone/gemfire/admin/doc-files/ds5_0.dtd  |   168 -
 .../internal/doc-files/mbeans-descriptors.dtd   |   232 -
 .../gemfire/admin/jmx/mbeans-descriptors.xml    |  1435 --
 .../gemfire/cache/doc-files/cache3_0.dtd        |   296 -
 .../gemfire/cache/doc-files/cache4_0.dtd        |   392 -
 .../gemfire/cache/doc-files/cache4_1.dtd        |   485 -
 .../gemfire/cache/doc-files/cache5_0.dtd        |   519 -
 .../gemfire/cache/doc-files/cache5_1.dtd        |   534 -
 .../gemfire/cache/doc-files/cache5_5.dtd        |   651 -
 .../gemfire/cache/doc-files/cache5_7.dtd        |   776 -
 .../gemfire/cache/doc-files/cache5_8.dtd        |   794 -
 .../gemfire/cache/doc-files/cache6_0.dtd        |   862 -
 .../gemfire/cache/doc-files/cache6_1.dtd        |   871 -
 .../gemfire/cache/doc-files/cache6_5.dtd        |   949 -
 .../gemfire/cache/doc-files/cache6_6.dtd        |  1006 -
 .../gemfire/cache/doc-files/cache7_0.dtd        |  1087 --
 .../gemfire/cache/doc-files/cache8_0.dtd        |  1107 --
 .../membership/gms/messenger/jgroups-config.xml |    72 -
 .../membership/gms/messenger/jgroups-mcast.xml  |    98 -
 .../internal/i18n/StringIdResourceBundle_ja.txt |  3811 ----
 .../internal/logging/log4j/log4j2-legacy.xml    |    17 -
 .../gemstone/gemfire/internal/privatekey.ser    |   Bin 756 -> 0 bytes
 .../com/gemstone/gemfire/internal/publickey.ser |   Bin 1029 -> 0 bytes
 .../tools/gfsh/app/windowsbindings.properties   |    83 -
 .../internal/cli/commands/support/gfmon.html    |    28 -
 .../management/internal/cli/modes/commands.json |     3 -
 .../management/internal/cli/modes/connect.json  |    29 -
 .../internal/cli/modes/stopserver.json          |    29 -
 .../com/gemstone/gemfire/statisticsType.dtd     |    87 -
 gemfire-core/src/main/resources/log4j2-cli.xml  |    17 -
 gemfire-core/src/main/resources/log4j2.xml      |    23 -
 .../batterytest/greplogs/ExpectedStrings.java   |   188 -
 .../java/batterytest/greplogs/LogConsumer.java  |   290 -
 .../src/test/java/cacheRunner/Portfolio.java    |   129 -
 .../src/test/java/cacheRunner/Position.java     |    74 -
 .../src/test/java/com/company/app/Customer.java |    37 -
 .../src/test/java/com/company/app/DBLoader.java |    64 -
 .../com/company/app/OrdersCacheListener.java    |    52 -
 .../java/com/company/data/DatabaseLoader.java   |    43 -
 .../java/com/company/data/MyDeclarable.java     |    33 -
 .../src/test/java/com/company/data/MySizer.java |    40 -
 .../com/company/data/MyTransactionListener.java |    39 -
 .../src/test/java/com/examples/LinkNode.java    |    78 -
 .../src/test/java/com/examples/SuperClass.java  |    93 -
 .../src/test/java/com/examples/TestObject.java  |    55 -
 .../src/test/java/com/examples/ds/Address.java  |    23 -
 .../src/test/java/com/examples/ds/Company.java  |    43 -
 .../java/com/examples/ds/CompanySerializer.java |    67 -
 .../src/test/java/com/examples/ds/Employee.java |    53 -
 .../com/examples/ds/PutDataSerializables.java   |    55 -
 .../src/test/java/com/examples/ds/User.java     |    58 -
 .../com/examples/snapshot/MyDataSerializer.java |    63 -
 .../java/com/examples/snapshot/MyObject.java    |    69 -
 .../snapshot/MyObjectDataSerializable.java      |    45 -
 .../java/com/examples/snapshot/MyObjectPdx.java |    33 -
 .../snapshot/MyObjectPdxSerializable.java       |    42 -
 .../com/examples/snapshot/MyPdxSerializer.java  |    64 -
 .../java/com/gemstone/gemfire/AppObject.java    |    24 -
 .../com/gemstone/gemfire/CopyJUnitTest.java     |   575 -
 .../com/gemstone/gemfire/DeltaTestImpl.java     |   397 -
 .../gemfire/DiskInstantiatorsJUnitTest.java     |   183 -
 .../com/gemstone/gemfire/GemFireTestCase.java   |    92 -
 .../java/com/gemstone/gemfire/Invariant.java    |    32 -
 .../com/gemstone/gemfire/InvariantResult.java   |    28 -
 .../com/gemstone/gemfire/JUnitTestSetup.java    |   143 -
 .../gemfire/JtaNoninvolvementJUnitTest.java     |   180 -
 .../gemfire/LocalStatisticsJUnitTest.java       |    50 -
 .../com/gemstone/gemfire/LonerDMJUnitTest.java  |   196 -
 .../gemstone/gemfire/StatisticsTestCase.java    |   388 -
 .../gemfire/StatisticsTypeJUnitTest.java        |    77 -
 .../gemfire/SystemFailureJUnitTest.java         |    60 -
 .../com/gemstone/gemfire/TXExpiryJUnitTest.java |   420 -
 .../java/com/gemstone/gemfire/TXJUnitTest.java  |  6825 -------
 .../com/gemstone/gemfire/TXWriterJUnitTest.java |   241 -
 .../gemstone/gemfire/TXWriterOOMEJUnitTest.java |    78 -
 .../com/gemstone/gemfire/TXWriterTestCase.java  |   152 -
 .../gemstone/gemfire/TestDataSerializer.java    |   117 -
 .../com/gemstone/gemfire/TimingTestCase.java    |    77 -
 .../com/gemstone/gemfire/UnitTestDoclet.java    |   264 -
 .../gemstone/gemfire/admin/AdminTestHelper.java |    45 -
 .../BindDistributedSystemJUnitTest.java         |    97 -
 .../internal/CacheHealthEvaluatorJUnitTest.java |   208 -
 .../internal/DistributedSystemTestCase.java     |    67 -
 .../admin/internal/HealthEvaluatorTestCase.java |    76 -
 .../MemberHealthEvaluatorJUnitTest.java         |   102 -
 .../cache/AttributesFactoryJUnitTest.java       |   420 -
 .../gemfire/cache/Bug36619JUnitTest.java        |    77 -
 .../gemfire/cache/Bug42039JUnitTest.java        |    96 -
 .../gemfire/cache/Bug52289JUnitTest.java        |    89 -
 .../gemfire/cache/CacheListenerJUnitTest.java   |   336 -
 .../cache/CacheRegionClearStatsDUnitTest.java   |   240 -
 .../gemstone/gemfire/cache/ClientHelper.java    |    73 -
 .../cache/ClientServerTimeSyncDUnitTest.java    |   203 -
 .../cache/ConnectionPoolAndLoaderDUnitTest.java |   489 -
 .../cache/ConnectionPoolFactoryJUnitTest.java   |   424 -
 .../gemfire/cache/OperationJUnitTest.java       |   933 -
 .../gemfire/cache/PoolManagerJUnitTest.java     |   135 -
 .../gemstone/gemfire/cache/ProxyJUnitTest.java  |  1169 --
 .../gemfire/cache/RegionFactoryJUnitTest.java   |  1195 --
 .../gemfire/cache/RoleExceptionJUnitTest.java   |   139 -
 .../SerialAsyncEventQueueImplJUnitTest.java     |    62 -
 .../client/ClientCacheFactoryJUnitTest.java     |   343 -
 .../client/ClientRegionFactoryJUnitTest.java    |   532 -
 .../ClientServerRegisterInterestsDUnitTest.java |   256 -
 .../internal/AutoConnectionSourceDUnitTest.java |   598 -
 .../AutoConnectionSourceImplJUnitTest.java      |   398 -
 .../CacheServerSSLConnectionDUnitTest.java      |   424 -
 .../internal/ConnectionPoolImplJUnitTest.java   |   260 -
 .../internal/LocatorLoadBalancingDUnitTest.java |   502 -
 .../cache/client/internal/LocatorTestBase.java  |   365 -
 .../internal/OpExecutorImplJUnitTest.java       |   664 -
 .../client/internal/QueueManagerJUnitTest.java  |   674 -
 .../internal/SSLNoClientAuthDUnitTest.java      |   277 -
 .../internal/ServerBlackListJUnitTest.java      |   123 -
 .../locator/LocatorStatusResponseJUnitTest.java |    77 -
 .../pooling/ConnectionManagerJUnitTest.java     |   878 -
 .../SignalledFlushObserverJUnitTest.java        |    97 -
 .../SortedListForAsyncQueueJUnitTest.java       |   565 -
 .../management/MXMemoryPoolListenerExample.java |   206 -
 .../management/MemoryThresholdsDUnitTest.java   |  2333 ---
 .../MemoryThresholdsOffHeapDUnitTest.java       |  1826 --
 .../management/ResourceManagerDUnitTest.java    |  1841 --
 .../ExceptionHandlingJUnitTest.java             |   177 -
 .../mapInterface/MapFunctionalJUnitTest.java    |   170 -
 .../mapInterface/PutAllGlobalLockJUnitTest.java |   109 -
 .../PutOperationContextJUnitTest.java           |   264 -
 .../GetOperationContextImplJUnitTest.java       |   291 -
 .../PartitionRegionHelperDUnitTest.java         |   742 -
 .../BaseLineAndCompareQueryPerfJUnitTest.java   |   537 -
 .../query/Bug32947ValueConstraintJUnitTest.java |   127 -
 .../gemfire/cache/query/BugJUnitTest.java       |   570 -
 .../gemfire/cache/query/CacheUtils.java         |   398 -
 .../cache/query/MultithreadedTester.java        |    73 -
 .../cache/query/PdxStringQueryJUnitTest.java    |   727 -
 .../gemstone/gemfire/cache/query/PerfQuery.java |   330 -
 .../gemfire/cache/query/QueryJUnitTest.java     |   457 -
 .../cache/query/QueryServiceJUnitTest.java      |   252 -
 .../gemfire/cache/query/QueryTestUtils.java     |  1640 --
 .../cache/query/QueryTestUtilsJUnitTest.java    |   134 -
 .../gemfire/cache/query/RegionJUnitTest.java    |   226 -
 .../cache/query/TypedIteratorJUnitTest.java     |   133 -
 .../com/gemstone/gemfire/cache/query/Utils.java |    57 -
 .../query/cq/dunit/CqQueryTestListener.java     |   398 -
 .../gemfire/cache/query/data/Address.java       |    51 -
 .../gemstone/gemfire/cache/query/data/City.java |    57 -
 .../cache/query/data/CollectionHolder.java      |    90 -
 .../cache/query/data/ComparableWrapper.java     |    70 -
 .../gemfire/cache/query/data/Country.java       |   100 -
 .../gemstone/gemfire/cache/query/data/Data.java |    47 -
 .../gemfire/cache/query/data/District.java      |    65 -
 .../gemfire/cache/query/data/Employee.java      |    72 -
 .../gemfire/cache/query/data/Inventory.java     |   127 -
 .../gemfire/cache/query/data/Keywords.java      |    90 -
 .../gemfire/cache/query/data/Manager.java       |    43 -
 .../gemfire/cache/query/data/Numbers.java       |    52 -
 .../gemfire/cache/query/data/PhoneNo.java       |    42 -
 .../gemfire/cache/query/data/Portfolio.java     |   314 -
 .../gemfire/cache/query/data/PortfolioData.java |   154 -
 .../gemfire/cache/query/data/PortfolioNoDS.java |   240 -
 .../gemfire/cache/query/data/PortfolioPdx.java  |   311 -
 .../gemfire/cache/query/data/Position.java      |   166 -
 .../gemfire/cache/query/data/PositionNoDS.java  |   130 -
 .../gemfire/cache/query/data/PositionPdx.java   |   182 -
 .../query/data/ProhibitedSecurityQuote.java     |    66 -
 .../gemfire/cache/query/data/Quote.java         |   114 -
 .../gemfire/cache/query/data/Restricted.java    |    80 -
 .../cache/query/data/SecurityMaster.java        |   262 -
 .../gemfire/cache/query/data/State.java         |    81 -
 .../gemfire/cache/query/data/Street.java        |    38 -
 .../gemfire/cache/query/data/Student.java       |    77 -
 .../gemfire/cache/query/data/Vehicle.java       |    39 -
 .../gemfire/cache/query/data/Village.java       |    55 -
 .../query/dunit/CloseCacheAuthorization.java    |    62 -
 .../query/dunit/CompactRangeIndexDUnitTest.java |   204 -
 .../cache/query/dunit/CqTimeTestListener.java   |   266 -
 .../cache/query/dunit/GroupByDUnitImpl.java     |   328 -
 .../dunit/GroupByPartitionedQueryDUnitTest.java |   110 -
 .../query/dunit/GroupByQueryDUnitTest.java      |   189 -
 .../cache/query/dunit/HashIndexDUnitTest.java   |   132 -
 .../cache/query/dunit/HelperTestCase.java       |   267 -
 .../dunit/NonDistinctOrderByDUnitImpl.java      |   266 -
 .../NonDistinctOrderByPartitionedDUnitTest.java |   154 -
 .../query/dunit/PdxStringQueryDUnitTest.java    |  1987 --
 .../dunit/QueryAPITestPartitionResolver.java    |    44 -
 .../cache/query/dunit/QueryAuthorization.java   |    70 -
 .../dunit/QueryDataInconsistencyDUnitTest.java  |   576 -
 .../dunit/QueryIndexUsingXMLDUnitTest.java      |   993 -
 .../QueryParamsAuthorizationDUnitTest.java      |   111 -
 .../QueryUsingFunctionContextDUnitTest.java     |  1041 -
 .../query/dunit/QueryUsingPoolDUnitTest.java    |  2588 ---
 .../cache/query/dunit/RemoteQueryDUnitTest.java |  1502 --
 ...esourceManagerWithQueryMonitorDUnitTest.java |  1166 --
 .../query/dunit/SelectStarQueryDUnitTest.java   |  1625 --
 .../cache/query/facets/lang/Address.java        |    60 -
 .../gemfire/cache/query/facets/lang/Course.java |    91 -
 .../cache/query/facets/lang/Department.java     |    96 -
 .../query/facets/lang/DerivedEmployee.java      |    29 -
 .../cache/query/facets/lang/Employee.java       |   140 -
 .../cache/query/facets/lang/Faculty.java        |   134 -
 .../cache/query/facets/lang/G_Student.java      |    66 -
 .../gemfire/cache/query/facets/lang/Person.java |    96 -
 .../cache/query/facets/lang/Student.java        |   103 -
 .../cache/query/facets/lang/UG_Student.java     |    66 -
 .../gemfire/cache/query/facets/lang/Utils.java  |   134 -
 .../ComparisonOperatorsJUnitTest.java           |   185 -
 .../query/functional/ConstantsJUnitTest.java    |   109 -
 .../query/functional/CountStarJUnitTest.java    |   686 -
 .../CustomerOptimizationsJUnitTest.java         |  1386 --
 .../DistinctAndNonDistinctQueryJUnitTest.java   |   154 -
 ...ctResultsWithDupValuesInRegionJUnitTest.java |   481 -
 .../query/functional/FunctionJUnitTest.java     |   315 -
 .../functional/GroupByPartitionedJUnitTest.java |    50 -
 .../functional/GroupByReplicatedJUnitTest.java  |    39 -
 .../cache/query/functional/GroupByTestImpl.java |  1010 -
 .../query/functional/GroupByTestInterface.java  |    58 -
 .../query/functional/INOperatorJUnitTest.java   |   471 -
 .../functional/IUM6Bug32345ReJUnitTest.java     |   224 -
 .../cache/query/functional/IUMJUnitTest.java    |   237 -
 .../IUMRCompositeIteratorJUnitTest.java         |   251 -
 .../IUMRMultiIndexesMultiRegionJUnitTest.java   |  1274 --
 .../IUMRShuffleIteratorsJUnitTest.java          |   489 -
 .../functional/IUMRSingleRegionJUnitTest.java   |   901 -
 ...ependentOperandsInWhereClause2JUnitTest.java |   200 -
 .../IndexCreationDeadLockJUnitTest.java         |   309 -
 .../functional/IndexCreationJUnitTest.java      |  1088 --
 .../IndexMaintenanceAsynchJUnitTest.java        |   178 -
 .../functional/IndexOnEntrySetJUnitTest.java    |   335 -
 .../functional/IndexOperatorJUnitTest.java      |   225 -
 .../IndexPrimaryKeyUsageJUnitTest.java          |   335 -
 .../IndexUsageInNestedQueryJUnitTest.java       |   152 -
 .../IndexUsageWithAliasAsProjAtrbt.java         |   177 -
 ...IndexUsageWithAliasAsProjAtrbtJUnitTest.java |   185 -
 .../IndexUseMultFrmSnglCondJUnitTest.java       |   274 -
 ...ndexWithSngleFrmAndMultCondQryJUnitTest.java |  1354 --
 .../functional/IteratorTypeDefEmpJUnitTest.java |    87 -
 .../functional/IteratorTypeDefJUnitTest.java    |   163 -
 .../IteratorTypeDefaultTypesJUnitTest.java      |   426 -
 .../functional/IumMultConditionJUnitTest.java   |   231 -
 .../functional/JavaSerializationJUnitTest.java  |    68 -
 .../functional/LikePredicateJUnitTest.java      |  2386 ---
 .../query/functional/LimitClauseJUnitTest.java  |  1850 --
 .../functional/LogicalOperatorsJUnitTest.java   |   201 -
 .../cache/query/functional/MiscJUnitTest.java   |   726 -
 .../functional/MultiIndexCreationJUnitTest.java |   385 -
 .../MultiRegionIndexUsageJUnitTest.java         |   903 -
 .../functional/MultipleRegionsJUnitTest.java    |   109 -
 .../NegativeNumberQueriesJUnitTest.java         |   127 -
 .../query/functional/NestedQueryJUnitTest.java  |   511 -
 .../NonDistinctOrderByPartitionedJUnitTest.java |   260 -
 .../NonDistinctOrderByReplicatedJUnitTest.java  |   411 -
 .../NonDistinctOrderByTestImplementation.java   |  1545 --
 .../query/functional/NumericQueryJUnitTest.java |   337 -
 .../functional/OrderByPartitionedJUnitTest.java |   667 -
 .../functional/OrderByReplicatedJUnitTest.java  |   836 -
 .../functional/OrderByTestImplementation.java   |  1184 --
 .../functional/ParameterBindingJUnitTest.java   |   178 -
 .../PdxGroupByPartitionedJUnitTest.java         |    40 -
 .../PdxGroupByReplicatedJUnitTest.java          |    37 -
 .../query/functional/PdxGroupByTestImpl.java    |  1025 -
 .../query/functional/PdxOrderByJUnitTest.java   |   357 -
 .../functional/QRegionInterfaceJUnitTest.java   |   164 -
 .../QueryREUpdateInProgressJUnitTest.java       |   436 -
 .../functional/QueryUndefinedJUnitTest.java     |   286 -
 .../functional/ReservedKeywordsJUnitTest.java   |    82 -
 .../ResultsDataSerializabilityJUnitTest.java    |   144 -
 .../query/functional/SelectToDateJUnitTest.java |   263 -
 .../functional/StructMemberAccessJUnitTest.java |   287 -
 .../query/functional/StructSetOrResultsSet.java |   456 -
 .../query/functional/TestNewFunctionSSorRS.java |   129 -
 .../CompiledAggregateFunctionJUnitTest.java     |   200 -
 .../CompiledGroupBySelectJUnitTest.java         |   161 -
 .../query/internal/CompiledInJUnitTest.java     |   460 -
 .../CompiledJunctionInternalsJUnitTest.java     |  3481 ----
 .../internal/CopyOnReadQueryJUnitTest.java      |   418 -
 .../internal/ExecutionContextJUnitTest.java     |   405 -
 .../query/internal/IndexManagerJUnitTest.java   |   182 -
 .../internal/NWayMergeResultsJUnitTest.java     |   551 -
 .../internal/OrderByComparatorJUnitTest.java    |   206 -
 .../internal/ProjectionAttributeJUnitTest.java  |   241 -
 .../query/internal/QCompilerJUnitTest.java      |   452 -
 .../QueryExecutionContextJUnitTest.java         |    67 -
 ...ueryFromClauseCanonicalizationJUnitTest.java |   257 -
 .../QueryObjectSerializationJUnitTest.java      |   151 -
 .../QueryObserverCallbackJUnitTest.java         |   424 -
 .../query/internal/QueryTraceJUnitTest.java     |   449 -
 .../query/internal/QueryUtilsJUnitTest.java     |   308 -
 .../query/internal/ResultsBagJUnitTest.java     |   307 -
 .../ResultsBagLimitBehaviourJUnitTest.java      |   585 -
 .../ResultsCollectionWrapperLimitJUnitTest.java |   367 -
 .../SelectResultsComparatorJUnitTest.java       |    91 -
 .../StructBagLimitBehaviourJUnitTest.java       |   129 -
 .../query/internal/StructSetJUnitTest.java      |    77 -
 .../internal/aggregate/AggregatorJUnitTest.java |   215 -
 ...syncIndexUpdaterThreadShutdownJUnitTest.java |   123 -
 .../index/AsynchIndexMaintenanceJUnitTest.java  |   261 -
 .../CompactRangeIndexIndexMapJUnitTest.java     |   187 -
 .../index/CompactRangeIndexJUnitTest.java       |   506 -
 ...rrentIndexInitOnOverflowRegionDUnitTest.java |   467 -
 ...ndexOperationsOnOverflowRegionDUnitTest.java |   724 -
 ...pdateWithInplaceObjectModFalseDUnitTest.java |   714 -
 ...ConcurrentIndexUpdateWithoutWLDUnitTest.java |   800 -
 .../index/CopyOnReadIndexDUnitTest.java         |   652 -
 .../index/CopyOnReadIndexJUnitTest.java         |   457 -
 .../DeclarativeIndexCreationJUnitTest.java      |   123 -
 .../query/internal/index/EquijoinDUnitTest.java |   437 -
 .../internal/index/HashIndexJUnitTest.java      |  1592 --
 .../internal/index/HashIndexSetJUnitTest.java   |   504 -
 .../index/IndexCreationInternalsJUnitTest.java  |   214 -
 .../internal/index/IndexElemArrayJUnitTest.java |   137 -
 .../internal/index/IndexHintJUnitTest.java      |   506 -
 .../query/internal/index/IndexJUnitTest.java    |    97 -
 .../index/IndexMaintainceJUnitTest.java         |   513 -
 .../index/IndexMaintenanceJUnitTest.java        |  1439 --
 .../index/IndexStatisticsJUnitTest.java         |   862 -
 .../IndexTrackingQueryObserverDUnitTest.java    |   329 -
 .../IndexTrackingQueryObserverJUnitTest.java    |   172 -
 .../query/internal/index/IndexUseJUnitTest.java |  1654 --
 .../IndexedMergeEquiJoinScenariosJUnitTest.java |   604 -
 ...itializeIndexEntryDestroyQueryDUnitTest.java |   455 -
 .../internal/index/MapIndexStoreJUnitTest.java  |   339 -
 .../MapRangeIndexMaintenanceJUnitTest.java      |   389 -
 .../index/MemoryIndexStoreJUnitTest.java        |   396 -
 ...exStoreWithInplaceModificationJUnitTest.java |    54 -
 .../index/MultiIndexCreationDUnitTest.java      |   201 -
 .../NewDeclarativeIndexCreationJUnitTest.java   |   173 -
 .../PartitionedRegionEquijoinDUnitTest.java     |   130 -
 .../index/PdxCopyOnReadQueryJUnitTest.java      |    77 -
 ...gRegionCreationIndexUpdateTypeJUnitTest.java |    98 -
 .../index/PutAllWithIndexPerfDUnitTest.java     |   216 -
 .../internal/index/RangeIndexAPIJUnitTest.java  |   422 -
 .../PRBasicIndexCreationDUnitTest.java          |  1050 -
 .../PRBasicIndexCreationDeadlockDUnitTest.java  |   235 -
 .../PRBasicMultiIndexCreationDUnitTest.java     |  1065 -
 .../partitioned/PRBasicQueryDUnitTest.java      |   273 -
 .../PRBasicRemoveIndexDUnitTest.java            |   142 -
 .../PRColocatedEquiJoinDUnitTest.java           |  1722 --
 .../partitioned/PRIndexStatisticsJUnitTest.java |   704 -
 .../partitioned/PRInvalidQueryDUnitTest.java    |   133 -
 .../partitioned/PRInvalidQueryJUnitTest.java    |   127 -
 .../partitioned/PRQueryCacheCloseDUnitTest.java |   341 -
 .../PRQueryCacheClosedJUnitTest.java            |   260 -
 .../query/partitioned/PRQueryDUnitHelper.java   |  3048 ---
 .../query/partitioned/PRQueryDUnitTest.java     |  1228 --
 .../query/partitioned/PRQueryJUnitTest.java     |   188 -
 .../partitioned/PRQueryNumThreadsJUnitTest.java |   165 -
 .../query/partitioned/PRQueryPerfDUnitTest.java |   505 -
 .../PRQueryRegionCloseDUnitTest.java            |   211 -
 .../PRQueryRegionClosedJUnitTest.java           |   257 -
 .../PRQueryRegionDestroyedDUnitTest.java        |   225 -
 .../PRQueryRegionDestroyedJUnitTest.java        |   254 -
 .../PRQueryRemoteNodeExceptionDUnitTest.java    |   786 -
 .../gemfire/cache/query/transaction/Person.java |    57 -
 .../query/transaction/QueryAndJtaJUnitTest.java |   479 -
 .../internal/ConnectionCountProbeJUnitTest.java |    51 -
 .../cache/snapshot/CacheSnapshotJUnitTest.java  |   128 -
 .../snapshot/ParallelSnapshotDUnitTest.java     |   197 -
 .../gemfire/cache/snapshot/RegionGenerator.java |   125 -
 .../cache/snapshot/RegionSnapshotJUnitTest.java |   294 -
 .../snapshot/SnapshotByteArrayDUnitTest.java    |   138 -
 .../cache/snapshot/SnapshotDUnitTest.java       |   224 -
 .../snapshot/SnapshotPerformanceDUnitTest.java  |   167 -
 .../cache/snapshot/SnapshotTestCase.java        |    92 -
 .../cache/snapshot/WanSnapshotJUnitTest.java    |    98 -
 .../cache/util/PasswordUtilJUnitTest.java       |    41 -
 .../gemfire/cache30/Bug34387DUnitTest.java      |   174 -
 .../gemfire/cache30/Bug34948DUnitTest.java      |   148 -
 .../gemfire/cache30/Bug35214DUnitTest.java      |   214 -
 .../gemfire/cache30/Bug38013DUnitTest.java      |   141 -
 .../gemfire/cache30/Bug38741DUnitTest.java      |   414 -
 .../gemfire/cache30/Bug40255JUnitTest.java      |   143 -
 .../gemfire/cache30/Bug40662JUnitTest.java      |    90 -
 .../gemfire/cache30/Bug44418JUnitTest.java      |   173 -
 .../gemfire/cache30/CacheCloseDUnitTest.java    |   104 -
 .../gemfire/cache30/CacheListenerTestCase.java  |   428 -
 .../gemfire/cache30/CacheLoaderTestCase.java    |   330 -
 .../gemfire/cache30/CacheLogRollDUnitTest.java  |   455 -
 .../gemfire/cache30/CacheMapTxnDUnitTest.java   |   534 -
 ...cheRegionsReliablityStatsCheckDUnitTest.java |   136 -
 .../cache30/CacheSerializableRunnable.java      |   114 -
 .../cache30/CacheStatisticsDUnitTest.java       |   515 -
 .../gemstone/gemfire/cache30/CacheTestCase.java |   653 -
 .../gemfire/cache30/CacheWriterTestCase.java    |   507 -
 .../cache30/CacheXMLPartitionResolver.java      |    78 -
 .../gemfire/cache30/CacheXml30DUnitTest.java    |   827 -
 .../gemfire/cache30/CacheXml40DUnitTest.java    |   150 -
 .../gemfire/cache30/CacheXml41DUnitTest.java    |   643 -
 .../gemfire/cache30/CacheXml45DUnitTest.java    |   398 -
 .../gemfire/cache30/CacheXml51DUnitTest.java    |   351 -
 .../gemfire/cache30/CacheXml55DUnitTest.java    |    53 -
 .../gemfire/cache30/CacheXml57DUnitTest.java    |   658 -
 .../gemfire/cache30/CacheXml58DUnitTest.java    |   505 -
 .../gemfire/cache30/CacheXml60DUnitTest.java    |   336 -
 .../gemfire/cache30/CacheXml61DUnitTest.java    |   125 -
 .../gemfire/cache30/CacheXml65DUnitTest.java    |  1159 --
 .../gemfire/cache30/CacheXml66DUnitTest.java    |   376 -
 .../gemfire/cache30/CacheXml70DUnitTest.java    |   289 -
 .../gemfire/cache30/CacheXml80DUnitTest.java    |   297 -
 .../gemfire/cache30/CacheXml81DUnitTest.java    |   158 -
 .../gemfire/cache30/CacheXml90DUnitTest.java    |   234 -
 .../gemfire/cache30/CacheXmlTestCase.java       |   157 -
 .../cache30/CachedAllEventsDUnitTest.java       |   111 -
 .../gemfire/cache30/CallbackArgDUnitTest.java   |   185 -
 .../cache30/CertifiableTestCacheListener.java   |   148 -
 .../cache30/ClearMultiVmCallBkDUnitTest.java    |   249 -
 .../gemfire/cache30/ClearMultiVmDUnitTest.java  |   467 -
 .../cache30/ClientMembershipDUnitTest.java      |  1659 --
 .../ClientMembershipSelectorDUnitTest.java      |    32 -
 .../ClientRegisterInterestDUnitTest.java        |   426 -
 ...ClientRegisterInterestSelectorDUnitTest.java |    32 -
 .../cache30/ClientServerCCEDUnitTest.java       |   633 -
 .../gemfire/cache30/ClientServerTestCase.java   |   391 -
 .../ConcurrentLeaveDuringGIIDUnitTest.java      |   216 -
 ...ibutedNoAckAsyncOverflowRegionDUnitTest.java |    61 -
 ...iskDistributedNoAckAsyncRegionDUnitTest.java |    53 -
 .../DiskDistributedNoAckRegionTestCase.java     |    42 -
 ...ributedNoAckSyncOverflowRegionDUnitTest.java |    63 -
 .../gemfire/cache30/DiskRegionDUnitTest.java    |  1636 --
 .../gemfire/cache30/DiskRegionTestImpl.java     |   247 -
 .../cache30/DistAckMapMethodsDUnitTest.java     |   705 -
 ...istributedAckOverflowRegionCCEDUnitTest.java |    82 -
 ...tedAckOverflowRegionCCEOffHeapDUnitTest.java |    82 -
 ...tributedAckPersistentRegionCCEDUnitTest.java |   228 -
 ...dAckPersistentRegionCCEOffHeapDUnitTest.java |    82 -
 .../DistributedAckRegionCCEDUnitTest.java       |   694 -
 ...DistributedAckRegionCCEOffHeapDUnitTest.java |    82 -
 ...istributedAckRegionCompressionDUnitTest.java |    72 -
 .../cache30/DistributedAckRegionDUnitTest.java  |   140 -
 .../DistributedAckRegionOffHeapDUnitTest.java   |    82 -
 .../DistributedMulticastRegionDUnitTest.java    |   212 -
 .../DistributedNoAckRegionCCEDUnitTest.java     |   586 -
 ...stributedNoAckRegionCCEOffHeapDUnitTest.java |    82 -
 .../DistributedNoAckRegionDUnitTest.java        |   311 -
 .../DistributedNoAckRegionOffHeapDUnitTest.java |    82 -
 .../gemfire/cache30/DynamicRegionDUnitTest.java |   288 -
 .../gemfire/cache30/GlobalLockingDUnitTest.java |   391 -
 .../cache30/GlobalRegionCCEDUnitTest.java       |   245 -
 .../GlobalRegionCCEOffHeapDUnitTest.java        |    82 -
 .../gemfire/cache30/GlobalRegionDUnitTest.java  |   417 -
 .../cache30/GlobalRegionOffHeapDUnitTest.java   |    89 -
 .../cache30/LRUEvictionControllerDUnitTest.java |   488 -
 .../gemfire/cache30/LocalRegionDUnitTest.java   |   264 -
 .../MemLRUEvictionControllerDUnitTest.java      |   276 -
 .../gemfire/cache30/MultiVMRegionTestCase.java  |  9177 ---------
 .../gemfire/cache30/MyGatewayEventFilter1.java  |    61 -
 .../gemfire/cache30/MyGatewayEventFilter2.java  |    66 -
 .../cache30/MyGatewayTransportFilter1.java      |    53 -
 .../cache30/MyGatewayTransportFilter2.java      |    55 -
 .../OffHeapLRUEvictionControllerDUnitTest.java  |    80 -
 .../PRBucketSynchronizationDUnitTest.java       |   306 -
 .../PartitionedRegionCompressionDUnitTest.java  |    70 -
 .../cache30/PartitionedRegionDUnitTest.java     |   554 -
 ...tionedRegionMembershipListenerDUnitTest.java |   150 -
 .../PartitionedRegionOffHeapDUnitTest.java      |    81 -
 .../cache30/PreloadedRegionTestCase.java        |   102 -
 .../gemfire/cache30/ProxyDUnitTest.java         |   546 -
 .../cache30/PutAllCallBkRemoteVMDUnitTest.java  |   401 -
 .../cache30/PutAllCallBkSingleVMDUnitTest.java  |   321 -
 .../gemfire/cache30/PutAllMultiVmDUnitTest.java |   366 -
 .../gemfire/cache30/QueueMsgDUnitTest.java      |   312 -
 .../cache30/RRSynchronizationDUnitTest.java     |   269 -
 .../gemfire/cache30/ReconnectDUnitTest.java     |  1173 --
 .../ReconnectedCacheServerDUnitTest.java        |    95 -
 .../cache30/RegionAttributesTestCase.java       |   266 -
 .../cache30/RegionExpirationDUnitTest.java      |   276 -
 .../RegionMembershipListenerDUnitTest.java      |   420 -
 .../RegionReliabilityDistAckDUnitTest.java      |    39 -
 .../RegionReliabilityDistNoAckDUnitTest.java    |    39 -
 .../RegionReliabilityGlobalDUnitTest.java       |    39 -
 .../RegionReliabilityListenerDUnitTest.java     |   209 -
 .../cache30/RegionReliabilityTestCase.java      |  1463 --
 .../gemfire/cache30/RegionTestCase.java         |  4101 ----
 .../gemfire/cache30/ReliabilityTestCase.java    |    59 -
 .../cache30/RemoveAllMultiVmDUnitTest.java      |   300 -
 .../gemfire/cache30/RequiredRolesDUnitTest.java |   440 -
 .../cache30/RolePerformanceDUnitTest.java       |   188 -
 .../gemfire/cache30/SearchAndLoadDUnitTest.java |  1017 -
 .../gemfire/cache30/SlowRecDUnitTest.java       |  1467 --
 .../gemfire/cache30/TXDistributedDUnitTest.java |  1527 --
 .../gemfire/cache30/TXOrderDUnitTest.java       |   434 -
 .../cache30/TXRestrictionsDUnitTest.java        |   100 -
 .../gemfire/cache30/TestCacheCallback.java      |   102 -
 .../gemfire/cache30/TestCacheListener.java      |   222 -
 .../gemfire/cache30/TestCacheLoader.java        |    45 -
 .../gemfire/cache30/TestCacheWriter.java        |   131 -
 .../gemfire/cache30/TestDiskRegion.java         |   257 -
 .../gemstone/gemfire/cache30/TestHeapLRU.java   |    90 -
 .../gemfire/cache30/TestPdxSerializer.java      |    69 -
 .../cache30/TestTransactionListener.java        |    93 -
 .../gemfire/cache30/TestTransactionWriter.java  |    44 -
 .../AnalyzeSerializablesJUnitTest.java          |   325 -
 .../codeAnalysis/ClassAndMethodDetails.java     |   154 -
 .../gemfire/codeAnalysis/ClassAndMethods.java   |    50 -
 .../codeAnalysis/ClassAndVariableDetails.java   |   108 -
 .../gemfire/codeAnalysis/ClassAndVariables.java |    64 -
 .../codeAnalysis/CompiledClassUtils.java        |   433 -
 .../codeAnalysis/decode/CompiledAttribute.java  |    46 -
 .../codeAnalysis/decode/CompiledClass.java      |   276 -
 .../codeAnalysis/decode/CompiledCode.java       |    70 -
 .../codeAnalysis/decode/CompiledField.java      |   116 -
 .../codeAnalysis/decode/CompiledMethod.java     |   153 -
 .../gemfire/codeAnalysis/decode/cp/Cp.java      |    78 -
 .../gemfire/codeAnalysis/decode/cp/CpClass.java |    42 -
 .../codeAnalysis/decode/cp/CpDouble.java        |    40 -
 .../codeAnalysis/decode/cp/CpFieldref.java      |    33 -
 .../gemfire/codeAnalysis/decode/cp/CpFloat.java |    31 -
 .../codeAnalysis/decode/cp/CpInteger.java       |    31 -
 .../decode/cp/CpInterfaceMethodref.java         |    24 -
 .../codeAnalysis/decode/cp/CpInvokeDynamic.java |    33 -
 .../gemfire/codeAnalysis/decode/cp/CpLong.java  |    39 -
 .../codeAnalysis/decode/cp/CpMethodHandle.java  |    33 -
 .../codeAnalysis/decode/cp/CpMethodType.java    |    31 -
 .../codeAnalysis/decode/cp/CpMethodref.java     |    25 -
 .../codeAnalysis/decode/cp/CpNameAndType.java   |    27 -
 .../codeAnalysis/decode/cp/CpString.java        |    25 -
 .../gemfire/codeAnalysis/decode/cp/CpUtf8.java  |   133 -
 .../AbstractLauncherIntegrationJUnitTest.java   |    71 -
 .../distributed/AbstractLauncherJUnitTest.java  |   300 -
 .../AbstractLauncherJUnitTestCase.java          |   255 -
 .../AbstractLauncherServiceStatusJUnitTest.java |   265 -
 .../AbstractLocatorLauncherJUnitTestCase.java   |   106 -
 .../AbstractServerLauncherJUnitTestCase.java    |    94 -
 .../gemfire/distributed/AuthInitializer.java    |    45 -
 .../distributed/DistributedMemberDUnitTest.java |   432 -
 .../DistributedSystemConnectPerf.java           |   135 -
 .../distributed/DistributedSystemDUnitTest.java |   406 -
 .../DistributedSystemIntegrationJUnitTest.java  |    91 -
 .../distributed/DistributedSystemJUnitTest.java |    78 -
 .../distributed/DistributedTestSuite.java       |    36 -
 .../distributed/HostedLocatorsDUnitTest.java    |   195 -
 .../LauncherMemberMXBeanJUnitTest.java          |   153 -
 .../gemfire/distributed/LauncherTestSuite.java  |    48 -
 .../gemfire/distributed/LocatorDUnitTest.java   |  1922 --
 .../gemfire/distributed/LocatorJUnitTest.java   |   200 -
 .../LocatorLauncherIntegrationJUnitTest.java    |   248 -
 .../distributed/LocatorLauncherJUnitTest.java   |   343 -
 .../LocatorLauncherLocalFileJUnitTest.java      |    52 -
 .../LocatorLauncherLocalJUnitTest.java          |   843 -
 .../LocatorLauncherRemoteFileJUnitTest.java     |   219 -
 .../LocatorLauncherRemoteJUnitTest.java         |  1005 -
 .../distributed/LocatorStateJUnitTest.java      |   208 -
 .../gemfire/distributed/MyAuthenticator.java    |    54 -
 .../gemfire/distributed/MyPrincipal.java        |    29 -
 .../gemfire/distributed/RoleDUnitTest.java      |   170 -
 .../ServerLauncherIntegrationJUnitTest.java     |   312 -
 .../distributed/ServerLauncherJUnitTest.java    |   831 -
 .../ServerLauncherLocalFileJUnitTest.java       |    55 -
 .../ServerLauncherLocalJUnitTest.java           |  1076 --
 .../ServerLauncherRemoteFileJUnitTest.java      |   223 -
 .../ServerLauncherRemoteJUnitTest.java          |  1428 --
 .../ServerLauncherWithSpringJUnitTest.java      |    99 -
 .../distributed/SystemAdminDUnitTest.java       |   125 -
 .../AtomicLongWithTerminalStateJUnitTest.java   |    41 -
 .../distributed/internal/Bug40751DUnitTest.java |   138 -
 .../ConsoleDistributionManagerDUnitTest.java    |   441 -
 .../distributed/internal/DateMessage.java       |    98 -
 .../internal/DistributionAdvisorDUnitTest.java  |    98 -
 .../internal/DistributionConfigJUnitTest.java   |   313 -
 .../internal/DistributionManagerDUnitTest.java  |   579 -
 .../InternalDistributedSystemJUnitTest.java     |   831 -
 .../gemfire/distributed/internal/LDM.java       |    71 -
 .../internal/LocatorLoadSnapshotJUnitTest.java  |   384 -
 .../internal/ProduceDateMessages.java           |    53 -
 .../internal/ProductUseLogDUnitTest.java        |   108 -
 .../internal/ProductUseLogJUnitTest.java        |    86 -
 .../internal/ServerLocatorJUnitTest.java        |    74 -
 .../internal/SharedConfigurationJUnitTest.java  |    57 -
 .../internal/StartupMessageDataJUnitTest.java   |   296 -
 .../deadlock/DeadlockDetectorJUnitTest.java     |   333 -
 .../deadlock/DependencyGraphJUnitTest.java      |    87 -
 .../GemFireDeadlockDetectorDUnitTest.java       |   243 -
 .../deadlock/UnsafeThreadLocalJUnitTest.java    |    61 -
 .../internal/locks/CollaborationJUnitTest.java  |   617 -
 .../internal/locks/DLockGrantorHelper.java      |    98 -
 .../locks/DLockReentrantLockJUnitTest.java      |    84 -
 .../membership/MembershipJUnitTest.java         |   364 -
 .../internal/membership/NetViewJUnitTest.java   |   269 -
 .../membership/gms/GMSMemberJUnitTest.java      |   164 -
 .../membership/gms/MembershipManagerHelper.java |   171 -
 .../gms/auth/GMSAuthenticatorJUnitTest.java     |   316 -
 .../gms/fd/GMSHealthMonitorJUnitTest.java       |   638 -
 .../locator/GMSLocatorRecoveryJUnitTest.java    |   186 -
 .../gms/membership/GMSJoinLeaveJUnitTest.java   |  1231 --
 .../gms/membership/StatRecorderJUnitTest.java   |   227 -
 .../messenger/GMSQuorumCheckerJUnitTest.java    |   359 -
 .../membership/gms/messenger/InterceptUDP.java  |   109 -
 .../messenger/JGroupsMessengerJUnitTest.java    |   895 -
 .../gms/mgr/GMSMembershipManagerJUnitTest.java  |   436 -
 .../StreamingOperationManyDUnitTest.java        |   223 -
 .../StreamingOperationOneDUnitTest.java         |   182 -
 .../TcpServerBackwardCompatDUnitTest.java       |   257 -
 .../internal/tcpserver/TcpServerJUnitTest.java  |   221 -
 .../support/DistributedSystemAdapter.java       |   258 -
 .../gemfire/disttx/CacheMapDistTXDUnitTest.java |    65 -
 .../gemfire/disttx/DistTXDebugDUnitTest.java    |  1014 -
 .../disttx/DistTXDistributedTestSuite.java      |    42 -
 .../gemfire/disttx/DistTXExpiryJUnitTest.java   |    57 -
 .../gemfire/disttx/DistTXJUnitTest.java         |    96 -
 .../disttx/DistTXManagerImplJUnitTest.java      |    54 -
 .../gemfire/disttx/DistTXOrderDUnitTest.java    |    55 -
 .../disttx/DistTXPersistentDebugDUnitTest.java  |   132 -
 .../DistTXReleasesOffHeapOnCloseJUnitTest.java  |    53 -
 .../disttx/DistTXRestrictionsDUnitTest.java     |    46 -
 .../disttx/DistTXWithDeltaDUnitTest.java        |    38 -
 .../gemfire/disttx/DistTXWriterJUnitTest.java   |    56 -
 .../disttx/DistTXWriterOOMEJUnitTest.java       |    57 -
 .../disttx/DistributedTransactionDUnitTest.java |  2203 ---
 .../gemfire/disttx/PRDistTXDUnitTest.java       |    65 -
 .../gemfire/disttx/PRDistTXJUnitTest.java       |    92 -
 .../disttx/PRDistTXWithVersionsDUnitTest.java   |    66 -
 ...entPartitionedRegionWithDistTXDUnitTest.java |    46 -
 .../internal/AbstractConfigJUnitTest.java       |   114 -
 .../gemfire/internal/ArrayEqualsJUnitTest.java  |   193 -
 .../gemfire/internal/AvailablePortHelper.java   |   133 -
 .../internal/AvailablePortJUnitTest.java        |    75 -
 ...wardCompatibilitySerializationDUnitTest.java |   300 -
 .../gemfire/internal/Bug49856JUnitTest.java     |    85 -
 .../gemfire/internal/Bug51616JUnitTest.java     |    61 -
 .../gemfire/internal/ByteArrayData.java         |    73 -
 .../gemstone/gemfire/internal/ClassBuilder.java |   291 -
 .../ClassNotFoundExceptionDUnitTest.java        |   244 -
 .../internal/ClassPathLoaderJUnitTest.java      |  1262 --
 .../gemfire/internal/ConfigSourceJUnitTest.java |    89 -
 .../internal/CopyOnWriteHashSetJUnitTest.java   |   103 -
 .../internal/DataSerializableJUnitTest.java     |  3671 ----
 .../gemfire/internal/FileUtilJUnitTest.java     |    87 -
 .../internal/GemFireStatSamplerJUnitTest.java   |   618 -
 .../GemFireVersionIntegrationJUnitTest.java     |    54 -
 .../internal/GemFireVersionJUnitTest.java       |   102 -
 .../internal/HeapDataOutputStreamJUnitTest.java |   154 -
 .../gemfire/internal/InlineKeyJUnitTest.java    |   173 -
 .../gemfire/internal/JSSESocketJUnitTest.java   |   247 -
 .../internal/JarClassLoaderJUnitTest.java       |   828 -
 .../gemfire/internal/JarDeployerDUnitTest.java  |   747 -
 .../com/gemstone/gemfire/internal/JavaExec.java |    69 -
 .../gemfire/internal/LineWrapUnitJUnitTest.java |    52 -
 .../gemstone/gemfire/internal/LongBuffer.java   |    96 -
 .../gemfire/internal/NanoTimerJUnitTest.java    |   134 -
 .../gemfire/internal/ObjIdMapJUnitTest.java     |   256 -
 .../internal/OneTaskOnlyDecoratorJUnitTest.java |   165 -
 .../internal/PdxDeleteFieldDUnitTest.java       |   213 -
 .../internal/PdxDeleteFieldJUnitTest.java       |   214 -
 .../gemfire/internal/PdxRenameDUnitTest.java    |   217 -
 .../gemfire/internal/PdxRenameJUnitTest.java    |   164 -
 .../PutAllOperationContextJUnitTest.java        |   197 -
 .../internal/SSLConfigIntegrationJUnitTest.java |    51 -
 .../gemfire/internal/SSLConfigJUnitTest.java    |  1233 --
 ...hreadPoolExecutorWithKeepAliveJUnitTest.java |   342 -
 .../internal/SimpleStatSamplerJUnitTest.java    |   358 -
 .../gemfire/internal/SocketCloserJUnitTest.java |   195 -
 .../internal/SocketCloserWithWaitJUnitTest.java |    38 -
 .../StatArchiveWriterReaderJUnitTest.java       |  1735 --
 .../gemfire/internal/StatSamplerJUnitTest.java  |   361 -
 .../gemfire/internal/StatSamplerTestCase.java   |   185 -
 .../internal/UniqueIdGeneratorJUnitTest.java    |    68 -
 .../internal/cache/AbstractRegionJUnitTest.java |   513 -
 .../internal/cache/AbstractRegionMapTest.java   |   186 -
 .../gemfire/internal/cache/BackupDUnitTest.java |   800 -
 .../gemfire/internal/cache/BackupJUnitTest.java |   435 -
 .../internal/cache/BucketRegionJUnitTest.java   |   208 -
 .../internal/cache/Bug33359DUnitTest.java       |   160 -
 .../internal/cache/Bug33726DUnitTest.java       |   161 -
 .../internal/cache/Bug33726JUnitTest.java       |   134 -
 .../Bug34179TooManyFilesOpenJUnitTest.java      |   130 -
 .../internal/cache/Bug34583JUnitTest.java       |   101 -
 .../internal/cache/Bug37241DUnitTest.java       |   231 -
 .../internal/cache/Bug37244JUnitTest.java       |   279 -
 .../internal/cache/Bug37377DUnitTest.java       |   380 -
 .../internal/cache/Bug37500JUnitTest.java       |   184 -
 .../internal/cache/Bug39079DUnitTest.java       |   410 -
 .../internal/cache/Bug40299DUnitTest.java       |   304 -
 .../internal/cache/Bug40632DUnitTest.java       |   148 -
 .../internal/cache/Bug41091DUnitTest.java       |   174 -
 .../internal/cache/Bug41733DUnitTest.java       |   216 -
 .../internal/cache/Bug41957DUnitTest.java       |   161 -
 .../internal/cache/Bug42055DUnitTest.java       |    88 -
 .../internal/cache/Bug45164DUnitTest.java       |   104 -
 .../internal/cache/Bug45934DUnitTest.java       |   134 -
 .../internal/cache/Bug47667DUnitTest.java       |    87 -
 .../internal/cache/Bug48182JUnitTest.java       |   200 -
 .../internal/cache/CacheAdvisorDUnitTest.java   |   281 -
 .../cache/CacheLifecycleListenerJUnitTest.java  |   324 -
 .../internal/cache/CacheServiceJUnitTest.java   |    59 -
 .../cache/ChunkValueWrapperJUnitTest.java       |   188 -
 .../internal/cache/ClearDAckDUnitTest.java      |   286 -
 .../internal/cache/ClearGlobalDUnitTest.java    |   214 -
 ...ssagesRegionCreationAndDestroyJUnitTest.java |   173 -
 .../cache/ClientServerGetAllDUnitTest.java      |   817 -
 ...ServerInvalidAndDestroyedEntryDUnitTest.java |   514 -
 .../ClientServerTransactionCCEDUnitTest.java    |   108 -
 .../cache/ClientServerTransactionDUnitTest.java |  3389 ----
 .../cache/ComplexDiskRegionJUnitTest.java       |   169 -
 .../ConcurrentDestroySubRegionDUnitTest.java    |   173 -
 ...entFlushingAndRegionOperationsJUnitTest.java |   641 -
 .../cache/ConcurrentMapLocalJUnitTest.java      |   105 -
 .../cache/ConcurrentMapOpsDUnitTest.java        |  1238 --
 .../ConcurrentRegionOperationsJUnitTest.java    |   925 -
 ...rentRollingAndRegionOperationsJUnitTest.java |   996 -
 .../internal/cache/ConflationJUnitTest.java     |   409 -
 .../cache/ConnectDisconnectDUnitTest.java       |   185 -
 .../cache/CustomerIDPartitionResolver.java      |    86 -
 .../internal/cache/DeltaFaultInDUnitTest.java   |   145 -
 .../cache/DeltaPropagationDUnitTest.java        |  1463 --
 .../cache/DeltaPropagationStatsDUnitTest.java   |   608 -
 .../internal/cache/DeltaSizingDUnitTest.java    |   265 -
 .../gemfire/internal/cache/DiskIFJUnitTest.java |   796 -
 .../gemfire/internal/cache/DiskIdJUnitTest.java |   238 -
 .../internal/cache/DiskInitFileJUnitTest.java   |   113 -
 .../cache/DiskOfflineCompactionJUnitTest.java   |   826 -
 .../internal/cache/DiskOldAPIsJUnitTest.java    |   437 -
 ...iskRandomOperationsAndRecoveryJUnitTest.java |   715 -
 .../cache/DiskRegByteArrayDUnitTest.java        |   270 -
 .../cache/DiskRegCacheXmlJUnitTest.java         |   299 -
 .../DiskRegCachexmlGeneratorJUnitTest.java      |   302 -
 .../internal/cache/DiskRegCbkChkJUnitTest.java  |   118 -
 .../DiskRegOplogSwtchingAndRollerJUnitTest.java |  1021 -
 .../cache/DiskRegRecoveryJUnitTest.java         |  1495 --
 .../cache/DiskRegionAsyncRecoveryJUnitTest.java |   538 -
 ...RegionChangingRegionAttributesJUnitTest.java |   143 -
 .../cache/DiskRegionClearJUnitTest.java         |   288 -
 .../internal/cache/DiskRegionHelperFactory.java |   263 -
 .../DiskRegionIllegalArguementsJUnitTest.java   |   281 -
 ...iskRegionIllegalCacheXMLvaluesJUnitTest.java |   146 -
 .../internal/cache/DiskRegionJUnitTest.java     |  3141 ---
 .../internal/cache/DiskRegionProperties.java    |   222 -
 .../internal/cache/DiskRegionTestingBase.java   |   404 -
 .../cache/DiskStoreFactoryJUnitTest.java        |   450 -
 .../cache/DiskWriteAttributesJUnitTest.java     |   223 -
 ...DistrbutedRegionProfileOffHeapDUnitTest.java |   252 -
 .../cache/DistributedCacheTestCase.java         |   472 -
 .../cache/EnumListenerEventJUnitTest.java       |    73 -
 .../internal/cache/EventTrackerDUnitTest.java   |   418 -
 .../internal/cache/EvictionDUnitTest.java       |   247 -
 .../cache/EvictionObjectSizerDUnitTest.java     |   358 -
 .../internal/cache/EvictionStatsDUnitTest.java  |   553 -
 .../internal/cache/EvictionTestBase.java        |   577 -
 .../internal/cache/FaultingInJUnitTest.java     |   236 -
 .../cache/FixedPRSinglehopDUnitTest.java        |   876 -
 .../internal/cache/GIIDeltaDUnitTest.java       |  2632 ---
 .../internal/cache/GIIFlowControlDUnitTest.java |   455 -
 .../internal/cache/GridAdvisorDUnitTest.java    |  1081 --
 .../HAOverflowMemObjectSizerDUnitTest.java      |   288 -
 .../cache/IncrementalBackupDUnitTest.java       |  1104 --
 .../cache/InterruptClientServerDUnitTest.java   |   252 -
 .../internal/cache/InterruptDiskJUnitTest.java  |   135 -
 ...InterruptsConserveSocketsFalseDUnitTest.java |    37 -
 .../internal/cache/InterruptsDUnitTest.java     |   213 -
 .../internal/cache/IteratorDUnitTest.java       |   104 -
 .../LIFOEvictionAlgoEnabledRegionJUnitTest.java |   343 -
 ...victionAlgoMemoryEnabledRegionJUnitTest.java |   436 -
 .../internal/cache/MapClearGIIDUnitTest.java    |   285 -
 .../internal/cache/MapInterface2JUnitTest.java  |   281 -
 .../internal/cache/MapInterfaceJUnitTest.java   |   301 -
 .../internal/cache/MockCacheService.java        |    24 -
 .../internal/cache/MockCacheServiceImpl.java    |    39 -
 .../MultipleOplogsRollingFeatureJUnitTest.java  |   257 -
 .../cache/NetSearchMessagingDUnitTest.java      |   442 -
 .../cache/OffHeapEvictionDUnitTest.java         |   135 -
 .../cache/OffHeapEvictionStatsDUnitTest.java    |    88 -
 .../gemfire/internal/cache/OffHeapTestUtil.java |    64 -
 .../cache/OfflineSnapshotJUnitTest.java         |   137 -
 .../gemfire/internal/cache/OldVLJUnitTest.java  |    92 -
 .../cache/OldValueImporterTestBase.java         |   181 -
 .../cache/OplogEntryIdMapJUnitTest.java         |    99 -
 .../cache/OplogEntryIdSetJUnitTest.java         |    83 -
 .../gemfire/internal/cache/OplogJUnitTest.java  |  4034 ----
 .../internal/cache/OplogRVVJUnitTest.java       |   173 -
 .../cache/OrderedTombstoneMapJUnitTest.java     |    59 -
 .../cache/P2PDeltaPropagationDUnitTest.java     |   599 -
 .../internal/cache/PRBadToDataDUnitTest.java    |   109 -
 .../cache/PRConcurrentMapOpsJUnitTest.java      |   231 -
 .../cache/PRDataStoreMemoryJUnitTest.java       |   154 -
 .../PRDataStoreMemoryOffHeapJUnitTest.java      |    51 -
 .../gemfire/internal/cache/PRTXJUnitTest.java   |   150 -
 .../cache/PartitionAttributesImplJUnitTest.java |   543 -
 .../cache/PartitionListenerDUnitTest.java       |   203 -
 ...dRegionAPIConserveSocketsFalseDUnitTest.java |    45 -
 .../cache/PartitionedRegionAPIDUnitTest.java    |  1512 --
 .../PartitionedRegionAsSubRegionDUnitTest.java  |   337 -
 ...gionBucketCreationDistributionDUnitTest.java |  1543 --
 .../PartitionedRegionCacheCloseDUnitTest.java   |   297 -
 ...rtitionedRegionCacheLoaderForRootRegion.java |    62 -
 ...artitionedRegionCacheLoaderForSubRegion.java |    65 -
 ...rtitionedRegionCacheXMLExampleDUnitTest.java |   134 -
 .../PartitionedRegionCreationDUnitTest.java     |   914 -
 .../PartitionedRegionCreationJUnitTest.java     |   548 -
 .../cache/PartitionedRegionDUnitTestCase.java   |   531 -
 .../PartitionedRegionDataStoreJUnitTest.java    |   260 -
 ...rtitionedRegionDelayedRecoveryDUnitTest.java |   310 -
 .../PartitionedRegionDestroyDUnitTest.java      |   309 -
 .../PartitionedRegionEntryCountDUnitTest.java   |   149 -
 .../PartitionedRegionEvictionDUnitTest.java     |  1762 --
 .../cache/PartitionedRegionHADUnitTest.java     |   506 -
 ...onedRegionHAFailureAndRecoveryDUnitTest.java |   535 -
 .../cache/PartitionedRegionHelperJUnitTest.java |    48 -
 .../PartitionedRegionInvalidateDUnitTest.java   |   212 -
 ...artitionedRegionLocalMaxMemoryDUnitTest.java |   318 -
 ...nedRegionLocalMaxMemoryOffHeapDUnitTest.java |    73 -
 .../PartitionedRegionMultipleDUnitTest.java     |   600 -
 ...rtitionedRegionOffHeapEvictionDUnitTest.java |    94 -
 .../cache/PartitionedRegionPRIDDUnitTest.java   |   270 -
 .../cache/PartitionedRegionQueryDUnitTest.java  |  1160 --
 ...artitionedRegionQueryEvaluatorJUnitTest.java |   307 -
 ...artitionedRegionRedundancyZoneDUnitTest.java |   165 -
 ...tionedRegionSerializableObjectJUnitTest.java |   178 -
 .../PartitionedRegionSingleHopDUnitTest.java    |  2258 ---
 ...RegionSingleHopWithServerGroupDUnitTest.java |  1665 --
 ...onedRegionSingleNodeOperationsJUnitTest.java |  1542 --
 .../cache/PartitionedRegionSizeDUnitTest.java   |   609 -
 .../cache/PartitionedRegionStatsDUnitTest.java  |   649 -
 .../cache/PartitionedRegionStatsJUnitTest.java  |   534 -
 .../cache/PartitionedRegionTestHelper.java      |   337 -
 .../PartitionedRegionTestUtilsDUnitTest.java    |   576 -
 .../PartitionedRegionWithSameNameDUnitTest.java |   924 -
 .../PersistentPartitionedRegionJUnitTest.java   |   225 -
 .../internal/cache/PutAllDAckDUnitTest.java     |   228 -
 .../internal/cache/PutAllGlobalDUnitTest.java   |   296 -
 .../cache/RegionEntryFlagsJUnitTest.java        |    97 -
 .../internal/cache/RegionListenerJUnitTest.java |    63 -
 .../cache/RemotePutReplyMessageJUnitTest.java   |    53 -
 .../cache/RemoteTransactionCCEDUnitTest.java    |    35 -
 .../cache/RemoteTransactionDUnitTest.java       |  4322 -----
 .../internal/cache/RemoveAllDAckDUnitTest.java  |   173 -
 .../internal/cache/RemoveDAckDUnitTest.java     |   201 -
 .../internal/cache/RemoveGlobalDUnitTest.java   |   250 -
 .../internal/cache/RunCacheInOldGemfire.java    |   188 -
 .../cache/SimpleDiskRegionJUnitTest.java        |   390 -
 .../internal/cache/SingleHopStatsDUnitTest.java |   523 -
 .../internal/cache/SizingFlagDUnitTest.java     |  1039 -
 .../internal/cache/SnapshotTestUtil.java        |    47 -
 .../internal/cache/SystemFailureDUnitTest.java  |   877 -
 .../internal/cache/TXManagerImplJUnitTest.java  |   334 -
 .../cache/TXReservationMgrJUnitTest.java        |   150 -
 .../gemfire/internal/cache/TestDelta.java       |    96 -
 .../internal/cache/TestHelperForHydraTests.java |    32 -
 .../internal/cache/TestNonSizerObject.java      |    63 -
 .../internal/cache/TestObjectSizerImpl.java     |    72 -
 .../gemfire/internal/cache/TestUtils.java       |    32 -
 .../cache/TombstoneCreationJUnitTest.java       |   231 -
 .../cache/TransactionsWithDeltaDUnitTest.java   |   376 -
 .../internal/cache/UnitTestValueHolder.java     |    43 -
 .../gemfire/internal/cache/UnzipUtil.java       |    84 -
 .../internal/cache/UpdateVersionJUnitTest.java  |   407 -
 .../gemfire/internal/cache/VLJUnitTest.java     |   130 -
 .../cache/control/FilterByPathJUnitTest.java    |    96 -
 .../cache/control/MemoryMonitorJUnitTest.java   |   762 -
 .../control/MemoryMonitorOffHeapJUnitTest.java  |   338 -
 .../control/MemoryThresholdsJUnitTest.java      |   152 -
 .../control/RebalanceOperationDUnitTest.java    |  3267 ----
 .../control/TestMemoryThresholdListener.java    |   169 -
 ...skRegOverflowAsyncGetInMemPerfJUnitTest.java |   136 -
 ...iskRegOverflowAsyncJUnitPerformanceTest.java |   167 -
 ...lowSyncGetInMemPerfJUnitPerformanceTest.java |   129 -
 ...DiskRegOverflowSyncJUnitPerformanceTest.java |   169 -
 ...egionOverflowAsyncRollingOpLogJUnitTest.java |   225 -
 ...RegionOverflowSyncRollingOpLogJUnitTest.java |   223 -
 .../DiskRegionPerfJUnitPerformanceTest.java     |   570 -
 .../DiskRegionPersistOnlySyncJUnitTest.java     |   234 -
 ...DiskRegionRollOpLogJUnitPerformanceTest.java |   638 -
 ...ltiThreadedOplogPerJUnitPerformanceTest.java |   216 -
 .../cache/execute/Bug51193DUnitTest.java        |   245 -
 .../ClientServerFunctionExecutionDUnitTest.java |   892 -
 .../execute/ColocationFailoverDUnitTest.java    |   528 -
 .../cache/execute/CustomResultCollector.java    |    50 -
 .../execute/CustomerIDPartitionResolver.java    |    82 -
 ...ributedRegionFunctionExecutionDUnitTest.java |  1356 --
 .../FunctionExecution_ExceptionDUnitTest.java   |   646 -
 .../execute/FunctionServiceStatsDUnitTest.java  |  1364 --
 .../cache/execute/LocalDataSetDUnitTest.java    |   390 -
 .../cache/execute/LocalDataSetFunction.java     |    90 -
 .../execute/LocalDataSetIndexingDUnitTest.java  |   303 -
 .../LocalFunctionExecutionDUnitTest.java        |   185 -
 .../MemberFunctionExecutionDUnitTest.java       |   673 -
 .../MultiRegionFunctionExecutionDUnitTest.java  |   298 -
 .../execute/MyFunctionExecutionException.java   |    59 -
 .../cache/execute/MyTransactionFunction.java    |   517 -
 .../OnGroupsFunctionExecutionDUnitTest.java     |  1246 --
 ...ntServerFunctionExecutionNoAckDUnitTest.java |   250 -
 ...tServerRegionFunctionExecutionDUnitTest.java |  1638 --
 ...egionFunctionExecutionFailoverDUnitTest.java |   499 -
 ...onFunctionExecutionNoSingleHopDUnitTest.java |  1189 --
 ...onExecutionSelectorNoSingleHopDUnitTest.java |  1153 --
 ...gionFunctionExecutionSingleHopDUnitTest.java |  1177 --
 .../cache/execute/PRClientServerTestBase.java   |   819 -
 .../cache/execute/PRColocationDUnitTest.java    |  2652 ---
 .../execute/PRCustomPartitioningDUnitTest.java  |   575 -
 .../execute/PRFunctionExecutionDUnitTest.java   |  3213 ---
 .../PRFunctionExecutionTimeOutDUnitTest.java    |   885 -
 ...ctionExecutionWithResultSenderDUnitTest.java |   663 -
 .../execute/PRPerformanceTestDUnitTest.java     |   425 -
 .../cache/execute/PRTransactionDUnitTest.java   |   749 -
 .../PRTransactionWithVersionsDUnitTest.java     |    29 -
 .../internal/cache/execute/PerfFunction.java    |    69 -
 .../internal/cache/execute/PerfTxFunction.java  |    74 -
 .../cache/execute/PerformanceTestFunction.java  |    74 -
 .../execute/SingleHopGetAllPutAllDUnitTest.java |   198 -
 .../internal/cache/execute/TestFunction.java    |   150 -
 .../internal/cache/execute/data/CustId.java     |    72 -
 .../internal/cache/execute/data/Customer.java   |    77 -
 .../internal/cache/execute/data/Order.java      |    65 -
 .../internal/cache/execute/data/OrderId.java    |    82 -
 .../internal/cache/execute/data/Shipment.java   |    65 -
 .../internal/cache/execute/data/ShipmentId.java |    89 -
 .../SimpleExtensionPointJUnitTest.java          |   215 -
 .../extension/mock/AbstractMockExtension.java   |    61 -
 .../mock/AbstractMockExtensionXmlGenerator.java |    41 -
 .../mock/AlterMockCacheExtensionFunction.java   |    90 -
 .../mock/AlterMockRegionExtensionFunction.java  |   104 -
 .../mock/CreateMockCacheExtensionFunction.java  |    86 -
 .../mock/CreateMockRegionExtensionFunction.java |   101 -
 .../mock/DestroyMockCacheExtensionFunction.java |    89 -
 .../DestroyMockRegionExtensionFunction.java     |    99 -
 .../extension/mock/MockCacheExtension.java      |    53 -
 .../mock/MockCacheExtensionXmlGenerator.java    |    57 -
 .../extension/mock/MockExtensionCommands.java   |   219 -
 .../extension/mock/MockExtensionXmlParser.java  |   102 -
 .../extension/mock/MockRegionExtension.java     |    47 -
 .../mock/MockRegionExtensionXmlGenerator.java   |    57 -
 ...gionFunctionFunctionInvocationException.java |    60 -
 .../functions/DistributedRegionFunction.java    |    97 -
 .../cache/functions/LocalDataSetFunction.java   |    89 -
 .../internal/cache/functions/TestFunction.java  |  1148 --
 .../ha/BlockingHARQAddOperationJUnitTest.java   |   239 -
 .../cache/ha/BlockingHARQStatsJUnitTest.java    |    77 -
 .../cache/ha/BlockingHARegionJUnitTest.java     |   480 -
 .../ha/BlockingHARegionQueueJUnitTest.java      |   213 -
 .../cache/ha/Bug36853EventsExpiryDUnitTest.java |   304 -
 .../internal/cache/ha/Bug48571DUnitTest.java    |   262 -
 .../internal/cache/ha/Bug48879DUnitTest.java    |   219 -
 .../internal/cache/ha/ConflatableObject.java    |   221 -
 .../cache/ha/EventIdOptimizationDUnitTest.java  |   583 -
 .../cache/ha/EventIdOptimizationJUnitTest.java  |   253 -
 .../internal/cache/ha/FailoverDUnitTest.java    |   345 -
 .../internal/cache/ha/HABugInPutDUnitTest.java  |   181 -
 .../internal/cache/ha/HAClearDUnitTest.java     |   657 -
 .../cache/ha/HAConflationDUnitTest.java         |   443 -
 .../internal/cache/ha/HADuplicateDUnitTest.java |   327 -
 .../cache/ha/HAEventIdPropagationDUnitTest.java |   851 -
 .../internal/cache/ha/HAExpiryDUnitTest.java    |   285 -
 .../internal/cache/ha/HAGIIBugDUnitTest.java    |   418 -
 .../internal/cache/ha/HAGIIDUnitTest.java       |   470 -
 .../gemfire/internal/cache/ha/HAHelper.java     |    51 -
 .../cache/ha/HARQAddOperationJUnitTest.java     |  1203 --
 .../cache/ha/HARQueueNewImplDUnitTest.java      |  1276 --
 .../internal/cache/ha/HARegionDUnitTest.java    |   406 -
 .../internal/cache/ha/HARegionJUnitTest.java    |   222 -
 .../cache/ha/HARegionQueueDUnitTest.java        |  1149 --
 .../cache/ha/HARegionQueueJUnitTest.java        |  2153 ---
 .../ha/HARegionQueueStartStopJUnitTest.java     |   133 -
 .../cache/ha/HARegionQueueStatsJUnitTest.java   |   504 -
 .../cache/ha/HASlowReceiverDUnitTest.java       |   290 -
 .../ha/OperationsPropagationDUnitTest.java      |   498 -
 .../internal/cache/ha/PutAllDUnitTest.java      |   585 -
 .../internal/cache/ha/StatsBugDUnitTest.java    |   371 -
 .../cache/ha/TestBlockingHARegionQueue.java     |   129 -
 .../cache/ha/ThreadIdentifierJUnitTest.java     |   116 -
 .../cache/locks/TXLockServiceDUnitTest.java     |   726 -
 .../internal/cache/lru/LRUClockJUnitTest.java   |   519 -
 .../cache/partitioned/Bug39356DUnitTest.java    |   236 -
 .../cache/partitioned/Bug43684DUnitTest.java    |   343 -
 .../cache/partitioned/Bug47388DUnitTest.java    |   287 -
 .../cache/partitioned/Bug51400DUnitTest.java    |   207 -
 .../partitioned/ElidedPutAllDUnitTest.java      |   123 -
 .../OfflineMembersDetailsJUnitTest.java         |    59 -
 .../partitioned/PartitionResolverDUnitTest.java |   411 -
 .../PartitionedRegionLoadModelJUnitTest.java    |  1560 --
 .../PartitionedRegionLoaderWriterDUnitTest.java |   210 -
 ...rtitionedRegionMetaDataCleanupDUnitTest.java |   193 -
 .../partitioned/PersistPRKRFDUnitTest.java      |   234 -
 ...tentColocatedPartitionedRegionDUnitTest.java |  1597 --
 .../PersistentPartitionedRegionDUnitTest.java   |  2227 ---
 ...tentPartitionedRegionOldConfigDUnitTest.java |    51 -
 .../PersistentPartitionedRegionTestBase.java    |   807 -
 ...rtitionedRegionWithTransactionDUnitTest.java |   185 -
 .../PutPutReplyMessageJUnitTest.java            |    54 -
 .../cache/partitioned/ShutdownAllDUnitTest.java |   847 -
 ...treamingPartitionOperationManyDUnitTest.java |   250 -
 ...StreamingPartitionOperationOneDUnitTest.java |   233 -
 .../fixed/CustomerFixedPartitionResolver.java   |   113 -
 .../fixed/FixedPartitioningDUnitTest.java       |  1482 --
 .../fixed/FixedPartitioningTestBase.java        |  1407 --
 ...ngWithColocationAndPersistenceDUnitTest.java |  1170 --
 .../cache/partitioned/fixed/MyDate1.java        |    72 -
 .../cache/partitioned/fixed/MyDate2.java        |    52 -
 .../cache/partitioned/fixed/MyDate3.java        |    72 -
 .../fixed/QuarterPartitionResolver.java         |   142 -
 .../SingleHopQuarterPartitionResolver.java      |   173 -
 .../persistence/BackupInspectorJUnitTest.java   |   236 -
 .../PersistentRVVRecoveryDUnitTest.java         |  1006 -
 .../PersistentRecoveryOrderDUnitTest.java       |  1843 --
 ...rsistentRecoveryOrderOldConfigDUnitTest.java |    66 -
 .../PersistentReplicatedTestBase.java           |   240 -
 .../TemporaryResultSetFactoryJUnitTest.java     |   136 -
 .../RegionEntryFactoryBuilderJUnitTest.java     |    85 -
 .../GFSnapshotJUnitPerformanceTest.java         |   158 -
 .../internal/cache/tier/Bug40396DUnitTest.java  |   213 -
 .../tier/sockets/AcceptorImplJUnitTest.java     |   276 -
 ...mpatibilityHigherVersionClientDUnitTest.java |   249 -
 .../cache/tier/sockets/Bug36269DUnitTest.java   |   226 -
 .../cache/tier/sockets/Bug36457DUnitTest.java   |   213 -
 .../cache/tier/sockets/Bug36805DUnitTest.java   |   244 -
 .../cache/tier/sockets/Bug36829DUnitTest.java   |   170 -
 .../cache/tier/sockets/Bug36995DUnitTest.java   |   256 -
 .../cache/tier/sockets/Bug37210DUnitTest.java   |   294 -
 .../cache/tier/sockets/Bug37805DUnitTest.java   |   139 -
 .../CacheServerMaxConnectionsJUnitTest.java     |   225 -
 ...heServerSelectorMaxConnectionsJUnitTest.java |    35 -
 .../cache/tier/sockets/CacheServerTestUtil.java |   646 -
 .../CacheServerTransactionsDUnitTest.java       |   817 -
 ...acheServerTransactionsSelectorDUnitTest.java |    35 -
 .../tier/sockets/ClearPropagationDUnitTest.java |   480 -
 .../tier/sockets/ClientConflationDUnitTest.java |   540 -
 .../sockets/ClientHealthMonitorJUnitTest.java   |   261 -
 .../ClientHealthMonitorSelectorJUnitTest.java   |    35 -
 .../sockets/ClientInterestNotifyDUnitTest.java  |   639 -
 .../tier/sockets/ClientServerMiscDUnitTest.java |  1389 --
 .../ClientServerMiscSelectorDUnitTest.java      |    36 -
 .../cache/tier/sockets/ConflationDUnitTest.java |   910 -
 .../tier/sockets/ConnectionProxyJUnitTest.java  |   857 -
 .../DataSerializerPropogationDUnitTest.java     |  1325 --
 .../cache/tier/sockets/DeltaEOFException.java   |   113 -
 .../DestroyEntryPropagationDUnitTest.java       |   497 -
 .../sockets/DurableClientBug39997DUnitTest.java |   126 -
 .../DurableClientQueueSizeDUnitTest.java        |   416 -
 .../DurableClientReconnectAutoDUnitTest.java    |    59 -
 .../DurableClientReconnectDUnitTest.java        |   763 -
 .../sockets/DurableClientStatsDUnitTest.java    |   381 -
 .../sockets/DurableRegistrationDUnitTest.java   |   777 -
 .../sockets/DurableResponseMatrixDUnitTest.java |   498 -
 .../sockets/EventIDVerificationDUnitTest.java   |   491 -
 .../EventIDVerificationInP2PDUnitTest.java      |   325 -
 .../cache/tier/sockets/FaultyDelta.java         |   162 -
 .../FilterProfileIntegrationJUnitTest.java      |   110 -
 .../tier/sockets/FilterProfileJUnitTest.java    |   412 -
 .../ForceInvalidateEvictionDUnitTest.java       |   401 -
 ...ForceInvalidateOffHeapEvictionDUnitTest.java |    65 -
 .../cache/tier/sockets/HABug36738DUnitTest.java |   194 -
 .../sockets/HAInterestDistributedTestCase.java  |    31 -
 .../tier/sockets/HAInterestPart1DUnitTest.java  |   213 -
 .../tier/sockets/HAInterestPart2DUnitTest.java  |   376 -
 .../cache/tier/sockets/HAInterestTestCase.java  |  1021 -
 .../sockets/HAStartupAndFailoverDUnitTest.java  |   742 -
 .../internal/cache/tier/sockets/HaHelper.java   |    33 -
 .../InstantiatorPropagationDUnitTest.java       |  1723 --
 .../tier/sockets/InterestListDUnitTest.java     |  1165 --
 .../sockets/InterestListEndpointDUnitTest.java  |   503 -
 .../InterestListEndpointPRDUnitTest.java        |    42 -
 .../InterestListEndpointSelectorDUnitTest.java  |    35 -
 .../sockets/InterestListFailoverDUnitTest.java  |   318 -
 .../sockets/InterestListRecoveryDUnitTest.java  |   519 -
 .../sockets/InterestRegrListenerDUnitTest.java  |   469 -
 .../sockets/InterestResultPolicyDUnitTest.java  |   398 -
 .../cache/tier/sockets/MessageJUnitTest.java    |   112 -
 .../sockets/NewRegionAttributesDUnitTest.java   |   489 -
 .../tier/sockets/ObjectPartListJUnitTest.java   |   130 -
 .../tier/sockets/RedundancyLevelJUnitTest.java  |   130 -
 .../sockets/RedundancyLevelPart1DUnitTest.java  |   538 -
 .../sockets/RedundancyLevelPart2DUnitTest.java  |   535 -
 .../sockets/RedundancyLevelPart3DUnitTest.java  |   249 -
 .../tier/sockets/RedundancyLevelTestBase.java   |   653 -
 .../tier/sockets/RegionCloseDUnitTest.java      |   246 -
 ...erInterestBeforeRegionCreationDUnitTest.java |   276 -
 .../sockets/RegisterInterestKeysDUnitTest.java  |   248 -
 .../RegisterInterestKeysPRDUnitTest.java        |    41 -
 .../sockets/ReliableMessagingDUnitTest.java     |   438 -
 .../internal/cache/tier/sockets/TestFilter.java |    58 -
 .../sockets/UnregisterInterestDUnitTest.java    |   342 -
 .../sockets/UpdatePropagationDUnitTest.java     |   586 -
 .../sockets/UpdatePropagationPRDUnitTest.java   |    37 -
 .../VerifyEventIDGenerationInP2PDUnitTest.java  |   185 -
 ...UpdatesFromNonInterestEndPointDUnitTest.java |   256 -
 .../tier/sockets/command/CommitCommandTest.java |    61 -
 .../cache/versions/RVVExceptionJUnitTest.java   |    48 -
 .../versions/RegionVersionHolder2JUnitTest.java |   178 -
 .../versions/RegionVersionHolderJUnitTest.java  |  1894 --
 .../RegionVersionHolderRandomJUnitTest.java     |   191 -
 ...RegionVersionHolderSmallBitSetJUnitTest.java |    46 -
 .../versions/RegionVersionVectorJUnitTest.java  |   546 -
 .../cache/wan/AsyncEventQueueTestBase.java      |  1672 --
 .../cache/wan/CustomAsyncEventListener.java     |    57 -
 .../gemfire/internal/cache/wan/Filter70.java    |    63 -
 .../cache/wan/MyAsyncEventListener.java         |    53 -
 .../cache/wan/MyAsyncEventListener2.java        |    98 -
 .../cache/wan/MyDistributedSystemListener.java  |    65 -
 .../cache/wan/MyGatewaySenderEventListener.java |    77 -
 .../wan/MyGatewaySenderEventListener2.java      |    77 -
 .../cache/wan/MyGatewayTransportFilter1.java    |    57 -
 .../cache/wan/MyGatewayTransportFilter2.java    |    56 -
 .../cache/wan/MyGatewayTransportFilter3.java    |    56 -
 .../cache/wan/MyGatewayTransportFilter4.java    |    56 -
 .../internal/cache/wan/QueueListener.java       |    79 -
 .../asyncqueue/AsyncEventListenerDUnitTest.java |  1529 --
 .../AsyncEventListenerOffHeapDUnitTest.java     |    33 -
 .../AsyncEventQueueStatsDUnitTest.java          |   289 -
 .../AsyncEventQueueValidationsJUnitTest.java    |    82 -
 .../ConcurrentAsyncEventQueueDUnitTest.java     |   274 -
 ...ncurrentAsyncEventQueueOffHeapDUnitTest.java |    32 -
 .../CommonParallelAsyncEventQueueDUnitTest.java |    58 -
 ...ParallelAsyncEventQueueOffHeapDUnitTest.java |    32 -
 .../ParallelGatewaySenderQueueJUnitTest.java    |    87 -
 ...ialGatewaySenderEventProcessorJUnitTest.java |    42 -
 .../xmlcache/AbstractXmlParserJUnitTest.java    |   168 -
 .../cache/xmlcache/CacheCreationJUnitTest.java  |   209 -
 .../cache/xmlcache/CacheXmlParserJUnitTest.java |   169 -
 .../xmlcache/CacheXmlVersionJUnitTest.java      |    75 -
 .../PivotalEntityResolverJUnitTest.java         |   145 -
 .../cache/xmlcache/RegionCreationJUnitTest.java |    57 -
 .../xmlcache/XmlGeneratorUtilsJUnitTest.java    |   250 -
 .../classpathloaderjunittest/DoesExist.java     |    21 -
 .../CompressionCacheConfigDUnitTest.java        |   190 -
 .../CompressionCacheListenerDUnitTest.java      |   362 -
 ...ompressionCacheListenerOffHeapDUnitTest.java |    76 -
 .../CompressionRegionConfigDUnitTest.java       |   527 -
 .../CompressionRegionFactoryDUnitTest.java      |   148 -
 .../CompressionRegionOperationsDUnitTest.java   |   541 -
 ...ressionRegionOperationsOffHeapDUnitTest.java |    69 -
 .../compression/CompressionStatsDUnitTest.java  |   681 -
 .../compression/SnappyCompressorJUnitTest.java  |    76 -
 .../datasource/AbstractPoolCacheJUnitTest.java  |   251 -
 .../internal/datasource/CleanUpJUnitTest.java   |   126 -
 .../ConnectionPoolCacheImplJUnitTest.java       |   213 -
 .../datasource/ConnectionPoolingJUnitTest.java  |   339 -
 .../datasource/DataSourceFactoryJUnitTest.java  |   115 -
 .../internal/datasource/RestartJUnitTest.java   |    82 -
 .../internal/i18n/BasicI18nJUnitTest.java       |   407 -
 .../io/CompositeOutputStreamJUnitTest.java      |   453 -
 .../gemfire/internal/jndi/ContextJUnitTest.java |   440 -
 .../internal/jta/BlockingTimeOutJUnitTest.java  |   311 -
 .../gemfire/internal/jta/CacheUtils.java        |   226 -
 .../internal/jta/DataSourceJTAJUnitTest.java    |  1024 -
 .../internal/jta/ExceptionJUnitTest.java        |   126 -
 .../jta/GlobalTransactionJUnitTest.java         |   254 -
 .../gemstone/gemfire/internal/jta/JTAUtils.java |   386 -
 .../internal/jta/JtaIntegrationJUnitTest.java   |   134 -
 .../gemstone/gemfire/internal/jta/SyncImpl.java |    39 -
 .../internal/jta/TransactionImplJUnitTest.java  |   109 -
 .../jta/TransactionManagerImplJUnitTest.java    |   298 -
 .../jta/TransactionTimeOutJUnitTest.java        |   333 -
 .../jta/UserTransactionImplJUnitTest.java       |   130 -
 .../internal/jta/dunit/CommitThread.java        |   176 -
 .../internal/jta/dunit/ExceptionsDUnitTest.java |   316 -
 .../jta/dunit/IdleTimeOutDUnitTest.java         |   344 -
 .../jta/dunit/LoginTimeOutDUnitTest.java        |   348 -
 .../jta/dunit/MaxPoolSizeDUnitTest.java         |   314 -
 .../internal/jta/dunit/RollbackThread.java      |   176 -
 .../jta/dunit/TransactionTimeOutDUnitTest.java  |   502 -
 .../dunit/TxnManagerMultiThreadDUnitTest.java   |   520 -
 .../internal/jta/dunit/TxnTimeOutDUnitTest.java |   310 -
 .../internal/jta/functional/CacheJUnitTest.java |  1199 --
 .../jta/functional/TestXACacheLoader.java       |   104 -
 .../internal/lang/ClassUtilsJUnitTest.java      |   165 -
 .../internal/lang/InOutParameterJUnitTest.java  |    74 -
 .../internal/lang/InitializerJUnitTest.java     |    75 -
 .../internal/lang/ObjectUtilsJUnitTest.java     |   189 -
 .../internal/lang/StringUtilsJUnitTest.java     |   351 -
 .../internal/lang/SystemUtilsJUnitTest.java     |   101 -
 .../internal/lang/ThreadUtilsJUnitTest.java     |   214 -
 .../DistributedSystemLogFileJUnitTest.java      |  1505 --
 .../logging/LocatorLogFileJUnitTest.java        |   125 -
 .../logging/LogServiceIntegrationJUnitTest.java |   223 -
 .../LogServiceIntegrationTestSupport.java       |    40 -
 .../internal/logging/LogServiceJUnitTest.java   |   120 -
 .../LogWriterDisabledPerformanceTest.java       |    64 -
 .../logging/LogWriterImplJUnitTest.java         |    83 -
 .../logging/LogWriterPerformanceTest.java       |   127 -
 .../logging/LoggingIntegrationTestSuite.java    |    35 -
 .../logging/LoggingPerformanceTestCase.java     |   200 -
 .../internal/logging/LoggingUnitTestSuite.java  |    42 -
 .../logging/MergeLogFilesJUnitTest.java         |   247 -
 .../gemfire/internal/logging/NullLogWriter.java |   146 -
 .../internal/logging/SortLogFileJUnitTest.java  |   115 -
 .../internal/logging/TestLogWriterFactory.java  |   134 -
 .../logging/log4j/AlertAppenderJUnitTest.java   |   257 -
 .../logging/log4j/ConfigLocatorJUnitTest.java   |   222 -
 .../log4j/FastLoggerIntegrationJUnitTest.java   |   575 -
 .../logging/log4j/FastLoggerJUnitTest.java      |   178 -
 .../FastLoggerWithDefaultConfigJUnitTest.java   |    90 -
 .../log4j/LocalizedMessageJUnitTest.java        |    64 -
 .../log4j/Log4J2DisabledPerformanceTest.java    |    73 -
 .../logging/log4j/Log4J2PerformanceTest.java    |   151 -
 .../log4j/Log4jIntegrationTestSuite.java        |    28 -
 .../logging/log4j/Log4jUnitTestSuite.java       |    32 -
 .../log4j/LogWriterAppenderJUnitTest.java       |   224 -
 .../LogWriterLoggerDisabledPerformanceTest.java |    72 -
 .../log4j/LogWriterLoggerPerformanceTest.java   |   150 -
 .../internal/net/SocketUtilsJUnitTest.java      |   130 -
 .../offheap/AbstractStoredObjectTestBase.java   |   203 -
 .../offheap/ByteArrayMemoryChunkJUnitTest.java  |    30 -
 .../offheap/DataAsAddressJUnitTest.java         |   368 -
 .../internal/offheap/DataTypeJUnitTest.java     |   913 -
 .../DirectByteBufferMemoryChunkJUnitTest.java   |    33 -
 ...tingOutOfOffHeapMemoryListenerJUnitTest.java |   100 -
 .../internal/offheap/FragmentJUnitTest.java     |   238 -
 .../internal/offheap/FreeListManagerTest.java   |   797 -
 .../offheap/FreeListOffHeapRegionJUnitTest.java |    46 -
 .../HeapByteBufferMemoryChunkJUnitTest.java     |    33 -
 .../internal/offheap/InlineKeyJUnitTest.java    |   185 -
 .../offheap/LifecycleListenerJUnitTest.java     |   230 -
 .../offheap/MemoryChunkJUnitTestBase.java       |   290 -
 .../internal/offheap/MemoryChunkTestSuite.java  |    32 -
 .../offheap/MemoryInspectorImplJUnitTest.java   |   142 -
 .../offheap/NullOffHeapMemoryStats.java         |   114 -
 .../offheap/NullOutOfOffHeapMemoryListener.java |    39 -
 .../internal/offheap/ObjectChunkJUnitTest.java  |   902 -
 .../offheap/ObjectChunkSliceJUnitTest.java      |    72 -
 .../ObjectChunkWithHeapFormJUnitTest.java       |    64 -
 .../offheap/OffHeapHelperJUnitTest.java         |   314 -
 .../internal/offheap/OffHeapIndexJUnitTest.java |    92 -
 .../internal/offheap/OffHeapRegionBase.java     |   593 -
 .../OffHeapRegionEntryHelperJUnitTest.java      |   870 -
 .../offheap/OffHeapStorageJUnitTest.java        |   285 -
 .../offheap/OffHeapValidationJUnitTest.java     |   540 -
 .../OffHeapWriteObjectAsByteArrayJUnitTest.java |   115 -
 .../OldFreeListOffHeapRegionJUnitTest.java      |    47 -
 .../offheap/OutOfOffHeapMemoryDUnitTest.java    |   304 -
 .../offheap/RefCountChangeInfoJUnitTest.java    |   207 -
 ...moryAllocatorFillPatternIntegrationTest.java |   246 -
 ...mpleMemoryAllocatorFillPatternJUnitTest.java |   183 -
 .../offheap/SimpleMemoryAllocatorJUnitTest.java |   631 -
 .../internal/offheap/StoredObjectTestSuite.java |    32 -
 .../offheap/SyncChunkStackJUnitTest.java        |   289 -
 .../TxReleasesOffHeapOnCloseJUnitTest.java      |    63 -
 .../offheap/UnsafeMemoryChunkJUnitTest.java     |    87 -
 .../BlockingProcessStreamReaderJUnitTest.java   |   480 -
 ...leProcessControllerIntegrationJUnitTest.java |   155 -
 .../LocalProcessControllerJUnitTest.java        |   119 -
 .../process/LocalProcessLauncherDUnitTest.java  |   148 -
 .../process/LocalProcessLauncherJUnitTest.java  |   182 -
 ...NonBlockingProcessStreamReaderJUnitTest.java |   411 -
 .../internal/process/PidFileJUnitTest.java      |   274 -
 .../ProcessControllerFactoryJUnitTest.java      |   159 -
 .../process/ProcessStreamReaderTestCase.java    |   238 -
 .../gemfire/internal/process/mbean/Process.java |    60 -
 .../internal/process/mbean/ProcessMBean.java    |    28 -
 ...tractSignalNotificationHandlerJUnitTest.java |   460 -
 .../internal/size/ObjectSizerJUnitTest.java     |    89 -
 .../internal/size/ObjectTraverserJUnitTest.java |   122 -
 .../internal/size/ObjectTraverserPerf.java      |   100 -
 .../size/SizeClassOnceObjectSizerJUnitTest.java |    70 -
 .../gemfire/internal/size/SizeTestUtil.java     |    33 -
 .../size/WellKnownClassSizerJUnitTest.java      |    62 -
 .../internal/statistics/DummyStatistics.java    |   209 -
 .../statistics/SampleCollectorJUnitTest.java    |   347 -
 .../statistics/StatMonitorHandlerJUnitTest.java |   256 -
 .../statistics/StatisticsDUnitTest.java         |   948 -
 .../statistics/StatisticsMonitorJUnitTest.java  |   227 -
 .../internal/statistics/TestSampleHandler.java  |   177 -
 .../statistics/TestStatArchiveWriter.java       |    60 -
 .../statistics/TestStatisticsManager.java       |    42 -
 .../statistics/TestStatisticsSampler.java       |    59 -
 .../statistics/ValueMonitorJUnitTest.java       |   374 -
 .../internal/stats50/AtomicStatsJUnitTest.java  |   128 -
 .../internal/tcp/ConnectionJUnitTest.java       |    88 -
 .../util/AbortableTaskServiceJUnitTest.java     |   199 -
 .../internal/util/ArrayUtilsJUnitTest.java      |   179 -
 .../gemfire/internal/util/BytesJUnitTest.java   |   116 -
 .../internal/util/CollectionUtilsJUnitTest.java |   487 -
 .../internal/util/DelayedActionJUnitTest.java   |    56 -
 .../gemfire/internal/util/IOUtilsJUnitTest.java |   315 -
 .../gemfire/internal/util/SerializableImpl.java |    38 -
 .../util/SerializableImplWithValue.java         |    57 -
 .../gemfire/internal/util/Valuable.java         |    40 -
 .../CompactConcurrentHashSetJUnitTest.java      |   103 -
 .../ConcurrentHashMapIteratorJUnitTest.java     |   124 -
 .../concurrent/CopyOnWriteHashMapJUnitTest.java |   505 -
 .../concurrent/ReentrantSemaphoreJUnitTest.java |   112 -
 .../SemaphoreReadWriteLockJUnitTest.java        |   185 -
 .../cm/ConcurrentHashMapJUnitTest.java          |   631 -
 .../concurrent/cm/CountedMapLoopsJUnitTest.java |   225 -
 .../concurrent/cm/IntMapCheckJUnitTest.java     |   618 -
 .../util/concurrent/cm/LoopHelpers.java         |   219 -
 .../util/concurrent/cm/MapCheckJUnitTest.java   |   631 -
 .../util/concurrent/cm/MapLoopsJUnitTest.java   |   230 -
 .../util/concurrent/cm/RLJBarJUnitTest.java     |   197 -
 .../concurrent/cm/StringMapLoopsJUnitTest.java  |   240 -
 .../management/CacheManagementDUnitTest.java    |   947 -
 .../management/ClientHealthStatsDUnitTest.java  |   446 -
 .../gemfire/management/CompositeStats.java      |   103 -
 .../gemfire/management/CompositeTestMBean.java  |    65 -
 .../gemfire/management/CompositeTestMXBean.java |    33 -
 .../management/CompositeTypeTestDUnitTest.java  |   170 -
 .../gemfire/management/CustomMBean.java         |    76 -
 .../gemfire/management/CustomMXBean.java        |    36 -
 .../management/DLockManagementDUnitTest.java    |   473 -
 .../DataBrowserJSONValidationJUnitTest.java     |   350 -
 .../management/DiskManagementDUnitTest.java     |   728 -
 .../management/DistributedSystemDUnitTest.java  |   894 -
 .../management/LocatorManagementDUnitTest.java  |   353 -
 .../gemstone/gemfire/management/MBeanUtil.java  |   550 -
 .../gemfire/management/ManagementTestBase.java  |   760 -
 .../MemberMBeanAttributesDUnitTest.java         |   270 -
 .../management/OffHeapManagementDUnitTest.java  |   978 -
 .../gemfire/management/QueryDataDUnitTest.java  |   873 -
 .../management/RegionManagementDUnitTest.java   |  1450 --
 .../gemfire/management/TypedJsonJUnitTest.java  |   288 -
 ...ersalMembershipListenerAdapterDUnitTest.java |  2153 ---
 .../stats/AsyncEventQueueStatsJUnitTest.java    |    66 -
 .../bean/stats/CacheServerStatsJUnitTest.java   |   167 -
 .../bean/stats/DiskStatsJUnitTest.java          |   122 -
 .../stats/DistributedSystemStatsDUnitTest.java  |   108 -
 .../stats/DistributedSystemStatsJUnitTest.java  |   122 -
 .../bean/stats/GatewayMBeanBridgeJUnitTest.java |   108 -
 .../stats/GatewayReceiverStatsJUnitTest.java    |   207 -
 .../bean/stats/MBeanStatsTestCase.java          |    86 -
 .../bean/stats/MemberLevelStatsJUnitTest.java   |   581 -
 .../bean/stats/RegionStatsJUnitTest.java        |   271 -
 .../bean/stats/StatsRateJUnitTest.java          |   191 -
 .../internal/JettyHelperJUnitTest.java          |    80 -
 .../beans/DistributedSystemBridgeJUnitTest.java |   106 -
 .../cli/ClasspathScanLoadHelperJUnitTest.java   |    92 -
 .../internal/cli/CliUtilDUnitTest.java          |   435 -
 .../internal/cli/CommandManagerJUnitTest.java   |   330 -
 .../cli/CommandSeparatorEscapeJUnitTest.java    |   138 -
 .../internal/cli/DataCommandJsonJUnitTest.java  |    61 -
 .../internal/cli/GfshParserJUnitTest.java       |  1154 --
 .../management/internal/cli/HeadlessGfsh.java   |   374 -
 .../internal/cli/HeadlessGfshJUnitTest.java     |    86 -
 .../management/internal/cli/ResultHandler.java  |    23 -
 .../internal/cli/TableBuilderJUnitTest.java     |   314 -
 .../cli/annotations/CliArgumentJUnitTest.java   |   214 -
 .../AbstractCommandsSupportJUnitTest.java       |   404 -
 .../cli/commands/CliCommandTestBase.java        |   565 -
 .../cli/commands/ConfigCommandsDUnitTest.java   |   502 -
 ...eateAlterDestroyRegionCommandsDUnitTest.java |  1150 --
 .../cli/commands/DeployCommandsDUnitTest.java   |   480 -
 .../commands/DiskStoreCommandsDUnitTest.java    |  1157 --
 .../commands/DiskStoreCommandsJUnitTest.java    |   405 -
 .../cli/commands/FunctionCommandsDUnitTest.java |   595 -
 .../commands/GemfireDataCommandsDUnitTest.java  |  2088 --
 ...WithCacheLoaderDuringCacheMissDUnitTest.java |   374 -
 .../HTTPServiceSSLSupportJUnitTest.java         |   158 -
 .../cli/commands/IndexCommandsDUnitTest.java    |   815 -
 .../cli/commands/IndexCommandsJUnitTest.java    |   208 -
 ...stAndDescribeDiskStoreCommandsDUnitTest.java |   194 -
 .../ListAndDescribeRegionDUnitTest.java         |   321 -
 .../cli/commands/ListIndexCommandDUnitTest.java |   669 -
 .../cli/commands/MemberCommandsDUnitTest.java   |   288 -
 .../MiscellaneousCommandsDUnitTest.java         |   498 -
 ...laneousCommandsExportLogsPart1DUnitTest.java |   140 -
 ...laneousCommandsExportLogsPart2DUnitTest.java |   144 -
 ...laneousCommandsExportLogsPart3DUnitTest.java |   151 -
 ...laneousCommandsExportLogsPart4DUnitTest.java |   137 -
 .../cli/commands/QueueCommandsDUnitTest.java    |   392 -
 .../SharedConfigurationCommandsDUnitTest.java   |   341 -
 .../cli/commands/ShellCommandsDUnitTest.java    |   367 -
 .../cli/commands/ShowDeadlockDUnitTest.java     |   274 -
 .../cli/commands/ShowMetricsDUnitTest.java      |   345 -
 .../cli/commands/ShowStackTraceDUnitTest.java   |   150 -
 .../cli/commands/UserCommandsDUnitTest.java     |   164 -
 .../RegionPathConverterJUnitTest.java           |    82 -
 .../internal/cli/domain/AbstractImpl.java       |    21 -
 .../management/internal/cli/domain/Impl1.java   |    21 -
 .../management/internal/cli/domain/Impl12.java  |    21 -
 .../internal/cli/domain/Interface1.java         |    21 -
 .../internal/cli/domain/Interface2.java         |    21 -
 .../management/internal/cli/domain/Stock.java   |    37 -
 .../management/internal/cli/dto/Car.java        |    75 -
 .../management/internal/cli/dto/Key1.java       |    67 -
 .../management/internal/cli/dto/Key2.java       |    64 -
 .../internal/cli/dto/ObjectWithCharAttr.java    |    60 -
 .../management/internal/cli/dto/Value1.java     |    97 -
 .../management/internal/cli/dto/Value2.java     |    90 -
 .../functions/DataCommandFunctionJUnitTest.java |   132 -
 .../DescribeDiskStoreFunctionJUnitTest.java     |  1676 --
 .../ListDiskStoresFunctionJUnitTest.java        |   328 -
 .../functions/ListIndexFunctionJUnitTest.java   |   435 -
 .../cli/parser/ParserUtilsJUnitTest.java        |    82 -
 .../preprocessor/PreprocessorJUnitTest.java     |   302 -
 .../PreprocessorUtilsJUnitTest.java             |   127 -
 .../cli/shell/GfshConfigInitFileJUnitTest.java  |   186 -
 .../shell/GfshExecutionStrategyJUnitTest.java   |   137 -
 .../cli/shell/GfshHistoryJUnitTest.java         |    89 -
 .../cli/shell/GfshInitFileJUnitTest.java        |   476 -
 .../SharedConfigurationDUnitTest.java           |   443 -
 .../configuration/ZipUtilsJUnitTest.java        |    96 -
 .../domain/CacheElementJUnitTest.java           |   144 -
 .../utils/XmlUtilsAddNewNodeJUnitTest.java      |   415 -
 .../configuration/utils/XmlUtilsJUnitTest.java  |   248 -
 .../internal/pulse/TestClientIdsDUnitTest.java  |   301 -
 .../internal/pulse/TestFunctionsDUnitTest.java  |   112 -
 .../internal/pulse/TestHeapDUnitTest.java       |   108 -
 .../internal/pulse/TestLocatorsDUnitTest.java   |    87 -
 .../pulse/TestSubscriptionsDUnitTest.java       |   307 -
 ...rDistributedSystemMXBeanIntegrationTest.java |    50 -
 ...horizeOperationForMBeansIntegrationTest.java |   323 -
 ...erationForRegionCommandsIntegrationTest.java |   136 -
 ...JSONAuthorizationDetailsIntegrationTest.java |   163 -
 ...tionCodesForDataCommandsIntegrationTest.java |   101 -
 ...tionCodesForDistributedSystemMXBeanTest.java |    76 -
 .../ReadOpFileAccessControllerJUnitTest.java    |   201 -
 .../WanCommandsControllerJUnitTest.java         |   140 -
 .../gemfire/management/model/EmptyObject.java   |    24 -
 .../gemstone/gemfire/management/model/Item.java |    95 -
 .../gemfire/management/model/Order.java         |    88 -
 .../gemfire/management/model/SubOrder.java      |    30 -
 .../DomainObjectsAsValuesJUnitTest.java         |   129 -
 .../GemcachedBinaryClientJUnitTest.java         |   148 -
 .../GemcachedDevelopmentJUnitTest.java          |   265 -
 .../gemfire/memcached/IntegrationJUnitTest.java |    94 -
 .../gemfire/pdx/AutoSerializableJUnitTest.java  |  1401 --
 .../gemfire/pdx/ByteSourceJUnitTest.java        |   752 -
 .../ClientsWithVersioningRetryDUnitTest.java    |   513 -
 .../com/gemstone/gemfire/pdx/DSInsidePdx.java   |   109 -
 .../pdx/DistributedSystemIdDUnitTest.java       |   157 -
 .../com/gemstone/gemfire/pdx/DomainObject.java  |   106 -
 .../gemstone/gemfire/pdx/DomainObjectBad.java   |    25 -
 .../gemfire/pdx/DomainObjectClassLoadable.java  |    27 -
 .../gemfire/pdx/DomainObjectPdxAuto.java        |   192 -
 ...DomainObjectPdxAutoNoDefaultConstructor.java |    63 -
 .../java/com/gemstone/gemfire/pdx/Employee.java |    92 -
 .../pdx/JSONPdxClientServerDUnitTest.java       |   629 -
 .../com/gemstone/gemfire/pdx/NestedPdx.java     |   114 -
 .../gemfire/pdx/NonDelegatingLoader.java        |    66 -
 .../OffHeapByteBufferByteSourceJUnitTest.java   |    52 -
 .../gemfire/pdx/OffHeapByteSourceJUnitTest.java |    65 -
 .../pdx/PDXAsyncEventQueueDUnitTest.java        |   154 -
 .../gemfire/pdx/PdxAttributesJUnitTest.java     |   250 -
 .../gemfire/pdx/PdxClientServerDUnitTest.java   |   799 -
 .../pdx/PdxDeserializationDUnitTest.java        |   413 -
 .../pdx/PdxFormatterPutGetJUnitTest.java        |   208 -
 .../com/gemstone/gemfire/pdx/PdxInsideDS.java   |   107 -
 .../pdx/PdxInstanceFactoryJUnitTest.java        |  1210 --
 .../gemfire/pdx/PdxInstanceJUnitTest.java       |   396 -
 .../gemfire/pdx/PdxSerializableDUnitTest.java   |   196 -
 .../gemfire/pdx/PdxSerializableJUnitTest.java   |  2171 ---
 .../gemfire/pdx/PdxStringJUnitTest.java         |   167 -
 .../gemfire/pdx/PdxTypeExportDUnitTest.java     |   130 -
 .../gemfire/pdx/SeparateClassloaderPdx.java     |    43 -
 .../com/gemstone/gemfire/pdx/SimpleClass.java   |    83 -
 .../com/gemstone/gemfire/pdx/SimpleClass1.java  |   151 -
 .../com/gemstone/gemfire/pdx/SimpleClass2.java  |    32 -
 .../gemfire/pdx/TestObjectForPdxFormatter.java  |  1003 -
 .../gemfire/pdx/VersionClassLoader.java         |    98 -
 .../gemstone/gemfire/redis/AuthJUnitTest.java   |   160 -
 .../gemfire/redis/ConcurrentStartTest.java      |    98 -
 .../gemstone/gemfire/redis/HashesJUnitTest.java |   191 -
 .../gemstone/gemfire/redis/ListsJUnitTest.java  |   254 -
 .../gemfire/redis/RedisDistDUnitTest.java       |   258 -
 .../gemstone/gemfire/redis/SetsJUnitTest.java   |   258 -
 .../gemfire/redis/SortedSetsJUnitTest.java      |   430 -
 .../gemfire/redis/StringsJunitTest.java         |   312 -
 .../web/controllers/AddFreeItemToOrders.java    |   153 -
 .../rest/internal/web/controllers/Customer.java |   109 -
 .../internal/web/controllers/DateTimeUtils.java |    40 -
 .../rest/internal/web/controllers/Gender.java   |    30 -
 .../internal/web/controllers/GetAllEntries.java |    68 -
 .../web/controllers/GetDeliveredOrders.java     |   106 -
 .../internal/web/controllers/GetRegions.java    |    76 -
 .../web/controllers/GetValueForKey.java         |    77 -
 .../rest/internal/web/controllers/Item.java     |   160 -
 .../rest/internal/web/controllers/Order.java    |   189 -
 .../rest/internal/web/controllers/Person.java   |   185 -
 .../web/controllers/PutKeyFunction.java         |    63 -
 .../web/controllers/RestAPITestBase.java        |   123 -
 .../internal/web/controllers/RestTestUtils.java |   110 -
 .../security/ClientAuthenticationDUnitTest.java |   905 -
 .../ClientAuthenticationPart2DUnitTest.java     |    88 -
 .../security/ClientAuthorizationDUnitTest.java  |   785 -
 .../security/ClientAuthorizationTestBase.java   |  1387 --
 .../security/ClientMultiUserAuthzDUnitTest.java |   523 -
 .../DeltaClientAuthorizationDUnitTest.java      |   352 -
 .../DeltaClientPostAuthorizationDUnitTest.java  |   538 -
 .../security/P2PAuthenticationDUnitTest.java    |   604 -
 .../gemfire/security/SecurityTestUtil.java      |  1875 --
 .../com/gemstone/gemfire/test/dunit/Assert.java |    66 -
 .../gemfire/test/dunit/AsyncInvocation.java     |   216 -
 .../gemstone/gemfire/test/dunit/DUnitEnv.java   |    78 -
 .../gemfire/test/dunit/DebuggerUtils.java       |    52 -
 .../gemfire/test/dunit/DistributedTestCase.java |   532 -
 .../test/dunit/DistributedTestUtils.java        |   167 -
 .../com/gemstone/gemfire/test/dunit/Host.java   |   213 -
 .../gemfire/test/dunit/IgnoredException.java    |   208 -
 .../com/gemstone/gemfire/test/dunit/Invoke.java |   160 -
 .../com/gemstone/gemfire/test/dunit/Jitter.java |    87 -
 .../gemfire/test/dunit/LogWriterUtils.java      |   111 -
 .../gemfire/test/dunit/NetworkUtils.java        |    69 -
 .../gemfire/test/dunit/RMIException.java        |   170 -
 .../gemfire/test/dunit/RepeatableRunnable.java  |    31 -
 .../test/dunit/SerializableCallable.java        |    70 -
 .../test/dunit/SerializableCallableIF.java      |    26 -
 .../test/dunit/SerializableRunnable.java        |    91 -
 .../test/dunit/SerializableRunnableIF.java      |    26 -
 .../test/dunit/StoppableWaitCriterion.java      |    35 -
 .../gemfire/test/dunit/ThreadUtils.java         |   155 -
 .../com/gemstone/gemfire/test/dunit/VM.java     |   450 -
 .../com/gemstone/gemfire/test/dunit/Wait.java   |   204 -
 .../gemfire/test/dunit/WaitCriterion.java       |    33 -
 .../dunit/rules/DistributedDisconnectRule.java  |   121 -
 .../rules/DistributedExternalResource.java      |    58 -
 .../DistributedRestoreSystemProperties.java     |    74 -
 .../gemfire/test/dunit/rules/RemoteInvoker.java |    43 -
 .../test/dunit/standalone/BounceResult.java     |    36 -
 .../gemfire/test/dunit/standalone/ChildVM.java  |    81 -
 .../test/dunit/standalone/DUnitLauncher.java    |   464 -
 .../test/dunit/standalone/ProcessManager.java   |   259 -
 .../test/dunit/standalone/RemoteDUnitVM.java    |   143 -
 .../test/dunit/standalone/RemoteDUnitVMIF.java  |    36 -
 .../dunit/standalone/StandAloneDUnitEnv.java    |    74 -
 .../test/dunit/tests/BasicDUnitTest.java        |   156 -
 .../tests/GetDefaultDiskStoreNameDUnitTest.java |    67 -
 .../dunit/tests/GetTestMethodNameDUnitTest.java |    54 -
 .../gemfire/test/dunit/tests/VMDUnitTest.java   |   206 -
 .../com/gemstone/gemfire/test/fake/Fakes.java   |    99 -
 .../gemfire/test/golden/ExecutableProcess.java  |    24 -
 .../gemfire/test/golden/FailOutputTestCase.java |    52 -
 .../golden/FailWithErrorInOutputJUnitTest.java  |    47 -
 .../FailWithExtraLineInOutputJUnitTest.java     |    76 -
 ...WithLineMissingFromEndOfOutputJUnitTest.java |    75 -
 ...hLineMissingFromMiddleOfOutputJUnitTest.java |    74 -
 .../FailWithLoggerErrorInOutputJUnitTest.java   |    46 -
 .../FailWithLoggerFatalInOutputJUnitTest.java   |    46 -
 .../FailWithLoggerWarnInOutputJUnitTest.java    |    46 -
 .../golden/FailWithProblemInOutputTestCase.java |    61 -
 .../golden/FailWithSevereInOutputJUnitTest.java |    47 -
 ...hTimeoutOfWaitForOutputToMatchJUnitTest.java |    68 -
 .../FailWithWarningInOutputJUnitTest.java       |    47 -
 .../gemfire/test/golden/GoldenComparator.java   |   142 -
 .../test/golden/GoldenStringComparator.java     |    39 -
 .../gemfire/test/golden/GoldenTestCase.java     |   157 -
 .../golden/GoldenTestFrameworkTestSuite.java    |    43 -
 .../gemfire/test/golden/PassJUnitTest.java      |    86 -
 .../golden/PassWithExpectedErrorJUnitTest.java  |    47 -
 .../golden/PassWithExpectedProblemTestCase.java |    91 -
 .../golden/PassWithExpectedSevereJUnitTest.java |    47 -
 .../PassWithExpectedWarningJUnitTest.java       |    47 -
 .../test/golden/RegexGoldenComparator.java      |    37 -
 .../test/golden/StringGoldenComparator.java     |    37 -
 .../gemfire/test/golden/log4j2-test.xml         |    18 -
 .../gemfire/test/process/MainLauncher.java      |    48 -
 .../test/process/MainLauncherJUnitTest.java     |   159 -
 .../gemfire/test/process/OutputFormatter.java   |    37 -
 .../test/process/ProcessOutputReader.java       |    89 -
 .../test/process/ProcessStreamReader.java       |    74 -
 .../process/ProcessTestFrameworkTestSuite.java  |    28 -
 .../gemfire/test/process/ProcessWrapper.java    |   464 -
 .../test/process/ProcessWrapperJUnitTest.java   |    72 -
 .../gemstone/gemfire/util/JSR166TestCase.java   |   482 -
 .../gemstone/gemfire/util/test/TestUtil.java    |    65 -
 .../com/gemstone/persistence/admin/Logger.java  |   278 -
 .../gemstone/persistence/logging/Formatter.java |    41 -
 .../gemstone/persistence/logging/Handler.java   |    98 -
 .../com/gemstone/persistence/logging/Level.java |   128 -
 .../gemstone/persistence/logging/LogRecord.java |   185 -
 .../gemstone/persistence/logging/Logger.java    |   566 -
 .../persistence/logging/SimpleFormatter.java    |    77 -
 .../persistence/logging/StreamHandler.java      |    61 -
 .../test/java/com/gemstone/sequence/Arrow.java  |   124 -
 .../java/com/gemstone/sequence/Lifeline.java    |    98 -
 .../com/gemstone/sequence/LifelineState.java    |   114 -
 .../java/com/gemstone/sequence/LineMapper.java  |    36 -
 .../com/gemstone/sequence/SequenceDiagram.java  |   315 -
 .../com/gemstone/sequence/SequencePanel.java    |    83 -
 .../com/gemstone/sequence/StateColorMap.java    |    66 -
 .../java/com/gemstone/sequence/TimeAxis.java    |   122 -
 .../com/gemstone/sequence/ZoomingPanel.java     |   188 -
 .../sequence/gemfire/DefaultLineMapper.java     |    42 -
 .../gemfire/GemfireSequenceDisplay.java         |   336 -
 .../sequence/gemfire/HydraLineMapper.java       |   135 -
 .../sequence/gemfire/SelectGraphDialog.java     |   155 -
 .../com/main/MyDistributedSystemListener.java   |   115 -
 .../com/main/WANBootStrapping_Site1_Add.java    |   122 -
 .../com/main/WANBootStrapping_Site1_Remove.java |    75 -
 .../com/main/WANBootStrapping_Site2_Add.java    |   107 -
 .../com/main/WANBootStrapping_Site2_Remove.java |    73 -
 gemfire-core/src/test/java/hydra/GsRandom.java  |   311 -
 .../test/java/hydra/HydraRuntimeException.java  |    33 -
 gemfire-core/src/test/java/hydra/Log.java       |   219 -
 .../src/test/java/hydra/LogVersionHelper.java   |    45 -
 .../src/test/java/hydra/MethExecutor.java       |   393 -
 .../src/test/java/hydra/MethExecutorResult.java |   186 -
 .../src/test/java/hydra/SchedulingOrder.java    |    36 -
 .../src/test/java/hydra/log/AnyLogWriter.java   |   555 -
 .../java/hydra/log/CircularOutputStream.java    |   131 -
 .../parReg/query/unittest/NewPortfolio.java     |   272 -
 .../java/parReg/query/unittest/Position.java    |   162 -
 .../src/test/java/perffmwk/Formatter.java       |   147 -
 .../java/security/AuthzCredentialGenerator.java |   462 -
 .../test/java/security/CredentialGenerator.java |   343 -
 .../security/DummyAuthzCredentialGenerator.java |   145 -
 .../java/security/DummyCredentialGenerator.java |    94 -
 .../security/LdapUserCredentialGenerator.java   |   160 -
 .../java/security/PKCSCredentialGenerator.java  |   112 -
 .../java/security/SSLCredentialGenerator.java   |   117 -
 .../UserPasswordWithExtraPropsAuthInit.java     |    77 -
 .../security/XmlAuthzCredentialGenerator.java   |   264 -
 .../templates/security/DummyAuthenticator.java  |    87 -
 .../templates/security/DummyAuthorization.java  |   118 -
 .../security/FunctionSecurityPrmsHolder.java    |    55 -
 .../security/LdapUserAuthenticator.java         |   117 -
 .../java/templates/security/PKCSAuthInit.java   |   133 -
 .../templates/security/PKCSAuthenticator.java   |   167 -
 .../java/templates/security/PKCSPrincipal.java  |    42 -
 .../security/UserPasswordAuthInit.java          |    84 -
 .../templates/security/UsernamePrincipal.java   |    46 -
 .../templates/security/XmlAuthorization.java    |   675 -
 .../templates/security/XmlErrorHandler.java     |    82 -
 .../src/test/java/util/TestException.java       |    35 -
 ...gemstone.gemfire.internal.cache.CacheService |     1 -
 ...ne.gemfire.internal.cache.xmlcache.XmlParser |     5 -
 ...org.springframework.shell.core.CommandMarker |     8 -
 .../ClientCacheFactoryJUnitTest_single_pool.xml |    30 -
 .../cache/client/internal/cacheserver.cer       |   Bin 782 -> 0 bytes
 .../cache/client/internal/cacheserver.keystore  |   Bin 1253 -> 0 bytes
 .../client/internal/cacheserver.truststore      |   Bin 844 -> 0 bytes
 .../gemfire/cache/client/internal/client.cer    |   Bin 782 -> 0 bytes
 .../cache/client/internal/client.keystore       |   Bin 1251 -> 0 bytes
 .../cache/client/internal/client.truststore     |   Bin 846 -> 0 bytes
 .../cache/client/internal/default.keystore      |   Bin 1115 -> 0 bytes
 .../cache/client/internal/trusted.keystore      |   Bin 1078 -> 0 bytes
 .../gemfire/cache/query/dunit/IndexCreation.xml |   131 -
 .../functional/index-creation-with-eviction.xml |    56 -
 .../index-creation-without-eviction.xml         |    67 -
 .../functional/index-recovery-overflow.xml      |    57 -
 .../query/internal/index/cachequeryindex.xml    |   125 -
 .../internal/index/cachequeryindexwitherror.xml |   134 -
 .../cache/query/partitioned/PRIndexCreation.xml |    44 -
 .../gemfire/cache30/attributesUnordered.xml     |    39 -
 .../com/gemstone/gemfire/cache30/badFloat.xml   |    30 -
 .../com/gemstone/gemfire/cache30/badInt.xml     |    33 -
 .../gemfire/cache30/badKeyConstraintClass.xml   |    31 -
 .../com/gemstone/gemfire/cache30/badScope.xml   |    30 -
 .../com/gemstone/gemfire/cache30/bug44710.xml   |    31 -
 .../gemfire/cache30/callbackNotDeclarable.xml   |    34 -
 .../gemfire/cache30/callbackWithException.xml   |    34 -
 .../com/gemstone/gemfire/cache30/coLocation.xml |    31 -
 .../gemstone/gemfire/cache30/coLocation3.xml    |    31 -
 .../com/gemstone/gemfire/cache30/ewtest.xml     |    68 -
 .../cache30/examples_3_0/example-cache.xml      |    87 -
 .../cache30/examples_4_0/example-cache.xml      |    94 -
 .../gemfire/cache30/loaderNotLoader.xml         |    33 -
 .../com/gemstone/gemfire/cache30/malformed.xml  |    29 -
 .../gemfire/cache30/namedAttributes.xml         |    59 -
 .../gemfire/cache30/partitionedRegion.xml       |    39 -
 .../gemfire/cache30/partitionedRegion51.xml     |    31 -
 .../gemstone/gemfire/cache30/sameRootRegion.xml |    37 -
 .../gemstone/gemfire/cache30/sameSubregion.xml  |    42 -
 .../gemfire/cache30/unknownNamedAttributes.xml  |    30 -
 .../gemfire/codeAnalysis/excludedClasses.txt    |   118 -
 .../gemstone/gemfire/codeAnalysis/openBugs.txt  |    23 -
 .../sanctionedDataSerializables.txt             |  2172 ---
 .../codeAnalysis/sanctionedSerializables.txt    |   827 -
 .../internal/SharedConfigurationJUnitTest.xml   |    23 -
 ...st_testWriteAfterSamplingBegins_expected.gfs |   Bin 1970 -> 0 bytes
 ...est_testWriteWhenSamplingBegins_expected.gfs |   Bin 1933 -> 0 bytes
 .../internal/cache/BackupJUnitTest.cache.xml    |    23 -
 .../internal/cache/DiskRegCacheXmlJUnitTest.xml |   233 -
 .../cache/PartitionRegionCacheExample1.xml      |    43 -
 .../cache/PartitionRegionCacheExample2.xml      |    42 -
 .../incorrect_bytes_threshold.xml               |    35 -
 .../faultyDiskXMLsForTesting/incorrect_dir.xml  |    35 -
 .../incorrect_dir_size.xml                      |    35 -
 .../incorrect_max_oplog_size.xml                |    35 -
 .../incorrect_roll_oplogs_value.xml             |    35 -
 .../incorrect_sync_value.xml                    |    35 -
 .../incorrect_time_interval.xml                 |    35 -
 .../mixed_diskstore_diskdir.xml                 |    38 -
 .../mixed_diskstore_diskwriteattrs.xml          |    38 -
 .../tier/sockets/RedundancyLevelJUnitTest.xml   |    38 -
 ...testDTDFallbackWithNonEnglishLocal.cache.xml |    23 -
 .../gemstone/gemfire/internal/jta/cachejta.xml  |   273 -
 .../domain/CacheElementJUnitTest.xml            |     7 -
 ...dNewNodeJUnitTest.testAddNewNodeNewNamed.xml |    25 -
 ...ewNodeJUnitTest.testAddNewNodeNewUnnamed.xml |    27 -
 ...itTest.testAddNewNodeNewUnnamedExtension.xml |    25 -
 ...NodeJUnitTest.testAddNewNodeReplaceNamed.xml |    22 -
 ...deJUnitTest.testAddNewNodeReplaceUnnamed.xml |    24 -
 ...st.testAddNewNodeReplaceUnnamedExtension.xml |    24 -
 ...sAddNewNodeJUnitTest.testDeleteNodeNamed.xml |    21 -
 ...ddNewNodeJUnitTest.testDeleteNodeUnnamed.xml |    23 -
 ...JUnitTest.testDeleteNodeUnnamedExtension.xml |    23 -
 .../utils/XmlUtilsAddNewNodeJUnitTest.xml       |    24 -
 ...Test.testBuildSchemaLocationMapAttribute.xml |    10 -
 ...testBuildSchemaLocationMapEmptyAttribute.xml |     8 -
 ...ationMapMapOfStringListOfStringAttribute.xml |    10 -
 ....testBuildSchemaLocationMapNullAttribute.xml |     7 -
 ...XmlUtilsJUnitTest.testQuerySingleElement.xml |    24 -
 .../management/internal/security/auth1.json     |    14 -
 .../management/internal/security/auth2.json     |    21 -
 .../management/internal/security/auth3.json     |    25 -
 .../internal/security/testInheritRole.json      |    40 -
 .../security/testSimpleUserAndRole.json         |    14 -
 .../testUserAndRoleRegionServerGroup.json       |    16 -
 .../internal/security/testUserMultipleRole.json |    20 -
 .../gemstone/gemfire/pdx/jsonStrings/array.txt  |    22 -
 .../gemfire/pdx/jsonStrings/attachment.txt      |    11 -
 .../gemfire/pdx/jsonStrings/attachment2.txt     |    13 -
 .../gemstone/gemfire/pdx/jsonStrings/book.txt   |    17 -
 .../gemstone/gemfire/pdx/jsonStrings/image.txt  |    13 -
 .../gemstone/gemfire/pdx/jsonStrings/json1.txt  |    22 -
 .../gemstone/gemfire/pdx/jsonStrings/json10.txt |    20 -
 .../gemstone/gemfire/pdx/jsonStrings/json11.txt |    33 -
 .../gemstone/gemfire/pdx/jsonStrings/json12.txt |    32 -
 .../gemstone/gemfire/pdx/jsonStrings/json13.txt |    42 -
 .../gemstone/gemfire/pdx/jsonStrings/json14.txt |    15 -
 .../gemstone/gemfire/pdx/jsonStrings/json15.txt |     1 -
 .../gemstone/gemfire/pdx/jsonStrings/json16.txt |    31 -
 .../gemfire/pdx/jsonStrings/json16_2.txt        |    31 -
 .../gemstone/gemfire/pdx/jsonStrings/json17.txt |    27 -
 .../gemstone/gemfire/pdx/jsonStrings/json18.txt |    71 -
 .../gemstone/gemfire/pdx/jsonStrings/json19.txt |    18 -
 .../gemstone/gemfire/pdx/jsonStrings/json2.txt  |    11 -
 .../gemstone/gemfire/pdx/jsonStrings/json20.txt |    36 -
 .../gemstone/gemfire/pdx/jsonStrings/json21.txt |    36 -
 .../gemstone/gemfire/pdx/jsonStrings/json22.txt |    36 -
 .../gemstone/gemfire/pdx/jsonStrings/json23.txt |    23 -
 .../gemstone/gemfire/pdx/jsonStrings/json24.txt |    15 -
 .../gemstone/gemfire/pdx/jsonStrings/json25.txt |    33 -
 .../gemstone/gemfire/pdx/jsonStrings/json26.txt |    13 -
 .../gemstone/gemfire/pdx/jsonStrings/json27.txt |    25 -
 .../gemstone/gemfire/pdx/jsonStrings/json28.txt |    84 -
 .../gemstone/gemfire/pdx/jsonStrings/json29.txt |    11 -
 .../gemstone/gemfire/pdx/jsonStrings/json3.txt  |    26 -
 .../gemstone/gemfire/pdx/jsonStrings/json31.txt |     9 -
 .../gemstone/gemfire/pdx/jsonStrings/json4.txt  |    88 -
 .../gemstone/gemfire/pdx/jsonStrings/json5.txt  |    27 -
 .../gemstone/gemfire/pdx/jsonStrings/json6.txt  |    11 -
 .../gemstone/gemfire/pdx/jsonStrings/json7.txt  |    32 -
 .../gemstone/gemfire/pdx/jsonStrings/json8.txt  |    53 -
 .../gemstone/gemfire/pdx/jsonStrings/json9.txt  |    77 -
 .../gemfire/pdx/jsonStrings/jsonMongo.txt       |    10 -
 .../pdx/jsonStrings/jsonMongoSingleQuote.tx0    |    10 -
 .../gemfire/pdx/jsonStrings/jsonProductdb.txt   |    33 -
 .../gemfire/pdx/jsonStrings/json_google.txt     |    33 -
 .../gemfire/pdx/jsonStrings/jsoncustomer.txt    |    24 -
 .../gemfire/pdx/jsonStrings/jsonemptyobject.txo |    44 -
 .../gemfire/pdx/jsonStrings/jsonemptyobject.txt |    23 -
 .../gemfire/pdx/jsonStrings/jsonfacebook.txt    |    45 -
 .../gemfire/pdx/jsonStrings/jsonfeed.txt        |    33 -
 .../gemfire/pdx/jsonStrings/jsonfeed2.txt       |    47 -
 .../gemfire/pdx/jsonStrings/jsonflicker.txt     |    21 -
 .../gemfire/pdx/jsonStrings/jsoniphone.txt      |    78 -
 .../pdx/jsonStrings/jsonsolrwithcomment.tx0     |    29 -
 .../pdx/jsonStrings/jsonsolrwithcomment.txt     |    29 -
 .../gemfire/pdx/jsonStrings/jsontwitter1.txt    |   430 -
 .../gemfire/pdx/jsonStrings/jsontwitter2.txt    |   574 -
 .../gemfire/pdx/jsonStrings/jsontwitter3.txt    |    70 -
 .../gemfire/pdx/jsonStrings/jsonutf.tx0         |     2 -
 .../gemfire/pdx/jsonStrings/jsonyahoo.txt       |    11 -
 .../gemfire/pdx/jsonStrings/jsonyoutube.txt     |    54 -
 .../gemfire/pdx/jsonStrings/linkden1.txt        |    16 -
 .../gemstone/gemfire/pdx/jsonStrings/odata.txt  |    16 -
 .../gemstone/gemfire/pdx/jsonStrings/odata2.txt |    18 -
 .../jsonStrings/unquoteJsonStrings/json1.txt    |    31 -
 .../gemfire/pdx/jsonStrings/weather.txt         |     1 -
 .../gemfire/test/golden/log4j2-test.xml         |    18 -
 .../src/test/resources/jta/cachejta.xml         |   273 -
 .../src/test/resources/lib/authz-dummy.xml      |   126 -
 .../src/test/resources/lib/authz-ldap.xml       |    85 -
 .../resources/lib/authz-multiUser-dummy.xml     |   106 -
 .../test/resources/lib/authz-multiUser-ldap.xml |    83 -
 .../test/resources/lib/keys/gemfire1.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire10.keystore  |   Bin 1546 -> 0 bytes
 .../test/resources/lib/keys/gemfire11.keystore  |   Bin 1546 -> 0 bytes
 .../test/resources/lib/keys/gemfire2.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire3.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire4.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire5.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire6.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire7.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire8.keystore   |   Bin 1536 -> 0 bytes
 .../test/resources/lib/keys/gemfire9.keystore   |   Bin 1536 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire1.keystore    |   Bin 1426 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire10.keystore   |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire11.keystore   |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire2.keystore    |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire3.keystore    |   Bin 1426 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire4.keystore    |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire5.keystore    |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire6.keystore    |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire7.keystore    |   Bin 1426 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire8.keystore    |   Bin 1434 -> 0 bytes
 .../resources/lib/keys/ibm/gemfire9.keystore    |   Bin 1426 -> 0 bytes
 .../test/resources/lib/keys/ibm/publickeyfile   |   Bin 4535 -> 0 bytes
 .../src/test/resources/lib/keys/publickeyfile   |   Bin 4535 -> 0 bytes
 .../resources/spring/spring-gemfire-context.xml |    42 -
 .../src/test/resources/ssl/trusted.keystore     |   Bin 1176 -> 0 bytes
 .../src/test/resources/ssl/untrusted.keystore   |   Bin 1181 -> 0 bytes
 .../resources/templates/security/authz5_5.dtd   |   105 -
 .../resources/templates/security/authz6_0.dtd   |   110 -
 gemfire-cq/build.gradle                         |    23 -
 .../cache/client/internal/CloseCQOp.java        |    72 -
 .../cache/client/internal/CreateCQOp.java       |   163 -
 .../cache/client/internal/CreateCQWithIROp.java |    92 -
 .../cache/client/internal/GetDurableCQsOp.java  |   135 -
 .../client/internal/ServerCQProxyImpl.java      |   111 -
 .../gemfire/cache/client/internal/StopCQOp.java |    72 -
 .../cache/query/internal/cq/ClientCQImpl.java   |   615 -
 .../internal/cq/CqAttributesMutatorImpl.java    |    68 -
 .../cache/query/internal/cq/CqConflatable.java  |   223 -
 .../cache/query/internal/cq/CqEventImpl.java    |   162 -
 .../cache/query/internal/cq/CqListenerImpl.java |    56 -
 .../cache/query/internal/cq/CqQueryImpl.java    |   383 -
 .../query/internal/cq/CqServiceFactoryImpl.java |    69 -
 .../cache/query/internal/cq/CqServiceImpl.java  |  2087 --
 .../internal/cq/CqServiceStatisticsImpl.java    |   100 -
 .../query/internal/cq/CqServiceVsdStats.java    |   411 -
 .../query/internal/cq/CqStatisticsImpl.java     |    75 -
 .../cache/query/internal/cq/ServerCQImpl.java   |   655 -
 .../tier/sockets/command/BaseCQCommand.java     |    59 -
 .../cache/tier/sockets/command/CloseCQ.java     |   131 -
 .../cache/tier/sockets/command/ExecuteCQ.java   |   168 -
 .../cache/tier/sockets/command/ExecuteCQ61.java |   220 -
 .../cache/tier/sockets/command/GetCQStats.java  |   100 -
 .../tier/sockets/command/GetDurableCQs.java     |   143 -
 .../cache/tier/sockets/command/MonitorCQ.java   |   100 -
 .../cache/tier/sockets/command/StopCQ.java      |   135 -
 ...cache.query.internal.cq.spi.CqServiceFactory |    15 -
 .../gemfire/cache/query/cq/CQJUnitTest.java     |   150 -
 .../cache/query/cq/dunit/CqDataDUnitTest.java   |  1165 --
 .../dunit/CqDataOptimizedExecuteDUnitTest.java  |    55 -
 .../cq/dunit/CqDataUsingPoolDUnitTest.java      |  1559 --
 ...qDataUsingPoolOptimizedExecuteDUnitTest.java |    54 -
 .../cache/query/cq/dunit/CqPerfDUnitTest.java   |  1048 -
 .../cq/dunit/CqPerfUsingPoolDUnitTest.java      |  1008 -
 .../cache/query/cq/dunit/CqQueryDUnitTest.java  |  3995 ----
 .../dunit/CqQueryOptimizedExecuteDUnitTest.java |   310 -
 .../cq/dunit/CqQueryUsingPoolDUnitTest.java     |  3325 ----
 ...QueryUsingPoolOptimizedExecuteDUnitTest.java |    50 -
 .../cq/dunit/CqResultSetUsingPoolDUnitTest.java |  1134 --
 ...ltSetUsingPoolOptimizedExecuteDUnitTest.java |   235 -
 .../cache/query/cq/dunit/CqStateDUnitTest.java  |   138 -
 .../cache/query/cq/dunit/CqStatsDUnitTest.java  |   445 -
 .../dunit/CqStatsOptimizedExecuteDUnitTest.java |    50 -
 .../cq/dunit/CqStatsUsingPoolDUnitTest.java     |   456 -
 ...StatsUsingPoolOptimizedExecuteDUnitTest.java |    50 -
 .../query/cq/dunit/CqTimeTestListener.java      |   266 -
 .../PartitionedRegionCqQueryDUnitTest.java      |  1792 --
 ...dRegionCqQueryOptimizedExecuteDUnitTest.java |   246 -
 .../query/cq/dunit/PrCqUsingPoolDUnitTest.java  |  2033 --
 .../PrCqUsingPoolOptimizedExecuteDUnitTest.java |    50 -
 .../cache/query/dunit/PdxQueryCQDUnitTest.java  |   706 -
 .../cache/query/dunit/PdxQueryCQTestBase.java   |   496 -
 .../dunit/QueryIndexUpdateRIDUnitTest.java      |   815 -
 .../query/dunit/QueryMonitorDUnitTest.java      |  1299 --
 .../cache/snapshot/ClientSnapshotDUnitTest.java |   286 -
 .../AnalyzeCQSerializablesJUnitTest.java        |    79 -
 .../cache/PRDeltaPropagationDUnitTest.java      |  1183 --
 .../internal/cache/PutAllCSDUnitTest.java       |  4426 -----
 .../cache/RemoteCQTransactionDUnitTest.java     |  1119 --
 .../internal/cache/ha/CQListGIIDUnitTest.java   |   812 -
 .../cache/ha/HADispatcherDUnitTest.java         |   692 -
 .../sockets/ClientToServerDeltaDUnitTest.java   |   984 -
 .../DeltaPropagationWithCQDUnitTest.java        |   337 -
 ...ToRegionRelationCQRegistrationDUnitTest.java |   754 -
 .../sockets/DurableClientCrashDUnitTest.java    |    99 -
 .../sockets/DurableClientNetDownDUnitTest.java  |    79 -
 .../sockets/DurableClientSimpleDUnitTest.java   |  3343 ----
 .../tier/sockets/DurableClientTestCase.java     |  2058 --
 .../CacheServerManagementDUnitTest.java         |   574 -
 .../cli/commands/ClientCommandsDUnitTest.java   |  1446 --
 .../DurableClientCommandsDUnitTest.java         |   436 -
 .../internal/pulse/TestCQDUnitTest.java         |   145 -
 .../internal/pulse/TestClientsDUnitTest.java    |   106 -
 .../internal/pulse/TestServerDUnitTest.java     |    97 -
 .../ClientAuthorizationTwoDUnitTest.java        |   239 -
 .../security/ClientAuthzObjectModDUnitTest.java |   412 -
 .../ClientCQPostAuthorizationDUnitTest.java     |   511 -
 .../ClientPostAuthorizationDUnitTest.java       |   390 -
 .../gemfire/security/MultiuserAPIDUnitTest.java |   383 -
 .../MultiuserDurableCQAuthzDUnitTest.java       |   477 -
 .../gemfire/codeAnalysis/excludedClasses.txt    |     2 -
 .../gemstone/gemfire/codeAnalysis/openBugs.txt  |    21 -
 .../sanctionedDataSerializables.txt             |     4 -
 .../codeAnalysis/sanctionedSerializables.txt    |     1 -
 .../tier/sockets/durablecq-client-cache.xml     |    37 -
 .../tier/sockets/durablecq-server-cache.xml     |    32 -
 .../java/joptsimple/AbstractOptionSpec.java     |   127 -
 .../joptsimple/AlternativeLongOptionSpec.java   |    54 -
 .../joptsimple/ArgumentAcceptingOptionSpec.java |   349 -
 .../src/main/java/joptsimple/ArgumentList.java  |    59 -
 .../java/joptsimple/BuiltinHelpFormatter.java   |   149 -
 .../src/main/java/joptsimple/HelpFormatter.java |    45 -
 .../IllegalOptionSpecificationException.java    |    52 -
 .../MissingRequiredOptionException.java         |    52 -
 .../MultipleArgumentsForOptionException.java    |    52 -
 .../java/joptsimple/NoArgumentOptionSpec.java   |    82 -
 .../OptionArgumentConversionException.java      |    63 -
 .../main/java/joptsimple/OptionDescriptor.java  |    94 -
 .../main/java/joptsimple/OptionException.java   |   111 -
 .../OptionMissingRequiredArgumentException.java |    52 -
 .../src/main/java/joptsimple/OptionParser.java  |   568 -
 .../main/java/joptsimple/OptionParserState.java |    81 -
 .../src/main/java/joptsimple/OptionSet.java     |   309 -
 .../src/main/java/joptsimple/OptionSpec.java    |    98 -
 .../main/java/joptsimple/OptionSpecBuilder.java |    96 -
 .../java/joptsimple/OptionSpecTokenizer.java    |   127 -
 .../joptsimple/OptionalArgumentOptionSpec.java  |    69 -
 .../src/main/java/joptsimple/ParserRules.java   |    84 -
 .../joptsimple/RequiredArgumentOptionSpec.java  |    54 -
 .../joptsimple/UnrecognizedOptionException.java |    52 -
 .../joptsimple/ValueConversionException.java    |    54 -
 .../main/java/joptsimple/ValueConverter.java    |    58 -
 .../joptsimple/internal/AbbreviationMap.java    |   233 -
 .../main/java/joptsimple/internal/Classes.java  |    74 -
 .../main/java/joptsimple/internal/Column.java   |   133 -
 .../internal/ColumnWidthCalculator.java         |    41 -
 .../java/joptsimple/internal/ColumnarData.java  |   163 -
 .../ConstructorInvokingValueConverter.java      |    58 -
 .../internal/MethodInvokingValueConverter.java  |    60 -
 .../main/java/joptsimple/internal/Objects.java  |    46 -
 .../java/joptsimple/internal/Reflection.java    |   143 -
 .../internal/ReflectionException.java           |    39 -
 .../main/java/joptsimple/internal/Strings.java  |   117 -
 .../java/joptsimple/util/DateConverter.java     |   104 -
 .../main/java/joptsimple/util/KeyValuePair.java |    83 -
 .../main/java/joptsimple/util/RegexMatcher.java |    88 -
 gemfire-json/src/main/java/org/json/CDL.java    |   279 -
 gemfire-json/src/main/java/org/json/Cookie.java |   169 -
 .../src/main/java/org/json/CookieList.java      |    90 -
 gemfire-json/src/main/java/org/json/HTTP.java   |   163 -
 .../src/main/java/org/json/HTTPTokener.java     |    77 -
 .../src/main/java/org/json/JSONArray.java       |   906 -
 .../src/main/java/org/json/JSONException.java   |    28 -
 gemfire-json/src/main/java/org/json/JSONML.java |   467 -
 .../src/main/java/org/json/JSONObject.java      |  1611 --
 .../src/main/java/org/json/JSONString.java      |    18 -
 .../src/main/java/org/json/JSONStringer.java    |    78 -
 .../src/main/java/org/json/JSONTokener.java     |   446 -
 .../src/main/java/org/json/JSONWriter.java      |   327 -
 gemfire-json/src/main/java/org/json/XML.java    |   508 -
 .../src/main/java/org/json/XMLTokener.java      |   365 -
 gemfire-junit/build.gradle                      |    21 -
 .../gemfire/test/junit/ConditionalIgnore.java   |    49 -
 .../gemfire/test/junit/IgnoreCondition.java     |    32 -
 .../gemfire/test/junit/IgnoreUntil.java         |    49 -
 .../com/gemstone/gemfire/test/junit/Repeat.java |    43 -
 .../com/gemstone/gemfire/test/junit/Retry.java  |    38 -
 .../test/junit/categories/ContainerTest.java    |    25 -
 .../test/junit/categories/DistributedTest.java  |    25 -
 .../categories/DistributedTransactionsTest.java |    26 -
 .../test/junit/categories/HydraTest.java        |    24 -
 .../test/junit/categories/IntegrationTest.java  |    25 -
 .../test/junit/categories/PerformanceTest.java  |    25 -
 .../gemfire/test/junit/categories/UITest.java   |    24 -
 .../gemfire/test/junit/categories/UnitTest.java |    25 -
 .../gemfire/test/junit/categories/WanTest.java  |    24 -
 .../test/junit/rules/ConditionalIgnoreRule.java |   123 -
 .../test/junit/rules/ExpectedTimeout.java       |   180 -
 .../test/junit/rules/ExpectedTimeoutRule.java   |   180 -
 .../test/junit/rules/IgnoreUntilRule.java       |   123 -
 .../gemfire/test/junit/rules/RepeatRule.java    |    81 -
 .../gemfire/test/junit/rules/RetryRule.java     |   181 -
 .../rules/SerializableExternalResource.java     |   107 -
 .../test/junit/rules/SerializableRuleChain.java |   119 -
 .../rules/SerializableTemporaryFolder.java      |    70 -
 .../test/junit/rules/SerializableTestName.java  |    54 -
 .../test/junit/rules/SerializableTestRule.java  |    33 -
 .../junit/rules/SerializableTestWatcher.java    |    29 -
 .../test/junit/rules/SerializableTimeout.java   |   119 -
 .../junit/support/DefaultIgnoreCondition.java   |    57 -
 .../IgnoreConditionEvaluationException.java     |    43 -
 .../junit/rules/ExpectedTimeoutJUnitTest.java   |   204 -
 .../examples/RepeatingTestCasesExampleTest.java |    94 -
 .../rules/examples/RetryRuleExampleTest.java    |    43 -
 .../rules/tests/ExpectedTimeoutRuleTest.java    |   214 -
 .../junit/rules/tests/IgnoreUntilRuleTest.java  |   121 -
 .../junit/rules/tests/JUnitRuleTestSuite.java   |    33 -
 .../test/junit/rules/tests/RepeatRuleTest.java  |   304 -
 .../tests/RetryRuleGlobalWithErrorTest.java     |   250 -
 .../tests/RetryRuleGlobalWithExceptionTest.java |   254 -
 .../tests/RetryRuleLocalWithErrorTest.java      |   207 -
 .../tests/RetryRuleLocalWithExceptionTest.java  |   213 -
 .../junit/rules/tests/RuleAndClassRuleTest.java |   138 -
 .../test/junit/rules/tests/TestRunner.java      |    37 -
 gemfire-lucene/build.gradle                     |    40 -
 .../gemfire/cache/lucene/LuceneIndex.java       |    60 -
 .../gemfire/cache/lucene/LuceneQuery.java       |    48 -
 .../cache/lucene/LuceneQueryFactory.java        |   100 -
 .../cache/lucene/LuceneQueryProvider.java       |    45 -
 .../cache/lucene/LuceneQueryResults.java        |    58 -
 .../cache/lucene/LuceneResultStruct.java        |    62 -
 .../gemfire/cache/lucene/LuceneService.java     |   118 -
 .../cache/lucene/LuceneServiceProvider.java     |    46 -
 .../lucene/internal/InternalLuceneIndex.java    |    29 -
 .../lucene/internal/InternalLuceneService.java  |    29 -
 .../lucene/internal/LuceneEventListener.java    |    99 -
 .../LuceneIndexForPartitionedRegion.java        |   136 -
 .../LuceneIndexForReplicatedRegion.java         |    48 -
 .../cache/lucene/internal/LuceneIndexImpl.java  |   107 -
 .../lucene/internal/LuceneQueryFactoryImpl.java |    67 -
 .../cache/lucene/internal/LuceneQueryImpl.java  |    87 -
 .../lucene/internal/LuceneQueryResultsImpl.java |   120 -
 .../lucene/internal/LuceneResultStructImpl.java |    94 -
 .../lucene/internal/LuceneServiceImpl.java      |   273 -
 .../internal/PartitionedRepositoryManager.java  |   163 -
 .../lucene/internal/StringQueryProvider.java    |   106 -
 .../internal/directory/FileIndexInput.java      |   131 -
 .../internal/directory/RegionDirectory.java     |   119 -
 .../internal/distributed/CollectorManager.java  |    55 -
 .../lucene/internal/distributed/EntryScore.java |    82 -
 .../internal/distributed/LuceneFunction.java    |   137 -
 .../distributed/LuceneFunctionContext.java      |   115 -
 .../lucene/internal/distributed/TopEntries.java |   133 -
 .../distributed/TopEntriesCollector.java        |   102 -
 .../distributed/TopEntriesCollectorManager.java |   178 -
 .../TopEntriesFunctionCollector.java            |   163 -
 .../lucene/internal/filesystem/ChunkKey.java    |   123 -
 .../cache/lucene/internal/filesystem/File.java  |   155 -
 .../internal/filesystem/FileInputStream.java    |   166 -
 .../internal/filesystem/FileOutputStream.java   |   103 -
 .../lucene/internal/filesystem/FileSystem.java  |   156 -
 .../filesystem/SeekableInputStream.java         |    43 -
 .../internal/repository/IndexRepository.java    |    74 -
 .../repository/IndexRepositoryImpl.java         |   113 -
 .../repository/IndexResultCollector.java        |    47 -
 .../internal/repository/RepositoryManager.java  |    44 -
 .../HeterogenousLuceneSerializer.java           |    83 -
 .../repository/serializer/LuceneSerializer.java |    35 -
 .../serializer/PdxLuceneSerializer.java         |    47 -
 .../serializer/ReflectionLuceneSerializer.java  |    74 -
 .../repository/serializer/SerializerUtil.java   |   168 -
 .../internal/xml/LuceneIndexCreation.java       |   111 -
 .../internal/xml/LuceneIndexXmlGenerator.java   |    65 -
 .../internal/xml/LuceneServiceXmlGenerator.java |    39 -
 .../lucene/internal/xml/LuceneXmlConstants.java |    31 -
 .../lucene/internal/xml/LuceneXmlParser.java    |    97 -
 .../geode.apache.org/lucene/lucene-1.0.xsd      |    57 -
 ...gemstone.gemfire.internal.cache.CacheService |     1 -
 ...ne.gemfire.internal.cache.xmlcache.XmlParser |     1 -
 .../internal/LuceneEventListenerJUnitTest.java  |   109 -
 .../LuceneIndexRecoveryHAJUnitTest.java         |   201 -
 .../LuceneQueryFactoryImplJUnitTest.java        |    50 -
 .../internal/LuceneQueryImplJUnitTest.java      |   123 -
 .../LuceneQueryResultsImplJUnitTest.java        |   126 -
 .../LuceneResultStructImpJUnitTest.java         |    51 -
 .../internal/LuceneServiceImplJUnitTest.java    |   226 -
 .../PartitionedRepositoryManagerJUnitTest.java  |   230 -
 .../internal/StringQueryProviderJUnitTest.java  |    90 -
 .../directory/RegionDirectoryJUnitTest.java     |    56 -
 .../DistributedScoringJUnitTest.java            |   155 -
 .../distributed/EntryScoreJUnitTest.java        |    40 -
 .../LuceneFunctionContextJUnitTest.java         |    64 -
 .../distributed/LuceneFunctionJUnitTest.java    |   423 -
 .../LuceneFunctionReadPathDUnitTest.java        |   240 -
 .../TopEntriesCollectorJUnitTest.java           |   139 -
 .../TopEntriesFunctionCollectorJUnitTest.java   |   323 -
 .../distributed/TopEntriesJUnitTest.java        |   146 -
 .../internal/filesystem/ChunkKeyJUnitTest.java  |    48 -
 .../internal/filesystem/FileJUnitTest.java      |    53 -
 .../filesystem/FileSystemJUnitTest.java         |   578 -
 .../IndexRepositoryImplJUnitTest.java           |   208 -
 .../IndexRepositoryImplPerformanceTest.java     |   439 -
 .../HeterogenousLuceneSerializerJUnitTest.java  |    90 -
 .../serializer/PdxFieldMapperJUnitTest.java     |    85 -
 .../ReflectionFieldMapperJUnitTest.java         |    85 -
 .../internal/repository/serializer/Type1.java   |    48 -
 .../internal/repository/serializer/Type2.java   |    34 -
 ...neIndexXmlGeneratorIntegrationJUnitTest.java |    78 -
 .../xml/LuceneIndexXmlGeneratorJUnitTest.java   |    80 -
 ...uceneIndexXmlParserIntegrationJUnitTest.java |   107 -
 .../xml/LuceneIndexXmlParserJUnitTest.java      |    72 -
 ...erIntegrationJUnitTest.createIndex.cache.xml |    41 -
 ...serIntegrationJUnitTest.parseIndex.cache.xml |    41 -
 gemfire-pulse/build.gradle                      |    98 -
 .../tools/pulse/internal/PulseAppListener.java  |   703 -
 .../controllers/ExceptionHandlingAdvice.java    |    52 -
 .../internal/controllers/PulseController.java   |   587 -
 .../tools/pulse/internal/data/Cluster.java      |  3826 ----
 .../tools/pulse/internal/data/DataBrowser.java  |   281 -
 .../pulse/internal/data/IClusterUpdater.java    |    37 -
 .../pulse/internal/data/JMXDataUpdater.java     |  2455 ---
 .../pulse/internal/data/JmxManagerFinder.java   |   171 -
 .../tools/pulse/internal/data/PulseConfig.java  |   126 -
 .../pulse/internal/data/PulseConstants.java     |   421 -
 .../tools/pulse/internal/data/PulseVersion.java |   104 -
 .../tools/pulse/internal/data/Repository.java   |   215 -
 .../gemfire/tools/pulse/internal/json/CDL.java  |   274 -
 .../tools/pulse/internal/json/Cookie.java       |   164 -
 .../tools/pulse/internal/json/CookieList.java   |    85 -
 .../gemfire/tools/pulse/internal/json/HTTP.java |   158 -
 .../tools/pulse/internal/json/HTTPTokener.java  |    72 -
 .../tools/pulse/internal/json/JSONArray.java    |   901 -
 .../pulse/internal/json/JSONException.java      |    47 -
 .../tools/pulse/internal/json/JSONML.java       |   462 -
 .../tools/pulse/internal/json/JSONObject.java   |  1585 --
 .../tools/pulse/internal/json/JSONString.java   |    37 -
 .../tools/pulse/internal/json/JSONStringer.java |    73 -
 .../tools/pulse/internal/json/JSONTokener.java  |   441 -
 .../tools/pulse/internal/json/JSONWriter.java   |   322 -
 .../gemfire/tools/pulse/internal/json/README    |    68 -
 .../gemfire/tools/pulse/internal/json/XML.java  |   503 -
 .../tools/pulse/internal/json/XMLTokener.java   |   360 -
 .../tools/pulse/internal/log/LogWriter.java     |   266 -
 .../pulse/internal/log/MessageFormatter.java    |   103 -
 .../pulse/internal/log/PulseLogWriter.java      |   306 -
 .../tools/pulse/internal/log/PulseLogger.java   |   144 -
 .../internal/service/ClusterDetailsService.java |   109 -
 .../service/ClusterDiskThroughputService.java   |    79 -
 .../service/ClusterGCPausesService.java         |    71 -
 .../service/ClusterKeyStatisticsService.java    |    79 -
 .../internal/service/ClusterMemberService.java  |   132 -
 .../service/ClusterMembersRGraphService.java    |   372 -
 .../service/ClusterMemoryUsageService.java      |    70 -
 .../internal/service/ClusterRegionService.java  |   241 -
 .../internal/service/ClusterRegionsService.java |   243 -
 .../service/ClusterSelectedRegionService.java   |   278 -
 .../ClusterSelectedRegionsMemberService.java    |   146 -
 .../internal/service/ClusterWANInfoService.java |    82 -
 .../service/MemberAsynchEventQueuesService.java |   107 -
 .../internal/service/MemberClientsService.java  |   123 -
 .../internal/service/MemberDetailsService.java  |   128 -
 .../service/MemberDiskThroughputService.java    |    93 -
 .../internal/service/MemberGCPausesService.java |    85 -
 .../service/MemberGatewayHubService.java        |   163 -
 .../service/MemberHeapUsageService.java         |    85 -
 .../service/MemberKeyStatisticsService.java     |    98 -
 .../internal/service/MemberRegionsService.java  |   140 -
 .../internal/service/MembersListService.java    |    77 -
 .../pulse/internal/service/PulseService.java    |    42 -
 .../internal/service/PulseServiceFactory.java   |    56 -
 .../internal/service/PulseVersionService.java   |    74 -
 .../service/QueryStatisticsService.java         |   152 -
 .../internal/service/SystemAlertsService.java   |   134 -
 .../pulse/internal/util/ConnectionUtil.java     |    47 -
 .../pulse/internal/util/IPAddressUtil.java      |    66 -
 .../tools/pulse/internal/util/StringUtils.java  |    86 -
 .../tools/pulse/internal/util/TimeUtils.java    |   121 -
 .../main/resources/LogMessages_en_US.properties |    97 -
 .../main/resources/LogMessages_fr_FR.properties |    91 -
 .../src/main/resources/default.properties       |    23 -
 .../src/main/resources/gemfire.properties       |    47 -
 .../src/main/resources/pulse-users.properties   |    30 -
 .../src/main/resources/pulse.properties         |    54 -
 .../src/main/resources/pulsesecurity.properties |    26 -
 .../src/main/resources/sqlfire.properties       |    47 -
 gemfire-pulse/src/main/webapp/DataBrowser.html  |   345 -
 gemfire-pulse/src/main/webapp/Login.html        |   114 -
 .../src/main/webapp/META-INF/MANIFEST.MF        |     3 -
 .../src/main/webapp/MemberDetails.html          |   603 -
 .../src/main/webapp/QueryStatistics.html        |   308 -
 .../webapp/WEB-INF/mvc-dispatcher-servlet.xml   |    35 -
 .../src/main/webapp/WEB-INF/spring-security.xml |    83 -
 gemfire-pulse/src/main/webapp/WEB-INF/web.xml   |    62 -
 .../src/main/webapp/clusterDetail.html          |   662 -
 .../src/main/webapp/css/ForceDirected.css       |    46 -
 gemfire-pulse/src/main/webapp/css/Treemap.css   |   134 -
 gemfire-pulse/src/main/webapp/css/base.css      |    74 -
 gemfire-pulse/src/main/webapp/css/common.css    |   240 -
 .../webapp/css/fonts/DroidSans-Bold-webfont.eot |   Bin 43462 -> 0 bytes
 .../webapp/css/fonts/DroidSans-Bold-webfont.svg |   271 -
 .../webapp/css/fonts/DroidSans-Bold-webfont.ttf |   Bin 43260 -> 0 bytes
 .../css/fonts/DroidSans-Bold-webfont.woff       |   Bin 27120 -> 0 bytes
 .../main/webapp/css/fonts/DroidSans-webfont.eot |   Bin 44926 -> 0 bytes
 .../main/webapp/css/fonts/DroidSans-webfont.svg |   271 -
 .../main/webapp/css/fonts/DroidSans-webfont.ttf |   Bin 44712 -> 0 bytes
 .../webapp/css/fonts/DroidSans-webfont.woff     |   Bin 27672 -> 0 bytes
 .../src/main/webapp/css/grid/ui.jqgrid.css      |   850 -
 .../src/main/webapp/css/grips/horizontal.png    |   Bin 2753 -> 0 bytes
 .../src/main/webapp/css/grips/vertical.png      |   Bin 91 -> 0 bytes
 gemfire-pulse/src/main/webapp/css/ie/ie.css     |    19 -
 gemfire-pulse/src/main/webapp/css/ie/ie7.css    |    21 -
 gemfire-pulse/src/main/webapp/css/ie/ie8.css    |    20 -
 gemfire-pulse/src/main/webapp/css/ie/ie9.css    |    20 -
 gemfire-pulse/src/main/webapp/css/jquery-ui.css |   566 -
 .../src/main/webapp/css/jquery.jscrollpane.css  |   121 -
 .../src/main/webapp/css/jquery.ui.all.css       |    11 -
 .../src/main/webapp/css/jquery.ui.core.css      |    41 -
 .../src/main/webapp/css/jquery.ui.theme.css     |   248 -
 .../src/main/webapp/css/jquery.ztreestyle.css   |    90 -
 .../css/multiselect/jquery.multiselect.css      |   301 -
 .../main/webapp/css/multiselect/prettify.css    |    46 -
 .../src/main/webapp/css/multiselect/style.css   |    35 -
 gemfire-pulse/src/main/webapp/css/popup.css     |    55 -
 gemfire-pulse/src/main/webapp/css/style.css     |  3105 ---
 .../src/main/webapp/css/treeView/Treemap.css    |   134 -
 .../src/main/webapp/images/about-gemfirexd.png  |   Bin 4440 -> 0 bytes
 .../src/main/webapp/images/about-geode.png      |   Bin 7640 -> 0 bytes
 .../src/main/webapp/images/about-sqlfire.png    |   Bin 6277 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/about.png  |   Bin 4421 -> 0 bytes
 .../src/main/webapp/images/acc-minus.png        |   Bin 1049 -> 0 bytes
 .../src/main/webapp/images/acc-n-minus.png      |   Bin 961 -> 0 bytes
 .../src/main/webapp/images/acc-n-plus.png       |   Bin 988 -> 0 bytes
 .../src/main/webapp/images/acc-plus.png         |   Bin 1047 -> 0 bytes
 .../src/main/webapp/images/activeServer.png     |   Bin 2846 -> 0 bytes
 .../main/webapp/images/apache_geode_logo.png    |   Bin 23616 -> 0 bytes
 .../src/main/webapp/images/arrow-down.png       |   Bin 986 -> 0 bytes
 .../src/main/webapp/images/arrow-up.png         |   Bin 988 -> 0 bytes
 .../src/main/webapp/images/bg-image.png         |   Bin 948 -> 0 bytes
 .../src/main/webapp/images/bg-imageLogin.png    |   Bin 946 -> 0 bytes
 .../src/main/webapp/images/blue-msg-icon.png    |   Bin 1194 -> 0 bytes
 .../src/main/webapp/images/border-left-grid.png |   Bin 927 -> 0 bytes
 .../src/main/webapp/images/bread-crumb.png      |   Bin 1182 -> 0 bytes
 .../src/main/webapp/images/bubble_arrow.png     |   Bin 1168 -> 0 bytes
 .../src/main/webapp/images/chart-active.png     |   Bin 1096 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/chart.png  |   Bin 1095 -> 0 bytes
 .../src/main/webapp/images/checkbox.png         |   Bin 1630 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/chkbox.png |   Bin 1313 -> 0 bytes
 .../src/main/webapp/images/copy_icon.png        |   Bin 1172 -> 0 bytes
 .../src/main/webapp/images/correct_icon.png     |   Bin 1143 -> 0 bytes
 .../main/webapp/images/correct_small_icon.png   |   Bin 1065 -> 0 bytes
 .../main/webapp/images/correct_white_icon.png   |   Bin 1122 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/cross.png  |   Bin 2954 -> 0 bytes
 .../main/webapp/images/dataViewWanEnabled.png   |   Bin 1204 -> 0 bytes
 .../src/main/webapp/images/dd_active.png        |   Bin 1065 -> 0 bytes
 .../src/main/webapp/images/dd_arrow.png         |   Bin 1058 -> 0 bytes
 .../webapp/images/error-locators-others.png     |   Bin 2052 -> 0 bytes
 .../src/main/webapp/images/error-locators.png   |   Bin 2023 -> 0 bytes
 .../images/error-manager-locator-others.png     |   Bin 2067 -> 0 bytes
 .../webapp/images/error-manager-locator.png     |   Bin 2047 -> 0 bytes
 .../webapp/images/error-managers-others.png     |   Bin 2051 -> 0 bytes
 .../src/main/webapp/images/error-managers.png   |   Bin 2025 -> 0 bytes
 .../main/webapp/images/error-message-icon.png   |   Bin 1193 -> 0 bytes
 .../src/main/webapp/images/error-msg-icon.png   |   Bin 1194 -> 0 bytes
 .../src/main/webapp/images/error-others.png     |   Bin 2066 -> 0 bytes
 .../src/main/webapp/images/error-otheruser.png  |   Bin 2002 -> 0 bytes
 .../main/webapp/images/error-status-icon.png    |   Bin 2024 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/error.png  |   Bin 1110 -> 0 bytes
 .../src/main/webapp/images/graph-active.png     |   Bin 1360 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/graph.png  |   Bin 1374 -> 0 bytes
 .../images/graph/key-statistics-graph.png       |   Bin 1617 -> 0 bytes
 .../webapp/images/graph/memory-usage-graph.png  |   Bin 4366 -> 0 bytes
 .../src/main/webapp/images/graph/reads.png      |   Bin 3423 -> 0 bytes
 .../images/graph/throughput-writes-graph.png    |   Bin 4340 -> 0 bytes
 .../src/main/webapp/images/graph/topology.png   |   Bin 14997 -> 0 bytes
 .../src/main/webapp/images/graph/treeview.png   |   Bin 3386 -> 0 bytes
 .../src/main/webapp/images/graph/writes.png     |   Bin 3527 -> 0 bytes
 .../src/main/webapp/images/grid-active.png      |   Bin 1095 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/grid.png   |   Bin 1094 -> 0 bytes
 .../webapp/images/header-bg-bottom-border.png   |   Bin 924 -> 0 bytes
 .../src/main/webapp/images/hide_ico.png         |   Bin 3281 -> 0 bytes
 .../src/main/webapp/images/history-icon.png     |   Bin 3533 -> 0 bytes
 .../src/main/webapp/images/history-remove.png   |   Bin 1185 -> 0 bytes
 .../src/main/webapp/images/hor-spiltter-dot.png |   Bin 990 -> 0 bytes
 .../webapp/images/icons members/locators.png    |   Bin 3106 -> 0 bytes
 .../images/icons members/locators_others.png    |   Bin 3118 -> 0 bytes
 .../webapp/images/icons members/managers.png    |   Bin 3103 -> 0 bytes
 .../images/icons members/managers_locators.png  |   Bin 3120 -> 0 bytes
 .../images/icons members/managers_others.png    |   Bin 3117 -> 0 bytes
 .../main/webapp/images/icons members/others.png |   Bin 3102 -> 0 bytes
 .../src/main/webapp/images/info-msg-icon.png    |   Bin 1194 -> 0 bytes
 .../src/main/webapp/images/lastLine.png         |   Bin 948 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/line.png   |   Bin 929 -> 0 bytes
 .../src/main/webapp/images/mask-bg.png          |   Bin 940 -> 0 bytes
 .../webapp/images/membersName_arror-off.png     |   Bin 1148 -> 0 bytes
 .../main/webapp/images/membersName_arror-on.png |   Bin 1170 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/minus.png  |   Bin 2959 -> 0 bytes
 .../webapp/images/normal-locators-others.png    |   Bin 2025 -> 0 bytes
 .../src/main/webapp/images/normal-locators.png  |   Bin 1995 -> 0 bytes
 .../images/normal-manager-locator-others.png    |   Bin 2037 -> 0 bytes
 .../webapp/images/normal-manager-locator.png    |   Bin 2029 -> 0 bytes
 .../webapp/images/normal-managers-others.png    |   Bin 2027 -> 0 bytes
 .../src/main/webapp/images/normal-managers.png  |   Bin 1997 -> 0 bytes
 .../src/main/webapp/images/normal-others.png    |   Bin 1988 -> 0 bytes
 .../src/main/webapp/images/normal-otheruser.png |   Bin 1968 -> 0 bytes
 .../main/webapp/images/normal-status-icon.png   |   Bin 1955 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/normal.png |   Bin 1110 -> 0 bytes
 .../src/main/webapp/images/orange-msg-icon.png  |   Bin 1194 -> 0 bytes
 .../src/main/webapp/images/pivotal-logo.png     |   Bin 3500 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/plus.png   |   Bin 1178 -> 0 bytes
 .../src/main/webapp/images/plusMinusIcon.png    |   Bin 1192 -> 0 bytes
 .../src/main/webapp/images/popup-arrow.png      |   Bin 1075 -> 0 bytes
 .../main/webapp/images/popup-close-button.png   |   Bin 1026 -> 0 bytes
 .../images/pulse-monitoring-gemfirexd-old.png   |   Bin 6606 -> 0 bytes
 .../images/pulse-monitoring-gemfirexd.png       |   Bin 4440 -> 0 bytes
 .../webapp/images/pulse-monitoring-sqlfire.png  |   Bin 6467 -> 0 bytes
 .../src/main/webapp/images/pulse-monitoring.png |   Bin 4741 -> 0 bytes
 .../src/main/webapp/images/radio-off.png        |   Bin 1252 -> 0 bytes
 .../src/main/webapp/images/radio-on.png         |   Bin 1306 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/radio.png  |   Bin 2476 -> 0 bytes
 .../src/main/webapp/images/regionIcons.png      |   Bin 1495 -> 0 bytes
 .../src/main/webapp/images/rightBorder.png      |   Bin 927 -> 0 bytes
 .../src/main/webapp/images/searchIcon.png       |   Bin 1592 -> 0 bytes
 .../src/main/webapp/images/seperator.png        |   Bin 929 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/server.png |   Bin 1233 -> 0 bytes
 .../webapp/images/severe-locators-others.png    |   Bin 2026 -> 0 bytes
 .../src/main/webapp/images/severe-locators.png  |   Bin 1980 -> 0 bytes
 .../images/severe-manager-locator-others.png    |   Bin 2032 -> 0 bytes
 .../webapp/images/severe-manager-locator.png    |   Bin 2026 -> 0 bytes
 .../webapp/images/severe-managers-others.png    |   Bin 2026 -> 0 bytes
 .../src/main/webapp/images/severe-managers.png  |   Bin 1985 -> 0 bytes
 .../src/main/webapp/images/severe-msg-icon.png  |   Bin 1194 -> 0 bytes
 .../src/main/webapp/images/severe-others.png    |   Bin 2007 -> 0 bytes
 .../src/main/webapp/images/severe-otheruser.png |   Bin 1959 -> 0 bytes
 .../main/webapp/images/severe-status-icon.png   |   Bin 2218 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/severe.png |   Bin 1110 -> 0 bytes
 .../src/main/webapp/images/show_ico.png         |   Bin 3296 -> 0 bytes
 gemfire-pulse/src/main/webapp/images/spacer.png |   Bin 922 -> 0 bytes
 .../src/main/webapp/images/sqlfire.png          |   Bin 6467 -> 0 bytes
 .../src/main/webapp/images/status-down.png      |   Bin 1125 -> 0 bytes
 .../src/main/webapp/images/status-up.png        |   Bin 1104 -> 0 bytes
 .../src/main/webapp/images/subServer.png        |   Bin 2201 -> 0 bytes
 .../src/main/webapp/images/tab-bottom-bg.png    |   Bin 929 -> 0 bytes
 .../src/main/webapp/images/treeView-img.png     |   Bin 962 -> 0 bytes
 .../main/webapp/images/ui-anim_basic_16x16.gif  |   Bin 1459 -> 0 bytes
 .../src/main/webapp/images/ver-spiltter-dot.png |   Bin 979 -> 0 bytes
 .../webapp/images/warning-locators-others.png   |   Bin 2048 -> 0 bytes
 .../src/main/webapp/images/warning-locators.png |   Bin 2032 -> 0 bytes
 .../images/warning-manager-locator-others.png   |   Bin 2071 -> 0 bytes
 .../webapp/images/warning-manager-locator.png   |   Bin 2052 -> 0 bytes
 .../webapp/images/warning-managers-others.png   |   Bin 2023 -> 0 bytes
 .../src/main/webapp/images/warning-managers.png |   Bin 2030 -> 0 bytes
 .../src/main/webapp/images/warning-msg-icon.png |   Bin 1194 -> 0 bytes
 .../src/main/webapp/images/warning-others.png   |   Bin 2027 -> 0 bytes
 .../main/webapp/images/warning-otheruser.png    |   Bin 2010 -> 0 bytes
 .../main/webapp/images/warning-status-icon.png  |   Bin 1714 -> 0 bytes
 .../src/main/webapp/images/warning.png          |   Bin 1107 -> 0 bytes
 .../src/main/webapp/images/yellow-msg-icon.png  |   Bin 1194 -> 0 bytes
 gemfire-pulse/src/main/webapp/index.html        |    67 -
 .../main/webapp/properties/default.properties   |    21 -
 .../webapp/properties/default_en.properties     |    21 -
 .../main/webapp/properties/gemfire.properties   |    45 -
 .../webapp/properties/gemfire_en.properties     |    45 -
 .../main/webapp/properties/gemfirexd.properties |    45 -
 .../webapp/properties/gemfirexd_en.properties   |    45 -
 .../src/main/webapp/properties/index.properties |    18 -
 .../main/webapp/properties/index_fr.properties  |    19 -
 .../main/webapp/properties/sqlfire.properties   |    45 -
 gemfire-pulse/src/main/webapp/regionDetail.html |   552 -
 .../src/main/webapp/scripts/lib/common.js       |   536 -
 .../src/main/webapp/scripts/lib/excanvas.js     |  1416 --
 .../main/webapp/scripts/lib/grid.locale-en.js   |   169 -
 .../src/main/webapp/scripts/lib/html5.js        |     3 -
 .../src/main/webapp/scripts/lib/jit.js          | 17208 -----------------
 .../src/main/webapp/scripts/lib/jquery-1.7.2.js |  9404 ---------
 .../webapp/scripts/lib/jquery.generateFile.js   |    77 -
 .../scripts/lib/jquery.i18n.properties.js       |   336 -
 .../webapp/scripts/lib/jquery.jqGrid.src.js     | 12182 ------------
 .../webapp/scripts/lib/jquery.jscrollpane.js    |  1340 --
 .../webapp/scripts/lib/jquery.mousewheel.js     |    84 -
 .../webapp/scripts/lib/jquery.placeholder.js    |   106 -
 .../main/webapp/scripts/lib/jquery.sparkline.js |  3001 ---
 .../main/webapp/scripts/lib/jquery.tablednd.js  |   383 -
 .../main/webapp/scripts/lib/jquery.timeago.js   |   193 -
 .../webapp/scripts/lib/jquery.ztree.core-3.5.js |  1650 --
 .../scripts/lib/jquery.ztree.excheck-3.5.js     |   624 -
 .../src/main/webapp/scripts/lib/split.js        |   375 -
 .../src/main/webapp/scripts/lib/tooltip.js      |   357 -
 .../webapp/scripts/multiselect/jquery-ui.js     | 14988 --------------
 .../scripts/multiselect/jquery.multiselect.js   |   816 -
 .../main/webapp/scripts/multiselect/prettify.js |  1522 --
 .../webapp/scripts/pulsescript/MemberDetails.js |  1045 -
 .../scripts/pulsescript/PulseCallbacks.js       |  1735 --
 .../scripts/pulsescript/PulseFunctions.js       |   227 -
 .../webapp/scripts/pulsescript/clusterDetail.js |  2370 ---
 .../scripts/pulsescript/clusterRGraphMembers.js |  1515 --
 .../main/webapp/scripts/pulsescript/common.js   |  1626 --
 .../scripts/pulsescript/pages/DataBrowser.js    |   667 -
 .../pulsescript/pages/DataBrowserQuery.js       |   964 -
 .../pages/DataBrowserQueryHistory.js            |    95 -
 .../webapp/scripts/pulsescript/pages/Login.js   |   170 -
 .../webapp/scripts/pulsescript/pages/index.js   |    26 -
 .../scripts/pulsescript/queryStatistics.js      |   315 -
 .../webapp/scripts/pulsescript/regionView.js    |   757 -
 .../pulse/testbed/GemFireDistributedSystem.java |   323 -
 .../tools/pulse/testbed/GemfireTopology.java    |    24 -
 .../tools/pulse/testbed/PropFileHelper.java     |   115 -
 .../pulse/testbed/PropMockDataUpdater.java      |   515 -
 .../gemfire/tools/pulse/testbed/TestBed.java    |    84 -
 .../tools/pulse/testbed/driver/PulseUITest.java |   284 -
 .../pulse/testbed/driver/TomcatHelper.java      |    77 -
 .../tools/pulse/tests/AggregateStatement.java   |   217 -
 .../pulse/tests/AggregateStatementMBean.java    |   168 -
 .../pulse/tests/DataBrowserResultLoader.java    |    84 -
 .../pulse/tests/GemFireXDAggregateTable.java    |    46 -
 .../tests/GemFireXDAggregateTableMBean.java     |    28 -
 .../tools/pulse/tests/GemFireXDCluster.java     |    95 -
 .../pulse/tests/GemFireXDClusterMBean.java      |    32 -
 .../tools/pulse/tests/GemFireXDMember.java      |    80 -
 .../tools/pulse/tests/GemFireXDMemberMBean.java |    31 -
 .../gemfire/tools/pulse/tests/JMXBaseBean.java  |    67 -
 .../tools/pulse/tests/JMXProperties.java        |    47 -
 .../gemfire/tools/pulse/tests/Member.java       |   193 -
 .../gemfire/tools/pulse/tests/MemberMBean.java  |    86 -
 .../tools/pulse/tests/PulseAutomatedTest.java   |   785 -
 .../tools/pulse/tests/PulseBaseTest.java        |   686 -
 .../gemfire/tools/pulse/tests/PulseTest.java    |  1056 -
 .../tools/pulse/tests/PulseTestData.java        |   106 -
 .../tools/pulse/tests/PulseTestLocators.java    |   225 -
 .../gemfire/tools/pulse/tests/Region.java       |   192 -
 .../gemfire/tools/pulse/tests/RegionMBean.java  |    59 -
 .../tools/pulse/tests/RegionOnMember.java       |    96 -
 .../tools/pulse/tests/RegionOnMemberMBean.java  |    50 -
 .../gemfire/tools/pulse/tests/Server.java       |   253 -
 .../gemfire/tools/pulse/tests/ServerObject.java |   264 -
 .../tools/pulse/tests/ServerObjectMBean.java    |    79 -
 .../gemfire/tools/pulse/tests/TomcatHelper.java |    97 -
 .../pulse/tests/junit/BaseServiceTest.java      |   250 -
 .../junit/ClusterSelectedRegionServiceTest.java |   350 -
 ...ClusterSelectedRegionsMemberServiceTest.java |   362 -
 .../junit/MemberGatewayHubServiceTest.java      |   423 -
 .../src/test/resources/NoDataFound1.txt         |     1 -
 .../src/test/resources/NoDataFound2.txt         |    35 -
 .../src/test/resources/NoDataFound3.txt         |     6 -
 gemfire-pulse/src/test/resources/message.txt    |     1 -
 .../src/test/resources/test.properties          |   326 -
 gemfire-pulse/src/test/resources/test1.txt      |     5 -
 gemfire-pulse/src/test/resources/test2.txt      |     7 -
 gemfire-pulse/src/test/resources/test3.txt      |     5 -
 gemfire-pulse/src/test/resources/test4.txt      |     4 -
 gemfire-pulse/src/test/resources/test5.txt      |     7 -
 gemfire-pulse/src/test/resources/test6.txt      |    11 -
 gemfire-pulse/src/test/resources/test7.txt      |    13 -
 .../resources/testNullObjectsAtRootLevel1.txt   |    25 -
 .../resources/testNullObjectsAtRootLevel2.txt   |    30 -
 .../src/test/resources/testQueryResult.txt      |   198 -
 .../src/test/resources/testQueryResult1000.txt  |  1023 -
 .../testQueryResultArrayAndArrayList.txt        |     8 -
 .../test/resources/testQueryResultArrayList.txt |     6 -
 .../resources/testQueryResultArrayOfList.txt    |    15 -
 .../resources/testQueryResultClusterSmall.txt   |    23 -
 .../testQueryResultClusterWithStruct.txt        |    10 -
 .../test/resources/testQueryResultHashMap.txt   |     8 -
 .../resources/testQueryResultHashMapSmall.txt   |    12 -
 .../src/test/resources/testQueryResultSmall.txt |    12 -
 .../resources/testQueryResultWithStruct.txt     |  1744 --
 .../testQueryResultWithStructSmall.txt          |    15 -
 gemfire-pulse/src/test/resources/test_pp.txt    |     7 -
 .../src/test/resources/testbed.properties       |   157 -
 gemfire-rebalancer/build.gradle                 |    28 -
 .../gemfire/cache/util/AutoBalancer.java        |   554 -
 .../util/AutoBalancerIntegrationJUnitTest.java  |   206 -
 .../cache/util/AutoBalancerJUnitTest.java       |   604 -
 gemfire-site/.gitignore                         |     1 -
 gemfire-site/website/.gitignore                 |     1 -
 gemfire-site/website/README.md                  |    54 -
 gemfire-site/website/Rules                      |    69 -
 gemfire-site/website/build.sh                   |    18 -
 .../website/content/bootstrap/bootstrap.min.css |     9 -
 .../website/content/community/index.html        |   291 -
 .../website/content/css/bootflat-extensions.css |   356 -
 .../website/content/css/bootflat-square.css     |    69 -
 gemfire-site/website/content/css/bootflat.css   |  1559 --
 .../website/content/css/font-awesome.min.css    |   405 -
 gemfire-site/website/content/css/geode-site.css |  1617 --
 gemfire-site/website/content/favicon.ico        |   Bin 20805 -> 0 bytes
 .../website/content/font/FontAwesome.otf        |   Bin 61896 -> 0 bytes
 .../content/font/fontawesome-webfont-eot.eot    |   Bin 37405 -> 0 bytes
 .../content/font/fontawesome-webfont-svg.svg    |   399 -
 .../content/font/fontawesome-webfont-ttf.ttf    |   Bin 79076 -> 0 bytes
 .../content/font/fontawesome-webfont-woff.woff  |   Bin 43572 -> 0 bytes
 .../website/content/img/apache_geode_logo.png   |   Bin 23616 -> 0 bytes
 .../content/img/apache_geode_logo_white.png     |   Bin 22695 -> 0 bytes
 .../img/apache_geode_logo_white_small.png       |   Bin 52948 -> 0 bytes
 .../website/content/img/check_flat/default.png  |   Bin 25851 -> 0 bytes
 gemfire-site/website/content/img/egg-logo.png   |   Bin 9938 -> 0 bytes
 gemfire-site/website/content/img/github.png     |   Bin 8936 -> 0 bytes
 gemfire-site/website/content/index.html         |   142 -
 .../website/content/js/bootstrap.min.js         |     8 -
 gemfire-site/website/content/js/head.js         |   708 -
 gemfire-site/website/content/js/html5shiv.js    |     8 -
 .../website/content/js/jquery-1.10.1.min.js     |     6 -
 .../website/content/js/jquery.icheck.js         |   397 -
 gemfire-site/website/content/js/respond.min.js  |     6 -
 .../website/content/js/usergrid-site.js         |    66 -
 .../website/content/releases/index.html         |   129 -
 gemfire-site/website/layouts/community.html     |     1 -
 gemfire-site/website/layouts/default.html       |    44 -
 gemfire-site/website/layouts/docs.html          |     1 -
 gemfire-site/website/layouts/footer.html        |    96 -
 gemfire-site/website/layouts/header.html        |   248 -
 gemfire-site/website/lib/default.rb             |    60 -
 gemfire-site/website/lib/helpers_.rb            |    16 -
 gemfire-site/website/lib/pandoc.template        |     4 -
 gemfire-site/website/nanoc.yaml                 |    94 -
 gemfire-site/website/run.sh                     |    18 -
 gemfire-site/website/utilities/map-markers.rb   |    75 -
 gemfire-site/website/utilities/markers.txt      |   440 -
 .../website/utilities/snapshot-apigee.rb        |    88 -
 gemfire-spark-connector/.gitignore              |     1 -
 gemfire-spark-connector/README.md               |    32 -
 gemfire-spark-connector/doc/10_demos.md         |    84 -
 gemfire-spark-connector/doc/1_building.md       |    36 -
 gemfire-spark-connector/doc/2_quick.md          |   178 -
 gemfire-spark-connector/doc/3_connecting.md     |    55 -
 gemfire-spark-connector/doc/4_loading.md        |   108 -
 gemfire-spark-connector/doc/5_rdd_join.md       |   237 -
 gemfire-spark-connector/doc/6_save_rdd.md       |    81 -
 gemfire-spark-connector/doc/7_save_dstream.md   |    68 -
 gemfire-spark-connector/doc/8_oql.md            |    58 -
 gemfire-spark-connector/doc/9_java_api.md       |   129 -
 .../connector/internal/RegionMetadata.java      |    93 -
 .../gemfirefunctions/QueryFunction.java         |    99 -
 .../RetrieveRegionFunction.java                 |   208 -
 .../RetrieveRegionMetadataFunction.java         |   118 -
 .../StructStreamingResultSender.java            |   219 -
 .../gemfire/spark/connector/Employee.java       |    54 -
 .../spark/connector/JavaApiIntegrationTest.java |   424 -
 .../gemfire/spark/connector/Portfolio.java      |   109 -
 .../gemfire/spark/connector/Position.java       |    73 -
 .../src/it/resources/test-regions.xml           |    49 -
 .../src/it/resources/test-retrieve-regions.xml  |    57 -
 .../spark/connector/BasicIntegrationTest.scala  |   598 -
 .../RDDJoinRegionIntegrationTest.scala          |   300 -
 .../RetrieveRegionIntegrationTest.scala         |   253 -
 .../gemfire/spark/connector/package.scala       |    29 -
 .../connector/testkit/GemFireCluster.scala      |    47 -
 .../spark/connector/testkit/GemFireRunner.scala |   148 -
 .../spark/connector/testkit/IOUtils.scala       |    94 -
 .../spark/streaming/ManualClockHelper.scala     |    28 -
 .../spark/streaming/TestInputDStream.scala      |    44 -
 .../javaapi/GemFireJavaDStreamFunctions.java    |    86 -
 .../GemFireJavaPairDStreamFunctions.java        |    77 -
 .../javaapi/GemFireJavaPairRDDFunctions.java    |   238 -
 .../javaapi/GemFireJavaRDDFunctions.java        |   178 -
 .../javaapi/GemFireJavaSQLContextFunctions.java |    49 -
 .../GemFireJavaSparkContextFunctions.java       |    87 -
 .../connector/javaapi/GemFireJavaUtil.java      |   122 -
 .../spark/connector/GemFireConnection.scala     |    67 -
 .../spark/connector/GemFireConnectionConf.scala |    73 -
 .../connector/GemFireConnectionManager.scala    |    31 -
 .../connector/GemFireFunctionDeployer.scala     |    81 -
 .../connector/GemFireKryoRegistrator.scala      |    29 -
 .../connector/GemFirePairRDDFunctions.scala     |   140 -
 .../spark/connector/GemFireRDDFunctions.scala   |   120 -
 .../connector/GemFireSQLContextFunctions.scala  |    42 -
 .../GemFireSparkContextFunctions.scala          |    39 -
 .../internal/DefaultGemFireConnection.scala     |   164 -
 .../DefaultGemFireConnectionManager.scala       |    77 -
 .../connector/internal/LocatorHelper.scala      |   135 -
 .../StructStreamingResultCollector.scala        |   152 -
 .../connector/internal/oql/QueryParser.scala    |    58 -
 .../spark/connector/internal/oql/QueryRDD.scala |    83 -
 .../internal/oql/QueryResultCollector.scala     |    69 -
 .../connector/internal/oql/RDDConverter.scala   |    40 -
 .../connector/internal/oql/RowBuilder.scala     |    38 -
 .../connector/internal/oql/SchemaBuilder.scala  |    73 -
 .../internal/oql/UndefinedSerializer.scala      |    46 -
 .../connector/internal/rdd/GemFireJoinRDD.scala |    67 -
 .../internal/rdd/GemFireOuterJoinRDD.scala      |    69 -
 .../internal/rdd/GemFireRDDPartition.scala      |    36 -
 .../internal/rdd/GemFireRDDPartitioner.scala    |    59 -
 .../rdd/GemFireRDDPartitionerImpl.scala         |    89 -
 .../internal/rdd/GemFireRDDWriter.scala         |    82 -
 .../internal/rdd/GemFireRegionRDD.scala         |   138 -
 .../javaapi/GemFireJavaRegionRDD.scala          |    26 -
 .../spark/connector/javaapi/JavaAPIHelper.scala |    53 -
 .../gemfire/spark/connector/package.scala       |    69 -
 .../streaming/GemFireDStreamFunctions.scala     |    89 -
 .../spark/connector/streaming/package.scala     |    32 -
 .../gemfire/spark/connector/JavaAPITest.java    |   163 -
 .../connector/GemFireFunctionDeployerTest.scala |    58 -
 .../DefaultGemFireConnectionManagerTest.scala   |    82 -
 ...tStreamingResultSenderAndCollectorTest.scala |   254 -
 .../internal/oql/QueryParserTest.scala          |    83 -
 .../connector/ConnectorImplicitsTest.scala      |    50 -
 .../connector/GemFireConnectionConfTest.scala   |   100 -
 .../connector/GemFireDStreamFunctionsTest.scala |    79 -
 .../connector/GemFireRDDFunctionsTest.scala     |   139 -
 .../spark/connector/LocatorHelperTest.scala     |   168 -
 .../rdd/GemFireRDDPartitionerTest.scala         |   190 -
 .../connector/rdd/GemFireRegionRDDTest.scala    |   117 -
 .../basic-demos/src/main/java/demo/Emp.java     |    95 -
 .../src/main/java/demo/OQLJavaDemo.java         |    59 -
 .../src/main/java/demo/PairRDDSaveJavaDemo.java |    86 -
 .../src/main/java/demo/RDDSaveJavaDemo.java     |    85 -
 .../src/main/java/demo/RegionToRDDJavaDemo.java |    57 -
 .../src/main/scala/demo/NetworkWordCount.scala  |    75 -
 .../project/Dependencies.scala                  |    45 -
 .../project/GemFireSparkBuild.scala             |    76 -
 gemfire-spark-connector/project/Settings.scala  |    57 -
 .../project/build.properties                    |     1 -
 gemfire-spark-connector/project/plugins.sbt     |     8 -
 gemfire-spark-connector/scalastyle-config.xml   |   117 -
 gemfire-wan/build.gradle                        |    23 -
 .../client/internal/GatewaySenderBatchOp.java   |   313 -
 .../cache/client/internal/SenderProxy.java      |    43 -
 .../internal/locator/wan/LocatorDiscovery.java  |   227 -
 .../internal/locator/wan/LocatorHelper.java     |   143 -
 .../locator/wan/LocatorJoinMessage.java         |   105 -
 .../wan/LocatorMembershipListenerImpl.java      |   230 -
 .../locator/wan/RemoteLocatorJoinRequest.java   |    87 -
 .../locator/wan/RemoteLocatorJoinResponse.java  |    89 -
 .../locator/wan/RemoteLocatorPingRequest.java   |    56 -
 .../locator/wan/RemoteLocatorPingResponse.java  |    55 -
 .../locator/wan/RemoteLocatorRequest.java       |    66 -
 .../locator/wan/RemoteLocatorResponse.java      |    74 -
 .../internal/locator/wan/WANFactoryImpl.java    |    74 -
 .../locator/wan/WanLocatorDiscovererImpl.java   |   138 -
 .../cache/wan/AbstractRemoteGatewaySender.java  |   169 -
 .../cache/wan/GatewayReceiverFactoryImpl.java   |   147 -
 .../internal/cache/wan/GatewayReceiverImpl.java |   253 -
 .../wan/GatewaySenderEventRemoteDispatcher.java |   766 -
 .../cache/wan/GatewaySenderFactoryImpl.java     |   389 -
 .../wan/parallel/ParallelGatewaySenderImpl.java |   267 -
 ...rentParallelGatewaySenderEventProcessor.java |    67 -
 ...moteParallelGatewaySenderEventProcessor.java |   122 -
 ...urrentSerialGatewaySenderEventProcessor.java |    45 -
 ...RemoteSerialGatewaySenderEventProcessor.java |    50 -
 .../wan/serial/SerialGatewaySenderImpl.java     |   260 -
 ...ternal.locator.wan.LocatorMembershipListener |    15 -
 ...ne.gemfire.internal.cache.wan.spi.WANFactory |    15 -
 .../cache/CacheXml70GatewayDUnitTest.java       |   243 -
 .../cache/CacheXml80GatewayDUnitTest.java       |   137 -
 .../AnalyzeWANSerializablesJUnitTest.java       |    91 -
 .../internal/cache/UpdateVersionDUnitTest.java  |   965 -
 .../gemfire/internal/cache/wan/WANTestBase.java |  5188 -----
 ...oncurrentParallelGatewaySenderDUnitTest.java |   805 -
 ...ntParallelGatewaySenderOffHeapDUnitTest.java |    32 -
 ...allelGatewaySenderOperation_1_DUnitTest.java |   830 -
 ...allelGatewaySenderOperation_2_DUnitTest.java |   528 -
 ...tSerialGatewaySenderOperationsDUnitTest.java |   111 -
 ...GatewaySenderOperationsOffHeapDUnitTest.java |    32 -
 .../ConcurrentWANPropogation_1_DUnitTest.java   |   590 -
 .../ConcurrentWANPropogation_2_DUnitTest.java   |   466 -
 .../cache/wan/disttx/DistTXWANDUnitTest.java    |   205 -
 .../CommonParallelGatewaySenderDUnitTest.java   |   470 -
 ...onParallelGatewaySenderOffHeapDUnitTest.java |    32 -
 ...wWANConcurrencyCheckForDestroyDUnitTest.java |   514 -
 .../cache/wan/misc/PDXNewWanDUnitTest.java      |   753 -
 ...dRegion_ParallelWANPersistenceDUnitTest.java |   688 -
 ...dRegion_ParallelWANPropogationDUnitTest.java |  1074 -
 .../SenderWithTransportFilterDUnitTest.java     |   231 -
 ...downAllPersistentGatewaySenderDUnitTest.java |   199 -
 .../wan/misc/WANConfigurationJUnitTest.java     |   609 -
 .../wan/misc/WANLocatorServerDUnitTest.java     |   195 -
 .../cache/wan/misc/WANSSLDUnitTest.java         |   145 -
 .../wan/misc/WanAutoDiscoveryDUnitTest.java     |   469 -
 .../cache/wan/misc/WanValidationsDUnitTest.java |  1542 --
 ...tewaySenderOperation_2_OffHeapDUnitTest.java |    32 -
 ...tewaySenderOperation_2_OffHeapDUnitTest.java |    32 -
 ...GatewaySenderOperationsOffHeapDUnitTest.java |    34 -
 ...ewaySenderQueueOverflowOffHeapDUnitTest.java |    34 -
 .../ParallelWANConflationOffHeapDUnitTest.java  |    34 -
 ...nceEnabledGatewaySenderOffHeapDUnitTest.java |    34 -
 ...ropogationConcurrentOpsOffHeapDUnitTest.java |    34 -
 .../ParallelWANPropogationOffHeapDUnitTest.java |    34 -
 ...erialGatewaySenderQueueOffHeapDUnitTest.java |    34 -
 ...nceEnabledGatewaySenderOffHeapDUnitTest.java |    34 -
 .../SerialWANPropogationOffHeapDUnitTest.java   |    34 -
 ...ation_PartitionedRegionOffHeapDUnitTest.java |    34 -
 ...allelGatewaySenderOperation_2_DUnitTest.java |    38 -
 ...arallelGatewaySenderOperationsDUnitTest.java |   634 -
 ...llelGatewaySenderQueueOverflowDUnitTest.java |   522 -
 .../ParallelWANConflationDUnitTest.java         |   497 -
 ...ersistenceEnabledGatewaySenderDUnitTest.java |  1731 --
 ...llelWANPropagationClientServerDUnitTest.java |   108 -
 ...lelWANPropagationConcurrentOpsDUnitTest.java |   285 -
 .../ParallelWANPropagationDUnitTest.java        |  1358 --
 ...ParallelWANPropagationLoopBackDUnitTest.java |   418 -
 .../wan/parallel/ParallelWANStatsDUnitTest.java |   486 -
 ...tewaySenderDistributedDeadlockDUnitTest.java |   395 -
 ...rialGatewaySenderEventListenerDUnitTest.java |   387 -
 .../SerialGatewaySenderOperationsDUnitTest.java |   654 -
 .../SerialGatewaySenderQueueDUnitTest.java      |   333 -
 ...ersistenceEnabledGatewaySenderDUnitTest.java |   563 -
 .../SerialWANPropagationLoopBackDUnitTest.java  |   494 -
 .../serial/SerialWANPropogationDUnitTest.java   |  1501 --
 ...NPropogation_PartitionedRegionDUnitTest.java |   423 -
 .../SerialWANPropogationsFeatureDUnitTest.java  |   353 -
 .../wan/serial/SerialWANStatsDUnitTest.java     |   580 -
 .../wan/wancommand/WANCommandTestBase.java      |   513 -
 ...anCommandCreateGatewayReceiverDUnitTest.java |   623 -
 .../WanCommandCreateGatewaySenderDUnitTest.java |   700 -
 ...WanCommandGatewayReceiverStartDUnitTest.java |   273 -
 .../WanCommandGatewayReceiverStopDUnitTest.java |   278 -
 .../WanCommandGatewaySenderStartDUnitTest.java  |   399 -
 .../WanCommandGatewaySenderStopDUnitTest.java   |   352 -
 .../wan/wancommand/WanCommandListDUnitTest.java |   380 -
 .../WanCommandPauseResumeDUnitTest.java         |   683 -
 .../wancommand/WanCommandStatusDUnitTest.java   |   543 -
 .../management/WANManagementDUnitTest.java      |   501 -
 .../ClusterConfigurationDUnitTest.java          |  1057 -
 .../pulse/TestRemoteClusterDUnitTest.java       |   262 -
 .../gemfire/codeAnalysis/excludedClasses.txt    |     2 -
 .../gemstone/gemfire/codeAnalysis/openBugs.txt  |    21 -
 .../sanctionedDataSerializables.txt             |    28 -
 .../codeAnalysis/sanctionedSerializables.txt    |     0
 gemfire-web-api/build.gradle                    |    55 -
 .../web/controllers/AbstractBaseController.java |   841 -
 .../web/controllers/BaseControllerAdvice.java   |   147 -
 .../web/controllers/CommonCrudController.java   |   249 -
 .../controllers/FunctionAccessController.java   |   246 -
 .../web/controllers/PdxBasedCrudController.java |   354 -
 .../web/controllers/QueryAccessController.java  |   354 -
 .../web/controllers/support/JSONTypes.java      |    25 -
 .../controllers/support/QueryResultTypes.java   |    32 -
 .../web/controllers/support/RegionData.java     |   170 -
 .../controllers/support/RegionEntryData.java    |   105 -
 .../support/RestServersResultCollector.java     |    55 -
 .../web/controllers/support/UpdateOp.java       |    31 -
 .../DataTypeNotSupportedException.java          |    50 -
 .../web/exception/GemfireRestException.java     |    48 -
 .../web/exception/MalformedJsonException.java   |    51 -
 .../web/exception/RegionNotFoundException.java  |    44 -
 .../exception/ResourceNotFoundException.java    |    45 -
 ...stomMappingJackson2HttpMessageConverter.java |   161 -
 .../web/swagger/config/RestApiPathProvider.java |    77 -
 .../web/swagger/config/SwaggerConfig.java       |   181 -
 .../rest/internal/web/util/ArrayUtils.java      |    60 -
 .../rest/internal/web/util/DateTimeUtils.java   |    54 -
 .../internal/web/util/IdentifiableUtils.java    |   109 -
 .../rest/internal/web/util/JSONUtils.java       |   253 -
 .../rest/internal/web/util/JsonWriter.java      |   597 -
 .../rest/internal/web/util/NumberUtils.java     |   146 -
 .../rest/internal/web/util/ValidationUtils.java |    41 -
 .../main/webapp/WEB-INF/gemfire-api-servlet.xml |    85 -
 gemfire-web-api/src/main/webapp/WEB-INF/web.xml |    65 -
 .../src/main/webapp/docs/css/reset.css          |   125 -
 .../src/main/webapp/docs/css/screen.css         |  1221 --
 .../main/webapp/docs/images/explorer_icons.png  |   Bin 5763 -> 0 bytes
 .../src/main/webapp/docs/images/logo_small.png  |   Bin 770 -> 0 bytes
 .../main/webapp/docs/images/pet_store_api.png   |   Bin 824 -> 0 bytes
 .../src/main/webapp/docs/images/throbber.gif    |   Bin 9257 -> 0 bytes
 .../src/main/webapp/docs/images/wordnik_api.png |   Bin 980 -> 0 bytes
 gemfire-web-api/src/main/webapp/docs/index.html |    81 -
 .../src/main/webapp/docs/lib/backbone-min.js    |    38 -
 .../main/webapp/docs/lib/handlebars-1.0.0.js    |  2278 ---
 .../main/webapp/docs/lib/highlight.7.3.pack.js  |     1 -
 .../main/webapp/docs/lib/jquery-1.8.0.min.js    |     2 -
 .../main/webapp/docs/lib/jquery.ba-bbq.min.js   |    18 -
 .../main/webapp/docs/lib/jquery.slideto.min.js  |     1 -
 .../main/webapp/docs/lib/jquery.wiggle.min.js   |     8 -
 .../src/main/webapp/docs/lib/shred.bundle.js    |  2765 ---
 .../src/main/webapp/docs/lib/shred/content.js   |   193 -
 .../src/main/webapp/docs/lib/swagger-oauth.js   |   211 -
 .../src/main/webapp/docs/lib/swagger.js         |  1527 --
 .../src/main/webapp/docs/lib/underscore-min.js  |    32 -
 gemfire-web-api/src/main/webapp/docs/o2c.html   |    15 -
 .../src/main/webapp/docs/swagger-ui.js          |  2269 ---
 .../src/main/webapp/docs/swagger-ui.min.js      |     1 -
 gemfire-web/build.gradle                        |    55 -
 .../src/main/webapp/WEB-INF/gemfire-servlet.xml |    59 -
 gemfire-web/src/main/webapp/WEB-INF/web.xml     |    56 -
 .../internal/web/AbstractWebTestCase.java       |    97 -
 .../ShellCommandsControllerJUnitTest.java       |   240 -
 ...entVariablesHandlerInterceptorJUnitTest.java |   268 -
 .../internal/web/domain/LinkIndexJUnitTest.java |   237 -
 .../internal/web/domain/LinkJUnitTest.java      |   124 -
 .../domain/QueryParameterSourceJUnitTest.java   |    93 -
 .../web/http/ClientHttpRequestJUnitTest.java    |   510 -
 ...ableObjectHttpMessageConverterJUnitTest.java |   166 -
 .../RestHttpOperationInvokerJUnitTest.java      |   454 -
 .../SimpleHttpOperationInvokerJUnitTest.java    |   199 -
 .../web/util/ConvertUtilsJUnitTest.java         |   171 -
 .../internal/web/util/UriUtilsJUnitTest.java    |   119 -
 geode-assembly/build.gradle                     |   345 +
 geode-assembly/src/main/dist/DISCLAIMER         |     6 +
 geode-assembly/src/main/dist/LICENSE            |   434 +
 geode-assembly/src/main/dist/NOTICE             |   467 +
 geode-assembly/src/main/dist/bin/gfsh           |   152 +
 .../src/main/dist/bin/gfsh-completion.bash      |   103 +
 geode-assembly/src/main/dist/bin/gfsh.bat       |    87 +
 geode-assembly/src/src/dist/gradlew             |   221 +
 .../LocatorLauncherAssemblyJUnitTest.java       |   157 +
 .../management/internal/AgentUtilJUnitTest.java |    50 +
 .../LauncherLifecycleCommandsDUnitTest.java     |  1007 +
 .../LauncherLifecycleCommandsJUnitTest.java     |   625 +
 .../SharedConfigurationEndToEndDUnitTest.java   |   450 +
 geode-common/build.gradle                       |    20 +
 .../gemfire/annotations/Experimental.java       |    56 +
 .../annotations/ExperimentalJUnitTest.java      |   199 +
 .../ClassInExperimentalPackage.java             |    27 +
 .../experimentalpackage/package-info.java       |    27 +
 .../ClassInNonExperimentalPackage.java          |    27 +
 .../nonexperimentalpackage/package-info.java    |    24 +
 geode-core/build.gradle                         |   204 +
 .../internal/ra/GFConnectionFactoryImpl.java    |    66 +
 .../gemfire/internal/ra/GFConnectionImpl.java   |    71 +
 .../internal/ra/spi/JCALocalTransaction.java    |   236 +
 .../internal/ra/spi/JCAManagedConnection.java   |   299 +
 .../ra/spi/JCAManagedConnectionFactory.java     |   145 +
 .../ra/spi/JCAManagedConnectionMetaData.java    |    67 +
 geode-core/src/jca/ra.xml                       |    52 +
 .../com/gemstone/gemfire/CancelCriterion.java   |   109 +
 .../com/gemstone/gemfire/CancelException.java   |    64 +
 .../gemstone/gemfire/CanonicalInstantiator.java |    86 +
 .../com/gemstone/gemfire/CopyException.java     |    67 +
 .../java/com/gemstone/gemfire/CopyHelper.java   |   268 +
 .../com/gemstone/gemfire/DataSerializable.java  |   140 +
 .../com/gemstone/gemfire/DataSerializer.java    |  3565 ++++
 .../main/java/com/gemstone/gemfire/Delta.java   |    66 +
 .../gemfire/DeltaSerializationException.java    |    59 +
 .../gemfire/ForcedDisconnectException.java      |    41 +
 .../gemstone/gemfire/GemFireCacheException.java |    50 +
 .../gemfire/GemFireCheckedException.java        |    90 +
 .../gemfire/GemFireConfigException.java         |    42 +
 .../com/gemstone/gemfire/GemFireException.java  |   149 +
 .../gemstone/gemfire/GemFireIOException.java    |    41 +
 .../gemstone/gemfire/GemFireRethrowable.java    |    47 +
 .../gemfire/IncompatibleSystemException.java    |    38 +
 .../java/com/gemstone/gemfire/Instantiator.java |   315 +
 .../gemstone/gemfire/InternalGemFireError.java  |   154 +
 .../gemfire/InternalGemFireException.java       |    56 +
 .../gemstone/gemfire/InvalidDeltaException.java |    63 +
 .../gemstone/gemfire/InvalidValueException.java |    42 +
 .../gemfire/InvalidVersionException.java        |    25 +
 .../com/gemstone/gemfire/LicenseException.java  |    54 +
 .../java/com/gemstone/gemfire/LogWriter.java    |   301 +
 .../com/gemstone/gemfire/NoSystemException.java |    48 +
 .../gemfire/OutOfOffHeapMemoryException.java    |    45 +
 .../gemfire/SerializationException.java         |    45 +
 .../gemstone/gemfire/StatisticDescriptor.java   |    82 +
 .../java/com/gemstone/gemfire/Statistics.java   |   446 +
 .../com/gemstone/gemfire/StatisticsFactory.java |   154 +
 .../com/gemstone/gemfire/StatisticsType.java    |    72 +
 .../gemstone/gemfire/StatisticsTypeFactory.java |   197 +
 .../gemfire/SystemConnectException.java         |    42 +
 .../com/gemstone/gemfire/SystemFailure.java     |  1239 ++
 .../gemfire/SystemIsRunningException.java       |    46 +
 .../gemfire/ThreadInterruptedException.java     |    31 +
 .../com/gemstone/gemfire/ToDataException.java   |    42 +
 .../gemfire/UncreatedSystemException.java       |    48 +
 .../gemstone/gemfire/UnmodifiableException.java |    36 +
 .../gemfire/UnstartedSystemException.java       |    49 +
 .../com/gemstone/gemfire/admin/AdminConfig.java |   157 +
 .../gemfire/admin/AdminDistributedSystem.java   |   478 +
 .../admin/AdminDistributedSystemFactory.java    |   163 +
 .../gemstone/gemfire/admin/AdminException.java  |    90 +
 .../gemfire/admin/AdminXmlException.java        |    48 +
 .../java/com/gemstone/gemfire/admin/Alert.java  |    56 +
 .../com/gemstone/gemfire/admin/AlertLevel.java  |   174 +
 .../gemstone/gemfire/admin/AlertListener.java   |    30 +
 .../gemstone/gemfire/admin/BackupStatus.java    |    49 +
 .../admin/CacheDoesNotExistException.java       |    87 +
 .../gemfire/admin/CacheHealthConfig.java        |   157 +
 .../com/gemstone/gemfire/admin/CacheServer.java |    46 +
 .../gemfire/admin/CacheServerConfig.java        |    55 +
 .../com/gemstone/gemfire/admin/CacheVm.java     |    38 +
 .../gemstone/gemfire/admin/CacheVmConfig.java   |    54 +
 .../gemfire/admin/ConfigurationParameter.java   |    74 +
 .../gemfire/admin/DistributedSystemConfig.java  |   682 +
 .../admin/DistributedSystemHealthConfig.java    |    77 +
 .../gemfire/admin/DistributionLocator.java      |    47 +
 .../admin/DistributionLocatorConfig.java        |    90 +
 .../gemstone/gemfire/admin/GemFireHealth.java   |   234 +
 .../gemfire/admin/GemFireHealthConfig.java      |    58 +
 .../gemfire/admin/GemFireMemberStatus.java      |   709 +
 .../gemstone/gemfire/admin/ManagedEntity.java   |   125 +
 .../gemfire/admin/ManagedEntityConfig.java      |   100 +
 .../gemfire/admin/MemberHealthConfig.java       |   142 +
 .../admin/OperationCancelledException.java      |    48 +
 .../gemfire/admin/RegionNotFoundException.java  |    39 +
 .../gemfire/admin/RegionSubRegionSnapshot.java  |   193 +
 .../gemfire/admin/RuntimeAdminException.java    |    50 +
 .../com/gemstone/gemfire/admin/Statistic.java   |    66 +
 .../gemfire/admin/StatisticResource.java        |    86 +
 .../gemstone/gemfire/admin/SystemMember.java    |   148 +
 .../gemfire/admin/SystemMemberBridgeServer.java |   309 +
 .../gemfire/admin/SystemMemberCache.java        |   205 +
 .../gemfire/admin/SystemMemberCacheEvent.java   |    34 +
 .../admin/SystemMemberCacheListener.java        |    73 +
 .../gemfire/admin/SystemMemberCacheServer.java  |   309 +
 .../gemfire/admin/SystemMemberRegion.java       |   322 +
 .../gemfire/admin/SystemMemberRegionEvent.java  |    33 +
 .../gemfire/admin/SystemMemberType.java         |   146 +
 .../gemfire/admin/SystemMembershipEvent.java    |    41 +
 .../gemfire/admin/SystemMembershipListener.java |    62 +
 .../UnmodifiableConfigurationException.java     |    89 +
 .../admin/internal/AbstractHealthEvaluator.java |   185 +
 .../internal/AdminDistributedSystemImpl.java    |  2510 +++
 .../admin/internal/BackupDataStoreHelper.java   |    76 +
 .../admin/internal/BackupDataStoreResult.java   |    57 +
 .../admin/internal/BackupStatusImpl.java        |    62 +
 .../admin/internal/CacheHealthConfigImpl.java   |    92 +
 .../admin/internal/CacheHealthEvaluator.java    |   324 +
 .../admin/internal/CacheServerConfigImpl.java   |   136 +
 .../gemfire/admin/internal/CacheServerImpl.java |   199 +
 .../internal/ConfigurationParameterImpl.java    |   281 +
 .../ConfigurationParameterListener.java         |    35 +
 .../DisabledManagedEntityController.java        |    92 +
 .../internal/DistributedSystemConfigImpl.java   |  1103 ++
 .../DistributedSystemHealthConfigImpl.java      |    59 +
 .../DistributedSystemHealthEvaluator.java       |   172 +
 .../DistributedSystemHealthMonitor.java         |   437 +
 .../internal/DistributionLocatorConfigImpl.java |   192 +
 .../admin/internal/DistributionLocatorImpl.java |   331 +
 .../EnabledManagedEntityController.java         |   412 +
 .../admin/internal/FinishBackupRequest.java     |   172 +
 .../admin/internal/FinishBackupResponse.java    |    79 +
 .../admin/internal/FlushToDiskRequest.java      |    98 +
 .../admin/internal/FlushToDiskResponse.java     |    46 +
 .../admin/internal/GemFireHealthConfigImpl.java |    84 +
 .../admin/internal/GemFireHealthEvaluator.java  |   188 +
 .../admin/internal/GemFireHealthImpl.java       |   536 +
 .../gemfire/admin/internal/InetAddressUtil.java |   209 +
 .../admin/internal/InternalManagedEntity.java   |   106 +
 .../gemfire/admin/internal/LogCollator.java     |   137 +
 .../admin/internal/ManagedEntityConfigImpl.java |   263 +
 .../admin/internal/ManagedEntityConfigXml.java  |   170 +
 .../ManagedEntityConfigXmlGenerator.java        |   386 +
 .../internal/ManagedEntityConfigXmlParser.java  |   623 +
 .../admin/internal/ManagedEntityController.java |    74 +
 .../ManagedEntityControllerFactory.java         |    61 +
 .../admin/internal/ManagedSystemMemberImpl.java |   271 +
 .../admin/internal/MemberHealthConfigImpl.java  |    96 +
 .../admin/internal/MemberHealthEvaluator.java   |   242 +
 .../admin/internal/PrepareBackupRequest.java    |   133 +
 .../admin/internal/PrepareBackupResponse.java   |    82 +
 .../gemfire/admin/internal/StatisticImpl.java   |    97 +
 .../admin/internal/StatisticResourceImpl.java   |   182 +
 .../internal/SystemMemberBridgeServerImpl.java  |   234 +
 .../internal/SystemMemberCacheEventImpl.java    |    61 +
 .../SystemMemberCacheEventProcessor.java        |   148 +
 .../admin/internal/SystemMemberCacheImpl.java   |   313 +
 .../admin/internal/SystemMemberImpl.java        |   520 +
 .../internal/SystemMemberRegionEventImpl.java   |    63 +
 .../admin/internal/SystemMemberRegionImpl.java  |   381 +
 .../internal/SystemMembershipEventImpl.java     |    71 +
 .../internal/doc-files/config-hierarchy.fig     |   156 +
 .../admin/internal/doc-files/health-classes.fig |   233 +
 .../admin/internal/doc-files/health-classes.gif |   Bin 0 -> 8973 bytes
 .../gemfire/admin/internal/package.html         |    53 +
 .../com/gemstone/gemfire/admin/jmx/Agent.java   |   165 +
 .../gemstone/gemfire/admin/jmx/AgentConfig.java |   884 +
 .../gemfire/admin/jmx/AgentFactory.java         |    52 +
 .../internal/AdminDistributedSystemJmxImpl.java |  2341 +++
 .../admin/jmx/internal/AgentConfigImpl.java     |  1847 ++
 .../gemfire/admin/jmx/internal/AgentImpl.java   |  1622 ++
 .../admin/jmx/internal/AgentLauncher.java       |   889 +
 .../admin/jmx/internal/CacheServerJmxImpl.java  |   642 +
 .../admin/jmx/internal/ConfigAttributeInfo.java |    77 +
 .../internal/ConfigurationParameterJmxImpl.java |   170 +
 .../DistributedSystemHealthConfigJmxImpl.java   |   108 +
 .../internal/DistributionLocatorJmxImpl.java    |   186 +
 .../admin/jmx/internal/DynamicManagedBean.java  |   142 +
 .../internal/GemFireHealthConfigJmxImpl.java    |   223 +
 .../jmx/internal/GemFireHealthJmxImpl.java      |   179 +
 .../admin/jmx/internal/GenerateMBeanHTML.java   |   514 +
 .../gemfire/admin/jmx/internal/MBeanUtil.java   |   769 +
 .../admin/jmx/internal/MX4JModelMBean.java      |  1255 ++
 .../jmx/internal/MX4JServerSocketFactory.java   |   160 +
 .../gemfire/admin/jmx/internal/MailManager.java |   333 +
 .../admin/jmx/internal/ManagedResource.java     |    78 +
 .../admin/jmx/internal/ManagedResourceType.java |   210 +
 .../jmx/internal/MemberInfoWithStatsMBean.java  |  1388 ++
 .../admin/jmx/internal/RMIRegistryService.java  |   239 +
 .../jmx/internal/RMIRegistryServiceMBean.java   |    85 +
 .../jmx/internal/RefreshNotificationType.java   |   133 +
 .../jmx/internal/StatAlertNotification.java     |   162 +
 .../jmx/internal/StatAlertsAggregator.java      |   125 +
 .../jmx/internal/StatisticAttributeInfo.java    |    79 +
 .../jmx/internal/StatisticResourceJmxImpl.java  |   361 +
 .../SystemMemberBridgeServerJmxImpl.java        |   135 +
 .../jmx/internal/SystemMemberCacheJmxImpl.java  |   475 +
 .../admin/jmx/internal/SystemMemberJmx.java     |   508 +
 .../admin/jmx/internal/SystemMemberJmxImpl.java |   593 +
 .../jmx/internal/SystemMemberRegionJmxImpl.java |   140 +
 .../gemfire/admin/jmx/internal/package.html     |   166 +
 .../com/gemstone/gemfire/admin/jmx/package.html |    28 +
 .../com/gemstone/gemfire/admin/package.html     |    78 +
 .../gemfire/cache/AttributesFactory.java        |  2056 ++
 .../gemfire/cache/AttributesMutator.java        |   224 +
 .../java/com/gemstone/gemfire/cache/Cache.java  |   457 +
 .../gemstone/gemfire/cache/CacheCallback.java   |    47 +
 .../gemfire/cache/CacheClosedException.java     |    77 +
 .../com/gemstone/gemfire/cache/CacheEvent.java  |   110 +
 .../gemstone/gemfire/cache/CacheException.java  |    70 +
 .../gemfire/cache/CacheExistsException.java     |    66 +
 .../gemstone/gemfire/cache/CacheFactory.java    |   392 +
 .../gemstone/gemfire/cache/CacheListener.java   |   174 +
 .../com/gemstone/gemfire/cache/CacheLoader.java |    64 +
 .../gemfire/cache/CacheLoaderException.java     |    66 +
 .../gemfire/cache/CacheRuntimeException.java    |    81 +
 .../gemstone/gemfire/cache/CacheStatistics.java |   130 +
 .../gemfire/cache/CacheTransactionManager.java  |   350 +
 .../com/gemstone/gemfire/cache/CacheWriter.java |   151 +
 .../gemfire/cache/CacheWriterException.java     |    70 +
 .../gemfire/cache/CacheXmlException.java        |    50 +
 .../gemstone/gemfire/cache/ClientSession.java   |   198 +
 .../gemfire/cache/CommitConflictException.java  |    57 +
 .../cache/CommitDistributionException.java      |    81 +
 .../cache/CommitIncompleteException.java        |    31 +
 .../gemfire/cache/CustomEvictionAttributes.java |    79 +
 .../gemstone/gemfire/cache/CustomExpiry.java    |    42 +
 .../com/gemstone/gemfire/cache/DataPolicy.java  |   266 +
 .../com/gemstone/gemfire/cache/Declarable.java  |    77 +
 .../gemfire/cache/DiskAccessException.java      |   141 +
 .../com/gemstone/gemfire/cache/DiskStore.java   |   216 +
 .../gemfire/cache/DiskStoreFactory.java         |   243 +
 .../gemfire/cache/DiskWriteAttributes.java      |   108 +
 .../cache/DiskWriteAttributesFactory.java       |   263 +
 .../DuplicatePrimaryPartitionException.java     |    65 +
 .../gemfire/cache/DynamicRegionFactory.java     |  1108 ++
 .../gemfire/cache/DynamicRegionListener.java    |    70 +
 .../gemfire/cache/EntryDestroyedException.java  |    61 +
 .../com/gemstone/gemfire/cache/EntryEvent.java  |   167 +
 .../gemfire/cache/EntryExistsException.java     |    62 +
 .../gemfire/cache/EntryNotFoundException.java   |    51 +
 .../gemfire/cache/EntryNotFoundInRegion.java    |    50 +
 .../gemstone/gemfire/cache/EntryOperation.java  |    86 +
 .../gemstone/gemfire/cache/EvictionAction.java  |   115 +
 .../gemfire/cache/EvictionAlgorithm.java        |   151 +
 .../gemfire/cache/EvictionAttributes.java       |   494 +
 .../cache/EvictionAttributesMutator.java        |    40 +
 .../gemfire/cache/EvictionCriteria.java         |    58 +
 .../gemfire/cache/ExpirationAction.java         |   123 +
 .../gemfire/cache/ExpirationAttributes.java     |   144 +
 .../cache/FailedSynchronizationException.java   |    59 +
 .../gemfire/cache/FixedPartitionAttributes.java |   115 +
 .../gemfire/cache/FixedPartitionResolver.java   |    79 +
 .../cache/GatewayConfigurationException.java    |    45 +
 .../gemfire/cache/GatewayException.java         |    68 +
 .../gemstone/gemfire/cache/GemFireCache.java    |   262 +
 .../cache/IncompatibleVersionException.java     |    48 +
 .../gemstone/gemfire/cache/InterestPolicy.java  |   149 +
 .../cache/InterestRegistrationEvent.java        |    92 +
 .../cache/InterestRegistrationListener.java     |    84 +
 .../gemfire/cache/InterestResultPolicy.java     |   122 +
 .../gemstone/gemfire/cache/LoaderHelper.java    |    81 +
 .../com/gemstone/gemfire/cache/LossAction.java  |   149 +
 .../gemfire/cache/LowMemoryException.java       |    67 +
 .../gemfire/cache/MembershipAttributes.java     |   269 +
 .../com/gemstone/gemfire/cache/MirrorType.java  |   136 +
 .../cache/NoQueueServersAvailableException.java |    64 +
 ...NoSubscriptionServersAvailableException.java |    64 +
 .../com/gemstone/gemfire/cache/Operation.java   |  1010 +
 .../cache/OperationAbortedException.java        |    63 +
 .../gemfire/cache/PartitionAttributes.java      |   171 +
 .../cache/PartitionAttributesFactory.java       |   457 +
 .../gemfire/cache/PartitionResolver.java        |    84 +
 .../PartitionedRegionDistributionException.java |    46 +
 .../PartitionedRegionStorageException.java      |    96 +
 .../java/com/gemstone/gemfire/cache/Region.java |  2403 +++
 .../gemfire/cache/RegionAccessException.java    |   118 +
 .../gemfire/cache/RegionAttributes.java         |   490 +
 .../gemfire/cache/RegionDestroyedException.java |    52 +
 .../cache/RegionDistributionException.java      |   123 +
 .../com/gemstone/gemfire/cache/RegionEvent.java |    41 +
 .../gemfire/cache/RegionExistsException.java    |    65 +
 .../gemstone/gemfire/cache/RegionFactory.java   |   934 +
 .../gemfire/cache/RegionMembershipListener.java |    83 +
 .../cache/RegionReinitializedException.java     |    48 +
 .../gemfire/cache/RegionRoleException.java      |    63 +
 .../gemfire/cache/RegionRoleListener.java       |    54 +
 .../gemstone/gemfire/cache/RegionService.java   |   142 +
 .../gemstone/gemfire/cache/RegionShortcut.java  |   238 +
 .../cache/RemoteTransactionException.java       |    42 +
 .../gemstone/gemfire/cache/RequiredRoles.java   |   117 +
 .../gemfire/cache/ResourceException.java        |    61 +
 .../gemfire/cache/ResumptionAction.java         |   114 +
 .../com/gemstone/gemfire/cache/RoleEvent.java   |    39 +
 .../gemstone/gemfire/cache/RoleException.java   |    68 +
 .../java/com/gemstone/gemfire/cache/Scope.java  |   168 +
 .../gemfire/cache/SerializedCacheValue.java     |    53 +
 .../cache/StatisticsDisabledException.java      |    68 +
 .../gemfire/cache/SubscriptionAttributes.java   |   117 +
 .../SynchronizationCommitConflictException.java |    49 +
 .../gemfire/cache/TimeoutException.java         |    73 +
 ...TransactionDataNodeHasDepartedException.java |    42 +
 .../TransactionDataNotColocatedException.java   |    46 +
 .../TransactionDataRebalancedException.java     |    38 +
 .../gemfire/cache/TransactionEvent.java         |   114 +
 .../gemfire/cache/TransactionException.java     |    43 +
 .../gemstone/gemfire/cache/TransactionId.java   |    33 +
 .../cache/TransactionInDoubtException.java      |    42 +
 .../gemfire/cache/TransactionListener.java      |    66 +
 .../gemfire/cache/TransactionWriter.java        |    44 +
 .../cache/TransactionWriterException.java       |    45 +
 ...upportedOperationInTransactionException.java |    37 +
 .../cache/UnsupportedVersionException.java      |    44 +
 .../gemfire/cache/VersionException.java         |    50 +
 .../gemfire/cache/asyncqueue/AsyncEvent.java    |    42 +
 .../cache/asyncqueue/AsyncEventListener.java    |    76 +
 .../cache/asyncqueue/AsyncEventQueue.java       |   151 +
 .../asyncqueue/AsyncEventQueueFactory.java      |   191 +
 .../internal/AsyncEventQueueFactoryImpl.java    |   299 +
 .../internal/AsyncEventQueueImpl.java           |   205 +
 .../internal/AsyncEventQueueStats.java          |   186 +
 .../internal/ParallelAsyncEventQueueImpl.java   |   260 +
 .../internal/SerialAsyncEventQueueImpl.java     |   257 +
 .../client/AllConnectionsInUseException.java    |    61 +
 .../gemfire/cache/client/ClientCache.java       |   168 +
 .../cache/client/ClientCacheFactory.java        |   695 +
 .../cache/client/ClientNotReadyException.java   |    56 +
 .../cache/client/ClientRegionFactory.java       |   346 +
 .../cache/client/ClientRegionShortcut.java      |   108 +
 .../client/NoAvailableLocatorsException.java    |    59 +
 .../client/NoAvailableServersException.java     |    59 +
 .../com/gemstone/gemfire/cache/client/Pool.java |   251 +
 .../gemfire/cache/client/PoolFactory.java       |   477 +
 .../gemfire/cache/client/PoolManager.java       |    98 +
 .../client/ServerConnectivityException.java     |    63 +
 .../cache/client/ServerOperationException.java  |    86 +
 .../ServerRefusedConnectionException.java       |    41 +
 .../client/SubscriptionNotEnabledException.java |    63 +
 .../client/doc-files/example-client-cache.xml   |    46 +
 .../cache/client/internal/AbstractOp.java       |   436 +
 .../cache/client/internal/AddPDXEnumOp.java     |    98 +
 .../cache/client/internal/AddPDXTypeOp.java     |    96 +
 .../client/internal/AuthenticateUserOp.java     |   312 +
 .../internal/AutoConnectionSourceImpl.java      |   387 +
 .../client/internal/CacheServerLoadMessage.java |   108 +
 .../gemfire/cache/client/internal/ClearOp.java  |   106 +
 .../client/internal/ClientMetadataService.java  |   848 +
 .../client/internal/ClientPartitionAdvisor.java |   288 +
 .../internal/ClientRegionFactoryImpl.java       |   271 +
 .../cache/client/internal/ClientUpdater.java    |    36 +
 .../client/internal/CloseConnectionOp.java      |    95 +
 .../gemfire/cache/client/internal/CommitOp.java |   109 +
 .../cache/client/internal/Connection.java       |    85 +
 .../client/internal/ConnectionFactory.java      |    68 +
 .../client/internal/ConnectionFactoryImpl.java  |   334 +
 .../cache/client/internal/ConnectionImpl.java   |   339 +
 .../cache/client/internal/ConnectionSource.java |    77 +
 .../cache/client/internal/ConnectionStats.java  |  3292 ++++
 .../cache/client/internal/ContainsKeyOp.java    |   102 +
 .../DataSerializerRecoveryListener.java         |   153 +
 .../cache/client/internal/DestroyOp.java        |   286 +
 .../cache/client/internal/DestroyRegionOp.java  |   104 +
 .../gemfire/cache/client/internal/Endpoint.java |   111 +
 .../cache/client/internal/EndpointManager.java  |   100 +
 .../client/internal/EndpointManagerImpl.java    |   308 +
 .../cache/client/internal/ExecutablePool.java   |   150 +
 .../client/internal/ExecuteFunctionHelper.java  |    30 +
 .../client/internal/ExecuteFunctionNoAckOp.java |   243 +
 .../client/internal/ExecuteFunctionOp.java      |   653 +
 .../internal/ExecuteRegionFunctionNoAckOp.java  |   227 +
 .../internal/ExecuteRegionFunctionOp.java       |   624 +
 .../ExecuteRegionFunctionSingleHopOp.java       |   500 +
 .../internal/ExplicitConnectionSourceImpl.java  |   277 +
 .../gemfire/cache/client/internal/GetAllOp.java |   242 +
 .../client/internal/GetClientPRMetaDataOp.java  |   171 +
 .../GetClientPartitionAttributesOp.java         |   177 +
 .../cache/client/internal/GetEntryOp.java       |    82 +
 .../cache/client/internal/GetEventValueOp.java  |   121 +
 .../client/internal/GetFunctionAttributeOp.java |    84 +
 .../gemfire/cache/client/internal/GetOp.java    |   245 +
 .../cache/client/internal/GetPDXEnumByIdOp.java |    92 +
 .../cache/client/internal/GetPDXEnumsOp.java    |   112 +
 .../client/internal/GetPDXIdForEnumOp.java      |   113 +
 .../client/internal/GetPDXIdForTypeOp.java      |   113 +
 .../cache/client/internal/GetPDXTypeByIdOp.java |    92 +
 .../cache/client/internal/GetPDXTypesOp.java    |   112 +
 .../internal/InstantiatorRecoveryListener.java  |   159 +
 .../cache/client/internal/InternalPool.java     |    43 +
 .../cache/client/internal/InvalidateOp.java     |   121 +
 .../gemfire/cache/client/internal/KeySetOp.java |   130 +
 .../cache/client/internal/LiveServerPinger.java |   117 +
 .../internal/LocatorDiscoveryCallback.java      |    47 +
 .../LocatorDiscoveryCallbackAdapter.java        |    36 +
 .../cache/client/internal/MakePrimaryOp.java    |    91 +
 .../gemfire/cache/client/internal/Op.java       |    43 +
 .../cache/client/internal/OpExecutorImpl.java   |   985 +
 .../internal/PdxRegistryRecoveryListener.java   |    90 +
 .../gemfire/cache/client/internal/PingOp.java   |    97 +
 .../gemfire/cache/client/internal/PoolImpl.java |  1522 ++
 .../cache/client/internal/PrimaryAckOp.java     |   101 +
 .../cache/client/internal/ProxyCache.java       |   248 +
 .../client/internal/ProxyCacheCloseOp.java      |   124 +
 .../cache/client/internal/ProxyRegion.java      |   698 +
 .../gemfire/cache/client/internal/PutAllOp.java |   430 +
 .../gemfire/cache/client/internal/PutOp.java    |   553 +
 .../gemfire/cache/client/internal/QueryOp.java  |   203 +
 .../client/internal/QueueConnectionImpl.java    |   226 +
 .../cache/client/internal/QueueManager.java     |    57 +
 .../cache/client/internal/QueueManagerImpl.java |  1487 ++
 .../cache/client/internal/QueueState.java       |    33 +
 .../cache/client/internal/QueueStateImpl.java   |   450 +
 .../cache/client/internal/ReadyForEventsOp.java |    91 +
 .../internal/RegisterDataSerializersOp.java     |   138 +
 .../internal/RegisterInstantiatorsOp.java       |   180 +
 .../client/internal/RegisterInterestListOp.java |   147 +
 .../client/internal/RegisterInterestOp.java     |   296 +
 .../internal/RegisterInterestTracker.java       |   419 +
 .../cache/client/internal/RemoveAllOp.java      |   391 +
 .../cache/client/internal/RollbackOp.java       |    99 +
 .../cache/client/internal/ServerBlackList.java  |   188 +
 .../cache/client/internal/ServerProxy.java      |    69 +
 .../client/internal/ServerRegionDataAccess.java |   143 +
 .../client/internal/ServerRegionProxy.java      |   878 +
 .../internal/SingleHopClientExecutor.java       |   415 +
 .../internal/SingleHopOperationCallable.java    |    83 +
 .../gemfire/cache/client/internal/SizeOp.java   |    92 +
 .../cache/client/internal/TXFailoverOp.java     |    93 +
 .../client/internal/TXSynchronizationOp.java    |   163 +
 .../internal/UnregisterInterestListOp.java      |   100 +
 .../client/internal/UnregisterInterestOp.java   |    98 +
 .../cache/client/internal/UserAttributes.java   |    59 +
 .../doc-files/ConnectionManagerImpl.dia         |   Bin 0 -> 2034 bytes
 .../doc-files/ConnectionManagerImpl.png         |   Bin 0 -> 11825 bytes
 .../client/internal/doc-files/PoolImpl.dia      |   Bin 0 -> 3083 bytes
 .../internal/doc-files/QueueManagerImpl.dia     |   Bin 0 -> 2180 bytes
 .../internal/doc-files/QueueManagerImpl.png     |   Bin 0 -> 15075 bytes
 .../doc-files/client_static_diagram.png         |   Bin 0 -> 29430 bytes
 .../locator/ClientConnectionRequest.java        |    68 +
 .../locator/ClientConnectionResponse.java       |    85 +
 .../locator/ClientReplacementRequest.java       |    75 +
 .../internal/locator/GetAllServersRequest.java  |    58 +
 .../internal/locator/GetAllServersResponse.java |    80 +
 .../internal/locator/LocatorListRequest.java    |    36 +
 .../internal/locator/LocatorListResponse.java   |    92 +
 .../internal/locator/LocatorStatusRequest.java  |    37 +
 .../internal/locator/LocatorStatusResponse.java |   321 +
 .../locator/QueueConnectionRequest.java         |    99 +
 .../locator/QueueConnectionResponse.java        |    87 +
 .../internal/locator/SerializationHelper.java   |   123 +
 .../internal/locator/ServerLocationRequest.java |    61 +
 .../locator/ServerLocationResponse.java         |    33 +
 .../locator/wan/LocatorMembershipListener.java  |    57 +
 .../gemfire/cache/client/internal/package.html  |    63 +
 .../pooling/ConnectionDestroyedException.java   |    48 +
 .../internal/pooling/ConnectionManager.java     |   132 +
 .../internal/pooling/ConnectionManagerImpl.java |  1587 ++
 .../internal/pooling/PooledConnection.java      |   354 +
 .../gemstone/gemfire/cache/client/package.html  |    67 +
 .../gemfire/cache/control/RebalanceFactory.java |    66 +
 .../cache/control/RebalanceOperation.java       |    75 +
 .../gemfire/cache/control/RebalanceResults.java |   106 +
 .../gemfire/cache/control/ResourceManager.java  |   260 +
 .../gemstone/gemfire/cache/control/package.html |    23 +
 .../gemfire/cache/doc-files/architecture.fig    |   170 +
 .../gemfire/cache/doc-files/architecture.gif    |   Bin 0 -> 9983 bytes
 .../cache/doc-files/entry-life-cycle.fig        |    64 +
 .../cache/doc-files/entry-life-cycle.gif        |   Bin 0 -> 3357 bytes
 .../gemfire/cache/doc-files/example-cache.xml   |    98 +
 .../gemfire/cache/doc-files/example2-cache.xml  |    63 +
 .../gemfire/cache/doc-files/example3-cache.xml  |    60 +
 .../cache/doc-files/partitioned-regions.fig     |   267 +
 .../cache/doc-files/partitioned-regions.gif     |   Bin 0 -> 9494 bytes
 .../execute/EmtpyRegionFunctionException.java   |    64 +
 .../gemfire/cache/execute/Execution.java        |   224 +
 .../gemfire/cache/execute/Function.java         |   112 +
 .../gemfire/cache/execute/FunctionAdapter.java  |   124 +
 .../gemfire/cache/execute/FunctionContext.java  |    80 +
 .../cache/execute/FunctionException.java        |   129 +
 .../FunctionInvocationTargetException.java      |    93 +
 .../gemfire/cache/execute/FunctionService.java  |   371 +
 .../cache/execute/RegionFunctionContext.java    |    72 +
 .../gemfire/cache/execute/ResultCollector.java  |   136 +
 .../gemfire/cache/execute/ResultSender.java     |    93 +
 .../internal/FunctionServiceManager.java        |   460 +
 .../gemstone/gemfire/cache/execute/package.html |   162 +
 .../gemfire/cache/hdfs/HDFSIOException.java     |    53 +
 .../gemstone/gemfire/cache/hdfs/HDFSStore.java  |   343 +
 .../gemfire/cache/hdfs/HDFSStoreFactory.java    |   205 +
 .../gemfire/cache/hdfs/HDFSStoreMutator.java    |   197 +
 .../cache/hdfs/StoreExistsException.java        |    33 +
 .../cache/hdfs/internal/FailureTracker.java     |    97 +
 .../cache/hdfs/internal/FlushObserver.java      |    54 +
 .../hdfs/internal/HDFSBucketRegionQueue.java    |  1233 ++
 .../cache/hdfs/internal/HDFSEntriesSet.java     |   329 +
 .../cache/hdfs/internal/HDFSEventListener.java  |   180 +
 .../hdfs/internal/HDFSEventQueueFilter.java     |    74 +
 .../hdfs/internal/HDFSGatewayEventImpl.java     |   181 +
 .../hdfs/internal/HDFSIntegrationUtil.java      |   118 +
 .../HDFSParallelGatewaySenderQueue.java         |   473 +
 .../hdfs/internal/HDFSStoreConfigHolder.java    |   560 +
 .../cache/hdfs/internal/HDFSStoreCreation.java  |   199 +
 .../hdfs/internal/HDFSStoreFactoryImpl.java     |    78 +
 .../cache/hdfs/internal/HDFSStoreImpl.java      |   639 +
 .../hdfs/internal/HDFSStoreMutatorImpl.java     |   200 +
 .../HDFSWriteOnlyStoreEventListener.java        |   185 +
 .../hdfs/internal/HoplogListenerForRegion.java  |    73 +
 .../cache/hdfs/internal/PersistedEventImpl.java |   203 +
 .../hdfs/internal/QueuedPersistentEvent.java    |    27 +
 .../hdfs/internal/SignalledFlushObserver.java   |   123 +
 .../internal/SortedHDFSQueuePersistedEvent.java |    87 +
 .../internal/SortedHoplogPersistedEvent.java    |   115 +
 .../UnsortedHDFSQueuePersistedEvent.java        |    77 +
 .../internal/UnsortedHoplogPersistedEvent.java  |    93 +
 .../hdfs/internal/hoplog/AbstractHoplog.java    |   357 +
 .../hoplog/AbstractHoplogOrganizer.java         |   430 +
 .../cache/hdfs/internal/hoplog/BloomFilter.java |    36 +
 .../hoplog/CloseTmpHoplogsTimerTask.java        |   109 +
 .../hdfs/internal/hoplog/CompactionStatus.java  |    73 +
 .../cache/hdfs/internal/hoplog/FlushStatus.java |    73 +
 .../internal/hoplog/HDFSCompactionManager.java  |   330 +
 .../internal/hoplog/HDFSFlushQueueArgs.java     |    94 +
 .../internal/hoplog/HDFSFlushQueueFunction.java |   287 +
 .../hoplog/HDFSForceCompactionArgs.java         |   108 +
 .../hoplog/HDFSForceCompactionFunction.java     |   130 +
 .../HDFSForceCompactionResultCollector.java     |   132 +
 .../hoplog/HDFSLastCompactionTimeFunction.java  |    57 +
 .../internal/hoplog/HDFSRegionDirector.java     |   480 +
 .../hdfs/internal/hoplog/HDFSStoreDirector.java |    79 +
 .../hoplog/HDFSUnsortedHoplogOrganizer.java     |   448 +
 .../hdfs/internal/hoplog/HFileSortedOplog.java  |   853 +
 .../hoplog/HdfsSortedOplogOrganizer.java        |  2007 ++
 .../cache/hdfs/internal/hoplog/Hoplog.java      |   264 +
 .../hdfs/internal/hoplog/HoplogConfig.java      |    75 +
 .../hdfs/internal/hoplog/HoplogListener.java    |    47 +
 .../hdfs/internal/hoplog/HoplogOrganizer.java   |   123 +
 .../hdfs/internal/hoplog/HoplogSetIterator.java |   166 +
 .../hdfs/internal/hoplog/HoplogSetReader.java   |   114 +
 .../internal/hoplog/SequenceFileHoplog.java     |   396 +
 .../hoplog/mapred/AbstractGFRecordReader.java   |   106 +
 .../internal/hoplog/mapred/GFInputFormat.java   |    95 +
 .../internal/hoplog/mapred/GFOutputFormat.java  |    76 +
 .../mapreduce/AbstractGFRecordReader.java       |   140 +
 .../hoplog/mapreduce/GFInputFormat.java         |   124 +
 .../hdfs/internal/hoplog/mapreduce/GFKey.java   |    72 +
 .../hoplog/mapreduce/GFOutputFormat.java        |   199 +
 .../hoplog/mapreduce/HDFSSplitIterator.java     |   198 +
 .../internal/hoplog/mapreduce/HoplogUtil.java   |   464 +
 .../hoplog/mapreduce/RWSplitIterator.java       |    49 +
 .../hoplog/mapreduce/StreamSplitIterator.java   |    47 +
 .../org/apache/hadoop/io/SequenceFile.java      |  3726 ++++
 .../operations/CloseCQOperationContext.java     |    65 +
 .../operations/DestroyOperationContext.java     |    63 +
 .../operations/ExecuteCQOperationContext.java   |    68 +
 .../ExecuteFunctionOperationContext.java        |    97 +
 .../GetDurableCQsOperationContext.java          |    60 +
 .../cache/operations/GetOperationContext.java   |    91 +
 .../operations/InterestOperationContext.java    |    84 +
 .../gemfire/cache/operations/InterestType.java  |   152 +
 .../operations/InvalidateOperationContext.java  |    64 +
 .../cache/operations/KeyOperationContext.java   |   125 +
 .../operations/KeySetOperationContext.java      |    97 +
 .../operations/KeyValueOperationContext.java    |   177 +
 .../cache/operations/OperationContext.java      |   521 +
 .../operations/PutAllOperationContext.java      |   407 +
 .../cache/operations/PutOperationContext.java   |   144 +
 .../cache/operations/QueryOperationContext.java |   172 +
 .../operations/RegionClearOperationContext.java |    51 +
 .../RegionCreateOperationContext.java           |    61 +
 .../RegionDestroyOperationContext.java          |    51 +
 .../operations/RegionOperationContext.java      |    87 +
 .../RegisterInterestOperationContext.java       |    72 +
 .../operations/RemoveAllOperationContext.java   |   101 +
 .../operations/StopCQOperationContext.java      |    66 +
 .../UnregisterInterestOperationContext.java     |    54 +
 .../internal/GetOperationContextImpl.java       |   124 +
 .../gemfire/cache/operations/package.html       |   107 +
 .../com/gemstone/gemfire/cache/package.html     |   608 +
 .../cache/partition/PartitionListener.java      |   132 +
 .../partition/PartitionListenerAdapter.java     |    50 +
 .../cache/partition/PartitionMemberInfo.java    |    74 +
 .../PartitionNotAvailableException.java         |    66 +
 .../cache/partition/PartitionRebalanceInfo.java |   150 +
 .../cache/partition/PartitionRegionHelper.java  |   552 +
 .../cache/partition/PartitionRegionInfo.java    |   113 +
 .../gemfire/cache/partition/package.html        |    23 +
 .../ConflictingPersistentDataException.java     |    57 +
 .../persistence/PartitionOfflineException.java  |    77 +
 .../gemfire/cache/persistence/PersistentID.java |    59 +
 .../PersistentReplicatesOfflineException.java   |    44 +
 .../persistence/RevokeFailedException.java      |    51 +
 .../RevokedPersistentDataException.java         |    58 +
 .../gemfire/cache/query/Aggregator.java         |    46 +
 .../cache/query/AmbiguousNameException.java     |    47 +
 .../gemfire/cache/query/CqAttributes.java       |    50 +
 .../cache/query/CqAttributesFactory.java        |   319 +
 .../cache/query/CqAttributesMutator.java        |    57 +
 .../gemfire/cache/query/CqClosedException.java  |    57 +
 .../gemstone/gemfire/cache/query/CqEvent.java   |    93 +
 .../gemfire/cache/query/CqException.java        |    57 +
 .../gemfire/cache/query/CqExistsException.java  |    53 +
 .../gemfire/cache/query/CqListener.java         |    59 +
 .../gemstone/gemfire/cache/query/CqQuery.java   |   155 +
 .../gemstone/gemfire/cache/query/CqResults.java |    51 +
 .../cache/query/CqServiceStatistics.java        |    70 +
 .../gemstone/gemfire/cache/query/CqState.java   |    55 +
 .../gemfire/cache/query/CqStatistics.java       |    53 +
 .../gemfire/cache/query/CqStatusListener.java   |    42 +
 .../cache/query/FunctionDomainException.java    |    36 +
 .../com/gemstone/gemfire/cache/query/Index.java |   112 +
 .../cache/query/IndexCreationException.java     |    46 +
 .../cache/query/IndexExistsException.java       |    52 +
 .../cache/query/IndexInvalidException.java      |    64 +
 .../cache/query/IndexMaintenanceException.java  |    66 +
 .../cache/query/IndexNameConflictException.java |    52 +
 .../gemfire/cache/query/IndexStatistics.java    |    76 +
 .../gemstone/gemfire/cache/query/IndexType.java |   106 +
 .../query/MultiIndexCreationException.java      |    82 +
 .../cache/query/NameNotFoundException.java      |    48 +
 .../cache/query/NameResolutionException.java    |    47 +
 .../query/ParameterCountInvalidException.java   |    38 +
 .../com/gemstone/gemfire/cache/query/Query.java |   328 +
 .../gemfire/cache/query/QueryException.java     |    66 +
 .../query/QueryExecutionLowMemoryException.java |    67 +
 .../query/QueryExecutionTimeoutException.java   |    62 +
 .../cache/query/QueryInvalidException.java      |    48 +
 .../query/QueryInvocationTargetException.java   |    54 +
 .../gemfire/cache/query/QueryService.java       |   852 +
 .../gemfire/cache/query/QueryStatistics.java    |    38 +
 .../cache/query/RegionNotFoundException.java    |    45 +
 .../gemfire/cache/query/SelectResults.java      |   122 +
 .../gemstone/gemfire/cache/query/Struct.java    |    59 +
 .../cache/query/TypeMismatchException.java      |    45 +
 .../query/internal/AbstractCompiledValue.java   |   323 +
 .../internal/AbstractGroupOrRangeJunction.java  |   596 +
 .../cache/query/internal/AllGroupJunction.java  |   276 +
 .../query/internal/AttributeDescriptor.java     |   420 +
 .../gemfire/cache/query/internal/Bag.java       |   726 +
 .../internal/CompiledAggregateFunction.java     |   185 +
 .../query/internal/CompiledBindArgument.java    |   100 +
 .../query/internal/CompiledComparison.java      |   877 +
 .../query/internal/CompiledConstruction.java    |    78 +
 .../cache/query/internal/CompiledFunction.java  |   117 +
 .../query/internal/CompiledGroupBySelect.java   |   522 +
 .../cache/query/internal/CompiledID.java        |    99 +
 .../cache/query/internal/CompiledIn.java        |   965 +
 .../query/internal/CompiledIndexOperation.java  |   183 +
 .../query/internal/CompiledIteratorDef.java     |   379 +
 .../cache/query/internal/CompiledJunction.java  |  1254 ++
 .../cache/query/internal/CompiledLike.java      |   548 +
 .../cache/query/internal/CompiledLiteral.java   |    85 +
 .../cache/query/internal/CompiledNegation.java  |    79 +
 .../cache/query/internal/CompiledOperation.java |   331 +
 .../cache/query/internal/CompiledPath.java      |   177 +
 .../cache/query/internal/CompiledRegion.java    |   111 +
 .../cache/query/internal/CompiledSelect.java    |  1590 ++
 .../query/internal/CompiledSortCriterion.java   |   320 +
 .../query/internal/CompiledUnaryMinus.java      |   102 +
 .../cache/query/internal/CompiledUndefined.java |   320 +
 .../cache/query/internal/CompiledValue.java     |   143 +
 .../query/internal/CompositeGroupJunction.java  |   555 +
 .../gemfire/cache/query/internal/CqEntry.java   |   112 +
 .../cache/query/internal/CqQueryVsdStats.java   |   342 +
 .../cache/query/internal/CqStateImpl.java       |   104 +
 .../internal/CumulativeNonDistinctResults.java  |   391 +
 .../cache/query/internal/DefaultQuery.java      |  1141 ++
 .../query/internal/DefaultQueryService.java     |  1003 +
 .../cache/query/internal/DerivedInfo.java       |   306 +
 .../cache/query/internal/ExecutionContext.java  |   736 +
 .../gemfire/cache/query/internal/Filter.java    |   178 +
 .../gemfire/cache/query/internal/Functions.java |   206 +
 .../cache/query/internal/GroupJunction.java     |   193 +
 .../cache/query/internal/HashingStrategy.java   |    55 +
 .../gemfire/cache/query/internal/IndexInfo.java |    78 +
 .../internal/IndexTrackingQueryObserver.java    |   217 +
 .../cache/query/internal/IndexUpdater.java      |   123 +
 .../gemfire/cache/query/internal/Indexable.java |    55 +
 .../cache/query/internal/LinkedResultSet.java   |   145 +
 .../cache/query/internal/LinkedStructSet.java   |   367 +
 .../cache/query/internal/MapIndexable.java      |    26 +
 .../cache/query/internal/MethodDispatch.java    |   232 +
 .../cache/query/internal/NWayMergeResults.java  |   546 +
 .../gemfire/cache/query/internal/Negatable.java |    26 +
 .../gemfire/cache/query/internal/NullToken.java |    77 +
 .../cache/query/internal/ObjectIntHashMap.java  |  1141 ++
 .../cache/query/internal/OrderByComparator.java |   237 +
 .../internal/OrderByComparatorUnmapped.java     |    90 +
 .../gemfire/cache/query/internal/Ordered.java   |    44 +
 .../cache/query/internal/OrganizedOperands.java |    55 +
 .../cache/query/internal/PRQueryTraceInfo.java  |   109 +
 .../gemfire/cache/query/internal/PathUtils.java |   269 +
 .../gemfire/cache/query/internal/PlanInfo.java  |    36 +
 .../cache/query/internal/ProxyQueryService.java |   451 +
 .../gemfire/cache/query/internal/QCompiler.java |   698 +
 .../gemfire/cache/query/internal/QRegion.java   |   539 +
 .../gemfire/cache/query/internal/QScope.java    |    92 +
 .../QueryExecutionCanceledException.java        |    63 +
 .../query/internal/QueryExecutionContext.java   |   242 +
 .../cache/query/internal/QueryExecutor.java     |    40 +
 .../cache/query/internal/QueryMonitor.java      |   361 +
 .../cache/query/internal/QueryObserver.java     |   338 +
 .../query/internal/QueryObserverAdapter.java    |   341 +
 .../query/internal/QueryObserverHolder.java     |    84 +
 .../cache/query/internal/QueryUtils.java        |  2079 ++
 .../cache/query/internal/RangeJunction.java     |  1255 ++
 .../cache/query/internal/ResultsBag.java        |   276 +
 .../ResultsCollectionCopyOnReadWrapper.java     |   228 +
 ...ResultsCollectionPdxDeserializerWrapper.java |   219 +
 .../internal/ResultsCollectionWrapper.java      |   664 +
 .../cache/query/internal/ResultsSet.java        |   150 +
 .../cache/query/internal/RuntimeIterator.java   |   338 +
 .../query/internal/SelectResultsComparator.java |    61 +
 .../cache/query/internal/SortedResultSet.java   |   134 +
 .../cache/query/internal/SortedResultsBag.java  |   260 +
 .../cache/query/internal/SortedStructBag.java   |   369 +
 .../cache/query/internal/SortedStructSet.java   |   385 +
 .../gemfire/cache/query/internal/StructBag.java |   474 +
 .../cache/query/internal/StructFields.java      |    42 +
 .../cache/query/internal/StructImpl.java        |   183 +
 .../gemfire/cache/query/internal/StructSet.java |   459 +
 .../gemfire/cache/query/internal/Support.java   |    95 +
 .../gemfire/cache/query/internal/Undefined.java |    87 +
 .../internal/aggregate/AbstractAggregator.java  |    47 +
 .../cache/query/internal/aggregate/Avg.java     |    50 +
 .../query/internal/aggregate/AvgBucketNode.java |    49 +
 .../query/internal/aggregate/AvgDistinct.java   |    43 +
 .../aggregate/AvgDistinctPRQueryNode.java       |    35 +
 .../internal/aggregate/AvgPRQueryNode.java      |    47 +
 .../cache/query/internal/aggregate/Count.java   |    49 +
 .../query/internal/aggregate/CountDistinct.java |    33 +
 .../aggregate/CountDistinctPRQueryNode.java     |    44 +
 .../internal/aggregate/CountPRQueryNode.java    |    48 +
 .../internal/aggregate/DistinctAggregator.java  |    56 +
 .../cache/query/internal/aggregate/MaxMin.java  |    68 +
 .../cache/query/internal/aggregate/Sum.java     |    48 +
 .../query/internal/aggregate/SumDistinct.java   |    35 +
 .../aggregate/SumDistinctPRQueryNode.java       |    46 +
 .../cache/query/internal/cq/ClientCQ.java       |    42 +
 .../cache/query/internal/cq/CqService.java      |   263 +
 .../query/internal/cq/CqServiceProvider.java    |    72 +
 .../query/internal/cq/InternalCqQuery.java      |    82 +
 .../query/internal/cq/MissingCqService.java     |   217 +
 .../internal/cq/MissingCqServiceStatistics.java |    52 +
 .../cache/query/internal/cq/ServerCQ.java       |    87 +
 .../query/internal/cq/spi/CqServiceFactory.java |    36 +
 .../query/internal/index/AbstractIndex.java     |  2405 +++
 .../query/internal/index/AbstractMapIndex.java  |   440 +
 .../internal/index/CompactMapRangeIndex.java    |   216 +
 .../query/internal/index/CompactRangeIndex.java |  1799 ++
 .../query/internal/index/DummyQRegion.java      |   252 +
 .../index/FunctionalIndexCreationHelper.java    |   721 +
 .../cache/query/internal/index/HashIndex.java   |  1573 ++
 .../query/internal/index/HashIndexSet.java      |   818 +
 .../query/internal/index/IMQException.java      |    59 +
 .../internal/index/IndexConcurrentHashSet.java  |    78 +
 .../query/internal/index/IndexCreationData.java |   166 +
 .../internal/index/IndexCreationHelper.java     |   113 +
 .../cache/query/internal/index/IndexData.java   |    72 +
 .../query/internal/index/IndexElemArray.java    |   361 +
 .../query/internal/index/IndexManager.java      |  1721 ++
 .../query/internal/index/IndexProtocol.java     |   222 +
 .../cache/query/internal/index/IndexStats.java  |   223 +
 .../cache/query/internal/index/IndexStore.java  |   153 +
 .../cache/query/internal/index/IndexUtils.java  |   135 +
 .../index/IndexedExpressionEvaluator.java       |    52 +
 .../query/internal/index/MapIndexStore.java     |   336 +
 .../query/internal/index/MapRangeIndex.java     |   195 +
 .../query/internal/index/MemoryIndexStore.java  |   822 +
 .../query/internal/index/PartitionedIndex.java  |   656 +
 .../query/internal/index/PrimaryKeyIndex.java   |   392 +
 .../index/PrimaryKeyIndexCreationHelper.java    |   135 +
 .../cache/query/internal/index/RangeIndex.java  |  1686 ++
 .../cache/query/internal/index/package.html     |   646 +
 .../gemfire/cache/query/internal/package.html   |    43 +
 .../query/internal/parse/ASTAggregateFunc.java  |    66 +
 .../cache/query/internal/parse/ASTAnd.java      |    39 +
 .../query/internal/parse/ASTCombination.java    |    46 +
 .../query/internal/parse/ASTCompareOp.java      |    38 +
 .../query/internal/parse/ASTConstruction.java   |    45 +
 .../query/internal/parse/ASTConversionExpr.java |    42 +
 .../cache/query/internal/parse/ASTDummy.java    |    39 +
 .../cache/query/internal/parse/ASTGroupBy.java  |    44 +
 .../cache/query/internal/parse/ASTHint.java     |    52 +
 .../query/internal/parse/ASTHintIdentifier.java |    52 +
 .../query/internal/parse/ASTIdentifier.java     |    42 +
 .../cache/query/internal/parse/ASTImport.java   |    57 +
 .../cache/query/internal/parse/ASTIn.java       |    43 +
 .../query/internal/parse/ASTIteratorDef.java    |    79 +
 .../cache/query/internal/parse/ASTLike.java     |    47 +
 .../cache/query/internal/parse/ASTLimit.java    |    41 +
 .../cache/query/internal/parse/ASTLiteral.java  |   232 +
 .../internal/parse/ASTMethodInvocation.java     |    68 +
 .../cache/query/internal/parse/ASTOr.java       |    38 +
 .../cache/query/internal/parse/ASTOrderBy.java  |    44 +
 .../query/internal/parse/ASTParameter.java      |    40 +
 .../cache/query/internal/parse/ASTPostfix.java  |    70 +
 .../query/internal/parse/ASTProjection.java     |    48 +
 .../query/internal/parse/ASTRegionPath.java     |    41 +
 .../cache/query/internal/parse/ASTSelect.java   |    68 +
 .../query/internal/parse/ASTSortCriterion.java  |    44 +
 .../cache/query/internal/parse/ASTTrace.java    |    41 +
 .../cache/query/internal/parse/ASTType.java     |    67 +
 .../cache/query/internal/parse/ASTTypeCast.java |    44 +
 .../cache/query/internal/parse/ASTUnary.java    |    65 +
 .../query/internal/parse/ASTUndefinedExpr.java  |    42 +
 .../query/internal/parse/ASTUnsupported.java    |    45 +
 .../cache/query/internal/parse/GemFireAST.java  |    61 +
 .../cache/query/internal/parse/OQLLexer.java    |  2265 +++
 .../internal/parse/OQLLexerTokenTypes.java      |   155 +
 .../query/internal/parse/OQLLexerTokenTypes.txt |   147 +
 .../cache/query/internal/parse/OQLParser.java   |  3833 ++++
 .../cache/query/internal/parse/UtilParser.java  |    92 +
 .../cache/query/internal/parse/fixantlr.sh      |    52 +
 .../gemfire/cache/query/internal/parse/oql.g    |  1195 ++
 .../internal/types/CollectionTypeImpl.java      |   126 +
 .../types/ExtendedNumericComparator.java        |    52 +
 .../cache/query/internal/types/MapTypeImpl.java |   100 +
 .../query/internal/types/NumericComparator.java |    96 +
 .../query/internal/types/ObjectTypeImpl.java    |   100 +
 .../query/internal/types/StructTypeImpl.java    |   160 +
 .../internal/types/TemporalComparator.java      |    77 +
 .../cache/query/internal/types/TypeUtils.java   |   476 +
 .../query/internal/utils/LimitIterator.java     |    63 +
 .../cache/query/internal/utils/PDXUtils.java    |    95 +
 .../gemstone/gemfire/cache/query/package.html   |   708 +
 .../cache/query/types/CollectionType.java       |    47 +
 .../gemfire/cache/query/types/MapType.java      |    42 +
 .../gemfire/cache/query/types/ObjectType.java   |    60 +
 .../gemfire/cache/query/types/StructType.java   |    52 +
 .../gemfire/cache/server/CacheServer.java       |   512 +
 .../cache/server/ClientSubscriptionConfig.java  |   148 +
 .../gemfire/cache/server/ServerLoad.java        |   187 +
 .../gemfire/cache/server/ServerLoadProbe.java   |    75 +
 .../cache/server/ServerLoadProbeAdapter.java    |    43 +
 .../gemfire/cache/server/ServerMetrics.java     |    53 +
 .../server/internal/ConnectionCountProbe.java   |    94 +
 .../cache/server/internal/LoadMonitor.java      |   242 +
 .../server/internal/ServerMetricsImpl.java      |    79 +
 .../gemstone/gemfire/cache/server/package.html  |    42 +
 .../cache/snapshot/CacheSnapshotService.java    |   149 +
 .../cache/snapshot/RegionSnapshotService.java   |   140 +
 .../gemfire/cache/snapshot/SnapshotFilter.java  |    45 +
 .../cache/snapshot/SnapshotIterator.java        |    62 +
 .../gemfire/cache/snapshot/SnapshotOptions.java |    62 +
 .../gemfire/cache/snapshot/SnapshotReader.java  |    58 +
 .../gemfire/cache/snapshot/package.html         |    54 +
 .../cache/util/BoundedLinkedHashMap.java        |    88 +
 .../cache/util/CacheListenerAdapter.java        |    67 +
 .../gemfire/cache/util/CacheWriterAdapter.java  |    54 +
 .../gemfire/cache/util/CqListenerAdapter.java   |    66 +
 .../gemstone/gemfire/cache/util/Gateway.java    |    53 +
 .../cache/util/GatewayConflictHelper.java       |    34 +
 .../cache/util/GatewayConflictResolver.java     |    48 +
 .../gemfire/cache/util/GatewayEvent.java        |    91 +
 .../gemfire/cache/util/ObjectSizer.java         |    83 +
 .../gemfire/cache/util/ObjectSizerImpl.java     |    35 +
 .../util/RegionMembershipListenerAdapter.java   |    44 +
 .../cache/util/RegionRoleListenerAdapter.java   |    40 +
 .../cache/util/TimestampedEntryEvent.java       |    40 +
 .../cache/util/TransactionListenerAdapter.java  |    43 +
 .../gemstone/gemfire/cache/util/package.html    |    31 +
 .../gemfire/cache/wan/EventSequenceID.java      |   104 +
 .../gemfire/cache/wan/GatewayEventFilter.java   |    64 +
 .../wan/GatewayEventSubstitutionFilter.java     |    40 +
 .../gemfire/cache/wan/GatewayQueueEvent.java    |    81 +
 .../gemfire/cache/wan/GatewayReceiver.java      |   174 +
 .../cache/wan/GatewayReceiverFactory.java       |   122 +
 .../gemfire/cache/wan/GatewaySender.java        |   415 +
 .../gemfire/cache/wan/GatewaySenderFactory.java |   239 +
 .../cache/wan/GatewayTransportFilter.java       |    27 +
 .../compression/CompressionException.java       |    43 +
 .../gemfire/compression/Compressor.java         |    48 +
 .../gemfire/compression/SnappyCompressor.java   |   110 +
 .../gemfire/distributed/AbstractLauncher.java   |   926 +
 .../distributed/ClientSocketFactory.java        |    47 +
 .../distributed/DistributedLockService.java     |   393 +
 .../gemfire/distributed/DistributedMember.java  |    80 +
 .../gemfire/distributed/DistributedSystem.java  |  2207 +++
 .../DistributedSystemDisconnectedException.java |    47 +
 .../distributed/DurableClientAttributes.java    |   147 +
 .../distributed/FutureCancelledException.java   |    47 +
 .../distributed/GatewayCancelledException.java  |    46 +
 .../distributed/LeaseExpiredException.java      |    38 +
 .../gemstone/gemfire/distributed/Locator.java   |   553 +
 .../gemfire/distributed/LocatorLauncher.java    |  2051 ++
 .../distributed/LockNotHeldException.java       |    51 +
 .../LockServiceDestroyedException.java          |    51 +
 .../distributed/OplogCancelledException.java    |    47 +
 .../distributed/PoolCancelledException.java     |    47 +
 .../com/gemstone/gemfire/distributed/Role.java  |    56 +
 .../gemfire/distributed/ServerLauncher.java     |  2613 +++
 .../TXManagerCancelledException.java            |    47 +
 .../internal/AbstractDistributionConfig.java    |  1161 ++
 .../distributed/internal/AdminMessageType.java  |    23 +
 .../internal/AtomicLongWithTerminalState.java   |    67 +
 .../internal/CollectingReplyProcessor.java      |    56 +
 .../distributed/internal/ConfigAttribute.java   |    36 +
 .../internal/ConfigAttributeChecker.java        |    31 +
 .../internal/ConfigAttributeDesc.java           |    31 +
 .../internal/ConfigAttributeGetter.java         |    31 +
 .../internal/ConfigAttributeSetter.java         |    31 +
 .../distributed/internal/ConflationKey.java     |    78 +
 .../gemfire/distributed/internal/DM.java        |   467 +
 .../gemfire/distributed/internal/DMStats.java   |   622 +
 .../gemfire/distributed/internal/DSClock.java   |   313 +
 .../internal/DirectReplyProcessor.java          |   172 +
 .../internal/DistributionAdvisee.java           |    93 +
 .../internal/DistributionAdvisor.java           |  1678 ++
 .../internal/DistributionChannel.java           |   166 +
 .../internal/DistributionConfig.java            |  3778 ++++
 .../internal/DistributionConfigImpl.java        |  3533 ++++
 .../internal/DistributionConfigSnapshot.java    |    71 +
 .../internal/DistributionException.java         |    37 +
 .../internal/DistributionManager.java           |  4811 +++++
 .../internal/DistributionMessage.java           |   711 +
 .../internal/DistributionMessageObserver.java   |    75 +
 .../distributed/internal/DistributionStats.java |  2065 ++
 .../distributed/internal/FlowControlParams.java |   114 +
 .../FunctionExecutionPooledExecutor.java        |   311 +
 .../distributed/internal/HealthMonitor.java     |    46 +
 .../distributed/internal/HealthMonitorImpl.java |   148 +
 .../internal/HighPriorityAckedMessage.java      |   235 +
 .../HighPriorityDistributionMessage.java        |    31 +
 .../distributed/internal/IgnoredByManager.java  |    26 +
 .../internal/InternalDistributedSystem.java     |  3079 +++
 .../distributed/internal/InternalLocator.java   |  1488 ++
 .../internal/LocatorLoadSnapshot.java           |   695 +
 .../distributed/internal/LocatorStats.java      |   245 +
 .../internal/LonerDistributionManager.java      |  1001 +
 .../gemfire/distributed/internal/MQueue.java    |    32 +
 .../internal/MembershipListener.java            |    77 +
 .../distributed/internal/MessageFactory.java    |    56 +
 .../distributed/internal/MessageWithReply.java  |    43 +
 .../internal/OverflowQueueWithDMStats.java      |   174 +
 .../distributed/internal/PoolStatHelper.java    |    38 +
 .../internal/PooledDistributionMessage.java     |    34 +
 .../internal/PooledExecutorWithDMStats.java     |   234 +
 .../distributed/internal/ProcessorKeeper21.java |   129 +
 .../distributed/internal/ProductUseLog.java     |   147 +
 .../distributed/internal/ProfileListener.java   |    55 +
 .../distributed/internal/QueueStatHelper.java   |    42 +
 .../internal/ReliableReplyException.java        |    37 +
 .../internal/ReliableReplyProcessor21.java      |   116 +
 .../distributed/internal/ReplyException.java    |   201 +
 .../distributed/internal/ReplyMessage.java      |   364 +
 .../distributed/internal/ReplyProcessor21.java  |  1298 ++
 .../distributed/internal/ReplySender.java       |    39 +
 .../distributed/internal/ResourceEvent.java     |    52 +
 .../internal/ResourceEventsListener.java        |    38 +
 .../internal/RuntimeDistributionConfigImpl.java |   138 +
 .../internal/SerialAckedMessage.java            |   159 +
 .../internal/SerialDistributionMessage.java     |    34 +
 .../SerialQueuedExecutorWithDMStats.java        |    51 +
 .../distributed/internal/ServerLocation.java    |   178 +
 .../distributed/internal/ServerLocator.java     |   486 +
 .../internal/SharedConfiguration.java           |   955 +
 .../distributed/internal/ShutdownMessage.java   |   121 +
 .../gemfire/distributed/internal/Sizeable.java  |    28 +
 .../distributed/internal/SizeableRunnable.java  |    39 +
 .../distributed/internal/StartupMessage.java    |   433 +
 .../internal/StartupMessageData.java            |   231 +
 .../internal/StartupMessageReplyProcessor.java  |   118 +
 .../distributed/internal/StartupOperation.java  |   136 +
 .../internal/StartupResponseMessage.java        |   294 +
 .../StartupResponseWithVersionMessage.java      |   108 +
 .../internal/ThrottledMemQueueStatHelper.java   |    49 +
 .../internal/ThrottledQueueStatHelper.java      |    39 +
 .../ThrottlingMemLinkedQueueWithDMStats.java    |   165 +
 .../internal/WaitForViewInstallation.java       |   126 +
 .../internal/WanLocatorDiscoverer.java          |    31 +
 .../deadlock/DLockDependencyMonitor.java        |   147 +
 .../internal/deadlock/DeadlockDetector.java     |   395 +
 .../internal/deadlock/Dependency.java           |    88 +
 .../internal/deadlock/DependencyGraph.java      |   340 +
 .../internal/deadlock/DependencyMonitor.java    |    45 +
 .../deadlock/DependencyMonitorManager.java      |   107 +
 .../deadlock/GemFireDeadlockDetector.java       |   142 +
 .../internal/deadlock/LocalLockInfo.java        |   101 +
 .../internal/deadlock/LocalThread.java          |   120 +
 .../deadlock/MessageDependencyMonitor.java      |   155 +
 .../internal/deadlock/ThreadReference.java      |    28 +
 .../internal/deadlock/UnsafeThreadLocal.java    |    92 +
 .../internal/direct/DirectChannel.java          |   939 +
 .../internal/direct/DirectChannelListener.java  |    38 +
 .../internal/direct/ShunnedMemberException.java |    34 +
 .../internal/distribution-overview.html         |    42 +
 .../internal/doc-files/config-classes.fig       |   138 +
 .../internal/doc-files/config-classes.gif       |   Bin 0 -> 4205 bytes
 .../doc-files/distribution-managers.fig         |    76 +
 .../doc-files/distribution-managers.gif         |   Bin 0 -> 3267 bytes
 .../internal/locks/Collaboration.java           |   454 +
 .../distributed/internal/locks/DLockBatch.java  |    46 +
 .../internal/locks/DLockBatchId.java            |    31 +
 .../internal/locks/DLockGrantor.java            |  3796 ++++
 .../locks/DLockLessorDepartureHandler.java      |    35 +
 .../internal/locks/DLockQueryProcessor.java     |   519 +
 .../locks/DLockRecoverGrantorProcessor.java     |   460 +
 .../internal/locks/DLockReleaseProcessor.java   |   450 +
 .../internal/locks/DLockRemoteToken.java        |   235 +
 .../internal/locks/DLockRequestProcessor.java   |  1284 ++
 .../internal/locks/DLockService.java            |  3377 ++++
 .../distributed/internal/locks/DLockStats.java  |   887 +
 .../distributed/internal/locks/DLockToken.java  |   572 +
 .../internal/locks/DeposeGrantorProcessor.java  |   210 +
 .../internal/locks/DistributedLockStats.java    |   201 +
 .../internal/locks/DistributedMemberLock.java   |   297 +
 .../internal/locks/DummyDLockStats.java         |   180 +
 .../internal/locks/ElderInitProcessor.java      |   314 +
 .../distributed/internal/locks/ElderState.java  |   399 +
 .../distributed/internal/locks/GrantorInfo.java |    87 +
 .../internal/locks/GrantorRequestProcessor.java |   751 +
 .../locks/LockGrantorDestroyedException.java    |    51 +
 .../internal/locks/LockGrantorId.java           |   243 +
 .../locks/NonGrantorDestroyedProcessor.java     |   308 +
 .../internal/locks/RemoteThread.java            |    88 +
 .../internal/locks/doc-files/elder.fig          |    84 +
 .../internal/locks/doc-files/elder.jpg          |   Bin 0 -> 55182 bytes
 .../internal/locks/doc-files/turks.fig          |   128 +
 .../internal/locks/doc-files/turks.jpg          |   Bin 0 -> 79859 bytes
 .../distributed/internal/locks/package.html     |   313 +
 .../DistributedMembershipListener.java          |    86 +
 .../membership/InternalDistributedMember.java   |  1304 ++
 .../internal/membership/InternalRole.java       |   169 +
 .../internal/membership/MemberAttributes.java   |   124 +
 .../internal/membership/MemberFactory.java      |   109 +
 .../internal/membership/MemberServices.java     |    90 +
 .../internal/membership/MembershipManager.java  |   326 +
 .../internal/membership/MembershipTestHook.java |    40 +
 .../internal/membership/NetMember.java          |    82 +
 .../internal/membership/NetView.java            |   614 +
 .../internal/membership/QuorumChecker.java      |    63 +
 .../internal/membership/gms/GMSMember.java      |   458 +
 .../membership/gms/GMSMemberFactory.java        |   133 +
 .../internal/membership/gms/GMSUtil.java        |   159 +
 .../internal/membership/gms/NetLocator.java     |    32 +
 .../internal/membership/gms/ServiceConfig.java  |   187 +
 .../internal/membership/gms/Services.java       |   387 +
 .../internal/membership/gms/SuspectMember.java  |    58 +
 .../membership/gms/auth/GMSAuthenticator.java   |   235 +
 .../membership/gms/fd/GMSHealthMonitor.java     |  1380 ++
 .../gms/interfaces/Authenticator.java           |    27 +
 .../gms/interfaces/HealthMonitor.java           |    64 +
 .../membership/gms/interfaces/JoinLeave.java    |    73 +
 .../membership/gms/interfaces/Locator.java      |    32 +
 .../membership/gms/interfaces/Manager.java      |   120 +
 .../gms/interfaces/MessageHandler.java          |    30 +
 .../membership/gms/interfaces/Messenger.java    |    81 +
 .../membership/gms/interfaces/Service.java      |    83 +
 .../gms/locator/FindCoordinatorRequest.java     |   148 +
 .../gms/locator/FindCoordinatorResponse.java    |   161 +
 .../membership/gms/locator/GMSLocator.java      |   373 +
 .../membership/gms/locator/GetViewRequest.java  |    49 +
 .../membership/gms/locator/GetViewResponse.java |    64 +
 .../gms/locator/PeerLocatorRequest.java         |    25 +
 .../membership/gms/membership/GMSJoinLeave.java |  2312 +++
 .../membership/gms/messages/HasMemberID.java    |    25 +
 .../gms/messages/HeartbeatMessage.java          |    74 +
 .../gms/messages/HeartbeatRequestMessage.java   |    80 +
 .../gms/messages/InstallViewMessage.java        |   106 +
 .../gms/messages/JoinRequestMessage.java        |    97 +
 .../gms/messages/JoinResponseMessage.java       |   129 +
 .../gms/messages/LeaveRequestMessage.java       |    94 +
 .../gms/messages/NetworkPartitionMessage.java   |    44 +
 .../gms/messages/RemoveMemberMessage.java       |    96 +
 .../gms/messages/SuspectMembersMessage.java     |    91 +
 .../membership/gms/messages/SuspectRequest.java |    72 +
 .../membership/gms/messages/ViewAckMessage.java |   103 +
 .../gms/messenger/AddressManager.java           |   121 +
 .../membership/gms/messenger/GMSPingPonger.java |    65 +
 .../gms/messenger/GMSQuorumChecker.java         |   274 +
 .../membership/gms/messenger/JGAddress.java     |   221 +
 .../gms/messenger/JGroupsMessenger.java         |  1116 ++
 .../membership/gms/messenger/StatRecorder.java  |   162 +
 .../membership/gms/messenger/Transport.java     |   163 +
 .../gms/mgr/GMSMembershipManager.java           |  2652 +++
 .../membership/gms/mgr/LocalViewMessage.java    |    85 +
 .../internal/membership/gms/package.html        |    57 +
 .../gemfire/distributed/internal/package.html   |    55 +
 .../internal/streaming/StreamingOperation.java  |   613 +
 .../internal/tcpserver/InfoRequest.java         |    41 +
 .../internal/tcpserver/InfoResponse.java        |    56 +
 .../internal/tcpserver/ShutdownRequest.java     |    39 +
 .../internal/tcpserver/ShutdownResponse.java    |    40 +
 .../internal/tcpserver/TcpClient.java           |   251 +
 .../internal/tcpserver/TcpHandler.java          |    61 +
 .../internal/tcpserver/TcpServer.java           |   546 +
 .../internal/tcpserver/VersionRequest.java      |    41 +
 .../internal/tcpserver/VersionResponse.java     |    54 +
 .../unsafe/RegisterSignalHandlerSupport.java    |    35 +
 .../gemstone/gemfire/distributed/package.html   |    37 +
 .../doc-files/data-serialization-exceptions.fig |   135 +
 .../doc-files/data-serialization-exceptions.gif |   Bin 0 -> 3666 bytes
 .../gemstone/gemfire/i18n/LogWriterI18n.java    |   420 +
 .../com/gemstone/gemfire/i18n/StringId.java     |   161 +
 .../gemfire/internal/AbstractConfig.java        |   403 +
 .../internal/AbstractStatisticsFactory.java     |   340 +
 .../gemfire/internal/ArchiveSplitter.java       |   522 +
 .../com/gemstone/gemfire/internal/Assert.java   |   177 +
 .../gemfire/internal/AvailablePort.java         |   588 +
 .../com/gemstone/gemfire/internal/Banner.java   |   172 +
 .../gemfire/internal/ByteArrayDataInput.java    |   458 +
 .../internal/ByteBufferOutputStream.java        |   102 +
 .../gemfire/internal/ByteBufferWriter.java      |    35 +
 .../gemfire/internal/ClassLoadUtil.java         |   124 +
 .../gemfire/internal/ClassPathLoader.java       |   726 +
 .../com/gemstone/gemfire/internal/Config.java   |   110 +
 .../gemstone/gemfire/internal/ConfigSource.java |   108 +
 .../gemfire/internal/ConnectionWatcher.java     |    41 +
 .../gemfire/internal/CopyOnWriteHashSet.java    |   177 +
 .../com/gemstone/gemfire/internal/DSCODE.java   |   416 +
 .../gemstone/gemfire/internal/DSFIDFactory.java |  1403 ++
 .../internal/DSFIDNotFoundException.java        |    52 +
 .../internal/DataSerializableFixedID.java       |   912 +
 .../gemfire/internal/DistributionLocator.java   |   190 +
 .../internal/DummyStatisticsFactory.java        |   134 +
 .../gemfire/internal/DummyStatisticsImpl.java   |   199 +
 .../gemfire/internal/ExternalizableDSFID.java   |    43 +
 .../com/gemstone/gemfire/internal/FileUtil.java |   331 +
 .../gemfire/internal/GemFireStatSampler.java    |   507 +
 .../gemfire/internal/GemFireUtilLauncher.java   |   166 +
 .../gemfire/internal/GemFireVersion.java        |   677 +
 .../internal/GfeConsoleReaderFactory.java       |    87 +
 .../gemfire/internal/HeapDataOutputStream.java  |  1374 ++
 .../gemfire/internal/HistogramStats.java        |    82 +
 .../gemfire/internal/HostStatHelper.java        |   289 +
 .../gemfire/internal/HostStatSampler.java       |   546 +
 .../InsufficientDiskSpaceException.java         |    54 +
 .../internal/InternalDataSerializer.java        |  4057 ++++
 .../gemfire/internal/InternalEntity.java        |    30 +
 .../gemfire/internal/InternalInstantiator.java  |  1061 +
 .../InternalStatisticsDisabledException.java    |    70 +
 .../gemfire/internal/JarClassLoader.java        |   701 +
 .../gemstone/gemfire/internal/JarDeployer.java  |   639 +
 .../gemfire/internal/LinuxProcFsStatistics.java |   786 +
 .../gemfire/internal/LinuxProcessStats.java     |    79 +
 .../gemfire/internal/LinuxSystemStats.java      |   311 +
 .../gemfire/internal/LocalStatListener.java     |    41 +
 .../internal/LocalStatisticsFactory.java        |   101 +
 .../gemfire/internal/LocalStatisticsImpl.java   |   269 +
 .../gemstone/gemfire/internal/ManagerInfo.java  |   386 +
 .../gemfire/internal/MigrationClient.java       |   260 +
 .../gemfire/internal/MigrationServer.java       |   566 +
 .../gemstone/gemfire/internal/NanoTimer.java    |   186 +
 .../gemfire/internal/NullDataOutputStream.java  |   379 +
 .../gemstone/gemfire/internal/OSProcess.java    |   753 +
 .../gemfire/internal/OSXProcessStats.java       |    83 +
 .../gemfire/internal/OSXSystemStats.java        |   228 +
 .../gemfire/internal/ObjIdConcurrentMap.java    |  1366 ++
 .../com/gemstone/gemfire/internal/ObjIdMap.java |   337 +
 .../internal/ObjToByteArraySerializer.java      |    35 +
 .../gemfire/internal/OneTaskOnlyExecutor.java   |   175 +
 .../gemfire/internal/OsStatisticsFactory.java   |    42 +
 .../gemfire/internal/PdxSerializerObject.java   |    33 +
 .../gemfire/internal/ProcessOutputReader.java   |   135 +
 .../gemstone/gemfire/internal/ProcessStats.java |    61 +
 .../gemstone/gemfire/internal/PureJavaMode.java |    80 +
 ...cheduledThreadPoolExecutorWithKeepAlive.java |   313 +
 .../com/gemstone/gemfire/internal/Sendable.java |    42 +
 .../gemfire/internal/SerializationVersions.java |    42 +
 .../com/gemstone/gemfire/internal/SetUtils.java |    68 +
 .../gemfire/internal/SharedLibrary.java         |   226 +
 .../gemfire/internal/SimpleStatSampler.java     |   114 +
 .../com/gemstone/gemfire/internal/SmHelper.java |   183 +
 .../gemstone/gemfire/internal/SocketCloser.java |   257 +
 .../gemfire/internal/SocketCreator.java         |  1364 ++
 .../gemfire/internal/SocketIOWithTimeout.java   |   491 +
 .../gemfire/internal/SocketInputStream.java     |   181 +
 .../gemfire/internal/SocketInputWrapper.java    |    93 +
 .../gemfire/internal/SocketOutputStream.java    |   174 +
 .../gemstone/gemfire/internal/SocketUtils.java  |   220 +
 .../gemfire/internal/SolarisProcessStats.java   |   217 +
 .../gemfire/internal/SolarisSystemStats.java    |   428 +
 .../gemfire/internal/StatArchiveFormat.java     |   197 +
 .../gemfire/internal/StatArchiveReader.java     |  3338 ++++
 .../gemfire/internal/StatArchiveWriter.java     |   748 +
 .../gemfire/internal/StatSamplerStats.java      |   123 +
 .../internal/StatisticDescriptorImpl.java       |   385 +
 .../gemfire/internal/StatisticsImpl.java        |   454 +
 .../gemfire/internal/StatisticsManager.java     |    79 +
 .../internal/StatisticsTypeFactoryImpl.java     |   141 +
 .../gemfire/internal/StatisticsTypeImpl.java    |   260 +
 .../gemfire/internal/StatisticsTypeXml.java     |   280 +
 .../gemstone/gemfire/internal/SystemAdmin.java  |  2305 +++
 .../gemfire/internal/SystemFailureTestHook.java |    48 +
 .../gemstone/gemfire/internal/SystemTimer.java  |   467 +
 .../gemfire/internal/UniqueIdGenerator.java     |   257 +
 .../com/gemstone/gemfire/internal/VMStats.java  |    87 +
 .../gemfire/internal/VMStatsContract.java       |    36 +
 .../internal/VMStatsContractFactory.java        |    60 +
 .../com/gemstone/gemfire/internal/Version.java  |   636 +
 .../internal/VersionedDataInputStream.java      |    67 +
 .../internal/VersionedDataOutputStream.java     |    57 +
 .../internal/VersionedDataSerializable.java     |    34 +
 .../gemfire/internal/VersionedDataStream.java   |    53 +
 .../gemfire/internal/VersionedObjectInput.java  |   245 +
 .../gemfire/internal/VersionedObjectOutput.java |   199 +
 .../gemfire/internal/WindowsProcessStats.java   |   160 +
 .../gemfire/internal/WindowsSystemStats.java    |   267 +
 .../internal/admin/AdminBridgeServer.java       |    33 +
 .../gemstone/gemfire/internal/admin/Alert.java  |    69 +
 .../gemfire/internal/admin/AlertListener.java   |    29 +
 .../gemfire/internal/admin/ApplicationVM.java   |    36 +
 .../gemfire/internal/admin/CacheCollector.java  |   277 +
 .../gemfire/internal/admin/CacheInfo.java       |   102 +
 .../gemfire/internal/admin/CacheSnapshot.java   |    34 +
 .../admin/ClientHealthMonitoringRegion.java     |   117 +
 .../internal/admin/ClientMembershipMessage.java |   187 +
 .../internal/admin/ClientStatsManager.java      |   263 +
 .../internal/admin/CompoundEntrySnapshot.java   |   201 +
 .../internal/admin/CompoundRegionSnapshot.java  |   387 +
 .../gemfire/internal/admin/DLockInfo.java       |    35 +
 .../gemfire/internal/admin/EntrySnapshot.java   |    29 +
 .../gemfire/internal/admin/EntryValueNode.java  |    53 +
 .../gemfire/internal/admin/GemFireVM.java       |   396 +
 .../gemfire/internal/admin/GfManagerAgent.java  |   112 +
 .../internal/admin/GfManagerAgentConfig.java    |    87 +
 .../internal/admin/GfManagerAgentFactory.java   |    42 +
 .../gemfire/internal/admin/GfObject.java        |    28 +
 .../gemfire/internal/admin/HealthListener.java  |    44 +
 .../internal/admin/JoinLeaveListener.java       |    27 +
 .../gemfire/internal/admin/ListenerIdMap.java   |   318 +
 .../gemfire/internal/admin/RegionSnapshot.java  |    31 +
 .../gemfire/internal/admin/SSLConfig.java       |   131 +
 .../gemfire/internal/admin/SnapshotClient.java  |    38 +
 .../gemstone/gemfire/internal/admin/Stat.java   |    44 +
 .../gemfire/internal/admin/StatAlert.java       |   140 +
 .../internal/admin/StatAlertDefinition.java     |   103 +
 .../internal/admin/StatAlertsManager.java       |   408 +
 .../gemfire/internal/admin/StatListener.java    |    43 +
 .../gemfire/internal/admin/StatResource.java    |    42 +
 .../gemfire/internal/admin/TransportConfig.java |    27 +
 .../admin/doc-files/class-hierarchy.fig         |   224 +
 .../admin/doc-files/class-hierarchy.gif         |   Bin 0 -> 11971 bytes
 .../gemfire/internal/admin/package.html         |    29 +
 .../admin/remote/AddHealthListenerRequest.java  |    89 +
 .../admin/remote/AddHealthListenerResponse.java |    76 +
 .../admin/remote/AddStatListenerRequest.java    |    85 +
 .../admin/remote/AddStatListenerResponse.java   |    79 +
 .../remote/AdminConsoleDisconnectMessage.java   |   125 +
 .../admin/remote/AdminConsoleMessage.java       |    83 +
 .../admin/remote/AdminFailureResponse.java      |    73 +
 .../remote/AdminMultipleReplyProcessor.java     |    91 +
 .../internal/admin/remote/AdminRegion.java      |   581 +
 .../admin/remote/AdminReplyProcessor.java       |   148 +
 .../internal/admin/remote/AdminRequest.java     |   193 +
 .../internal/admin/remote/AdminResponse.java    |    90 +
 .../internal/admin/remote/AdminWaiters.java     |   184 +
 .../admin/remote/AlertLevelChangeMessage.java   |    96 +
 .../admin/remote/AlertListenerMessage.java      |   147 +
 .../admin/remote/AlertsNotificationMessage.java |   110 +
 .../admin/remote/AppCacheSnapshotMessage.java   |   163 +
 .../admin/remote/BridgeServerRequest.java       |   202 +
 .../admin/remote/BridgeServerResponse.java      |   181 +
 .../admin/remote/CacheConfigRequest.java        |    88 +
 .../admin/remote/CacheConfigResponse.java       |   119 +
 .../internal/admin/remote/CacheDisplay.java     |    86 +
 .../internal/admin/remote/CacheInfoRequest.java |    73 +
 .../admin/remote/CacheInfoResponse.java         |    83 +
 .../admin/remote/CancelStatListenerRequest.java |    79 +
 .../remote/CancelStatListenerResponse.java      |    74 +
 .../internal/admin/remote/Cancellable.java      |    27 +
 .../admin/remote/CancellationMessage.java       |    70 +
 .../admin/remote/CancellationRegistry.java      |    95 +
 .../remote/ChangeRefreshIntervalMessage.java    |    98 +
 .../internal/admin/remote/CliLegacyMessage.java |    58 +
 .../admin/remote/ClientHealthStats.java         |   308 +
 .../internal/admin/remote/CompactRequest.java   |   145 +
 .../internal/admin/remote/CompactResponse.java  |    66 +
 .../admin/remote/DestroyEntryMessage.java       |   100 +
 .../admin/remote/DestroyRegionMessage.java      |    96 +
 .../admin/remote/DistributionLocatorId.java     |   394 +
 .../internal/admin/remote/DummyEntry.java       |    77 +
 .../admin/remote/DurableClientInfoRequest.java  |   109 +
 .../admin/remote/DurableClientInfoResponse.java |   108 +
 .../admin/remote/EntryValueNodeImpl.java        |   393 +
 .../admin/remote/FetchDistLockInfoRequest.java  |    68 +
 .../admin/remote/FetchDistLockInfoResponse.java |    93 +
 .../remote/FetchHealthDiagnosisRequest.java     |    91 +
 .../remote/FetchHealthDiagnosisResponse.java    |    92 +
 .../internal/admin/remote/FetchHostRequest.java |    70 +
 .../admin/remote/FetchHostResponse.java         |   173 +
 .../remote/FetchResourceAttributesRequest.java  |    70 +
 .../remote/FetchResourceAttributesResponse.java |    81 +
 .../admin/remote/FetchStatsRequest.java         |    72 +
 .../admin/remote/FetchStatsResponse.java        |   145 +
 .../admin/remote/FetchSysCfgRequest.java        |    76 +
 .../admin/remote/FetchSysCfgResponse.java       |    77 +
 .../remote/FlushAppCacheSnapshotMessage.java    |    69 +
 .../admin/remote/HealthListenerMessage.java     |    89 +
 .../remote/InspectionClasspathManager.java      |    90 +
 .../admin/remote/LicenseInfoRequest.java        |    72 +
 .../admin/remote/LicenseInfoResponse.java       |    79 +
 .../remote/MissingPersistentIDsRequest.java     |   141 +
 .../remote/MissingPersistentIDsResponse.java    |   115 +
 .../admin/remote/ObjectDetailsRequest.java      |   103 +
 .../admin/remote/ObjectDetailsResponse.java     |   155 +
 .../admin/remote/ObjectNamesRequest.java        |    89 +
 .../admin/remote/ObjectNamesResponse.java       |    98 +
 .../PrepareRevokePersistentIDRequest.java       |   127 +
 .../remote/RefreshMemberSnapshotRequest.java    |    74 +
 .../remote/RefreshMemberSnapshotResponse.java   |    95 +
 .../admin/remote/RegionAdminMessage.java        |    66 +
 .../admin/remote/RegionAdminRequest.java        |    74 +
 .../admin/remote/RegionAttributesRequest.java   |    74 +
 .../admin/remote/RegionAttributesResponse.java  |    75 +
 .../internal/admin/remote/RegionRequest.java    |   175 +
 .../internal/admin/remote/RegionResponse.java   |   149 +
 .../admin/remote/RegionSizeRequest.java         |    90 +
 .../admin/remote/RegionSizeResponse.java        |    96 +
 .../admin/remote/RegionStatisticsRequest.java   |    74 +
 .../admin/remote/RegionStatisticsResponse.java  |    75 +
 .../remote/RegionSubRegionSizeRequest.java      |    94 +
 .../remote/RegionSubRegionsSizeResponse.java    |   162 +
 .../internal/admin/remote/RemoteAlert.java      |   205 +
 .../admin/remote/RemoteApplicationVM.java       |    61 +
 .../admin/remote/RemoteBridgeServer.java        |   300 +
 .../internal/admin/remote/RemoteCacheInfo.java  |   192 +
 .../admin/remote/RemoteCacheStatistics.java     |    87 +
 .../internal/admin/remote/RemoteDLockInfo.java  |   115 +
 .../admin/remote/RemoteEntrySnapshot.java       |   131 +
 .../internal/admin/remote/RemoteGemFireVM.java  |   998 +
 .../admin/remote/RemoteGfManagerAgent.java      |  1489 ++
 .../internal/admin/remote/RemoteObjectName.java |    95 +
 .../admin/remote/RemoteRegionAttributes.java    |   702 +
 .../admin/remote/RemoteRegionSnapshot.java      |   158 +
 .../internal/admin/remote/RemoteStat.java       |   118 +
 .../admin/remote/RemoteStatResource.java        |   154 +
 .../admin/remote/RemoteTransportConfig.java     |   376 +
 .../remote/RemoveHealthListenerRequest.java     |    80 +
 .../remote/RemoveHealthListenerResponse.java    |    67 +
 .../admin/remote/ResetHealthStatusRequest.java  |    80 +
 .../admin/remote/ResetHealthStatusResponse.java |    72 +
 .../admin/remote/RevokePersistentIDRequest.java |   103 +
 .../remote/RevokePersistentIDResponse.java      |    36 +
 .../admin/remote/RootRegionRequest.java         |    76 +
 .../admin/remote/RootRegionResponse.java        |   115 +
 .../remote/ShutdownAllGatewayHubsRequest.java   |    68 +
 .../admin/remote/ShutdownAllRequest.java        |   301 +
 .../admin/remote/ShutdownAllResponse.java       |    80 +
 .../admin/remote/SnapshotResultMessage.java     |    85 +
 .../remote/StatAlertsManagerAssignMessage.java  |   152 +
 .../admin/remote/StatListenerMessage.java       |   118 +
 .../admin/remote/StoreSysCfgRequest.java        |    81 +
 .../admin/remote/StoreSysCfgResponse.java       |    77 +
 .../internal/admin/remote/SubRegionRequest.java |    74 +
 .../admin/remote/SubRegionResponse.java         |   100 +
 .../internal/admin/remote/TailLogRequest.java   |    62 +
 .../internal/admin/remote/TailLogResponse.java  |   169 +
 .../remote/UpdateAlertDefinitionMessage.java    |   162 +
 .../admin/remote/VersionInfoRequest.java        |    73 +
 .../admin/remote/VersionInfoResponse.java       |    74 +
 .../admin/remote/VersionMismatchAlert.java      |    66 +
 .../gemfire/internal/admin/remote/package.html  |    41 +
 .../admin/statalerts/BaseDecoratorImpl.java     |   224 +
 .../statalerts/DummyStatisticInfoImpl.java      |   146 +
 .../admin/statalerts/FunctionDecoratorImpl.java |   133 +
 .../admin/statalerts/FunctionHelper.java        |   257 +
 .../statalerts/GaugeThresholdDecoratorImpl.java |   156 +
 .../statalerts/MultiAttrDefinitionImpl.java     |   207 +
 .../NumberThresholdDecoratorImpl.java           |   153 +
 .../statalerts/SingleAttrDefinitionImpl.java    |   213 +
 .../admin/statalerts/StatisticInfo.java         |    85 +
 .../admin/statalerts/StatisticInfoImpl.java     |   157 +
 .../cache/AbstractBucketRegionQueue.java        |   563 +
 .../internal/cache/AbstractCacheServer.java     |   407 +
 .../cache/AbstractDiskLRURegionEntry.java       |    42 +
 .../internal/cache/AbstractDiskRegion.java      |   992 +
 .../internal/cache/AbstractDiskRegionEntry.java |    76 +
 .../internal/cache/AbstractLRURegionEntry.java  |    46 +
 .../internal/cache/AbstractLRURegionMap.java    |   861 +
 .../cache/AbstractOplogDiskRegionEntry.java     |   173 +
 .../gemfire/internal/cache/AbstractRegion.java  |  2134 ++
 .../internal/cache/AbstractRegionEntry.java     |  2243 +++
 .../internal/cache/AbstractRegionMap.java       |  4164 ++++
 .../internal/cache/AbstractUpdateOperation.java |   338 +
 .../gemfire/internal/cache/AcceptHelper.java    |   101 +
 .../cache/AddCacheServerProfileMessage.java     |   161 +
 .../gemfire/internal/cache/BackupLock.java      |    91 +
 .../gemfire/internal/cache/BucketAdvisor.java   |  3002 +++
 .../gemfire/internal/cache/BucketDump.java      |   144 +
 .../internal/cache/BucketNotFoundException.java |    38 +
 .../cache/BucketPersistenceAdvisor.java         |   463 +
 .../gemfire/internal/cache/BucketRegion.java    |  2622 +++
 .../internal/cache/BucketRegionEvictior.java    |    63 +
 .../internal/cache/BucketRegionQueue.java       |   548 +
 .../internal/cache/BucketServerLocation.java    |    88 +
 .../internal/cache/BucketServerLocation66.java  |   113 +
 .../cache/BytesAndBitsForCompactor.java         |    94 +
 .../internal/cache/CacheClientStatus.java       |   101 +
 .../gemfire/internal/cache/CacheConfig.java     |   228 +
 .../cache/CacheDistributionAdvisee.java         |    58 +
 .../cache/CacheDistributionAdvisor.java         |  1260 ++
 .../internal/cache/CacheLifecycleListener.java  |    37 +
 .../gemfire/internal/cache/CacheObserver.java   |   190 +
 .../internal/cache/CacheObserverAdapter.java    |   154 +
 .../internal/cache/CacheObserverHolder.java     |    78 +
 .../gemfire/internal/cache/CachePerfStats.java  |  1419 ++
 .../internal/cache/CacheServerAdvisor.java      |   173 +
 .../gemfire/internal/cache/CacheServerImpl.java |   832 +
 .../internal/cache/CacheServerLauncher.java     |  1393 ++
 .../gemfire/internal/cache/CacheService.java    |    42 +
 .../internal/cache/CacheStatisticsImpl.java     |   111 +
 .../internal/cache/CachedDeserializable.java    |   114 +
 .../cache/CachedDeserializableFactory.java      |   275 +
 .../internal/cache/ClientRegionEventImpl.java   |   117 +
 .../internal/cache/ClientServerObserver.java    |    99 +
 .../cache/ClientServerObserverAdapter.java      |   116 +
 .../cache/ClientServerObserverHolder.java       |    62 +
 .../cache/ClientSubscriptionConfigImpl.java     |   178 +
 .../internal/cache/CloseCacheMessage.java       |   116 +
 .../cache/ClusterConfigurationLoader.java       |   245 +
 .../internal/cache/ColocationHelper.java        |   569 +
 .../internal/cache/CommitReplyException.java    |    73 +
 .../internal/cache/CompactableOplog.java        |    37 +
 .../gemfire/internal/cache/Conflatable.java     |    76 +
 .../internal/cache/ControllerAdvisor.java       |   171 +
 .../internal/cache/CountingDataInputStream.java |   125 +
 .../internal/cache/CreateRegionProcessor.java   |   914 +
 .../internal/cache/CustomEntryExpiryTask.java   |    49 +
 .../cache/CustomEvictionAttributesImpl.java     |    36 +
 .../internal/cache/DataLocationException.java   |    43 +
 .../internal/cache/DestroyOperation.java        |   303 +
 .../cache/DestroyPartitionedRegionMessage.java  |   252 +
 .../internal/cache/DestroyRegionOperation.java  |   547 +
 .../gemfire/internal/cache/DestroyedEntry.java  |    85 +
 .../internal/cache/DirectReplyMessage.java      |    58 +
 .../gemfire/internal/cache/DirectoryHolder.java |   123 +
 .../internal/cache/DiskDirectoryStats.java      |   117 +
 .../gemfire/internal/cache/DiskEntry.java       |  2028 ++
 .../gemstone/gemfire/internal/cache/DiskId.java |   730 +
 .../gemfire/internal/cache/DiskInitFile.java    |  2877 +++
 .../gemfire/internal/cache/DiskRegion.java      |   876 +
 .../gemfire/internal/cache/DiskRegionStats.java |   326 +
 .../internal/cache/DiskStoreAttributes.java     |   196 +
 .../gemfire/internal/cache/DiskStoreBackup.java |    98 +
 .../internal/cache/DiskStoreFactoryImpl.java    |   291 +
 .../gemfire/internal/cache/DiskStoreImpl.java   |  4873 +++++
 .../internal/cache/DiskStoreMonitor.java        |   413 +
 .../internal/cache/DiskStoreObserver.java       |    63 +
 .../gemfire/internal/cache/DiskStoreStats.java  |   528 +
 .../gemfire/internal/cache/DiskStoreTask.java   |    27 +
 .../internal/cache/DiskWriteAttributesImpl.java |   564 +
 .../internal/cache/DistPeerTXStateStub.java     |   374 +
 .../cache/DistTXAdjunctCommitMessage.java       |    51 +
 .../internal/cache/DistTXCommitMessage.java     |   500 +
 .../cache/DistTXCoordinatorInterface.java       |    73 +
 .../internal/cache/DistTXPrecommitMessage.java  |   548 +
 .../internal/cache/DistTXRollbackMessage.java   |   507 +
 .../gemfire/internal/cache/DistTXState.java     |   746 +
 .../cache/DistTXStateOnCoordinator.java         |   416 +
 .../internal/cache/DistTXStateProxyImpl.java    |    48 +
 .../DistTXStateProxyImplOnCoordinator.java      |  1068 +
 .../cache/DistTXStateProxyImplOnDatanode.java   |   128 +
 .../cache/DistributedCacheOperation.java        |  1615 ++
 .../cache/DistributedClearOperation.java        |   356 +
 .../cache/DistributedPutAllOperation.java       |  1384 ++
 .../internal/cache/DistributedRegion.java       |  4311 +++++
 ...stributedRegionFunctionStreamingMessage.java |   460 +
 .../cache/DistributedRemoveAllOperation.java    |  1097 ++
 .../cache/DistributedTombstoneOperation.java    |   227 +
 .../internal/cache/DummyCachePerfStats.java     |   485 +
 .../internal/cache/DynamicRegionAttributes.java |    52 +
 .../cache/DynamicRegionFactoryImpl.java         |    44 +
 .../gemfire/internal/cache/EntriesMap.java      |   155 +
 .../gemfire/internal/cache/EntriesSet.java      |   294 +
 .../gemfire/internal/cache/EntryBits.java       |   128 +
 .../gemfire/internal/cache/EntryEventImpl.java  |  3142 +++
 .../gemfire/internal/cache/EntryExpiryTask.java |   358 +
 .../internal/cache/EntryOperationImpl.java      |   119 +
 .../gemfire/internal/cache/EntrySnapshot.java   |   285 +
 .../internal/cache/EnumListenerEvent.java       |   475 +
 .../gemfire/internal/cache/EventID.java         |   804 +
 .../internal/cache/EventStateHelper.java        |   196 +
 .../gemfire/internal/cache/EventTracker.java    |   812 +
 .../internal/cache/EvictionAttributesImpl.java  |   243 +
 .../gemfire/internal/cache/EvictorService.java  |   285 +
 .../internal/cache/ExpirationScheduler.java     |   106 +
 .../gemfire/internal/cache/ExpiryTask.java      |   540 +
 .../internal/cache/ExportDiskRegion.java        |    84 +
 .../gemfire/internal/cache/FilterProfile.java   |  2218 +++
 .../internal/cache/FilterRoutingInfo.java       |   519 +
 .../cache/FindDurableQueueProcessor.java        |   256 +
 .../internal/cache/FindRemoteTXMessage.java     |   281 +
 .../internal/cache/FindVersionTagOperation.java |   254 +
 .../cache/FixedPartitionAttributesImpl.java     |   156 +
 .../internal/cache/ForceReattemptException.java |   121 +
 .../cache/ForceableLinkedBlockingQueue.java     |   864 +
 .../FunctionStreamingOrderedReplyMessage.java   |    64 +
 .../cache/FunctionStreamingReplyMessage.java    |   145 +
 .../internal/cache/GatewayEventFilter.java      |    27 +
 .../internal/cache/GemFireCacheImpl.java        |  5467 ++++++
 .../internal/cache/GemfireCacheHelper.java      |    38 +
 .../gemfire/internal/cache/GridAdvisor.java     |   442 +
 .../gemfire/internal/cache/HARegion.java        |   618 +
 .../internal/cache/HDFSLRURegionMap.java        |   112 +
 .../gemfire/internal/cache/HDFSRegionMap.java   |    33 +
 .../internal/cache/HDFSRegionMapDelegate.java   |   541 +
 .../internal/cache/HDFSRegionMapImpl.java       |    75 +
 .../internal/cache/HasCachePerfStats.java       |    22 +
 .../internal/cache/IdentityArrayList.java       |   473 +
 .../gemfire/internal/cache/ImageState.java      |    89 +
 .../cache/InMemoryPersistentMemberView.java     |   136 +
 .../internal/cache/IncomingGatewayStatus.java   |    83 +
 .../internal/cache/InitialImageFlowControl.java |   253 +
 .../internal/cache/InitialImageOperation.java   |  4310 +++++
 .../gemfire/internal/cache/InlineKeyHelper.java |    71 +
 .../gemfire/internal/cache/InterestEvent.java   |    68 +
 .../gemfire/internal/cache/InterestFilter.java  |    34 +
 .../cache/InterestRegistrationEventImpl.java    |   152 +
 .../gemfire/internal/cache/InternalCache.java   |    52 +
 .../internal/cache/InternalCacheEvent.java      |    87 +
 .../internal/cache/InternalDataView.java        |   255 +
 .../internal/cache/InternalRegionArguments.java |   337 +
 .../internal/cache/InvalidateOperation.java     |   236 +
 .../InvalidatePartitionedRegionMessage.java     |   102 +
 .../cache/InvalidateRegionOperation.java        |   108 +
 .../cache/JtaAfterCompletionMessage.java        |   128 +
 .../cache/JtaBeforeCompletionMessage.java       |    82 +
 .../gemfire/internal/cache/KeyInfo.java         |   129 +
 .../internal/cache/KeyWithRegionContext.java    |    71 +
 .../gemfire/internal/cache/ListOfDeltas.java    |   101 +
 .../internal/cache/LoaderHelperFactory.java     |    40 +
 .../internal/cache/LoaderHelperImpl.java        |   169 +
 .../gemfire/internal/cache/LocalDataSet.java    |   750 +
 .../gemfire/internal/cache/LocalRegion.java     | 12975 +++++++++++++
 .../internal/cache/LocalRegionDataView.java     |   273 +
 .../cache/MemberFunctionStreamingMessage.java   |   416 +
 .../cache/MinimumSystemRequirements.java        |    92 +
 .../cache/NetSearchExpirationCalculator.java    |    49 +
 .../gemstone/gemfire/internal/cache/Node.java   |   187 +
 .../internal/cache/NonLocalRegionEntry.java     |   579 +
 .../cache/NonLocalRegionEntryWithStats.java     |    86 +
 .../internal/cache/OffHeapRegionEntry.java      |    42 +
 .../cache/OfflineCompactionDiskRegion.java      |   124 +
 .../gemstone/gemfire/internal/cache/OpType.java |    59 +
 .../gemstone/gemfire/internal/cache/Oplog.java  |  7969 ++++++++
 .../gemfire/internal/cache/OplogSet.java        |    34 +
 .../internal/cache/OrderedTombstoneMap.java     |   123 +
 .../gemfire/internal/cache/OverflowOplog.java   |  1613 ++
 .../internal/cache/OverflowOplogSet.java        |   328 +
 .../internal/cache/PRContainsValueFunction.java |    60 +
 .../internal/cache/PRHARedundancyProvider.java  |  2384 +++
 .../internal/cache/PRQueryProcessor.java        |   658 +
 .../internal/cache/PRSystemPropertyGetter.java  |    70 +
 .../internal/cache/PartitionAttributesImpl.java |   828 +
 .../internal/cache/PartitionRegionConfig.java   |   477 +
 .../cache/PartitionRegionConfigValidator.java   |   511 +
 .../internal/cache/PartitionedRegion.java       | 11398 +++++++++++
 .../PartitionedRegionBucketMgmtHelper.java      |    54 +
 .../cache/PartitionedRegionDataStore.java       |  3284 ++++
 .../cache/PartitionedRegionDataView.java        |   142 +
 .../cache/PartitionedRegionException.java       |    48 +
 .../internal/cache/PartitionedRegionHelper.java |  1132 ++
 .../cache/PartitionedRegionQueryEvaluator.java  |  1486 ++
 .../internal/cache/PartitionedRegionStats.java  |  1267 ++
 .../internal/cache/PartitionedRegionStatus.java |    86 +
 .../gemfire/internal/cache/PeerTXStateStub.java |   257 +
 .../internal/cache/PersistentOplogSet.java      |  1184 ++
 .../internal/cache/PlaceHolderDiskRegion.java   |   207 +
 .../gemfire/internal/cache/PoolFactoryImpl.java |   529 +
 .../gemfire/internal/cache/PoolManagerImpl.java |   336 +
 .../gemfire/internal/cache/PoolStats.java       |   319 +
 .../cache/PreferBytesCachedDeserializable.java  |   157 +
 .../internal/cache/PrimaryBucketException.java  |    49 +
 .../cache/ProfileExchangeProcessor.java         |    41 +
 .../internal/cache/ProxyBucketRegion.java       |   657 +
 .../gemfire/internal/cache/ProxyRegionMap.java  |   794 +
 .../cache/PutAllPartialResultException.java     |   229 +
 .../gemfire/internal/cache/QueuedOperation.java |   196 +
 .../internal/cache/RegionClearedException.java  |    62 +
 .../gemfire/internal/cache/RegionEntry.java     |   519 +
 .../internal/cache/RegionEntryContext.java      |    41 +
 .../internal/cache/RegionEntryFactory.java      |    50 +
 .../gemfire/internal/cache/RegionEventImpl.java |   352 +
 .../internal/cache/RegionEvictorTask.java       |   144 +
 .../internal/cache/RegionExpiryTask.java        |   162 +
 .../internal/cache/RegionFactoryImpl.java       |    50 +
 .../internal/cache/RegionIdleExpiryTask.java    |    73 +
 .../gemfire/internal/cache/RegionListener.java  |    46 +
 .../gemfire/internal/cache/RegionMap.java       |   404 +
 .../internal/cache/RegionMapFactory.java        |    76 +
 .../gemfire/internal/cache/RegionQueue.java     |   158 +
 .../internal/cache/RegionQueueException.java    |    49 +
 .../gemfire/internal/cache/RegionStatus.java    |    88 +
 .../internal/cache/RegionTTLExpiryTask.java     |    75 +
 .../internal/cache/ReleaseClearLockMessage.java |   113 +
 .../cache/ReliableDistributionData.java         |    43 +
 .../internal/cache/ReliableMessageQueue.java    |    66 +
 .../cache/ReliableMessageQueueFactory.java      |    43 +
 .../cache/ReliableMessageQueueFactoryImpl.java  |   230 +
 .../cache/RemoteContainsKeyValueMessage.java    |   342 +
 .../internal/cache/RemoteDestroyMessage.java    |   745 +
 .../internal/cache/RemoteFetchEntryMessage.java |   386 +
 .../cache/RemoteFetchVersionMessage.java        |   261 +
 .../internal/cache/RemoteGetMessage.java        |   462 +
 .../internal/cache/RemoteInvalidateMessage.java |   439 +
 .../cache/RemoteOperationException.java         |   119 +
 .../internal/cache/RemoteOperationMessage.java  |   656 +
 .../RemoteOperationMessageWithDirectReply.java  |    85 +
 .../internal/cache/RemotePutAllMessage.java     |   549 +
 .../internal/cache/RemotePutMessage.java        |  1236 ++
 .../internal/cache/RemoteRegionOperation.java   |   224 +
 .../internal/cache/RemoteRemoveAllMessage.java  |   531 +
 .../gemfire/internal/cache/RoleEventImpl.java   |    96 +
 .../cache/SearchLoadAndWriteProcessor.java      |  2802 +++
 .../internal/cache/SendQueueOperation.java      |   191 +
 .../internal/cache/SerializationHelper.java     |    24 +
 .../internal/cache/ServerPingMessage.java       |   136 +
 .../internal/cache/StateFlushOperation.java     |   783 +
 .../cache/StoreAllCachedDeserializable.java     |   159 +
 .../internal/cache/TXBucketRegionState.java     |    37 +
 .../gemfire/internal/cache/TXCommitMessage.java |  2478 +++
 .../gemfire/internal/cache/TXEntry.java         |   274 +
 .../gemfire/internal/cache/TXEntryState.java    |  2270 +++
 .../internal/cache/TXEntryStateFactory.java     |    38 +
 .../internal/cache/TXEntryUserAttrState.java    |    67 +
 .../gemfire/internal/cache/TXEvent.java         |   148 +
 .../internal/cache/TXFarSideCMTracker.java      |   360 +
 .../gemstone/gemfire/internal/cache/TXId.java   |   130 +
 .../gemfire/internal/cache/TXLockRequest.java   |   144 +
 .../gemfire/internal/cache/TXManagerImpl.java   |  1511 ++
 .../gemfire/internal/cache/TXMessage.java       |   215 +
 .../internal/cache/TXRegionLockRequestImpl.java |   209 +
 .../gemfire/internal/cache/TXRegionState.java   |   629 +
 .../internal/cache/TXRemoteCommitMessage.java   |   320 +
 .../internal/cache/TXRemoteRollbackMessage.java |    88 +
 .../internal/cache/TXReservationMgr.java        |   154 +
 .../gemfire/internal/cache/TXRmtEvent.java      |   243 +
 .../gemfire/internal/cache/TXState.java         |  1839 ++
 .../internal/cache/TXStateInterface.java        |   224 +
 .../gemfire/internal/cache/TXStateProxy.java    |    96 +
 .../internal/cache/TXStateProxyImpl.java        |  1036 +
 .../gemfire/internal/cache/TXStateStub.java     |   577 +
 .../cache/TXSynchronizationRunnable.java        |   160 +
 .../cache/TestHeapThresholdObserver.java        |    62 +
 .../cache/TimestampedEntryEventImpl.java        |    73 +
 .../gemstone/gemfire/internal/cache/Token.java  |   301 +
 .../internal/cache/TombstoneService.java        |  1007 +
 .../internal/cache/TransactionMessage.java      |    75 +
 .../gemfire/internal/cache/TxEntryFactory.java  |    35 +
 .../internal/cache/UnsharedImageState.java      |   293 +
 .../cache/UpdateAttributesProcessor.java        |   553 +
 .../cache/UpdateEntryVersionOperation.java      |   195 +
 .../gemfire/internal/cache/UpdateOperation.java |   629 +
 .../cache/UserSpecifiedDiskStoreAttributes.java |   191 +
 .../cache/UserSpecifiedRegionAttributes.java    |   624 +
 .../internal/cache/VMCachedDeserializable.java  |   263 +
 .../gemfire/internal/cache/VMLRURegionMap.java  |    65 +
 .../gemfire/internal/cache/VMRegionMap.java     |    39 +
 .../cache/VMStatsDiskLRURegionEntry.java        |    40 +
 .../cache/VMStatsDiskLRURegionEntryHeap.java    |    69 +
 .../VMStatsDiskLRURegionEntryHeapIntKey.java    |   345 +
 .../VMStatsDiskLRURegionEntryHeapLongKey.java   |   345 +
 .../VMStatsDiskLRURegionEntryHeapObjectKey.java |   338 +
 ...VMStatsDiskLRURegionEntryHeapStringKey1.java |   407 +
 ...VMStatsDiskLRURegionEntryHeapStringKey2.java |   448 +
 .../VMStatsDiskLRURegionEntryHeapUUIDKey.java   |   349 +
 .../cache/VMStatsDiskLRURegionEntryOffHeap.java |    69 +
 .../VMStatsDiskLRURegionEntryOffHeapIntKey.java |   394 +
 ...VMStatsDiskLRURegionEntryOffHeapLongKey.java |   394 +
 ...StatsDiskLRURegionEntryOffHeapObjectKey.java |   387 +
 ...tatsDiskLRURegionEntryOffHeapStringKey1.java |   456 +
 ...tatsDiskLRURegionEntryOffHeapStringKey2.java |   497 +
 ...VMStatsDiskLRURegionEntryOffHeapUUIDKey.java |   398 +
 .../internal/cache/VMStatsDiskRegionEntry.java  |    39 +
 .../cache/VMStatsDiskRegionEntryHeap.java       |    69 +
 .../cache/VMStatsDiskRegionEntryHeapIntKey.java |   248 +
 .../VMStatsDiskRegionEntryHeapLongKey.java      |   248 +
 .../VMStatsDiskRegionEntryHeapObjectKey.java    |   241 +
 .../VMStatsDiskRegionEntryHeapStringKey1.java   |   310 +
 .../VMStatsDiskRegionEntryHeapStringKey2.java   |   351 +
 .../VMStatsDiskRegionEntryHeapUUIDKey.java      |   252 +
 .../cache/VMStatsDiskRegionEntryOffHeap.java    |    69 +
 .../VMStatsDiskRegionEntryOffHeapIntKey.java    |   297 +
 .../VMStatsDiskRegionEntryOffHeapLongKey.java   |   297 +
 .../VMStatsDiskRegionEntryOffHeapObjectKey.java |   290 +
 ...VMStatsDiskRegionEntryOffHeapStringKey1.java |   359 +
 ...VMStatsDiskRegionEntryOffHeapStringKey2.java |   400 +
 .../VMStatsDiskRegionEntryOffHeapUUIDKey.java   |   301 +
 .../internal/cache/VMStatsLRURegionEntry.java   |    43 +
 .../cache/VMStatsLRURegionEntryHeap.java        |    69 +
 .../cache/VMStatsLRURegionEntryHeapIntKey.java  |   256 +
 .../cache/VMStatsLRURegionEntryHeapLongKey.java |   256 +
 .../VMStatsLRURegionEntryHeapObjectKey.java     |   249 +
 .../VMStatsLRURegionEntryHeapStringKey1.java    |   318 +
 .../VMStatsLRURegionEntryHeapStringKey2.java    |   359 +
 .../cache/VMStatsLRURegionEntryHeapUUIDKey.java |   260 +
 .../cache/VMStatsLRURegionEntryOffHeap.java     |    69 +
 .../VMStatsLRURegionEntryOffHeapIntKey.java     |   305 +
 .../VMStatsLRURegionEntryOffHeapLongKey.java    |   305 +
 .../VMStatsLRURegionEntryOffHeapObjectKey.java  |   298 +
 .../VMStatsLRURegionEntryOffHeapStringKey1.java |   367 +
 .../VMStatsLRURegionEntryOffHeapStringKey2.java |   408 +
 .../VMStatsLRURegionEntryOffHeapUUIDKey.java    |   309 +
 .../internal/cache/VMStatsRegionEntry.java      |    39 +
 .../internal/cache/VMStatsRegionEntryHeap.java  |    69 +
 .../cache/VMStatsRegionEntryHeapIntKey.java     |   175 +
 .../cache/VMStatsRegionEntryHeapLongKey.java    |   175 +
 .../cache/VMStatsRegionEntryHeapObjectKey.java  |   168 +
 .../cache/VMStatsRegionEntryHeapStringKey1.java |   237 +
 .../cache/VMStatsRegionEntryHeapStringKey2.java |   278 +
 .../cache/VMStatsRegionEntryHeapUUIDKey.java    |   179 +
 .../cache/VMStatsRegionEntryOffHeap.java        |    69 +
 .../cache/VMStatsRegionEntryOffHeapIntKey.java  |   224 +
 .../cache/VMStatsRegionEntryOffHeapLongKey.java |   224 +
 .../VMStatsRegionEntryOffHeapObjectKey.java     |   217 +
 .../VMStatsRegionEntryOffHeapStringKey1.java    |   286 +
 .../VMStatsRegionEntryOffHeapStringKey2.java    |   327 +
 .../cache/VMStatsRegionEntryOffHeapUUIDKey.java |   228 +
 .../cache/VMThinDiskLRURegionEntry.java         |    39 +
 .../cache/VMThinDiskLRURegionEntryHeap.java     |    69 +
 .../VMThinDiskLRURegionEntryHeapIntKey.java     |   280 +
 .../VMThinDiskLRURegionEntryHeapLongKey.java    |   280 +
 .../VMThinDiskLRURegionEntryHeapObjectKey.java  |   273 +
 .../VMThinDiskLRURegionEntryHeapStringKey1.java |   342 +
 .../VMThinDiskLRURegionEntryHeapStringKey2.java |   383 +
 .../VMThinDiskLRURegionEntryHeapUUIDKey.java    |   284 +
 .../cache/VMThinDiskLRURegionEntryOffHeap.java  |    69 +
 .../VMThinDiskLRURegionEntryOffHeapIntKey.java  |   329 +
 .../VMThinDiskLRURegionEntryOffHeapLongKey.java |   329 +
 ...MThinDiskLRURegionEntryOffHeapObjectKey.java |   322 +
 ...ThinDiskLRURegionEntryOffHeapStringKey1.java |   391 +
 ...ThinDiskLRURegionEntryOffHeapStringKey2.java |   432 +
 .../VMThinDiskLRURegionEntryOffHeapUUIDKey.java |   333 +
 .../internal/cache/VMThinDiskRegionEntry.java   |    41 +
 .../cache/VMThinDiskRegionEntryHeap.java        |    69 +
 .../cache/VMThinDiskRegionEntryHeapIntKey.java  |   182 +
 .../cache/VMThinDiskRegionEntryHeapLongKey.java |   182 +
 .../VMThinDiskRegionEntryHeapObjectKey.java     |   175 +
 .../VMThinDiskRegionEntryHeapStringKey1.java    |   244 +
 .../VMThinDiskRegionEntryHeapStringKey2.java    |   285 +
 .../cache/VMThinDiskRegionEntryHeapUUIDKey.java |   186 +
 .../cache/VMThinDiskRegionEntryOffHeap.java     |    69 +
 .../VMThinDiskRegionEntryOffHeapIntKey.java     |   231 +
 .../VMThinDiskRegionEntryOffHeapLongKey.java    |   231 +
 .../VMThinDiskRegionEntryOffHeapObjectKey.java  |   224 +
 .../VMThinDiskRegionEntryOffHeapStringKey1.java |   293 +
 .../VMThinDiskRegionEntryOffHeapStringKey2.java |   334 +
 .../VMThinDiskRegionEntryOffHeapUUIDKey.java    |   235 +
 .../internal/cache/VMThinLRURegionEntry.java    |    37 +
 .../cache/VMThinLRURegionEntryHeap.java         |    69 +
 .../cache/VMThinLRURegionEntryHeapIntKey.java   |   191 +
 .../cache/VMThinLRURegionEntryHeapLongKey.java  |   191 +
 .../VMThinLRURegionEntryHeapObjectKey.java      |   184 +
 .../VMThinLRURegionEntryHeapStringKey1.java     |   253 +
 .../VMThinLRURegionEntryHeapStringKey2.java     |   294 +
 .../cache/VMThinLRURegionEntryHeapUUIDKey.java  |   195 +
 .../cache/VMThinLRURegionEntryOffHeap.java      |    69 +
 .../VMThinLRURegionEntryOffHeapIntKey.java      |   240 +
 .../VMThinLRURegionEntryOffHeapLongKey.java     |   240 +
 .../VMThinLRURegionEntryOffHeapObjectKey.java   |   233 +
 .../VMThinLRURegionEntryOffHeapStringKey1.java  |   302 +
 .../VMThinLRURegionEntryOffHeapStringKey2.java  |   343 +
 .../VMThinLRURegionEntryOffHeapUUIDKey.java     |   244 +
 .../internal/cache/VMThinRegionEntry.java       |    35 +
 .../internal/cache/VMThinRegionEntryHeap.java   |    71 +
 .../cache/VMThinRegionEntryHeapIntKey.java      |   109 +
 .../cache/VMThinRegionEntryHeapLongKey.java     |   109 +
 .../cache/VMThinRegionEntryHeapObjectKey.java   |   102 +
 .../cache/VMThinRegionEntryHeapStringKey1.java  |   171 +
 .../cache/VMThinRegionEntryHeapStringKey2.java  |   212 +
 .../cache/VMThinRegionEntryHeapUUIDKey.java     |   113 +
 .../cache/VMThinRegionEntryOffHeap.java         |    71 +
 .../cache/VMThinRegionEntryOffHeapIntKey.java   |   158 +
 .../cache/VMThinRegionEntryOffHeapLongKey.java  |   158 +
 .../VMThinRegionEntryOffHeapObjectKey.java      |   151 +
 .../VMThinRegionEntryOffHeapStringKey1.java     |   220 +
 .../VMThinRegionEntryOffHeapStringKey2.java     |   261 +
 .../cache/VMThinRegionEntryOffHeapUUIDKey.java  |   162 +
 .../internal/cache/ValidatingDiskRegion.java    |   519 +
 .../internal/cache/ValueByteWrapper.java        |    70 +
 .../internal/cache/VersionTimestamp.java        |    47 +
 .../cache/VersionedStatsDiskLRURegionEntry.java |    33 +
 .../VersionedStatsDiskLRURegionEntryHeap.java   |    70 +
 ...sionedStatsDiskLRURegionEntryHeapIntKey.java |   430 +
 ...ionedStatsDiskLRURegionEntryHeapLongKey.java |   430 +
 ...nedStatsDiskLRURegionEntryHeapObjectKey.java |   423 +
 ...edStatsDiskLRURegionEntryHeapStringKey1.java |   492 +
 ...edStatsDiskLRURegionEntryHeapStringKey2.java |   533 +
 ...ionedStatsDiskLRURegionEntryHeapUUIDKey.java |   434 +
 ...VersionedStatsDiskLRURegionEntryOffHeap.java |    70 +
 ...nedStatsDiskLRURegionEntryOffHeapIntKey.java |   479 +
 ...edStatsDiskLRURegionEntryOffHeapLongKey.java |   479 +
 ...StatsDiskLRURegionEntryOffHeapObjectKey.java |   472 +
 ...tatsDiskLRURegionEntryOffHeapStringKey1.java |   541 +
 ...tatsDiskLRURegionEntryOffHeapStringKey2.java |   582 +
 ...edStatsDiskLRURegionEntryOffHeapUUIDKey.java |   483 +
 .../cache/VersionedStatsDiskRegionEntry.java    |    33 +
 .../VersionedStatsDiskRegionEntryHeap.java      |    70 +
 ...VersionedStatsDiskRegionEntryHeapIntKey.java |   333 +
 ...ersionedStatsDiskRegionEntryHeapLongKey.java |   333 +
 ...sionedStatsDiskRegionEntryHeapObjectKey.java |   326 +
 ...ionedStatsDiskRegionEntryHeapStringKey1.java |   395 +
 ...ionedStatsDiskRegionEntryHeapStringKey2.java |   436 +
 ...ersionedStatsDiskRegionEntryHeapUUIDKey.java |   337 +
 .../VersionedStatsDiskRegionEntryOffHeap.java   |    70 +
 ...sionedStatsDiskRegionEntryOffHeapIntKey.java |   382 +
 ...ionedStatsDiskRegionEntryOffHeapLongKey.java |   382 +
 ...nedStatsDiskRegionEntryOffHeapObjectKey.java |   375 +
 ...edStatsDiskRegionEntryOffHeapStringKey1.java |   444 +
 ...edStatsDiskRegionEntryOffHeapStringKey2.java |   485 +
 ...ionedStatsDiskRegionEntryOffHeapUUIDKey.java |   386 +
 .../cache/VersionedStatsLRURegionEntry.java     |    34 +
 .../cache/VersionedStatsLRURegionEntryHeap.java |    70 +
 .../VersionedStatsLRURegionEntryHeapIntKey.java |   341 +
 ...VersionedStatsLRURegionEntryHeapLongKey.java |   341 +
 ...rsionedStatsLRURegionEntryHeapObjectKey.java |   334 +
 ...sionedStatsLRURegionEntryHeapStringKey1.java |   403 +
 ...sionedStatsLRURegionEntryHeapStringKey2.java |   444 +
 ...VersionedStatsLRURegionEntryHeapUUIDKey.java |   345 +
 .../VersionedStatsLRURegionEntryOffHeap.java    |    70 +
 ...rsionedStatsLRURegionEntryOffHeapIntKey.java |   390 +
 ...sionedStatsLRURegionEntryOffHeapLongKey.java |   390 +
 ...onedStatsLRURegionEntryOffHeapObjectKey.java |   383 +
 ...nedStatsLRURegionEntryOffHeapStringKey1.java |   452 +
 ...nedStatsLRURegionEntryOffHeapStringKey2.java |   493 +
 ...sionedStatsLRURegionEntryOffHeapUUIDKey.java |   394 +
 .../cache/VersionedStatsRegionEntry.java        |    34 +
 .../cache/VersionedStatsRegionEntryHeap.java    |    69 +
 .../VersionedStatsRegionEntryHeapIntKey.java    |   260 +
 .../VersionedStatsRegionEntryHeapLongKey.java   |   260 +
 .../VersionedStatsRegionEntryHeapObjectKey.java |   253 +
 ...VersionedStatsRegionEntryHeapStringKey1.java |   322 +
 ...VersionedStatsRegionEntryHeapStringKey2.java |   363 +
 .../VersionedStatsRegionEntryHeapUUIDKey.java   |   264 +
 .../cache/VersionedStatsRegionEntryOffHeap.java |    69 +
 .../VersionedStatsRegionEntryOffHeapIntKey.java |   309 +
 ...VersionedStatsRegionEntryOffHeapLongKey.java |   309 +
 ...rsionedStatsRegionEntryOffHeapObjectKey.java |   302 +
 ...sionedStatsRegionEntryOffHeapStringKey1.java |   371 +
 ...sionedStatsRegionEntryOffHeapStringKey2.java |   412 +
 ...VersionedStatsRegionEntryOffHeapUUIDKey.java |   313 +
 .../cache/VersionedThinDiskLRURegionEntry.java  |    33 +
 .../VersionedThinDiskLRURegionEntryHeap.java    |    70 +
 ...rsionedThinDiskLRURegionEntryHeapIntKey.java |   365 +
 ...sionedThinDiskLRURegionEntryHeapLongKey.java |   365 +
 ...onedThinDiskLRURegionEntryHeapObjectKey.java |   358 +
 ...nedThinDiskLRURegionEntryHeapStringKey1.java |   427 +
 ...nedThinDiskLRURegionEntryHeapStringKey2.java |   468 +
 ...sionedThinDiskLRURegionEntryHeapUUIDKey.java |   369 +
 .../VersionedThinDiskLRURegionEntryOffHeap.java |    70 +
 ...onedThinDiskLRURegionEntryOffHeapIntKey.java |   414 +
 ...nedThinDiskLRURegionEntryOffHeapLongKey.java |   414 +
 ...dThinDiskLRURegionEntryOffHeapObjectKey.java |   407 +
 ...ThinDiskLRURegionEntryOffHeapStringKey1.java |   476 +
 ...ThinDiskLRURegionEntryOffHeapStringKey2.java |   517 +
 ...nedThinDiskLRURegionEntryOffHeapUUIDKey.java |   418 +
 .../cache/VersionedThinDiskRegionEntry.java     |    33 +
 .../cache/VersionedThinDiskRegionEntryHeap.java |    70 +
 .../VersionedThinDiskRegionEntryHeapIntKey.java |   267 +
 ...VersionedThinDiskRegionEntryHeapLongKey.java |   267 +
 ...rsionedThinDiskRegionEntryHeapObjectKey.java |   260 +
 ...sionedThinDiskRegionEntryHeapStringKey1.java |   329 +
 ...sionedThinDiskRegionEntryHeapStringKey2.java |   370 +
 ...VersionedThinDiskRegionEntryHeapUUIDKey.java |   271 +
 .../VersionedThinDiskRegionEntryOffHeap.java    |    70 +
 ...rsionedThinDiskRegionEntryOffHeapIntKey.java |   316 +
 ...sionedThinDiskRegionEntryOffHeapLongKey.java |   316 +
 ...onedThinDiskRegionEntryOffHeapObjectKey.java |   309 +
 ...nedThinDiskRegionEntryOffHeapStringKey1.java |   378 +
 ...nedThinDiskRegionEntryOffHeapStringKey2.java |   419 +
 ...sionedThinDiskRegionEntryOffHeapUUIDKey.java |   320 +
 .../cache/VersionedThinLRURegionEntry.java      |    38 +
 .../cache/VersionedThinLRURegionEntryHeap.java  |    69 +
 .../VersionedThinLRURegionEntryHeapIntKey.java  |   276 +
 .../VersionedThinLRURegionEntryHeapLongKey.java |   276 +
 ...ersionedThinLRURegionEntryHeapObjectKey.java |   269 +
 ...rsionedThinLRURegionEntryHeapStringKey1.java |   338 +
 ...rsionedThinLRURegionEntryHeapStringKey2.java |   379 +
 .../VersionedThinLRURegionEntryHeapUUIDKey.java |   280 +
 .../VersionedThinLRURegionEntryOffHeap.java     |    69 +
 ...ersionedThinLRURegionEntryOffHeapIntKey.java |   325 +
 ...rsionedThinLRURegionEntryOffHeapLongKey.java |   325 +
 ...ionedThinLRURegionEntryOffHeapObjectKey.java |   318 +
 ...onedThinLRURegionEntryOffHeapStringKey1.java |   387 +
 ...onedThinLRURegionEntryOffHeapStringKey2.java |   428 +
 ...rsionedThinLRURegionEntryOffHeapUUIDKey.java |   329 +
 .../cache/VersionedThinRegionEntry.java         |    33 +
 .../cache/VersionedThinRegionEntryHeap.java     |    69 +
 .../VersionedThinRegionEntryHeapIntKey.java     |   194 +
 .../VersionedThinRegionEntryHeapLongKey.java    |   194 +
 .../VersionedThinRegionEntryHeapObjectKey.java  |   187 +
 .../VersionedThinRegionEntryHeapStringKey1.java |   256 +
 .../VersionedThinRegionEntryHeapStringKey2.java |   297 +
 .../VersionedThinRegionEntryHeapUUIDKey.java    |   198 +
 .../cache/VersionedThinRegionEntryOffHeap.java  |    69 +
 .../VersionedThinRegionEntryOffHeapIntKey.java  |   243 +
 .../VersionedThinRegionEntryOffHeapLongKey.java |   243 +
 ...ersionedThinRegionEntryOffHeapObjectKey.java |   236 +
 ...rsionedThinRegionEntryOffHeapStringKey1.java |   305 +
 ...rsionedThinRegionEntryOffHeapStringKey2.java |   346 +
 .../VersionedThinRegionEntryOffHeapUUIDKey.java |   247 +
 .../internal/cache/WrappedCallbackArgument.java |   105 +
 .../cache/WrappedRegionMembershipListener.java  |   200 +
 .../CompressedCachedDeserializable.java         |   197 +
 .../SnappyCompressedCachedDeserializable.java   |    83 +
 .../internal/cache/control/FilterByPath.java    |    66 +
 .../cache/control/HeapMemoryMonitor.java        |   881 +
 .../cache/control/InternalResourceManager.java  |   620 +
 .../internal/cache/control/MemoryEvent.java     |    93 +
 .../cache/control/MemoryThresholds.java         |   282 +
 .../cache/control/OffHeapMemoryMonitor.java     |   562 +
 .../control/PartitionRebalanceDetailsImpl.java  |   159 +
 .../cache/control/RebalanceOperationImpl.java   |   263 +
 .../cache/control/RebalanceResultsImpl.java     |   104 +
 .../internal/cache/control/RegionFilter.java    |    27 +
 .../internal/cache/control/ResourceAdvisor.java |   475 +
 .../internal/cache/control/ResourceEvent.java   |    33 +
 .../cache/control/ResourceListener.java         |    33 +
 .../cache/control/ResourceManagerStats.java     |   607 +
 .../internal/cache/control/ResourceMonitor.java |    54 +
 .../gemfire/internal/cache/delta/Delta.java     |    57 +
 .../cache/doc-files/BucketAdvisor-state.png     |   Bin 0 -> 39148 bytes
 .../internal/cache/doc-files/eventmatrix.xls    |   Bin 0 -> 24576 bytes
 .../cache/doc-files/extensible-hashing.fig      |   159 +
 .../cache/doc-files/extensible-hashing.gif      |   Bin 0 -> 6605 bytes
 .../cache/doc-files/jcache-get-flow.fig         |   349 +
 .../cache/doc-files/jcache-get-flow.pdf         |   Bin 0 -> 7519 bytes
 .../cache/doc-files/jcache-put-flow.fig         |   359 +
 .../cache/doc-files/jcache-put-flow.pdf         |   Bin 0 -> 7667 bytes
 .../doc-files/jcache-update-message-flow.fig    |   334 +
 .../doc-files/jcache-update-message-flow.pdf    |   Bin 0 -> 5937 bytes
 .../cache/doc-files/partitioned-regions.fig     |   255 +
 .../cache/doc-files/partitioned-regions.gif     |   Bin 0 -> 9273 bytes
 .../internal/cache/doc-files/properties.html    |  3937 ++++
 .../cache/doc-files/region-implementation.fig   |   262 +
 .../cache/execute/AbstractExecution.java        |   635 +
 .../cache/execute/BucketMovedException.java     |    57 +
 .../cache/execute/DefaultResultCollector.java   |   108 +
 .../DistributedRegionFunctionExecutor.java      |   444 +
 .../DistributedRegionFunctionResultSender.java  |   263 +
 .../DistributedRegionFunctionResultWaiter.java  |    60 +
 .../cache/execute/FunctionContextImpl.java      |   107 +
 .../execute/FunctionExecutionNodePruner.java    |   260 +
 .../cache/execute/FunctionRemoteContext.java    |   131 +
 .../cache/execute/FunctionServiceStats.java     |   440 +
 .../internal/cache/execute/FunctionStats.java   |   536 +
 .../FunctionStreamingResultCollector.java       |   636 +
 .../cache/execute/InternalExecution.java        |   112 +
 .../execute/InternalFunctionException.java      |    78 +
 ...ternalFunctionInvocationTargetException.java |    96 +
 .../cache/execute/InternalFunctionService.java  |   199 +
 .../execute/InternalRegionFunctionContext.java  |    84 +
 .../cache/execute/InternalResultSender.java     |    35 +
 .../cache/execute/LocalResultCollector.java     |    43 +
 .../cache/execute/LocalResultCollectorImpl.java |   212 +
 .../cache/execute/MemberFunctionExecutor.java   |   283 +
 .../execute/MemberFunctionResultSender.java     |   278 +
 .../execute/MemberFunctionResultWaiter.java     |    51 +
 .../cache/execute/MemberMappedArgument.java     |    74 +
 .../execute/MultiRegionFunctionContext.java     |    50 +
 .../execute/MultiRegionFunctionContextImpl.java |    56 +
 .../execute/MultiRegionFunctionExecutor.java    |   416 +
 .../MultiRegionFunctionResultWaiter.java        |    61 +
 .../internal/cache/execute/NoResult.java        |    79 +
 .../PartitionedRegionFunctionExecutor.java      |   378 +
 .../PartitionedRegionFunctionResultSender.java  |   340 +
 .../PartitionedRegionFunctionResultWaiter.java  |   125 +
 .../execute/RegionFunctionContextImpl.java      |   160 +
 .../cache/execute/ServerFunctionExecutor.java   |   428 +
 .../execute/ServerRegionFunctionExecutor.java   |   501 +
 .../ServerToClientFunctionResultSender.java     |   319 +
 .../ServerToClientFunctionResultSender65.java   |   289 +
 .../execute/StreamingFunctionOperation.java     |   127 +
 .../cache/execute/util/CommitFunction.java      |   142 +
 .../util/FindRestEnabledServersFunction.java    |    83 +
 .../execute/util/NestedTransactionFunction.java |   117 +
 .../cache/execute/util/RollbackFunction.java    |   137 +
 .../internal/cache/extension/Extensible.java    |    43 +
 .../internal/cache/extension/Extension.java     |    53 +
 .../cache/extension/ExtensionPoint.java         |    65 +
 .../cache/extension/SimpleExtensionPoint.java   |    85 +
 .../internal/cache/ha/HAContainerMap.java       |   203 +
 .../internal/cache/ha/HAContainerRegion.java    |   170 +
 .../internal/cache/ha/HAContainerWrapper.java   |    47 +
 .../internal/cache/ha/HARegionQueue.java        |  4226 ++++
 .../cache/ha/HARegionQueueAttributes.java       |   109 +
 .../internal/cache/ha/HARegionQueueStats.java   |   411 +
 .../internal/cache/ha/QueueRemovalMessage.java  |   240 +
 .../internal/cache/ha/ThreadIdentifier.java     |   330 +
 .../cache/locks/TXLessorDepartureHandler.java   |   102 +
 .../internal/cache/locks/TXLockBatch.java       |   148 +
 .../gemfire/internal/cache/locks/TXLockId.java  |    35 +
 .../internal/cache/locks/TXLockIdImpl.java      |   140 +
 .../internal/cache/locks/TXLockService.java     |   161 +
 .../internal/cache/locks/TXLockServiceImpl.java |   278 +
 .../internal/cache/locks/TXLockToken.java       |    95 +
 .../locks/TXLockUpdateParticipantsMessage.java  |   186 +
 .../locks/TXOriginatorRecoveryProcessor.java    |   312 +
 .../locks/TXRecoverGrantorMessageProcessor.java |   157 +
 .../cache/locks/TXRegionLockRequest.java        |    39 +
 .../gemfire/internal/cache/lru/EnableLRU.java   |   122 +
 .../gemfire/internal/cache/lru/HeapEvictor.java |   492 +
 .../cache/lru/HeapLRUCapacityController.java    |   335 +
 .../internal/cache/lru/HeapLRUStatistics.java   |    68 +
 .../internal/cache/lru/LRUAlgorithm.java        |   352 +
 .../cache/lru/LRUCapacityController.java        |   356 +
 .../internal/cache/lru/LRUClockNode.java        |    45 +
 .../gemfire/internal/cache/lru/LRUEntry.java    |    32 +
 .../internal/cache/lru/LRUMapCallbacks.java     |    61 +
 .../internal/cache/lru/LRUStatistics.java       |   210 +
 .../cache/lru/MemLRUCapacityController.java     |   545 +
 .../internal/cache/lru/NewLIFOClockHand.java    |    98 +
 .../internal/cache/lru/NewLRUClockHand.java     |   468 +
 .../internal/cache/lru/OffHeapEvictor.java      |    97 +
 .../gemfire/internal/cache/lru/Sizeable.java    |    63 +
 .../operations/ContainsKeyOperationContext.java |    52 +
 .../gemfire/internal/cache/package.html         |   241 +
 .../AllBucketProfilesUpdateMessage.java         |   170 +
 .../partitioned/BecomePrimaryBucketMessage.java |   332 +
 .../internal/cache/partitioned/Bucket.java      |    80 +
 .../cache/partitioned/BucketBackupMessage.java  |   137 +
 .../cache/partitioned/BucketCountLoadProbe.java |    75 +
 .../partitioned/BucketProfileUpdateMessage.java |   192 +
 .../cache/partitioned/BucketSizeMessage.java    |   286 +
 .../partitioned/ContainsKeyValueMessage.java    |   348 +
 .../cache/partitioned/CreateBucketMessage.java  |   371 +
 .../partitioned/CreateMissingBucketsTask.java   |    70 +
 .../partitioned/DeposePrimaryBucketMessage.java |   285 +
 .../cache/partitioned/DestroyMessage.java       |   621 +
 .../DestroyRegionOnDataStoreMessage.java        |   118 +
 .../partitioned/DumpAllPRConfigMessage.java     |    77 +
 .../cache/partitioned/DumpB2NRegion.java        |   343 +
 .../cache/partitioned/DumpBucketsMessage.java   |   111 +
 .../partitioned/EndBucketCreationMessage.java   |   149 +
 .../partitioned/FetchBulkEntriesMessage.java    |   670 +
 .../cache/partitioned/FetchEntriesMessage.java  |   659 +
 .../cache/partitioned/FetchEntryMessage.java    |   431 +
 .../cache/partitioned/FetchKeysMessage.java     |   574 +
 .../FetchPartitionDetailsMessage.java           |   397 +
 .../cache/partitioned/FlushMessage.java         |   154 +
 .../internal/cache/partitioned/GetMessage.java  |   669 +
 .../partitioned/IdentityRequestMessage.java     |   342 +
 .../partitioned/IdentityUpdateMessage.java      |   167 +
 .../cache/partitioned/IndexCreationMsg.java     |   687 +
 .../cache/partitioned/InterestEventMessage.java |   284 +
 .../cache/partitioned/InternalPRInfo.java       |    44 +
 .../partitioned/InternalPartitionDetails.java   |    45 +
 .../cache/partitioned/InvalidateMessage.java    |   409 +
 .../internal/cache/partitioned/LoadProbe.java   |    33 +
 .../internal/cache/partitioned/LockObject.java  |    42 +
 .../partitioned/ManageBackupBucketMessage.java  |   437 +
 .../cache/partitioned/ManageBucketMessage.java  |   419 +
 .../cache/partitioned/MoveBucketMessage.java    |   324 +
 .../cache/partitioned/OfflineMemberDetails.java |    48 +
 .../partitioned/OfflineMemberDetailsImpl.java   |    79 +
 .../cache/partitioned/PREntriesIterator.java    |    44 +
 .../PRFunctionStreamingResultCollector.java     |   436 +
 .../internal/cache/partitioned/PRLoad.java      |   154 +
 .../PRLocallyDestroyedException.java            |    40 +
 .../cache/partitioned/PRSanityCheckMessage.java |   164 +
 .../cache/partitioned/PRTombstoneMessage.java   |   182 +
 .../PRUpdateEntryVersionMessage.java            |   295 +
 .../partitioned/PartitionMemberInfoImpl.java    |   167 +
 .../cache/partitioned/PartitionMessage.java     |   849 +
 .../PartitionMessageWithDirectReply.java        |   141 +
 .../partitioned/PartitionRegionInfoImpl.java    |   139 +
 ...rtitionedRegionFunctionStreamingMessage.java |   205 +
 .../partitioned/PartitionedRegionObserver.java  |    44 +
 .../PartitionedRegionObserverAdapter.java       |    47 +
 .../PartitionedRegionObserverHolder.java        |    63 +
 .../PartitionedRegionRebalanceOp.java           |   913 +
 .../partitioned/PrimaryRequestMessage.java      |   238 +
 .../cache/partitioned/PutAllPRMessage.java      |   912 +
 .../internal/cache/partitioned/PutMessage.java  |  1380 ++
 .../cache/partitioned/QueryMessage.java         |   326 +
 .../cache/partitioned/RecoveryRunnable.java     |    86 +
 .../RedundancyAlreadyMetException.java          |    42 +
 .../cache/partitioned/RedundancyLogger.java     |   395 +
 .../cache/partitioned/RegionAdvisor.java        |  1965 ++
 .../partitioned/RemoteFetchKeysMessage.java     |   489 +
 .../cache/partitioned/RemoteSizeMessage.java    |   363 +
 .../cache/partitioned/RemoveAllPRMessage.java   |   823 +
 .../cache/partitioned/RemoveBucketMessage.java  |   323 +
 .../cache/partitioned/RemoveIndexesMessage.java |   545 +
 .../internal/cache/partitioned/SizeMessage.java |   379 +
 .../cache/partitioned/SizedBasedLoadProbe.java  |    83 +
 .../StreamingPartitionOperation.java            |   471 +
 .../partitioned/rebalance/BucketOperator.java   |   101 +
 .../rebalance/CompositeDirector.java            |   127 +
 .../rebalance/ExplicitMoveDirector.java         |    99 +
 .../partitioned/rebalance/FPRDirector.java      |    79 +
 .../partitioned/rebalance/MoveBuckets.java      |    63 +
 .../partitioned/rebalance/MovePrimaries.java    |    63 +
 .../partitioned/rebalance/MovePrimariesFPR.java |   105 +
 .../rebalance/ParallelBucketOperator.java       |   167 +
 .../rebalance/PartitionedRegionLoadModel.java   |  1640 ++
 .../rebalance/PercentageMoveDirector.java       |   165 +
 .../rebalance/RebalanceDirector.java            |    79 +
 .../rebalance/RebalanceDirectorAdapter.java     |    39 +
 .../rebalance/RemoveOverRedundancy.java         |    82 +
 .../rebalance/SatisfyRedundancy.java            |    92 +
 .../rebalance/SatisfyRedundancyFPR.java         |    90 +
 .../rebalance/SimulatedBucketOperator.java      |    55 +
 .../cache/persistence/BackupInspector.java      |   345 +
 .../cache/persistence/BackupManager.java        |   377 +
 .../cache/persistence/BytesAndBits.java         |    51 +
 .../cache/persistence/CanonicalIdHolder.java    |   101 +
 .../CreatePersistentRegionProcessor.java        |    58 +
 .../cache/persistence/DiskExceptionHandler.java |    38 +
 .../persistence/DiskInitFileInterpreter.java    |   148 +
 .../cache/persistence/DiskInitFileParser.java   |   652 +
 .../cache/persistence/DiskRecoveryStore.java    |    64 +
 .../cache/persistence/DiskRegionView.java       |   109 +
 .../cache/persistence/DiskStoreFilter.java      |    57 +
 .../internal/cache/persistence/DiskStoreID.java |   167 +
 .../persistence/MembershipFlushRequest.java     |   141 +
 .../persistence/MembershipViewRequest.java      |   254 +
 .../internal/cache/persistence/OplogType.java   |    32 +
 .../cache/persistence/PRPersistentConfig.java   |    74 +
 .../cache/persistence/PersistenceAdvisor.java   |   190 +
 .../persistence/PersistenceAdvisorImpl.java     |  1300 ++
 .../persistence/PersistenceObserverHolder.java  |   102 +
 .../cache/persistence/PersistentMemberID.java   |   171 +
 .../persistence/PersistentMemberManager.java    |   270 +
 .../persistence/PersistentMemberPattern.java    |   229 +
 .../persistence/PersistentMemberState.java      |    41 +
 .../cache/persistence/PersistentMemberView.java |   150 +
 .../persistence/PersistentMembershipView.java   |   112 +
 .../persistence/PersistentStateListener.java    |    38 +
 .../PersistentStateQueryMessage.java            |   308 +
 .../PersistentStateQueryResults.java            |    57 +
 .../PrepareNewPersistentMemberMessage.java      |   168 +
 .../RemovePersistentMemberMessage.java          |   182 +
 .../cache/persistence/RestoreScript.java        |   223 +
 .../persistence/UninterruptibleFileChannel.java |    29 +
 .../UninterruptibleRandomAccessFile.java        |   251 +
 .../persistence/query/CloseableIterator.java    |    33 +
 .../persistence/query/IdentityExtractor.java    |    26 +
 .../cache/persistence/query/IndexMap.java       |   187 +
 .../cache/persistence/query/ResultBag.java      |    60 +
 .../cache/persistence/query/ResultList.java     |    58 +
 .../cache/persistence/query/ResultMap.java      |   124 +
 .../cache/persistence/query/ResultSet.java      |    60 +
 .../persistence/query/SortKeyExtractor.java     |    21 +
 .../query/TemporaryResultSetFactory.java        |    79 +
 .../persistence/query/mock/ByteComparator.java  |    86 +
 .../mock/CachedDeserializableComparator.java    |    54 +
 .../persistence/query/mock/IndexMapImpl.java    |   278 +
 .../persistence/query/mock/ItrAdapter.java      |    62 +
 .../query/mock/NaturalComparator.java           |    33 +
 .../cache/persistence/query/mock/Pair.java      |    72 +
 .../persistence/query/mock/PairComparator.java  |    46 +
 .../persistence/query/mock/ResultListImpl.java  |    55 +
 .../query/mock/ReverseComparator.java           |    40 +
 .../query/mock/SortedResultBagImpl.java         |    64 +
 .../query/mock/SortedResultMapImpl.java         |   184 +
 .../query/mock/SortedResultSetImpl.java         |    52 +
 .../persistence/soplog/ByteComparator.java      |    56 +
 .../persistence/soplog/CursorIterator.java      |    82 +
 .../soplog/DelegatingSerializedComparator.java  |    38 +
 .../soplog/HFileStoreStatistics.java            |   205 +
 .../persistence/soplog/KeyValueIterator.java    |    43 +
 .../soplog/SortedOplogStatistics.java           |   505 +
 .../cache/persistence/soplog/SortedReader.java  |   256 +
 .../persistence/soplog/TrackedReference.java    |   154 +
 .../region/entry/RegionEntryFactoryBuilder.java |   103 +
 .../snapshot/CacheSnapshotServiceImpl.java      |   130 +
 .../internal/cache/snapshot/ClientExporter.java |   229 +
 .../cache/snapshot/ExportedRegistry.java        |   104 +
 .../internal/cache/snapshot/FlowController.java |   350 +
 .../internal/cache/snapshot/GFSnapshot.java     |   417 +
 .../internal/cache/snapshot/LocalExporter.java  |    58 +
 .../snapshot/RegionSnapshotServiceImpl.java     |   565 +
 .../cache/snapshot/SnapshotFileMapper.java      |    93 +
 .../cache/snapshot/SnapshotOptionsImpl.java     |   124 +
 .../internal/cache/snapshot/SnapshotPacket.java |   270 +
 .../cache/snapshot/WindowedExporter.java        |   401 +
 .../gemfire/internal/cache/tier/Acceptor.java   |   115 +
 .../internal/cache/tier/BatchException.java     |    72 +
 .../internal/cache/tier/CachedRegionHelper.java |   109 +
 .../internal/cache/tier/ClientHandShake.java    |    46 +
 .../gemfire/internal/cache/tier/Command.java    |    36 +
 .../internal/cache/tier/ConnectionProxy.java    |    35 +
 .../internal/cache/tier/InterestType.java       |    64 +
 .../cache/tier/InternalClientMembership.java    |   626 +
 .../internal/cache/tier/MessageType.java        |   569 +
 .../gemfire/internal/cache/tier/package.html    |    23 +
 .../cache/tier/sockets/AcceptorImpl.java        |  1872 ++
 .../cache/tier/sockets/BaseCommand.java         |  1611 ++
 .../cache/tier/sockets/BaseCommandQuery.java    |   578 +
 .../cache/tier/sockets/CacheClientNotifier.java |  2743 +++
 .../tier/sockets/CacheClientNotifierStats.java  |   295 +
 .../cache/tier/sockets/CacheClientProxy.java    |  3116 +++
 .../tier/sockets/CacheClientProxyStats.java     |   405 +
 .../cache/tier/sockets/CacheClientUpdater.java  |  2007 ++
 .../cache/tier/sockets/CacheServerHelper.java   |   193 +
 .../cache/tier/sockets/CacheServerStats.java    |  1148 ++
 .../cache/tier/sockets/ChunkedMessage.java      |   376 +
 .../tier/sockets/ClientBlacklistProcessor.java  |   174 +
 .../sockets/ClientDataSerializerMessage.java    |   256 +
 .../cache/tier/sockets/ClientHealthMonitor.java |   972 +
 .../tier/sockets/ClientInstantiatorMessage.java |   230 +
 .../tier/sockets/ClientInterestMessageImpl.java |   274 +
 .../tier/sockets/ClientMarkerMessageImpl.java   |   127 +
 .../cache/tier/sockets/ClientMessage.java       |    46 +
 .../tier/sockets/ClientPingMessageImpl.java     |   111 +
 .../tier/sockets/ClientProxyMembershipID.java   |   623 +
 .../tier/sockets/ClientTombstoneMessage.java    |   188 +
 .../cache/tier/sockets/ClientUpdateMessage.java |   188 +
 .../tier/sockets/ClientUpdateMessageImpl.java   |  1725 ++
 .../cache/tier/sockets/ClientUserAuths.java     |   201 +
 .../cache/tier/sockets/CommandInitializer.java  |   342 +
 .../cache/tier/sockets/ConnectionListener.java  |    55 +
 .../tier/sockets/ConnectionListenerAdapter.java |    38 +
 .../cache/tier/sockets/HAEventWrapper.java      |   435 +
 .../internal/cache/tier/sockets/HandShake.java  |  1934 ++
 .../tier/sockets/InterestResultPolicyImpl.java  |    59 +
 .../internal/cache/tier/sockets/Message.java    |  1116 ++
 .../cache/tier/sockets/MessageStats.java        |    29 +
 .../tier/sockets/MessageTooLargeException.java  |    29 +
 .../cache/tier/sockets/ObjectPartList.java      |   273 +
 .../cache/tier/sockets/ObjectPartList651.java   |   166 +
 .../internal/cache/tier/sockets/Part.java       |   452 +
 .../RemoveClientFromBlacklistMessage.java       |   114 +
 .../tier/sockets/SerializedObjectPartList.java  |   132 +
 .../cache/tier/sockets/ServerConnection.java    |  2077 ++
 .../tier/sockets/ServerHandShakeProcessor.java  |   464 +
 .../cache/tier/sockets/ServerQueueStatus.java   |   132 +
 .../tier/sockets/ServerResponseMatrix.java      |   141 +
 .../tier/sockets/UnregisterAllInterest.java     |    50 +
 .../cache/tier/sockets/UserAuthAttributes.java  |    81 +
 .../cache/tier/sockets/VersionedObjectList.java |   753 +
 .../cache/tier/sockets/command/AddPdxEnum.java  |    73 +
 .../cache/tier/sockets/command/AddPdxType.java  |    78 +
 .../cache/tier/sockets/command/ClearRegion.java |   150 +
 .../cache/tier/sockets/command/ClientReady.java |    76 +
 .../tier/sockets/command/CloseConnection.java   |    77 +
 .../tier/sockets/command/CommitCommand.java     |   142 +
 .../cache/tier/sockets/command/ContainsKey.java |   145 +
 .../tier/sockets/command/ContainsKey66.java     |   162 +
 .../tier/sockets/command/CreateRegion.java      |   137 +
 .../cache/tier/sockets/command/Default.java     |    52 +
 .../cache/tier/sockets/command/Destroy.java     |   219 +
 .../cache/tier/sockets/command/Destroy65.java   |   340 +
 .../cache/tier/sockets/command/Destroy70.java   |   118 +
 .../tier/sockets/command/DestroyRegion.java     |   175 +
 .../tier/sockets/command/ExecuteFunction.java   |   242 +
 .../tier/sockets/command/ExecuteFunction65.java |   273 +
 .../tier/sockets/command/ExecuteFunction66.java |   431 +
 .../tier/sockets/command/ExecuteFunction70.java |   144 +
 .../sockets/command/ExecuteRegionFunction.java  |   270 +
 .../command/ExecuteRegionFunction61.java        |   292 +
 .../command/ExecuteRegionFunction65.java        |   400 +
 .../command/ExecuteRegionFunction66.java        |   435 +
 .../command/ExecuteRegionFunctionSingleHop.java |   420 +
 .../sockets/command/GatewayReceiverCommand.java |   805 +
 .../cache/tier/sockets/command/Get70.java       |   531 +
 .../cache/tier/sockets/command/GetAll.java      |   260 +
 .../cache/tier/sockets/command/GetAll651.java   |   284 +
 .../cache/tier/sockets/command/GetAll70.java    |   293 +
 .../cache/tier/sockets/command/GetAllForRI.java |    52 +
 .../sockets/command/GetAllWithCallback.java     |   285 +
 .../command/GetClientPRMetadataCommand.java     |   114 +
 .../command/GetClientPRMetadataCommand66.java   |   105 +
 .../GetClientPartitionAttributesCommand.java    |   141 +
 .../GetClientPartitionAttributesCommand66.java  |   158 +
 .../cache/tier/sockets/command/GetEntry70.java  |    77 +
 .../tier/sockets/command/GetEntryCommand.java   |    64 +
 .../sockets/command/GetFunctionAttribute.java   |    81 +
 .../tier/sockets/command/GetPDXEnumById.java    |    73 +
 .../tier/sockets/command/GetPDXIdForEnum.java   |    74 +
 .../tier/sockets/command/GetPDXIdForType.java   |    75 +
 .../tier/sockets/command/GetPDXTypeById.java    |    73 +
 .../tier/sockets/command/GetPdxEnums70.java     |    68 +
 .../tier/sockets/command/GetPdxTypes70.java     |    67 +
 .../cache/tier/sockets/command/Invalid.java     |    49 +
 .../cache/tier/sockets/command/Invalidate.java  |   249 +
 .../tier/sockets/command/Invalidate70.java      |   107 +
 .../cache/tier/sockets/command/KeySet.java      |   193 +
 .../cache/tier/sockets/command/MakePrimary.java |    66 +
 .../tier/sockets/command/ManagementCommand.java |    39 +
 .../cache/tier/sockets/command/PeriodicAck.java |    79 +
 .../cache/tier/sockets/command/Ping.java        |    93 +
 .../cache/tier/sockets/command/Put.java         |   261 +
 .../cache/tier/sockets/command/Put61.java       |   319 +
 .../cache/tier/sockets/command/Put65.java       |   539 +
 .../cache/tier/sockets/command/Put70.java       |   126 +
 .../cache/tier/sockets/command/PutAll.java      |   268 +
 .../cache/tier/sockets/command/PutAll70.java    |   380 +
 .../cache/tier/sockets/command/PutAll80.java    |   469 +
 .../sockets/command/PutAllWithCallback.java     |    53 +
 .../sockets/command/PutUserCredentials.java     |    81 +
 .../cache/tier/sockets/command/Query.java       |   107 +
 .../cache/tier/sockets/command/Query651.java    |   137 +
 .../command/RegisterDataSerializers.java        |   114 +
 .../sockets/command/RegisterInstantiators.java  |   148 +
 .../tier/sockets/command/RegisterInterest.java  |   245 +
 .../sockets/command/RegisterInterest61.java     |   282 +
 .../sockets/command/RegisterInterestList.java   |   253 +
 .../sockets/command/RegisterInterestList61.java |   265 +
 .../sockets/command/RegisterInterestList66.java |   267 +
 .../cache/tier/sockets/command/RemoveAll.java   |   404 +
 .../tier/sockets/command/RemoveUserAuth.java    |    84 +
 .../cache/tier/sockets/command/Request.java     |   278 +
 .../tier/sockets/command/RequestEventValue.java |   176 +
 .../tier/sockets/command/RollbackCommand.java   |    90 +
 .../cache/tier/sockets/command/Size.java        |   167 +
 .../tier/sockets/command/TXFailoverCommand.java |   132 +
 .../command/TXSynchronizationCommand.java       |   210 +
 .../sockets/command/UnregisterInterest.java     |   152 +
 .../sockets/command/UnregisterInterestList.java |   171 +
 .../command/UpdateClientNotification.java       |    79 +
 .../doc-files/communication-architecture.fig    |   158 +
 .../doc-files/communication-architecture.gif    |   Bin 0 -> 5485 bytes
 .../internal/cache/tier/sockets/package.html    |    23 +
 .../cache/tx/AbstractPeerTXRegionStub.java      |    56 +
 .../internal/cache/tx/ClientTXRegionStub.java   |   158 +
 .../internal/cache/tx/ClientTXStateStub.java    |   292 +
 .../cache/tx/DistClientTXStateStub.java         |   140 +
 .../internal/cache/tx/DistTxEntryEvent.java     |   288 +
 .../internal/cache/tx/DistTxKeyInfo.java        |    54 +
 .../cache/tx/DistributedTXRegionStub.java       |   255 +
 .../cache/tx/PartitionedTXRegionStub.java       |   535 +
 .../gemfire/internal/cache/tx/TXRegionStub.java |    65 +
 .../cache/tx/TransactionalOperation.java        |   111 +
 .../cache/versions/CompactVersionHolder.java    |   105 +
 .../ConcurrentCacheModificationException.java   |    41 +
 .../cache/versions/DiskRegionVersionVector.java |   103 +
 .../internal/cache/versions/DiskVersionTag.java |    83 +
 .../internal/cache/versions/RVVException.java   |   207 +
 .../internal/cache/versions/RVVExceptionB.java  |   296 +
 .../internal/cache/versions/RVVExceptionT.java  |   283 +
 .../cache/versions/RegionVersionHolder.java     |   789 +
 .../cache/versions/RegionVersionVector.java     |  1531 ++
 .../cache/versions/VMRegionVersionVector.java   |   101 +
 .../internal/cache/versions/VMVersionTag.java   |    74 +
 .../internal/cache/versions/VersionHolder.java  |    57 +
 .../internal/cache/versions/VersionSource.java  |    43 +
 .../internal/cache/versions/VersionStamp.java   |    93 +
 .../internal/cache/versions/VersionTag.java     |   548 +
 .../internal/cache/vmotion/VMotionObserver.java |    44 +
 .../cache/vmotion/VMotionObserverAdapter.java   |    49 +
 .../cache/vmotion/VMotionObserverHolder.java    |    57 +
 .../cache/wan/AbstractGatewaySender.java        |  1331 ++
 .../AbstractGatewaySenderEventProcessor.java    |  1353 ++
 .../AsyncEventQueueConfigurationException.java  |    73 +
 .../internal/cache/wan/BatchException70.java    |   108 +
 .../cache/wan/DistributedSystemListener.java    |    32 +
 .../cache/wan/GatewayEventFilterImpl.java       |    45 +
 .../cache/wan/GatewayReceiverException.java     |    69 +
 .../cache/wan/GatewayReceiverStats.java         |   278 +
 .../cache/wan/GatewaySenderAdvisor.java         |   747 +
 .../cache/wan/GatewaySenderAttributes.java      |   200 +
 .../GatewaySenderConfigurationException.java    |    49 +
 .../wan/GatewaySenderEventCallbackArgument.java |   201 +
 .../GatewaySenderEventCallbackDispatcher.java   |   203 +
 .../cache/wan/GatewaySenderEventDispatcher.java |    35 +
 .../cache/wan/GatewaySenderEventImpl.java       |  1286 ++
 .../cache/wan/GatewaySenderException.java       |    63 +
 .../internal/cache/wan/GatewaySenderStats.java  |   744 +
 .../cache/wan/InternalGatewaySenderFactory.java |    38 +
 .../cache/wan/TransportFilterServerSocket.java  |    40 +
 .../cache/wan/TransportFilterSocket.java        |    78 +
 .../cache/wan/TransportFilterSocketFactory.java |    41 +
 .../internal/cache/wan/WANServiceProvider.java  |    76 +
 .../BucketRegionQueueUnavailableException.java  |    35 +
 ...rentParallelGatewaySenderEventProcessor.java |   376 +
 .../ConcurrentParallelGatewaySenderQueue.java   |   229 +
 .../ParallelGatewaySenderEventProcessor.java    |   245 +
 .../parallel/ParallelGatewaySenderQueue.java    |  1886 ++
 .../ParallelQueueBatchRemovalMessage.java       |   279 +
 .../parallel/ParallelQueueRemovalMessage.java   |   282 +
 .../cache/wan/parallel/RREventIDResolver.java   |    54 +
 .../cache/wan/serial/BatchDestroyOperation.java |   243 +
 ...urrentSerialGatewaySenderEventProcessor.java |   386 +
 .../SerialGatewaySenderEventProcessor.java      |   848 +
 .../wan/serial/SerialGatewaySenderQueue.java    |  1300 ++
 .../serial/SerialSecondaryGatewayListener.java  |   100 +
 .../internal/cache/wan/spi/WANFactory.java      |    37 +
 .../cache/xmlcache/AbstractXmlParser.java       |    95 +
 .../cache/xmlcache/AsyncEventQueueCreation.java |   223 +
 .../cache/xmlcache/BindingCreation.java         |    61 +
 .../internal/cache/xmlcache/CacheCreation.java  |  1695 ++
 .../cache/xmlcache/CacheServerCreation.java     |   257 +
 .../CacheTransactionManagerCreation.java        |   145 +
 .../internal/cache/xmlcache/CacheXml.java       |  1056 +
 .../cache/xmlcache/CacheXmlGenerator.java       |  2877 +++
 .../internal/cache/xmlcache/CacheXmlParser.java |  3795 ++++
 .../xmlcache/CacheXmlPropertyResolver.java      |   147 +
 .../CacheXmlPropertyResolverHelper.java         |   152 +
 .../cache/xmlcache/CacheXmlVersion.java         |   132 +
 .../cache/xmlcache/ClientCacheCreation.java     |   306 +
 .../cache/xmlcache/ClientHaQueueCreation.java   |   100 +
 .../internal/cache/xmlcache/Declarable2.java    |    39 +
 .../cache/xmlcache/DefaultEntityResolver2.java  |    75 +
 .../xmlcache/DiskStoreAttributesCreation.java   |   314 +
 .../cache/xmlcache/FunctionServiceCreation.java |    53 +
 .../cache/xmlcache/GatewayReceiverCreation.java |   190 +
 .../cache/xmlcache/GeodeEntityResolver.java     |    58 +
 .../cache/xmlcache/IndexCreationData.java       |   144 +
 .../ParallelAsyncEventQueueCreation.java        |   119 +
 .../xmlcache/ParallelGatewaySenderCreation.java |   123 +
 .../cache/xmlcache/PivotalEntityResolver.java   |    58 +
 .../cache/xmlcache/PropertyResolver.java        |    57 +
 .../xmlcache/RegionAttributesCreation.java      |  1671 ++
 .../internal/cache/xmlcache/RegionCreation.java |   969 +
 .../cache/xmlcache/ResourceManagerCreation.java |   215 +
 .../xmlcache/SerialAsyncEventQueueCreation.java |   115 +
 .../xmlcache/SerialGatewaySenderCreation.java   |   115 +
 .../cache/xmlcache/SerializerCreation.java      |   108 +
 .../internal/cache/xmlcache/XmlGenerator.java   |    62 +
 .../cache/xmlcache/XmlGeneratorUtils.java       |   151 +
 .../internal/cache/xmlcache/XmlParser.java      |    58 +
 .../internal/cache/xmlcache/package.html        |    32 +
 .../gemfire/internal/concurrent/AL.java         |   127 +
 .../internal/concurrent/AtomicLong5.java        |    48 +
 .../gemfire/internal/concurrent/Atomics.java    |    67 +
 .../concurrent/CompactConcurrentHashSet2.java   |  2514 +++
 .../internal/concurrent/ConcurrentHashSet.java  |    89 +
 .../gemfire/internal/concurrent/LI.java         |    95 +
 .../internal/concurrent/MapCallback.java        |   269 +
 .../internal/concurrent/MapCallbackAdapter.java |   140 +
 .../gemfire/internal/concurrent/MapResult.java  |    43 +
 .../internal/datasource/AbstractDataSource.java |   241 +
 .../internal/datasource/AbstractPoolCache.java  |   553 +
 .../ClientConnectionFactoryWrapper.java         |    54 +
 .../internal/datasource/ConfigProperty.java     |    65 +
 .../ConfiguredDataSourceProperties.java         |   288 +
 .../ConnectionEventListenerAdaptor.java         |    76 +
 .../datasource/ConnectionPoolCache.java         |    52 +
 .../datasource/ConnectionPoolCacheImpl.java     |   104 +
 .../internal/datasource/ConnectionProvider.java |    50 +
 .../datasource/ConnectionProviderException.java |    67 +
 .../datasource/DataSourceCreateException.java   |    62 +
 .../internal/datasource/DataSourceFactory.java  |   374 +
 .../datasource/DataSourceResources.java         |    49 +
 .../FacetsJCAConnectionManagerImpl.java         |   269 +
 .../datasource/GemFireBasicDataSource.java      |   150 +
 .../datasource/GemFireConnPooledDataSource.java |   225 +
 .../GemFireConnectionPoolManager.java           |   108 +
 .../GemFireTransactionDataSource.java           |   264 +
 .../datasource/JCAConnectionManagerImpl.java    |   220 +
 .../datasource/ManagedPoolCacheImpl.java        |   104 +
 .../internal/datasource/PoolException.java      |    55 +
 .../internal/datasource/TranxPoolCacheImpl.java |   102 +
 .../gemfire/internal/doc-files/cs-maps.fig      |   150 +
 .../gemfire/internal/doc-files/cs-maps.gif      |   Bin 0 -> 5951 bytes
 .../gemfire/internal/doc-files/ds-map.fig       |   105 +
 .../gemfire/internal/doc-files/ds-map.gif       |   Bin 0 -> 4867 bytes
 .../internal/doc-files/merge-log-files.fig      |   153 +
 .../internal/doc-files/merge-log-files.gif      |   Bin 0 -> 2646 bytes
 .../com/gemstone/gemfire/internal/hll/Bits.java |    48 +
 .../internal/hll/CardinalityMergeException.java |    26 +
 .../gemfire/internal/hll/HyperLogLog.java       |   345 +
 .../gemfire/internal/hll/HyperLogLogPlus.java   |  1053 +
 .../gemstone/gemfire/internal/hll/IBuilder.java |    24 +
 .../gemfire/internal/hll/ICardinality.java      |    72 +
 .../gemfire/internal/hll/MurmurHash.java        |   245 +
 .../gemfire/internal/hll/RegisterSet.java       |   110 +
 .../i18n/AbstractStringIdResourceBundle.java    |   156 +
 .../gemfire/internal/i18n/LocalizedStrings.java |  2161 +++
 .../internal/i18n/ParentLocalizedStrings.java   |  2399 +++
 .../gemfire/internal/i18n/StringId.java         |    58 +
 .../internal/io/CompositeOutputStream.java      |   176 +
 .../internal/io/CompositePrintStream.java       |    79 +
 .../gemfire/internal/io/TeeOutputStream.java    |    93 +
 .../gemfire/internal/io/TeePrintStream.java     |    45 +
 .../gemfire/internal/jndi/ContextImpl.java      |   779 +
 .../jndi/InitialContextFactoryImpl.java         |   102 +
 .../gemfire/internal/jndi/JNDIInvoker.java      |   401 +
 .../gemfire/internal/jndi/NameParserImpl.java   |    55 +
 .../gemfire/internal/jta/GlobalTransaction.java |   732 +
 .../gemfire/internal/jta/TransactionImpl.java   |   270 +
 .../internal/jta/TransactionManagerImpl.java    |   867 +
 .../gemfire/internal/jta/TransactionUtils.java  |    59 +
 .../internal/jta/UserTransactionImpl.java       |   145 +
 .../gemstone/gemfire/internal/jta/XidImpl.java  |    94 +
 .../gemfire/internal/lang/ClassUtils.java       |   131 +
 .../gemstone/gemfire/internal/lang/Filter.java  |    30 +
 .../gemfire/internal/lang/InOutParameter.java   |   102 +
 .../gemfire/internal/lang/Initable.java         |    36 +
 .../gemfire/internal/lang/Initializer.java      |    46 +
 .../internal/lang/MutableIdentifiable.java      |    39 +
 .../gemfire/internal/lang/ObjectUtils.java      |   192 +
 .../gemfire/internal/lang/Orderable.java        |    41 +
 .../gemstone/gemfire/internal/lang/Ordered.java |    44 +
 .../gemfire/internal/lang/StringUtils.java      |   716 +
 .../gemfire/internal/lang/SystemUtils.java      |   244 +
 .../gemfire/internal/lang/ThreadUtils.java      |   131 +
 .../gemfire/internal/logging/DateFormatter.java |    94 +
 .../internal/logging/DebugLogWriter.java        |   126 +
 .../internal/logging/GemFireFormatter.java      |   104 +
 .../internal/logging/GemFireHandler.java        |    81 +
 .../gemfire/internal/logging/GemFireLevel.java  |    78 +
 .../internal/logging/InternalLogWriter.java     |   134 +
 .../internal/logging/LocalLogWriter.java        |    95 +
 .../gemfire/internal/logging/LogConfig.java     |    63 +
 .../gemfire/internal/logging/LogFileParser.java |   513 +
 .../gemfire/internal/logging/LogService.java    |   279 +
 .../internal/logging/LogWriterFactory.java      |   109 +
 .../gemfire/internal/logging/LogWriterImpl.java |  1051 +
 .../internal/logging/LoggingThreadGroup.java    |   347 +
 .../internal/logging/ManagerLogWriter.java      |   692 +
 .../gemfire/internal/logging/MergeLogFiles.java |  1008 +
 .../gemfire/internal/logging/PureLogWriter.java |   283 +
 .../logging/SecurityLocalLogWriter.java         |    87 +
 .../internal/logging/SecurityLogConfig.java     |    66 +
 .../internal/logging/SecurityLogWriter.java     |    80 +
 .../logging/SecurityManagerLogWriter.java       |    73 +
 .../gemfire/internal/logging/SortLogFile.java   |   149 +
 .../internal/logging/StandardErrorPrinter.java  |    43 +
 .../internal/logging/StandardOutputPrinter.java |    43 +
 .../internal/logging/log4j/AlertAppender.java   |   351 +
 .../internal/logging/log4j/AppenderContext.java |    80 +
 .../internal/logging/log4j/ConfigLocator.java   |    85 +
 .../internal/logging/log4j/Configurator.java    |   205 +
 .../internal/logging/log4j/FastLogger.java      |    79 +
 .../internal/logging/log4j/GemFireLogger.java   |   923 +
 .../logging/log4j/LocalizedMessage.java         |    81 +
 .../internal/logging/log4j/LogMarker.java       |    98 +
 .../logging/log4j/LogWriterAppender.java        |   212 +
 .../logging/log4j/LogWriterAppenders.java       |   299 +
 .../internal/logging/log4j/LogWriterLogger.java |  2035 ++
 .../logging/log4j/ThreadIdPatternConverter.java |    61 +
 .../gemfire/internal/memcached/Command.java     |   501 +
 .../internal/memcached/CommandProcessor.java    |    42 +
 .../internal/memcached/ConnectionHandler.java   |    93 +
 .../gemfire/internal/memcached/KeyWrapper.java  |    95 +
 .../gemfire/internal/memcached/Reply.java       |   121 +
 .../internal/memcached/RequestReader.java       |   291 +
 .../internal/memcached/ResponseStatus.java      |    64 +
 .../internal/memcached/ValueWrapper.java        |   146 +
 .../memcached/commands/AbstractCommand.java     |   223 +
 .../internal/memcached/commands/AddCommand.java |    90 +
 .../memcached/commands/AddQCommand.java         |    30 +
 .../memcached/commands/AppendCommand.java       |    92 +
 .../memcached/commands/AppendQCommand.java      |    29 +
 .../internal/memcached/commands/CASCommand.java |    76 +
 .../memcached/commands/ClientError.java         |    39 +
 .../memcached/commands/DecrementCommand.java    |   173 +
 .../memcached/commands/DecrementQCommand.java   |    29 +
 .../memcached/commands/DeleteCommand.java       |   101 +
 .../memcached/commands/DeleteQCommand.java      |    29 +
 .../memcached/commands/FlushAllCommand.java     |   119 +
 .../memcached/commands/FlushAllQCommand.java    |    29 +
 .../internal/memcached/commands/GATCommand.java |    29 +
 .../memcached/commands/GATQCommand.java         |    29 +
 .../internal/memcached/commands/GetCommand.java |   224 +
 .../memcached/commands/GetKCommand.java         |    30 +
 .../memcached/commands/GetKQCommand.java        |    30 +
 .../memcached/commands/GetQCommand.java         |    38 +
 .../memcached/commands/IncrementCommand.java    |   170 +
 .../memcached/commands/IncrementQCommand.java   |    29 +
 .../memcached/commands/NoOpCommand.java         |    40 +
 .../memcached/commands/NotSupportedCommand.java |    41 +
 .../memcached/commands/PrependCommand.java      |    88 +
 .../memcached/commands/PrependQCommand.java     |    29 +
 .../memcached/commands/QuitCommand.java         |    56 +
 .../memcached/commands/QuitQCommand.java        |    29 +
 .../memcached/commands/ReplaceCommand.java      |   102 +
 .../memcached/commands/ReplaceQCommand.java     |    29 +
 .../internal/memcached/commands/SetCommand.java |    90 +
 .../memcached/commands/SetQCommand.java         |    30 +
 .../memcached/commands/StatsCommand.java        |    50 +
 .../memcached/commands/StorageCommand.java      |   218 +
 .../memcached/commands/TouchCommand.java        |   104 +
 .../memcached/commands/VerbosityCommand.java    |    48 +
 .../memcached/commands/VersionCommand.java      |    49 +
 .../modules/util/RegionConfiguration.java       |   293 +
 .../gemfire/internal/net/SocketUtils.java       |    76 +
 .../internal/offheap/AbstractStoredObject.java  |   107 +
 .../offheap/AddressableMemoryChunk.java         |    29 +
 .../offheap/AddressableMemoryChunkFactory.java  |    27 +
 .../internal/offheap/ByteArrayMemoryChunk.java  |    77 +
 .../internal/offheap/ByteBufferMemoryChunk.java |    90 +
 .../gemfire/internal/offheap/DataAsAddress.java |   131 +
 .../gemfire/internal/offheap/DataType.java      |   269 +
 ...DisconnectingOutOfOffHeapMemoryListener.java |    77 +
 .../gemfire/internal/offheap/Fragment.java      |   139 +
 .../internal/offheap/FreeListManager.java       |   920 +
 .../internal/offheap/LifecycleListener.java     |    98 +
 .../internal/offheap/MemoryAllocator.java       |    62 +
 .../gemfire/internal/offheap/MemoryBlock.java   |    70 +
 .../internal/offheap/MemoryBlockNode.java       |   162 +
 .../gemfire/internal/offheap/MemoryChunk.java   |    47 +
 .../offheap/MemoryChunkWithRefCount.java        |    34 +
 .../internal/offheap/MemoryInspector.java       |    43 +
 .../internal/offheap/MemoryInspectorImpl.java   |    99 +
 .../internal/offheap/MemoryUsageListener.java   |    27 +
 .../gemfire/internal/offheap/ObjectChunk.java   |   737 +
 .../internal/offheap/ObjectChunkSlice.java      |    44 +
 .../offheap/ObjectChunkWithHeapForm.java        |    40 +
 .../offheap/OffHeapCachedDeserializable.java    |   142 +
 .../gemfire/internal/offheap/OffHeapHelper.java |   133 +
 .../internal/offheap/OffHeapMemoryStats.java    |    54 +
 .../offheap/OffHeapRegionEntryHelper.java       |   406 +
 .../internal/offheap/OffHeapStorage.java        |   394 +
 .../offheap/OutOfOffHeapMemoryListener.java     |    44 +
 .../internal/offheap/RefCountChangeInfo.java    |   130 +
 .../internal/offheap/ReferenceCountHelper.java  |   254 +
 .../gemfire/internal/offheap/Releasable.java    |    31 +
 .../offheap/SimpleMemoryAllocatorImpl.java      |   511 +
 .../gemfire/internal/offheap/StoredObject.java  |    95 +
 .../internal/offheap/SyncChunkStack.java        |   141 +
 .../internal/offheap/UnsafeMemoryChunk.java     |   217 +
 .../offheap/annotations/OffHeapIdentifier.java  |    69 +
 .../internal/offheap/annotations/Released.java  |    49 +
 .../internal/offheap/annotations/Retained.java  |    51 +
 .../offheap/annotations/Unretained.java         |    51 +
 .../com/gemstone/gemfire/internal/package.html  |    45 +
 .../internal/process/AttachProcessUtils.java    |    57 +
 .../process/BlockingProcessStreamReader.java    |    73 +
 ...usterConfigurationNotAvailableException.java |    31 +
 .../process/ConnectionFailedException.java      |    50 +
 .../internal/process/ControlFileWatchdog.java   |   158 +
 .../process/ControlNotificationHandler.java     |    32 +
 .../internal/process/ControllableProcess.java   |   132 +
 .../process/FileAlreadyExistsException.java     |    52 +
 .../process/FileControllerParameters.java       |    33 +
 .../internal/process/FileProcessController.java |   162 +
 .../process/LocalProcessController.java         |   478 +
 .../internal/process/LocalProcessLauncher.java  |   128 +
 .../process/MBeanControllerParameters.java      |    37 +
 .../process/MBeanInvocationFailedException.java |    50 +
 .../process/MBeanProcessController.java         |   391 +
 .../internal/process/NativeProcessUtils.java    |    53 +
 .../process/NonBlockingProcessStreamReader.java |   101 +
 .../gemfire/internal/process/PidFile.java       |   169 +
 .../process/PidUnavailableException.java        |    51 +
 .../internal/process/ProcessController.java     |    61 +
 .../process/ProcessControllerFactory.java       |   102 +
 .../process/ProcessControllerParameters.java    |    30 +
 .../process/ProcessLauncherContext.java         |   176 +
 .../internal/process/ProcessStreamReader.java   |   265 +
 .../ProcessTerminatedAbnormallyException.java   |    90 +
 .../gemfire/internal/process/ProcessType.java   |    69 +
 .../gemfire/internal/process/ProcessUtils.java  |   195 +
 .../gemfire/internal/process/StartupStatus.java |    63 +
 .../internal/process/StartupStatusListener.java |    30 +
 .../UnableToControlProcessException.java        |    51 +
 .../AbstractSignalNotificationHandler.java      |   179 +
 .../gemfire/internal/process/signal/Signal.java |   128 +
 .../internal/process/signal/SignalEvent.java    |    53 +
 .../internal/process/signal/SignalListener.java |    34 +
 .../internal/process/signal/SignalType.java     |    44 +
 .../internal/redis/ByteArrayWrapper.java        |   181 +
 .../internal/redis/ByteToCommandDecoder.java    |   189 +
 .../gemstone/gemfire/internal/redis/Coder.java  |   517 +
 .../gemfire/internal/redis/Command.java         |   150 +
 .../gemfire/internal/redis/DoubleWrapper.java   |    79 +
 .../internal/redis/ExecutionHandlerContext.java |   380 +
 .../gemfire/internal/redis/Executor.java        |    38 +
 .../gemfire/internal/redis/Extendable.java      |    33 +
 .../redis/RedisCommandParserException.java      |    45 +
 .../internal/redis/RedisCommandType.java        |  2345 +++
 .../gemfire/internal/redis/RedisConstants.java  |   202 +
 .../gemfire/internal/redis/RedisDataType.java   |   118 +
 .../redis/RedisDataTypeMismatchException.java   |    39 +
 .../internal/redis/RegionCreationException.java |    39 +
 .../gemfire/internal/redis/RegionProvider.java  |   553 +
 .../redis/executor/AbstractExecutor.java        |   139 +
 .../redis/executor/AbstractScanExecutor.java    |    47 +
 .../internal/redis/executor/AuthExecutor.java   |    54 +
 .../internal/redis/executor/DBSizeExecutor.java |    31 +
 .../internal/redis/executor/DelExecutor.java    |    55 +
 .../internal/redis/executor/EchoExecutor.java   |    40 +
 .../internal/redis/executor/ExistsExecutor.java |    49 +
 .../redis/executor/ExpirationExecutor.java      |    41 +
 .../redis/executor/ExpireAtExecutor.java        |    93 +
 .../internal/redis/executor/ExpireExecutor.java |    93 +
 .../redis/executor/FlushAllExecutor.java        |    49 +
 .../internal/redis/executor/KeysExecutor.java   |    70 +
 .../internal/redis/executor/ListQuery.java      |    53 +
 .../redis/executor/PExpireAtExecutor.java       |    32 +
 .../redis/executor/PExpireExecutor.java         |    32 +
 .../internal/redis/executor/PTTLExecutor.java   |    33 +
 .../redis/executor/PersistExecutor.java         |    52 +
 .../internal/redis/executor/PingExecutor.java   |    31 +
 .../internal/redis/executor/QuitExecutor.java   |    31 +
 .../internal/redis/executor/ScanExecutor.java   |   144 +
 .../redis/executor/ShutDownExecutor.java        |    28 +
 .../internal/redis/executor/SortedSetQuery.java |   204 +
 .../internal/redis/executor/TTLExecutor.java    |    77 +
 .../internal/redis/executor/TimeExecutor.java   |    51 +
 .../internal/redis/executor/TypeExecutor.java   |    48 +
 .../internal/redis/executor/UnkownExecutor.java |    31 +
 .../redis/executor/hash/HDelExecutor.java       |    67 +
 .../redis/executor/hash/HExistsExecutor.java    |    66 +
 .../redis/executor/hash/HGetAllExecutor.java    |    63 +
 .../redis/executor/hash/HGetExecutor.java       |    62 +
 .../redis/executor/hash/HIncrByExecutor.java    |   109 +
 .../executor/hash/HIncrByFloatExecutor.java     |    99 +
 .../redis/executor/hash/HKeysExecutor.java      |    63 +
 .../redis/executor/hash/HLenExecutor.java       |    57 +
 .../redis/executor/hash/HMGetExecutor.java      |    72 +
 .../redis/executor/hash/HMSetExecutor.java      |    62 +
 .../redis/executor/hash/HScanExecutor.java      |   163 +
 .../redis/executor/hash/HSetExecutor.java       |    78 +
 .../redis/executor/hash/HSetNXExecutor.java     |    33 +
 .../redis/executor/hash/HValsExecutor.java      |    62 +
 .../redis/executor/hash/HashExecutor.java       |    39 +
 .../redis/executor/hll/HllExecutor.java         |    38 +
 .../redis/executor/hll/PFAddExecutor.java       |    66 +
 .../redis/executor/hll/PFCountExecutor.java     |    70 +
 .../redis/executor/hll/PFMergeExecutor.java     |    74 +
 .../internal/redis/executor/hll/Varint.java     |   241 +
 .../redis/executor/list/LIndexExecutor.java     |   118 +
 .../redis/executor/list/LInsertExecutor.java    |    29 +
 .../redis/executor/list/LLenExecutor.java       |    58 +
 .../redis/executor/list/LPopExecutor.java       |    34 +
 .../redis/executor/list/LPushExecutor.java      |    34 +
 .../redis/executor/list/LPushXExecutor.java     |    34 +
 .../redis/executor/list/LRangeExecutor.java     |   113 +
 .../redis/executor/list/LRemExecutor.java       |   116 +
 .../redis/executor/list/LSetExecutor.java       |   108 +
 .../redis/executor/list/LTrimExecutor.java      |   124 +
 .../redis/executor/list/ListExecutor.java       |   150 +
 .../redis/executor/list/PopExecutor.java        |   150 +
 .../redis/executor/list/PushExecutor.java       |    54 +
 .../redis/executor/list/PushXExecutor.java      |    59 +
 .../redis/executor/list/RPopExecutor.java       |    34 +
 .../redis/executor/list/RPushExecutor.java      |    34 +
 .../redis/executor/list/RPushXExecutor.java     |    34 +
 .../redis/executor/set/SAddExecutor.java        |    60 +
 .../redis/executor/set/SCardExecutor.java       |    55 +
 .../redis/executor/set/SDiffExecutor.java       |    46 +
 .../redis/executor/set/SDiffStoreExecutor.java  |    33 +
 .../redis/executor/set/SInterExecutor.java      |    49 +
 .../redis/executor/set/SInterStoreExecutor.java |    34 +
 .../redis/executor/set/SIsMemberExecutor.java   |    62 +
 .../redis/executor/set/SMembersExecutor.java    |    56 +
 .../redis/executor/set/SMoveExecutor.java       |    72 +
 .../redis/executor/set/SPopExecutor.java        |    61 +
 .../redis/executor/set/SRandMemberExecutor.java |    96 +
 .../redis/executor/set/SRemExecutor.java        |    63 +
 .../redis/executor/set/SScanExecutor.java       |   154 +
 .../redis/executor/set/SUnionExecutor.java      |    51 +
 .../redis/executor/set/SUnionStoreExecutor.java |    34 +
 .../redis/executor/set/SetExecutor.java         |    23 +
 .../redis/executor/set/SetOpExecutor.java       |   109 +
 .../executor/sortedset/SortedSetExecutor.java   |    41 +
 .../redis/executor/sortedset/ZAddExecutor.java  |    88 +
 .../redis/executor/sortedset/ZCardExecutor.java |    54 +
 .../executor/sortedset/ZCountExecutor.java      |   145 +
 .../executor/sortedset/ZIncrByExecutor.java     |    77 +
 .../executor/sortedset/ZLexCountExecutor.java   |   143 +
 .../executor/sortedset/ZRangeByLexExecutor.java |   209 +
 .../sortedset/ZRangeByScoreExecutor.java        |   209 +
 .../executor/sortedset/ZRangeExecutor.java      |   125 +
 .../redis/executor/sortedset/ZRankExecutor.java |    98 +
 .../redis/executor/sortedset/ZRemExecutor.java  |    64 +
 .../sortedset/ZRemRangeByLexExecutor.java       |   153 +
 .../sortedset/ZRemRangeByRankExecutor.java      |   121 +
 .../sortedset/ZRemRangeByScoreExecutor.java     |   143 +
 .../sortedset/ZRevRangeByScoreExecutor.java     |    33 +
 .../executor/sortedset/ZRevRangeExecutor.java   |    34 +
 .../executor/sortedset/ZRevRankExecutor.java    |    32 +
 .../redis/executor/sortedset/ZScanExecutor.java |   161 +
 .../executor/sortedset/ZScoreExecutor.java      |    59 +
 .../redis/executor/string/AppendExecutor.java   |    69 +
 .../redis/executor/string/BitCountExecutor.java |    97 +
 .../redis/executor/string/BitOpExecutor.java    |   153 +
 .../redis/executor/string/BitPosExecutor.java   |   134 +
 .../redis/executor/string/DecrByExecutor.java   |   110 +
 .../redis/executor/string/DecrExecutor.java     |    95 +
 .../redis/executor/string/GetBitExecutor.java   |    82 +
 .../redis/executor/string/GetExecutor.java      |    51 +
 .../redis/executor/string/GetRangeExecutor.java |    98 +
 .../redis/executor/string/GetSetExecutor.java   |    59 +
 .../redis/executor/string/IncrByExecutor.java   |   107 +
 .../executor/string/IncrByFloatExecutor.java    |   122 +
 .../redis/executor/string/IncrExecutor.java     |    91 +
 .../redis/executor/string/MGetExecutor.java     |    73 +
 .../redis/executor/string/MSetExecutor.java     |    64 +
 .../redis/executor/string/MSetNXExecutor.java   |    88 +
 .../redis/executor/string/PSetEXExecutor.java   |    34 +
 .../redis/executor/string/SetBitExecutor.java   |   106 +
 .../redis/executor/string/SetEXExecutor.java    |    88 +
 .../redis/executor/string/SetExecutor.java      |   154 +
 .../redis/executor/string/SetNXExecutor.java    |    60 +
 .../redis/executor/string/SetRangeExecutor.java |    96 +
 .../redis/executor/string/StringExecutor.java   |    45 +
 .../redis/executor/string/StrlenExecutor.java   |    56 +
 .../executor/transactions/DiscardExecutor.java  |    42 +
 .../executor/transactions/ExecExecutor.java     |    88 +
 .../executor/transactions/MultiExecutor.java    |    47 +
 .../transactions/TransactionExecutor.java       |    23 +
 .../executor/transactions/UnwatchExecutor.java  |    31 +
 .../executor/transactions/WatchExecutor.java    |    31 +
 .../redis/org/apache/hadoop/fs/GlobPattern.java |   164 +
 .../internal/security/AuthorizeRequest.java     |   757 +
 .../internal/security/AuthorizeRequestPP.java   |   250 +
 .../security/FilterPostAuthorization.java       |   235 +
 .../security/FilterPreAuthorization.java        |   160 +
 .../internal/security/ObjectWithAuthz.java      |    69 +
 .../gemfire/internal/security/package.html      |    25 +
 .../internal/sequencelog/EntryLogger.java       |   210 +
 .../gemfire/internal/sequencelog/GraphType.java |    60 +
 .../internal/sequencelog/MembershipLogger.java  |    47 +
 .../internal/sequencelog/MessageLogger.java     |    40 +
 .../internal/sequencelog/RegionLogger.java      |    88 +
 .../internal/sequencelog/SequenceLogger.java    |    63 +
 .../sequencelog/SequenceLoggerImpl.java         |   149 +
 .../internal/sequencelog/Transition.java        |    88 +
 .../gemfire/internal/sequencelog/io/Filter.java |    32 +
 .../sequencelog/io/GemfireLogConverter.java     |   251 +
 .../internal/sequencelog/io/GraphReader.java    |    90 +
 .../sequencelog/io/InputStreamReader.java       |   103 +
 .../sequencelog/io/OutputStreamAppender.java    |   117 +
 .../internal/sequencelog/model/Edge.java        |   111 +
 .../internal/sequencelog/model/Graph.java       |   105 +
 .../internal/sequencelog/model/GraphID.java     |    95 +
 .../sequencelog/model/GraphReaderCallback.java  |    37 +
 .../internal/sequencelog/model/GraphSet.java    |   165 +
 .../internal/sequencelog/model/Vertex.java      |   124 +
 .../visualization/text/TextDisplay.java         |    85 +
 .../gemfire/internal/shared/NativeCalls.java    |   633 +
 .../internal/shared/NativeCallsJNAImpl.java     |  1217 ++
 .../internal/shared/NativeErrorException.java   |    43 +
 .../gemfire/internal/shared/OSType.java         |    93 +
 .../internal/shared/StringPrintWriter.java      |   236 +
 .../internal/shared/TCPSocketOptions.java       |    48 +
 .../internal/size/CachingSingleObjectSizer.java |    51 +
 .../size/InstrumentationSingleObjectSizer.java  |    42 +
 .../gemfire/internal/size/ObjectGraphSizer.java |   252 +
 .../gemfire/internal/size/ObjectTraverser.java  |   205 +
 .../internal/size/ReflectionObjectSizer.java    |    94 +
 .../size/ReflectionSingleObjectSizer.java       |   183 +
 .../internal/size/SingleObjectSizer.java        |    28 +
 .../internal/size/SizeClassOnceObjectSizer.java |    96 +
 .../gemfire/internal/size/SizeOfUtil0.java      |    33 +
 .../internal/size/WellKnownClassSizer.java      |    60 +
 .../internal/statistics/CounterMonitor.java     |    58 +
 .../internal/statistics/GaugeMonitor.java       |    53 +
 .../statistics/IgnoreResourceException.java     |    65 +
 .../MapBasedStatisticsNotification.java         |    88 +
 .../internal/statistics/ResourceInstance.java   |   120 +
 .../internal/statistics/ResourceType.java       |    70 +
 .../internal/statistics/SampleCollector.java    |   786 +
 .../internal/statistics/SampleHandler.java      |    72 +
 .../internal/statistics/SimpleStatisticId.java  |    67 +
 .../statistics/StatArchiveDescriptor.java       |   134 +
 .../internal/statistics/StatArchiveHandler.java |   676 +
 .../statistics/StatArchiveHandlerConfig.java    |    67 +
 .../internal/statistics/StatMonitorHandler.java |   336 +
 .../internal/statistics/StatisticId.java        |    39 +
 .../statistics/StatisticNotFoundException.java  |    62 +
 .../internal/statistics/StatisticsListener.java |    27 +
 .../internal/statistics/StatisticsMonitor.java  |   166 +
 .../statistics/StatisticsNotification.java      |    66 +
 .../internal/statistics/StatisticsSampler.java  |    57 +
 .../internal/statistics/ValueMonitor.java       |   133 +
 .../gemfire/internal/statistics/package.html    |    31 +
 .../stats50/Atomic50StatisticsImpl.java         |   497 +
 .../gemfire/internal/stats50/VMStats50.java     |   703 +
 .../gemfire/internal/tcp/BaseMsgStreamer.java   |    65 +
 .../gemstone/gemfire/internal/tcp/Buffers.java  |   170 +
 .../internal/tcp/ByteBufferInputStream.java     |  1022 +
 .../gemfire/internal/tcp/ConnectExceptions.java |    93 +
 .../gemfire/internal/tcp/Connection.java        |  4154 ++++
 .../internal/tcp/ConnectionException.java       |    38 +
 .../gemfire/internal/tcp/ConnectionTable.java   |  1428 ++
 .../gemfire/internal/tcp/DirectReplySender.java |   105 +
 .../tcp/ImmutableByteBufferInputStream.java     |    85 +
 .../internal/tcp/MemberShunnedException.java    |    50 +
 .../gemfire/internal/tcp/MsgDestreamer.java     |   536 +
 .../gemfire/internal/tcp/MsgIdGenerator.java    |    54 +
 .../gemfire/internal/tcp/MsgOutputStream.java   |   427 +
 .../gemfire/internal/tcp/MsgReader.java         |   129 +
 .../gemfire/internal/tcp/MsgStreamer.java       |  1004 +
 .../gemfire/internal/tcp/MsgStreamerList.java   |   169 +
 .../gemfire/internal/tcp/NIOMsgReader.java      |   113 +
 .../gemfire/internal/tcp/OioMsgReader.java      |    43 +
 .../internal/tcp/ReenteredConnectException.java |    51 +
 .../gemfire/internal/tcp/ServerDelegate.java    |    47 +
 .../gemfire/internal/tcp/TCPConduit.java        |  1207 ++
 .../tcp/VersionedByteBufferInputStream.java     |    79 +
 .../internal/tcp/VersionedMsgStreamer.java      |    60 +
 .../gemstone/gemfire/internal/tcp/package.html  |   138 +
 .../internal/util/AbortableTaskService.java     |   174 +
 .../gemfire/internal/util/ArrayUtils.java       |   369 +
 .../gemfire/internal/util/BlobHelper.java       |   195 +
 .../gemfire/internal/util/Breadcrumbs.java      |   265 +
 .../gemstone/gemfire/internal/util/Bytes.java   |   259 +
 .../gemfire/internal/util/Callable.java         |    48 +
 .../gemfire/internal/util/CollectionUtils.java  |   282 +
 .../gemfire/internal/util/DebuggerSupport.java  |    65 +
 .../gemfire/internal/util/DelayedAction.java    |    65 +
 .../com/gemstone/gemfire/internal/util/Hex.java |    57 +
 .../gemstone/gemfire/internal/util/IOUtils.java |   347 +
 .../internal/util/JavaCommandBuilder.java       |   123 +
 .../gemfire/internal/util/LogFileUtils.java     |   178 +
 .../internal/util/ObjectIntProcedure.java       |    30 +
 .../gemfire/internal/util/PasswordUtil.java     |   132 +
 .../gemfire/internal/util/PluckStacks.java      |   523 +
 .../internal/util/SingletonCallable.java        |    87 +
 .../gemfire/internal/util/SingletonValue.java   |   318 +
 .../internal/util/StackTraceCollector.java      |   169 +
 .../gemfire/internal/util/StopWatch.java        |    80 +
 .../internal/util/SunAPINotFoundException.java  |    46 +
 .../gemfire/internal/util/TransformUtils.java   |   132 +
 .../gemfire/internal/util/Transformer.java      |    33 +
 .../gemfire/internal/util/Versionable.java      |    37 +
 .../internal/util/VersionedArrayList.java       |   346 +
 .../util/concurrent/CopyOnWriteHashMap.java     |   209 +
 .../util/concurrent/CopyOnWriteWeakHashMap.java |    98 +
 .../CustomEntryConcurrentHashMap.java           |  2679 +++
 .../internal/util/concurrent/FutureResult.java  |    93 +
 .../util/concurrent/ReentrantSemaphore.java     |   161 +
 .../util/concurrent/SemaphoreReadWriteLock.java |   217 +
 .../util/concurrent/StoppableCondition.java     |   113 +
 .../concurrent/StoppableCountDownLatch.java     |    98 +
 .../concurrent/StoppableCountDownOrUpLatch.java |   211 +
 .../concurrent/StoppableNonReentrantLock.java   |    92 +
 .../util/concurrent/StoppableReadWriteLock.java |    35 +
 .../util/concurrent/StoppableReentrantLock.java |   131 +
 .../StoppableReentrantReadWriteLock.java        |   244 +
 .../internal/util/doc-files/call-stack.fig      |    34 +
 .../internal/util/doc-files/class-loaders.fig   |    49 +
 .../lang/AttachAPINotFoundException.java        |    67 +
 .../com/gemstone/gemfire/lang/Identifiable.java |    40 +
 .../management/AlreadyRunningException.java     |    46 +
 .../management/AsyncEventQueueMXBean.java       |   118 +
 .../gemfire/management/CacheServerMXBean.java   |   397 +
 .../gemfire/management/ClientHealthStatus.java  |   346 +
 .../gemfire/management/ClientQueueDetail.java   |   165 +
 .../DependenciesNotFoundException.java          |    58 +
 .../gemfire/management/DiskBackupResult.java    |    68 +
 .../gemfire/management/DiskBackupStatus.java    |    73 +
 .../gemfire/management/DiskMetrics.java         |   124 +
 .../gemfire/management/DiskStoreMXBean.java     |   212 +
 .../DistributedLockServiceMXBean.java           |    66 +
 .../management/DistributedRegionMXBean.java     |   317 +
 .../management/DistributedSystemMXBean.java     |   696 +
 .../management/EvictionAttributesData.java      |   112 +
 .../FixedPartitionAttributesData.java           |    95 +
 .../management/GatewayReceiverMXBean.java       |   211 +
 .../gemfire/management/GatewaySenderMXBean.java |   249 +
 .../gemfire/management/GemFireProperties.java   |  1589 ++
 .../gemfire/management/JMXNotificationType.java |   208 +
 .../management/JMXNotificationUserData.java     |    46 +
 .../gemstone/gemfire/management/JVMMetrics.java |   151 +
 .../gemfire/management/LocatorMXBean.java       |    76 +
 .../gemfire/management/LockServiceMXBean.java   |    85 +
 .../gemfire/management/ManagementException.java |    88 +
 .../gemfire/management/ManagementService.java   |   427 +
 .../gemfire/management/ManagerMXBean.java       |    83 +
 .../gemfire/management/MemberMXBean.java        |   855 +
 .../management/MembershipAttributesData.java    |   113 +
 .../gemfire/management/NetworkMetrics.java      |    59 +
 .../gemstone/gemfire/management/OSMetrics.java  |   231 +
 .../management/PartitionAttributesData.java     |   146 +
 .../management/PersistentMemberDetails.java     |    68 +
 .../management/RegionAttributesData.java        |   438 +
 .../gemfire/management/RegionMXBean.java        |   360 +
 .../gemfire/management/ServerLoadData.java      |    93 +
 .../gemfire/management/cli/CliMetaData.java     |   104 +
 .../cli/CommandProcessingException.java         |   125 +
 .../gemfire/management/cli/CommandService.java  |   205 +
 .../management/cli/CommandServiceException.java |    68 +
 .../management/cli/CommandStatement.java        |    58 +
 .../gemfire/management/cli/ConverterHint.java   |    52 +
 .../gemstone/gemfire/management/cli/Result.java |   130 +
 .../gemfire/management/cli/package.html         |    23 +
 .../gemfire/management/internal/AgentUtil.java  |   134 +
 .../management/internal/AlertDetails.java       |   162 +
 .../management/internal/ArrayConverter.java     |    82 +
 .../internal/BaseManagementService.java         |   185 +
 .../internal/CollectionConverter.java           |   110 +
 .../management/internal/CompositeConverter.java |   146 +
 .../management/internal/EnumConverter.java      |    50 +
 .../management/internal/FederatingManager.java  |   626 +
 .../internal/FederationComponent.java           |   306 +
 .../management/internal/FilterChain.java        |    59 +
 .../management/internal/FilterParam.java        |    71 +
 .../management/internal/IdentityConverter.java  |    47 +
 .../management/internal/JettyHelper.java        |   228 +
 .../management/internal/JmxManagerAdvisee.java  |   149 +
 .../management/internal/JmxManagerAdvisor.java  |   384 +
 .../management/internal/JmxManagerLocator.java  |   241 +
 .../internal/JmxManagerLocatorRequest.java      |   118 +
 .../internal/JmxManagerLocatorResponse.java     |   104 +
 .../management/internal/LocalFilterChain.java   |    63 +
 .../management/internal/LocalManager.java       |   466 +
 .../management/internal/MBeanJMXAdapter.java    |   621 +
 .../management/internal/MBeanProxyFactory.java  |   355 +
 .../internal/MBeanProxyInfoRepository.java      |   171 +
 .../internal/MBeanProxyInvocationHandler.java   |   546 +
 .../internal/MXBeanProxyInvocationHandler.java  |   260 +
 .../management/internal/ManagementAgent.java    |   516 +
 .../internal/ManagementCacheListener.java       |   122 +
 .../internal/ManagementConstants.java           |   187 +
 .../management/internal/ManagementFunction.java |   173 +
 .../internal/ManagementMembershipListener.java  |    94 +
 .../internal/ManagementResourceRepo.java        |   262 +
 .../management/internal/ManagementStrings.java  |   153 +
 .../gemfire/management/internal/Manager.java    |    90 +
 .../internal/ManagerStartupMessage.java         |    76 +
 .../management/internal/MemberMessenger.java    |   105 +
 .../internal/MonitoringRegionCacheListener.java |   116 +
 .../internal/NotificationBroadCasterProxy.java  |    38 +
 .../internal/NotificationCacheListener.java     |   120 +
 .../management/internal/NotificationHub.java    |   206 +
 .../internal/NotificationHubClient.java         |    77 +
 .../management/internal/NotificationKey.java    |    66 +
 .../gemfire/management/internal/OpenMethod.java |   190 +
 .../management/internal/OpenTypeConverter.java  |  1018 +
 .../management/internal/OpenTypeUtil.java       |   117 +
 .../gemfire/management/internal/ProxyInfo.java  |    83 +
 .../management/internal/ProxyInterface.java     |    40 +
 .../management/internal/ProxyListener.java      |   137 +
 .../management/internal/RemoteFilterChain.java  |    95 +
 .../gemfire/management/internal/RestAgent.java  |   217 +
 .../gemfire/management/internal/SSLUtil.java    |    82 +
 .../management/internal/StringBasedFilter.java  |   122 +
 .../internal/SystemManagementService.java       |   837 +
 .../management/internal/TableConverter.java     |   102 +
 .../internal/beans/AggregateHandler.java        |    92 +
 .../internal/beans/AsyncEventQueueMBean.java    |   113 +
 .../beans/AsyncEventQueueMBeanBridge.java       |   121 +
 .../internal/beans/BeanUtilFuncs.java           |   393 +
 .../internal/beans/CacheServerBridge.java       |   772 +
 .../internal/beans/CacheServerMBean.java        |   317 +
 .../internal/beans/DiskRegionBridge.java        |   138 +
 .../internal/beans/DiskStoreMBean.java          |   182 +
 .../internal/beans/DiskStoreMBeanBridge.java    |   288 +
 .../beans/DistributedLockServiceBridge.java     |   227 +
 .../beans/DistributedLockServiceMBean.java      |    68 +
 .../internal/beans/DistributedRegionBridge.java |   683 +
 .../internal/beans/DistributedRegionMBean.java  |   330 +
 .../internal/beans/DistributedSystemBridge.java |  1888 ++
 .../internal/beans/DistributedSystemMBean.java  |   461 +
 .../internal/beans/GatewayReceiverMBean.java    |   220 +
 .../beans/GatewayReceiverMBeanBridge.java       |   224 +
 .../internal/beans/GatewaySenderMBean.java      |   226 +
 .../beans/GatewaySenderMBeanBridge.java         |   293 +
 .../internal/beans/HDFSRegionBridge.java        |   174 +
 .../management/internal/beans/LocatorMBean.java |    79 +
 .../internal/beans/LocatorMBeanBridge.java      |   157 +
 .../internal/beans/LockServiceMBean.java        |    94 +
 .../internal/beans/LockServiceMBeanBridge.java  |   129 +
 .../internal/beans/MBeanAggregator.java         |   435 +
 .../internal/beans/ManagementAdapter.java       |  1134 ++
 .../internal/beans/ManagementListener.java      |   215 +
 .../management/internal/beans/ManagerMBean.java |    71 +
 .../internal/beans/ManagerMBeanBridge.java      |    80 +
 .../management/internal/beans/MemberMBean.java  |   685 +
 .../internal/beans/MemberMBeanBridge.java       |  1999 ++
 .../internal/beans/MetricsCalculator.java       |   138 +
 .../internal/beans/PartitionedRegionBridge.java |   317 +
 .../internal/beans/QueryDataFunction.java       |   613 +
 .../management/internal/beans/RegionMBean.java  |   323 +
 .../internal/beans/RegionMBeanBridge.java       |   599 +
 .../beans/RegionMBeanCompositeDataFactory.java  |   229 +
 .../internal/beans/SequenceNumber.java          |    50 +
 .../management/internal/beans/ServerBridge.java |   184 +
 .../stats/AggregateRegionStatsMonitor.java      |   298 +
 .../internal/beans/stats/GCStatsMonitor.java    |    94 +
 .../GatewayReceiverClusterStatsMonitor.java     |    80 +
 .../stats/GatewaySenderClusterStatsMonitor.java |    93 +
 .../stats/IntegerStatsDeltaAggregator.java      |    93 +
 .../beans/stats/LongStatsDeltaAggregator.java   |    92 +
 .../internal/beans/stats/MBeanStatsMonitor.java |   120 +
 .../beans/stats/MemberClusterStatsMonitor.java  |   255 +
 .../beans/stats/MemberLevelDiskMonitor.java     |   311 +
 .../beans/stats/RegionClusterStatsMonitor.java  |   475 +
 .../beans/stats/ServerClusterStatsMonitor.java  |    86 +
 .../internal/beans/stats/StatType.java          |    29 +
 .../internal/beans/stats/StatsAggregator.java   |   305 +
 .../beans/stats/StatsAverageLatency.java        |    55 +
 .../internal/beans/stats/StatsKey.java          |   355 +
 .../internal/beans/stats/StatsLatency.java      |    70 +
 .../internal/beans/stats/StatsRate.java         |    92 +
 .../internal/beans/stats/VMStatsMonitor.java    |   129 +
 .../cli/AbstractCliAroundInterceptor.java       |   133 +
 .../internal/cli/CliAroundInterceptor.java      |    36 +
 .../management/internal/cli/CliUtil.java        |   758 +
 .../management/internal/cli/CommandManager.java |   632 +
 .../management/internal/cli/CommandRequest.java |   134 +
 .../internal/cli/CommandResponse.java           |   350 +
 .../internal/cli/CommandResponseBuilder.java    |    88 +
 .../internal/cli/CommandResponseWriter.java     |    66 +
 .../internal/cli/GfshParseResult.java           |   102 +
 .../management/internal/cli/GfshParser.java     |  1520 ++
 .../management/internal/cli/Launcher.java       |   315 +
 .../management/internal/cli/LogWrapper.java     |   440 +
 .../internal/cli/MultipleValueAdapter.java      |    39 +
 .../internal/cli/MultipleValueConverter.java    |    60 +
 .../internal/cli/annotation/CliArgument.java    |    88 +
 .../cli/commands/AbstractCommandsSupport.java   |   197 +
 .../internal/cli/commands/ClientCommands.java   |   328 +
 .../internal/cli/commands/ConfigCommands.java   |   484 +
 .../CreateAlterDestroyRegionCommands.java       |  1200 ++
 .../internal/cli/commands/DataCommands.java     |  1402 ++
 .../internal/cli/commands/DeployCommands.java   |   345 +
 .../cli/commands/DiskStoreCommands.java         |  1450 ++
 .../cli/commands/DurableClientCommands.java     |   430 +
 ...ExportImportSharedConfigurationCommands.java |   292 +
 .../internal/cli/commands/FunctionCommands.java |   642 +
 .../internal/cli/commands/GfshHelpCommands.java |   106 +
 .../internal/cli/commands/IndexCommands.java    |   674 +
 .../cli/commands/LauncherLifecycleCommands.java |  2803 +++
 .../internal/cli/commands/MemberCommands.java   |   204 +
 .../cli/commands/MiscellaneousCommands.java     |  2128 ++
 .../internal/cli/commands/PDXCommands.java      |   286 +
 .../internal/cli/commands/QueueCommands.java    |   281 +
 .../internal/cli/commands/RegionCommands.java   |   493 +
 .../internal/cli/commands/ShellCommands.java    |  1081 ++
 .../internal/cli/commands/StatusCommands.java   |    92 +
 .../internal/cli/commands/WanCommands.java      |  1281 ++
 .../cli/commands/dto/RegionAttributesInfo.java  |   164 +
 .../cli/commands/dto/RegionDetails.java         |   231 +
 .../cli/commands/dto/RegionMemberDetails.java   |   199 +
 .../cli/converters/BooleanConverter.java        |    54 +
 .../ClusterMemberIdNameConverter.java           |    80 +
 .../converters/ConnectionEndpointConverter.java |   145 +
 .../internal/cli/converters/DirConverter.java   |   174 +
 .../cli/converters/DirPathConverter.java        |   143 +
 .../cli/converters/DiskStoreNameConverter.java  |    93 +
 .../internal/cli/converters/EnumConverter.java  |    67 +
 .../cli/converters/FilePathConverter.java       |   136 +
 .../cli/converters/FilePathStringConverter.java |   132 +
 .../converters/GatewayReceiverIdsConverter.java |    73 +
 .../converters/GatewaySenderIdConverter.java    |    81 +
 .../internal/cli/converters/HelpConverter.java  |    73 +
 .../cli/converters/HintTopicConverter.java      |    74 +
 .../cli/converters/IndexTypeConverter.java      |    57 +
 .../LocatorDiscoveryConfigConverter.java        |    80 +
 .../cli/converters/LocatorIdNameConverter.java  |    79 +
 .../cli/converters/LogLevelConverter.java       |    64 +
 .../cli/converters/MemberGroupConverter.java    |    83 +
 .../cli/converters/MemberIdNameConverter.java   |    82 +
 .../cli/converters/RegionPathConverter.java     |   100 +
 .../cli/converters/StringArrayConverter.java    |    59 +
 .../cli/converters/StringListConverter.java     |    60 +
 .../cli/domain/AsyncEventQueueDetails.java      |    77 +
 .../internal/cli/domain/CacheServerInfo.java    |    72 +
 .../cli/domain/ConnectToLocatorResult.java      |    56 +
 .../internal/cli/domain/DataCommandRequest.java |   214 +
 .../internal/cli/domain/DataCommandResult.java  |   904 +
 .../internal/cli/domain/DiskStoreDetails.java   |   692 +
 .../cli/domain/DurableCqNamesResult.java        |    64 +
 .../cli/domain/EvictionAttributesInfo.java      |   100 +
 .../domain/FixedPartitionAttributesInfo.java    |    70 +
 .../internal/cli/domain/IndexDetails.java       |   330 +
 .../internal/cli/domain/IndexInfo.java          |   103 +
 .../cli/domain/MemberConfigurationInfo.java     |   118 +
 .../internal/cli/domain/MemberInformation.java  |   202 +
 .../internal/cli/domain/MemberResult.java       |   114 +
 .../cli/domain/PartitionAttributesInfo.java     |   171 +
 .../cli/domain/RegionAttributesInfo.java        |   492 +
 .../internal/cli/domain/RegionDescription.java  |   247 +
 .../cli/domain/RegionDescriptionPerMember.java  |   137 +
 .../internal/cli/domain/RegionInformation.java  |   157 +
 .../cli/domain/StackTracesPerMember.java        |    39 +
 .../cli/domain/SubscriptionQueueSizeResult.java |    51 +
 .../cli/exceptions/CliCommandException.java     |    65 +
 .../exceptions/CliCommandInvalidException.java  |    33 +
 .../CliCommandMultiModeOptionException.java     |    48 +
 .../CliCommandNotAvailableException.java        |    33 +
 .../exceptions/CliCommandOptionException.java   |    53 +
 ...CommandOptionHasMultipleValuesException.java |    33 +
 .../CliCommandOptionInvalidException.java       |    34 +
 .../CliCommandOptionMissingException.java       |    35 +
 .../CliCommandOptionNotApplicableException.java |    36 +
 ...liCommandOptionValueConversionException.java |    36 +
 .../CliCommandOptionValueException.java         |    42 +
 .../CliCommandOptionValueMissingException.java  |    36 +
 .../internal/cli/exceptions/CliException.java   |    21 +
 .../exceptions/CreateSubregionException.java    |    41 +
 .../cli/exceptions/ExceptionGenerator.java      |    46 +
 .../cli/exceptions/ExceptionHandler.java        |   106 +
 .../cli/exceptions/IndexNotFoundException.java  |    35 +
 .../functions/AlterRuntimeConfigFunction.java   |    96 +
 .../cli/functions/ChangeLogLevelFunction.java   |    96 +
 .../cli/functions/CliFunctionResult.java        |   248 +
 .../functions/CloseDurableClientFunction.java   |    77 +
 .../cli/functions/CloseDurableCqFunction.java   |    79 +
 .../cli/functions/ContunuousQueryFunction.java  |   152 +
 .../CreateAsyncEventQueueFunction.java          |   183 +
 .../functions/CreateDefinedIndexesFunction.java |    91 +
 .../cli/functions/CreateDiskStoreFunction.java  |    91 +
 .../cli/functions/CreateIndexFunction.java      |   100 +
 .../cli/functions/DataCommandFunction.java      |  1048 +
 .../internal/cli/functions/DeployFunction.java  |   115 +
 .../functions/DescribeDiskStoreFunction.java    |   259 +
 .../functions/DescribeHDFSStoreFunction.java    |    87 +
 .../cli/functions/DestroyDiskStoreFunction.java |   103 +
 .../cli/functions/DestroyIndexFunction.java     |   122 +
 .../cli/functions/ExportConfigFunction.java     |   132 +
 .../cli/functions/ExportDataFunction.java       |    74 +
 .../ExportSharedConfigurationFunction.java      |    72 +
 .../FetchRegionAttributesFunction.java          |   144 +
 .../FetchSharedConfigurationStatusFunction.java |    54 +
 .../functions/GarbageCollectionFunction.java    |    93 +
 .../GatewayReceiverCreateFunction.java          |   226 +
 .../functions/GatewayReceiverFunctionArgs.java  |    80 +
 .../functions/GatewaySenderCreateFunction.java  |   219 +
 .../functions/GatewaySenderFunctionArgs.java    |   144 +
 .../GetMemberConfigInformationFunction.java     |   213 +
 .../functions/GetMemberInformationFunction.java |   150 +
 .../functions/GetRegionDescriptionFunction.java |    62 +
 .../cli/functions/GetRegionsFunction.java       |    75 +
 .../cli/functions/GetStackTracesFunction.java   |    54 +
 .../GetSubscriptionQueueSizeFunction.java       |   101 +
 .../cli/functions/ImportDataFunction.java       |    70 +
 ...ortSharedConfigurationArtifactsFunction.java |    77 +
 .../functions/ListAsyncEventQueuesFunction.java |   109 +
 .../cli/functions/ListDeployedFunction.java     |   106 +
 .../cli/functions/ListDiskStoresFunction.java   |    85 +
 .../functions/ListDurableCqNamesFunction.java   |    99 +
 .../cli/functions/ListFunctionFunction.java     |   115 +
 .../cli/functions/ListIndexFunction.java        |    74 +
 .../LoadSharedConfigurationFunction.java        |    65 +
 .../internal/cli/functions/LogFileFunction.java |   298 +
 .../cli/functions/MemberRegionFunction.java     |    85 +
 .../cli/functions/MembersForRegionFunction.java |    96 +
 .../internal/cli/functions/NetstatFunction.java |   272 +
 .../cli/functions/RebalanceFunction.java        |   124 +
 .../cli/functions/RegionAlterFunction.java      |   344 +
 .../cli/functions/RegionCreateFunction.java     |   415 +
 .../cli/functions/RegionDestroyFunction.java    |    85 +
 .../cli/functions/RegionFunctionArgs.java       |   764 +
 .../cli/functions/ShutDownFunction.java         |    87 +
 .../cli/functions/UndeployFunction.java         |   133 +
 .../cli/functions/UnregisterFunction.java       |    76 +
 .../cli/functions/UserFunctionExecution.java    |   227 +
 .../management/internal/cli/help/CliTopic.java  |   131 +
 .../internal/cli/help/format/Block.java         |    45 +
 .../internal/cli/help/format/DataNode.java      |    51 +
 .../internal/cli/help/format/Help.java          |    47 +
 .../internal/cli/help/format/NewHelp.java       |    55 +
 .../internal/cli/help/format/Row.java           |    30 +
 .../internal/cli/help/utils/FormatOutput.java   |    35 +
 .../internal/cli/help/utils/HelpUtils.java      |   418 +
 .../internal/cli/i18n/CliStrings.java           |  2231 +++
 .../internal/cli/json/GfJsonArray.java          |   242 +
 .../internal/cli/json/GfJsonException.java      |    37 +
 .../internal/cli/json/GfJsonObject.java         |   393 +
 .../management/internal/cli/json/TypedJson.java |   820 +
 .../internal/cli/modes/CommandModes.java        |   155 +
 .../cli/multistep/CLIMultiStepHelper.java       |   400 +
 .../internal/cli/multistep/CLIRemoteStep.java   |    35 +
 .../internal/cli/multistep/CLIStep.java         |    34 +
 .../cli/multistep/CLIStepExecption.java         |    38 +
 .../cli/multistep/MultiStepCommand.java         |    34 +
 .../internal/cli/parser/Argument.java           |    76 +
 .../internal/cli/parser/AvailabilityTarget.java |   107 +
 .../internal/cli/parser/CommandTarget.java      |   188 +
 .../internal/cli/parser/GfshMethodTarget.java   |   134 +
 .../internal/cli/parser/GfshOptionParser.java   |    40 +
 .../internal/cli/parser/MethodParameter.java    |    42 +
 .../management/internal/cli/parser/Option.java  |   223 +
 .../internal/cli/parser/OptionSet.java          |   132 +
 .../internal/cli/parser/Parameter.java          |   119 +
 .../internal/cli/parser/ParserUtils.java        |   190 +
 .../internal/cli/parser/SyntaxConstants.java    |    37 +
 .../cli/parser/jopt/JoptOptionParser.java       |   300 +
 .../preprocessor/EnclosingCharacters.java       |    35 +
 .../cli/parser/preprocessor/Preprocessor.java   |   140 +
 .../parser/preprocessor/PreprocessorUtils.java  |   338 +
 .../internal/cli/parser/preprocessor/Stack.java |    55 +
 .../cli/parser/preprocessor/TrimmedInput.java   |    47 +
 .../cli/remote/CommandExecutionContext.java     |   127 +
 .../internal/cli/remote/CommandProcessor.java   |   166 +
 .../cli/remote/CommandStatementImpl.java        |   100 +
 .../cli/remote/MemberCommandService.java        |    84 +
 .../cli/remote/RemoteExecutionStrategy.java     |   169 +
 .../internal/cli/remote/WrapperThreadLocal.java |    42 +
 .../internal/cli/result/AbstractResultData.java |   340 +
 .../cli/result/CliJsonSerializable.java         |    45 +
 .../cli/result/CliJsonSerializableFactory.java  |    48 +
 .../cli/result/CliJsonSerializableIds.java      |    34 +
 .../internal/cli/result/CommandResult.java      |   661 +
 .../cli/result/CommandResultException.java      |    39 +
 .../cli/result/CompositeResultData.java         |   361 +
 .../internal/cli/result/ErrorResultData.java    |   104 +
 .../internal/cli/result/FileResult.java         |   117 +
 .../internal/cli/result/InfoResultData.java     |    91 +
 .../internal/cli/result/ObjectResultData.java   |    88 +
 .../internal/cli/result/ResultBuilder.java      |   475 +
 .../internal/cli/result/ResultData.java         |    53 +
 .../cli/result/ResultDataException.java         |    35 +
 .../internal/cli/result/TableBuilder.java       |   475 +
 .../internal/cli/result/TableBuilderHelper.java |   176 +
 .../internal/cli/result/TabularResultData.java  |   174 +
 .../management/internal/cli/shell/Gfsh.java     |  1259 ++
 .../internal/cli/shell/GfshConfig.java          |   253 +
 .../cli/shell/GfshExecutionStrategy.java        |   294 +
 .../cli/shell/JMXConnectionException.java       |    56 +
 .../cli/shell/JMXInvocationException.java       |    42 +
 .../internal/cli/shell/JmxOperationInvoker.java |   416 +
 .../internal/cli/shell/MultiCommandHelper.java  |    70 +
 .../internal/cli/shell/OperationInvoker.java    |   135 +
 .../internal/cli/shell/jline/ANSIBuffer.java    |   433 +
 .../internal/cli/shell/jline/ANSIHandler.java   |   113 +
 .../cli/shell/jline/CygwinMinttyTerminal.java   |    56 +
 .../internal/cli/shell/jline/GfshHistory.java   |    63 +
 .../shell/jline/GfshUnsupportedTerminal.java    |    33 +
 .../cli/shell/unsafe/GfshSignalHandler.java     |    85 +
 .../internal/cli/util/CLIConsoleBufferUtil.java |    37 +
 .../internal/cli/util/CauseFinder.java          |   214 +
 .../cli/util/ClasspathScanLoadHelper.java       |   258 +
 .../internal/cli/util/CommandStringBuilder.java |   105 +
 .../internal/cli/util/CommentSkipHelper.java    |    78 +
 .../internal/cli/util/ConnectionEndpoint.java   |    73 +
 .../internal/cli/util/DiskStoreCompacter.java   |   134 +
 .../cli/util/DiskStoreNotFoundException.java    |    49 +
 .../internal/cli/util/DiskStoreUpgrader.java    |   130 +
 .../internal/cli/util/DiskStoreValidater.java   |    60 +
 .../cli/util/EvictionAttributesInfo.java        |    63 +
 .../cli/util/FixedPartitionAttributesInfo.java  |    65 +
 .../internal/cli/util/GfshConsoleReader.java    |    90 +
 .../cli/util/HDFSStoreNotFoundException.java    |    47 +
 .../cli/util/JConsoleNotFoundException.java     |    47 +
 .../management/internal/cli/util/JsonUtil.java  |   606 +
 .../internal/cli/util/MemberInformation.java    |   157 +
 .../cli/util/MemberNotFoundException.java       |    49 +
 .../management/internal/cli/util/MergeLogs.java |    87 +
 .../internal/cli/util/ReadWriteFile.java        |   232 +
 .../cli/util/RegionAttributesDefault.java       |    90 +
 .../cli/util/RegionAttributesNames.java         |    89 +
 .../internal/cli/util/RegionPath.java           |   128 +
 .../cli/util/VisualVmNotFoundException.java     |    48 +
 .../SharedConfigurationWriter.java              |   180 +
 .../callbacks/ConfigurationChangeListener.java  |    59 +
 .../configuration/domain/CacheElement.java      |   253 +
 .../configuration/domain/Configuration.java     |   207 +
 .../domain/ConfigurationChangeResult.java       |   126 +
 .../domain/SharedConfigurationStatus.java       |    26 +
 .../configuration/domain/XmlEntity.java         |   551 +
 .../configuration/functions/AddJarFunction.java |    67 +
 .../functions/AddXmlEntityFunction.java         |    60 +
 .../functions/DeleteJarFunction.java            |    68 +
 .../functions/DeleteXmlEntityFunction.java      |    65 +
 .../functions/GetAllJarsFunction.java           |    67 +
 .../functions/ModifyPropertiesFunction.java     |    65 +
 .../handlers/ConfigurationRequestHandler.java   |    85 +
 ...SharedConfigurationStatusRequestHandler.java |    65 +
 .../messages/ConfigurationRequest.java          |   128 +
 .../messages/ConfigurationResponse.java         |   174 +
 .../SharedConfigurationStatusRequest.java       |    44 +
 .../SharedConfigurationStatusResponse.java      |    78 +
 .../configuration/utils/DtdResolver.java        |    92 +
 .../configuration/utils/XmlConstants.java       |    56 +
 .../internal/configuration/utils/XmlUtils.java  |   685 +
 .../internal/configuration/utils/ZipUtils.java  |   122 +
 .../internal/messages/CompactRequest.java       |   174 +
 .../internal/messages/CompactResponse.java      |    70 +
 .../internal/security/AccessControl.java        |    51 +
 .../internal/security/AccessControlContext.java |    37 +
 .../internal/security/AccessControlMXBean.java  |    23 +
 .../internal/security/CLIOperationContext.java  |   138 +
 .../internal/security/JMXOperationContext.java  |   177 +
 .../internal/security/JSONAuthorization.java    |   308 +
 .../internal/security/MBeanServerWrapper.java   |   286 +
 .../security/ManagementInterceptor.java         |   271 +
 .../management/internal/security/Resource.java  |    26 +
 .../internal/security/ResourceConstants.java    |   115 +
 .../internal/security/ResourceOperation.java    |    34 +
 .../security/ResourceOperationContext.java      |   203 +
 .../unsafe/ReadOpFileAccessController.java      |    63 +
 .../controllers/AbstractCommandsController.java |   618 +
 .../AbstractMultiPartCommandsController.java    |    78 +
 .../controllers/ClientCommandsController.java   |    60 +
 .../controllers/ClusterCommandsController.java  |    49 +
 .../controllers/ConfigCommandsController.java   |   214 +
 .../web/controllers/DataCommandsController.java |   241 +
 .../controllers/DeployCommandsController.java   |   110 +
 .../DiskStoreCommandsController.java            |   177 +
 .../DurableClientCommandsController.java        |   158 +
 .../controllers/FunctionCommandsController.java |   142 +
 .../controllers/IndexCommandsController.java    |   172 +
 .../LauncherLifecycleCommandsController.java    |    55 +
 .../controllers/MemberCommandsController.java   |    78 +
 .../MiscellaneousCommandsController.java        |   271 +
 .../web/controllers/PdxCommandsController.java  |   122 +
 .../controllers/QueueCommandsController.java    |   133 +
 .../controllers/RegionCommandsController.java   |   332 +
 .../controllers/ShellCommandsController.java    |   286 +
 .../web/controllers/WanCommandsController.java  |   403 +
 .../EnvironmentVariablesHandlerInterceptor.java |    93 +
 .../support/MemberMXBeanAdapter.java            |   660 +
 .../management/internal/web/domain/Link.java    |   161 +
 .../internal/web/domain/LinkIndex.java          |   140 +
 .../web/domain/QueryParameterSource.java        |    63 +
 .../internal/web/http/ClientHttpRequest.java    |   451 +
 .../internal/web/http/HttpHeader.java           |   100 +
 .../internal/web/http/HttpMethod.java           |    36 +
 .../SerializableObjectHttpMessageConverter.java |   103 +
 .../web/http/support/SimpleHttpRequester.java   |   140 +
 .../internal/web/io/MultipartFileAdapter.java   |    68 +
 .../web/io/MultipartFileResourceAdapter.java    |    68 +
 .../web/shell/AbstractHttpOperationInvoker.java |   801 +
 .../web/shell/HttpOperationInvoker.java         |    31 +
 .../web/shell/MBeanAccessException.java         |    45 +
 .../RestApiCallForCommandNotFoundException.java |    44 +
 .../web/shell/RestHttpOperationInvoker.java     |   424 +
 .../web/shell/SimpleHttpOperationInvoker.java   |   161 +
 .../shell/support/HttpInvocationHandler.java    |    95 +
 .../shell/support/HttpMBeanProxyFactory.java    |    41 +
 .../internal/web/util/ConvertUtils.java         |   132 +
 .../management/internal/web/util/UriUtils.java  |   257 +
 .../management/membership/ClientMembership.java |    67 +
 .../membership/ClientMembershipEvent.java       |    51 +
 .../membership/ClientMembershipListener.java    |    48 +
 .../ClientMembershipListenerAdapter.java        |    52 +
 .../management/membership/MembershipEvent.java  |    42 +
 .../membership/MembershipListener.java          |    53 +
 .../UniversalMembershipListenerAdapter.java     |   384 +
 .../gemstone/gemfire/management/package.html    |    24 +
 .../memcached/GemFireMemcachedServer.java       |   284 +
 .../main/java/com/gemstone/gemfire/package.html |    86 +
 .../com/gemstone/gemfire/pdx/FieldType.java     |   158 +
 .../com/gemstone/gemfire/pdx/JSONFormatter.java |   630 +
 .../gemfire/pdx/JSONFormatterException.java     |    47 +
 .../gemfire/pdx/NonPortableClassException.java  |    34 +
 .../gemfire/pdx/PdxConfigurationException.java  |    41 +
 .../pdx/PdxFieldAlreadyExistsException.java     |    46 +
 .../pdx/PdxFieldDoesNotExistException.java      |    42 +
 .../pdx/PdxFieldTypeMismatchException.java      |    46 +
 .../gemfire/pdx/PdxInitializationException.java |    51 +
 .../com/gemstone/gemfire/pdx/PdxInstance.java   |   202 +
 .../gemfire/pdx/PdxInstanceFactory.java         |   472 +
 .../com/gemstone/gemfire/pdx/PdxReader.java     |   265 +
 .../pdx/PdxRegistryMismatchException.java       |    37 +
 .../gemstone/gemfire/pdx/PdxSerializable.java   |    71 +
 .../gemfire/pdx/PdxSerializationException.java  |    53 +
 .../com/gemstone/gemfire/pdx/PdxSerializer.java |    94 +
 .../gemstone/gemfire/pdx/PdxUnreadFields.java   |    42 +
 .../com/gemstone/gemfire/pdx/PdxWriter.java     |   479 +
 .../pdx/ReflectionBasedAutoSerializer.java      |   561 +
 .../gemfire/pdx/WritablePdxInstance.java        |    44 +
 .../pdx/internal/AutoSerializableManager.java   |  2304 +++
 .../pdx/internal/CheckTypeRegistryState.java    |   110 +
 .../pdx/internal/ClientTypeRegistration.java    |   418 +
 .../gemfire/pdx/internal/ComparableEnum.java    |    24 +
 .../pdx/internal/ConvertableToBytes.java        |    23 +
 .../gemstone/gemfire/pdx/internal/DataSize.java |    49 +
 .../gemfire/pdx/internal/DefaultPdxField.java   |    40 +
 .../gemstone/gemfire/pdx/internal/EnumId.java   |    96 +
 .../gemstone/gemfire/pdx/internal/EnumInfo.java |   333 +
 .../pdx/internal/FieldNotFoundInPdxVersion.java |    27 +
 .../gemfire/pdx/internal/InternalPdxReader.java |    85 +
 .../pdx/internal/LonerTypeRegistration.java     |   186 +
 .../pdx/internal/NullTypeRegistration.java      |   120 +
 .../gemstone/gemfire/pdx/internal/PdxField.java |   259 +
 .../gemfire/pdx/internal/PdxInputStream.java    |   439 +
 .../gemfire/pdx/internal/PdxInstanceEnum.java   |   183 +
 .../pdx/internal/PdxInstanceFactoryImpl.java    |   270 +
 .../gemfire/pdx/internal/PdxInstanceImpl.java   |   646 +
 .../pdx/internal/PdxInstanceInputStream.java    |   115 +
 .../gemfire/pdx/internal/PdxOutputStream.java   |   242 +
 .../gemfire/pdx/internal/PdxReaderImpl.java     |   904 +
 .../gemfire/pdx/internal/PdxString.java         |   210 +
 .../gemstone/gemfire/pdx/internal/PdxType.java  |   495 +
 .../gemfire/pdx/internal/PdxUnreadData.java     |   118 +
 .../gemfire/pdx/internal/PdxWriterImpl.java     |   910 +
 .../pdx/internal/PeerTypeRegistration.java      |   776 +
 .../pdx/internal/TrackingPdxReaderImpl.java     |   354 +
 .../gemfire/pdx/internal/TypeRegistration.java  |   102 +
 .../gemfire/pdx/internal/TypeRegistry.java      |   525 +
 .../gemfire/pdx/internal/UnreadPdxType.java     |    73 +
 .../internal/WeakConcurrentIdentityHashMap.java |   137 +
 .../pdx/internal/WritablePdxInstanceImpl.java   |   288 +
 .../gemfire/pdx/internal/json/JsonHelper.java   |   182 +
 .../pdx/internal/json/PdxInstanceHelper.java    |   195 +
 .../pdx/internal/json/PdxListHelper.java        |   190 +
 .../gemfire/pdx/internal/json/PdxToJSON.java    |   322 +
 .../pdx/internal/unsafe/UnsafeWrapper.java      |   188 +
 .../java/com/gemstone/gemfire/pdx/package.html  |   112 +
 .../com/gemstone/gemfire/ra/GFConnection.java   |    27 +
 .../gemfire/ra/GFConnectionFactory.java         |    29 +
 .../gemfire/redis/GemFireRedisServer.java       |   717 +
 .../gemfire/security/AccessControl.java         |    95 +
 .../gemfire/security/AuthInitialize.java        |    88 +
 .../security/AuthenticationFailedException.java |    54 +
 .../AuthenticationRequiredException.java        |    54 +
 .../gemfire/security/Authenticator.java         |    87 +
 .../security/GemFireSecurityException.java      |    55 +
 .../security/NotAuthorizedException.java        |    63 +
 .../com/gemstone/gemfire/security/package.html  |    39 +
 .../message/GemFireParameterizedMessage.java    |   554 +
 .../GemFireParameterizedMessageFactory.java     |    54 +
 geode-core/src/main/java/external-overview.html |    43 +
 geode-core/src/main/java/internal-overview.html |    26 +
 .../gemfire/cache/cache-8.1.xsd                 |  1512 ++
 .../gemfire/cache/cache-9.0.xsd                 |  1519 ++
 .../services/org.xml.sax.ext.EntityResolver2    |     2 +
 .../gemstone/gemfire/admin/doc-files/ds4_0.dtd  |   176 +
 .../gemstone/gemfire/admin/doc-files/ds5_0.dtd  |   168 +
 .../internal/doc-files/mbeans-descriptors.dtd   |   232 +
 .../gemfire/admin/jmx/mbeans-descriptors.xml    |  1435 ++
 .../gemfire/cache/doc-files/cache3_0.dtd        |   296 +
 .../gemfire/cache/doc-files/cache4_0.dtd        |   392 +
 .../gemfire/cache/doc-files/cache4_1.dtd        |   485 +
 .../gemfire/cache/doc-files/cache5_0.dtd        |   519 +
 .../gemfire/cache/doc-files/cache5_1.dtd        |   534 +
 .../gemfire/cache/doc-files/cache5_5.dtd        |   651 +
 .../gemfire/cache/doc-files/cache5_7.dtd        |   776 +
 .../gemfire/cache/doc-files/cache5_8.dtd        |   794 +
 .../gemfire/cache/doc-files/cache6_0.dtd        |   862 +
 .../gemfire/cache/doc-files/cache6_1.dtd        |   871 +
 .../gemfire/cache/doc-files/cache6_5.dtd        |   949 +
 .../gemfire/cache/doc-files/cache6_6.dtd        |  1006 +
 .../gemfire/cache/doc-files/cache7_0.dtd        |  1087 ++
 .../gemfire/cache/doc-files/cache8_0.dtd        |  1107 ++
 .../membership/gms/messenger/jgroups-config.xml |    72 +
 .../membership/gms/messenger/jgroups-mcast.xml  |    98 +
 .../internal/i18n/StringIdResourceBundle_ja.txt |  3811 ++++
 .../internal/logging/log4j/log4j2-legacy.xml    |    17 +
 .../gemstone/gemfire/internal/privatekey.ser    |   Bin 0 -> 756 bytes
 .../com/gemstone/gemfire/internal/publickey.ser |   Bin 0 -> 1029 bytes
 .../tools/gfsh/app/windowsbindings.properties   |    83 +
 .../internal/cli/commands/support/gfmon.html    |    28 +
 .../management/internal/cli/modes/commands.json |     3 +
 .../management/internal/cli/modes/connect.json  |    29 +
 .../internal/cli/modes/stopserver.json          |    29 +
 .../com/gemstone/gemfire/statisticsType.dtd     |    87 +
 geode-core/src/main/resources/log4j2-cli.xml    |    17 +
 geode-core/src/main/resources/log4j2.xml        |    23 +
 .../batterytest/greplogs/ExpectedStrings.java   |   188 +
 .../java/batterytest/greplogs/LogConsumer.java  |   290 +
 .../src/test/java/cacheRunner/Portfolio.java    |   129 +
 .../src/test/java/cacheRunner/Position.java     |    74 +
 .../src/test/java/com/company/app/Customer.java |    37 +
 .../src/test/java/com/company/app/DBLoader.java |    64 +
 .../com/company/app/OrdersCacheListener.java    |    52 +
 .../java/com/company/data/DatabaseLoader.java   |    43 +
 .../java/com/company/data/MyDeclarable.java     |    33 +
 .../src/test/java/com/company/data/MySizer.java |    40 +
 .../com/company/data/MyTransactionListener.java |    39 +
 .../src/test/java/com/examples/LinkNode.java    |    78 +
 .../src/test/java/com/examples/SuperClass.java  |    93 +
 .../src/test/java/com/examples/TestObject.java  |    55 +
 .../src/test/java/com/examples/ds/Address.java  |    23 +
 .../src/test/java/com/examples/ds/Company.java  |    43 +
 .../java/com/examples/ds/CompanySerializer.java |    67 +
 .../src/test/java/com/examples/ds/Employee.java |    53 +
 .../com/examples/ds/PutDataSerializables.java   |    55 +
 .../src/test/java/com/examples/ds/User.java     |    58 +
 .../com/examples/snapshot/MyDataSerializer.java |    63 +
 .../java/com/examples/snapshot/MyObject.java    |    69 +
 .../snapshot/MyObjectDataSerializable.java      |    45 +
 .../java/com/examples/snapshot/MyObjectPdx.java |    33 +
 .../snapshot/MyObjectPdxSerializable.java       |    42 +
 .../com/examples/snapshot/MyPdxSerializer.java  |    64 +
 .../java/com/gemstone/gemfire/AppObject.java    |    24 +
 .../com/gemstone/gemfire/CopyJUnitTest.java     |   575 +
 .../com/gemstone/gemfire/DeltaTestImpl.java     |   397 +
 .../gemfire/DiskInstantiatorsJUnitTest.java     |   183 +
 .../com/gemstone/gemfire/GemFireTestCase.java   |    92 +
 .../java/com/gemstone/gemfire/Invariant.java    |    32 +
 .../com/gemstone/gemfire/InvariantResult.java   |    28 +
 .../com/gemstone/gemfire/JUnitTestSetup.java    |   143 +
 .../gemfire/JtaNoninvolvementJUnitTest.java     |   180 +
 .../gemfire/LocalStatisticsJUnitTest.java       |    50 +
 .../com/gemstone/gemfire/LonerDMJUnitTest.java  |   196 +
 .../gemstone/gemfire/StatisticsTestCase.java    |   388 +
 .../gemfire/StatisticsTypeJUnitTest.java        |    77 +
 .../gemfire/SystemFailureJUnitTest.java         |    60 +
 .../com/gemstone/gemfire/TXExpiryJUnitTest.java |   420 +
 .../java/com/gemstone/gemfire/TXJUnitTest.java  |  6825 +++++++
 .../com/gemstone/gemfire/TXWriterJUnitTest.java |   241 +
 .../gemstone/gemfire/TXWriterOOMEJUnitTest.java |    78 +
 .../com/gemstone/gemfire/TXWriterTestCase.java  |   152 +
 .../gemstone/gemfire/TestDataSerializer.java    |   117 +
 .../com/gemstone/gemfire/TimingTestCase.java    |    77 +
 .../com/gemstone/gemfire/UnitTestDoclet.java    |   264 +
 .../gemstone/gemfire/admin/AdminTestHelper.java |    45 +
 .../BindDistributedSystemJUnitTest.java         |    97 +
 .../internal/CacheHealthEvaluatorJUnitTest.java |   208 +
 .../internal/DistributedSystemTestCase.java     |    67 +
 .../admin/internal/HealthEvaluatorTestCase.java |    76 +
 .../MemberHealthEvaluatorJUnitTest.java         |   102 +
 .../cache/AttributesFactoryJUnitTest.java       |   420 +
 .../gemfire/cache/Bug36619JUnitTest.java        |    77 +
 .../gemfire/cache/Bug42039JUnitTest.java        |    96 +
 .../gemfire/cache/Bug52289JUnitTest.java        |    89 +
 .../gemfire/cache/CacheListenerJUnitTest.java   |   336 +
 .../cache/CacheRegionClearStatsDUnitTest.java   |   240 +
 .../gemstone/gemfire/cache/ClientHelper.java    |    73 +
 .../cache/ClientServerTimeSyncDUnitTest.java    |   203 +
 .../cache/ConnectionPoolAndLoaderDUnitTest.java |   489 +
 .../cache/ConnectionPoolFactoryJUnitTest.java   |   424 +
 .../gemfire/cache/OperationJUnitTest.java       |   933 +
 .../gemfire/cache/PoolManagerJUnitTest.java     |   135 +
 .../gemstone/gemfire/cache/ProxyJUnitTest.java  |  1169 ++
 .../gemfire/cache/RegionFactoryJUnitTest.java   |  1195 ++
 .../gemfire/cache/RoleExceptionJUnitTest.java   |   139 +
 .../SerialAsyncEventQueueImplJUnitTest.java     |    62 +
 .../client/ClientCacheFactoryJUnitTest.java     |   343 +
 .../client/ClientRegionFactoryJUnitTest.java    |   532 +
 .../ClientServerRegisterInterestsDUnitTest.java |   256 +
 .../internal/AutoConnectionSourceDUnitTest.java |   598 +
 .../AutoConnectionSourceImplJUnitTest.java      |   398 +
 .../CacheServerSSLConnectionDUnitTest.java      |   424 +
 .../internal/ConnectionPoolImplJUnitTest.java   |   260 +
 .../internal/LocatorLoadBalancingDUnitTest.java |   502 +
 .../cache/client/internal/LocatorTestBase.java  |   365 +
 .../internal/OpExecutorImplJUnitTest.java       |   664 +
 .../client/internal/QueueManagerJUnitTest.java  |   674 +
 .../internal/SSLNoClientAuthDUnitTest.java      |   277 +
 .../internal/ServerBlackListJUnitTest.java      |   123 +
 .../locator/LocatorStatusResponseJUnitTest.java |    77 +
 .../pooling/ConnectionManagerJUnitTest.java     |   878 +
 .../SignalledFlushObserverJUnitTest.java        |    97 +
 .../SortedListForAsyncQueueJUnitTest.java       |   565 +
 .../management/MXMemoryPoolListenerExample.java |   206 +
 .../management/MemoryThresholdsDUnitTest.java   |  2333 +++
 .../MemoryThresholdsOffHeapDUnitTest.java       |  1826 ++
 .../management/ResourceManagerDUnitTest.java    |  1841 ++
 .../ExceptionHandlingJUnitTest.java             |   177 +
 .../mapInterface/MapFunctionalJUnitTest.java    |   170 +
 .../mapInterface/PutAllGlobalLockJUnitTest.java |   109 +
 .../PutOperationContextJUnitTest.java           |   264 +
 .../GetOperationContextImplJUnitTest.java       |   291 +
 .../PartitionRegionHelperDUnitTest.java         |   742 +
 .../BaseLineAndCompareQueryPerfJUnitTest.java   |   537 +
 .../query/Bug32947ValueConstraintJUnitTest.java |   127 +
 .../gemfire/cache/query/BugJUnitTest.java       |   570 +
 .../gemfire/cache/query/CacheUtils.java         |   398 +
 .../cache/query/MultithreadedTester.java        |    73 +
 .../cache/query/PdxStringQueryJUnitTest.java    |   727 +
 .../gemstone/gemfire/cache/query/PerfQuery.java |   330 +
 .../gemfire/cache/query/QueryJUnitTest.java     |   457 +
 .../cache/query/QueryServiceJUnitTest.java      |   252 +
 .../gemfire/cache/query/QueryTestUtils.java     |  1640 ++
 .../cache/query/QueryTestUtilsJUnitTest.java    |   134 +
 .../gemfire/cache/query/RegionJUnitTest.java    |   226 +
 .../cache/query/TypedIteratorJUnitTest.java     |   133 +
 .../com/gemstone/gemfire/cache/query/Utils.java |    57 +
 .../query/cq/dunit/CqQueryTestListener.java     |   398 +
 .../gemfire/cache/query/data/Address.java       |    51 +
 .../gemstone/gemfire/cache/query/data/City.java |    57 +
 .../cache/query/data/CollectionHolder.java      |    90 +
 .../cache/query/data/ComparableWrapper.java     |    70 +
 .../gemfire/cache/query/data/Country.java       |   100 +
 .../gemstone/gemfire/cache/query/data/Data.java |    47 +
 .../gemfire/cache/query/data/District.java      |    65 +
 .../gemfire/cache/query/data/Employee.java      |    72 +
 .../gemfire/cache/query/data/Inventory.java     |   127 +
 .../gemfire/cache/query/data/Keywords.java      |    90 +
 .../gemfire/cache/query/data/Manager.java       |    43 +
 .../gemfire/cache/query/data/Numbers.java       |    52 +
 .../gemfire/cache/query/data/PhoneNo.java       |    42 +
 .../gemfire/cache/query/data/Portfolio.java     |   314 +
 .../gemfire/cache/query/data/PortfolioData.java |   154 +
 .../gemfire/cache/query/data/PortfolioNoDS.java |   240 +
 .../gemfire/cache/query/data/PortfolioPdx.java  |   311 +
 .../gemfire/cache/query/data/Position.java      |   166 +
 .../gemfire/cache/query/data/PositionNoDS.java  |   130 +
 .../gemfire/cache/query/data/PositionPdx.java   |   182 +
 .../query/data/ProhibitedSecurityQuote.java     |    66 +
 .../gemfire/cache/query/data/Quote.java         |   114 +
 .../gemfire/cache/query/data/Restricted.java    |    80 +
 .../cache/query/data/SecurityMaster.java        |   262 +
 .../gemfire/cache/query/data/State.java         |    81 +
 .../gemfire/cache/query/data/Street.java        |    38 +
 .../gemfire/cache/query/data/Student.java       |    77 +
 .../gemfire/cache/query/data/Vehicle.java       |    39 +
 .../gemfire/cache/query/data/Village.java       |    55 +
 .../query/dunit/CloseCacheAuthorization.java    |    62 +
 .../query/dunit/CompactRangeIndexDUnitTest.java |   204 +
 .../cache/query/dunit/CqTimeTestListener.java   |   266 +
 .../cache/query/dunit/GroupByDUnitImpl.java     |   328 +
 .../dunit/GroupByPartitionedQueryDUnitTest.java |   110 +
 .../query/dunit/GroupByQueryDUnitTest.java      |   189 +
 .../cache/query/dunit/HashIndexDUnitTest.java   |   132 +
 .../cache/query/dunit/HelperTestCase.java       |   267 +
 .../dunit/NonDistinctOrderByDUnitImpl.java      |   266 +
 .../NonDistinctOrderByPartitionedDUnitTest.java |   154 +
 .../query/dunit/PdxStringQueryDUnitTest.java    |  1987 ++
 .../dunit/QueryAPITestPartitionResolver.java    |    44 +
 .../cache/query/dunit/QueryAuthorization.java   |    70 +
 .../dunit/QueryDataInconsistencyDUnitTest.java  |   576 +
 .../dunit/QueryIndexUsingXMLDUnitTest.java      |   993 +
 .../QueryParamsAuthorizationDUnitTest.java      |   111 +
 .../QueryUsingFunctionContextDUnitTest.java     |  1041 +
 .../query/dunit/QueryUsingPoolDUnitTest.java    |  2588 +++
 .../cache/query/dunit/RemoteQueryDUnitTest.java |  1502 ++
 ...esourceManagerWithQueryMonitorDUnitTest.java |  1166 ++
 .../query/dunit/SelectStarQueryDUnitTest.java   |  1625 ++
 .../cache/query/facets/lang/Address.java        |    60 +
 .../gemfire/cache/query/facets/lang/Course.java |    91 +
 .../cache/query/facets/lang/Department.java     |    96 +
 .../query/facets/lang/DerivedEmployee.java      |    29 +
 .../cache/query/facets/lang/Employee.java       |   140 +
 .../cache/query/facets/lang/Faculty.java        |   134 +
 .../cache/query/facets/lang/G_Student.java      |    66 +
 .../gemfire/cache/query/facets/lang/Person.java |    96 +
 .../cache/query/facets/lang/Student.java        |   103 +
 .../cache/query/facets/lang/UG_Student.java     |    66 +
 .../gemfire/cache/query/facets/lang/Utils.java  |   134 +
 .../ComparisonOperatorsJUnitTest.java           |   185 +
 .../query/functional/ConstantsJUnitTest.java    |   109 +
 .../query/functional/CountStarJUnitTest.java    |   686 +
 .../CustomerOptimizationsJUnitTest.java         |  1386 ++
 .../DistinctAndNonDistinctQueryJUnitTest.java   |   154 +
 ...ctResultsWithDupValuesInRegionJUnitTest.java |   481 +
 .../query/functional/FunctionJUnitTest.java     |   315 +
 .../functional/GroupByPartitionedJUnitTest.java |    50 +
 .../functional/GroupByReplicatedJUnitTest.java  |    39 +
 .../cache/query/functional/GroupByTestImpl.java |  1010 +
 .../query/functional/GroupByTestInterface.java  |    58 +
 .../query/functional/INOperatorJUnitTest.java   |   471 +
 .../functional/IUM6Bug32345ReJUnitTest.java     |   224 +
 .../cache/query/functional/IUMJUnitTest.java    |   237 +
 .../IUMRCompositeIteratorJUnitTest.java         |   251 +
 .../IUMRMultiIndexesMultiRegionJUnitTest.java   |  1274 ++
 .../IUMRShuffleIteratorsJUnitTest.java          |   489 +
 .../functional/IUMRSingleRegionJUnitTest.java   |   901 +
 ...ependentOperandsInWhereClause2JUnitTest.java |   200 +
 .../IndexCreationDeadLockJUnitTest.java         |   309 +
 .../functional/IndexCreationJUnitTest.java      |  1088 ++
 .../IndexMaintenanceAsynchJUnitTest.java        |   178 +
 .../functional/IndexOnEntrySetJUnitTest.java    |   335 +
 .../functional/IndexOperatorJUnitTest.java      |   225 +
 .../IndexPrimaryKeyUsageJUnitTest.java          |   335 +
 .../IndexUsageInNestedQueryJUnitTest.java       |   152 +
 .../IndexUsageWithAliasAsProjAtrbt.java         |   177 +
 ...IndexUsageWithAliasAsProjAtrbtJUnitTest.java |   185 +
 .../IndexUseMultFrmSnglCondJUnitTest.java       |   274 +
 ...ndexWithSngleFrmAndMultCondQryJUnitTest.java |  1354 ++
 .../functional/IteratorTypeDefEmpJUnitTest.java |    87 +
 .../functional/IteratorTypeDefJUnitTest.java    |   163 +
 .../IteratorTypeDefaultTypesJUnitTest.java      |   426 +
 .../functional/IumMultConditionJUnitTest.java   |   231 +
 .../functional/JavaSerializationJUnitTest.java  |    68 +
 .../functional/LikePredicateJUnitTest.java      |  2386 +++
 .../query/functional/LimitClauseJUnitTest.java  |  1850 ++
 .../functional/LogicalOperatorsJUnitTest.java   |   201 +
 .../cache/query/functional/MiscJUnitTest.java   |   726 +
 .../functional/MultiIndexCreationJUnitTest.java |   385 +
 .../MultiRegionIndexUsageJUnitTest.java         |   903 +
 .../functional/MultipleRegionsJUnitTest.java    |   109 +
 .../NegativeNumberQueriesJUnitTest.java         |   127 +
 .../query/functional/NestedQueryJUnitTest.java  |   511 +
 .../NonDistinctOrderByPartitionedJUnitTest.java |   260 +
 .../NonDistinctOrderByReplicatedJUnitTest.java  |   411 +
 .../NonDistinctOrderByTestImplementation.java   |  1545 ++
 .../query/functional/NumericQueryJUnitTest.java |   337 +
 .../functional/OrderByPartitionedJUnitTest.java |   667 +
 .../functional/OrderByReplicatedJUnitTest.java  |   836 +
 .../functional/OrderByTestImplementation.java   |  1184 ++
 .../functional/ParameterBindingJUnitTest.java   |   178 +
 .../PdxGroupByPartitionedJUnitTest.java         |    40 +
 .../PdxGroupByReplicatedJUnitTest.java          |    37 +
 .../query/functional/PdxGroupByTestImpl.java    |  1025 +
 .../query/functional/PdxOrderByJUnitTest.java   |   357 +
 .../functional/QRegionInterfaceJUnitTest.java   |   164 +
 .../QueryREUpdateInProgressJUnitTest.java       |   436 +
 .../functional/QueryUndefinedJUnitTest.java     |   286 +
 .../functional/ReservedKeywordsJUnitTest.java   |    82 +
 .../ResultsDataSerializabilityJUnitTest.java    |   144 +
 .../query/functional/SelectToDateJUnitTest.java |   263 +
 .../functional/StructMemberAccessJUnitTest.java |   287 +
 .../query/functional/StructSetOrResultsSet.java |   456 +
 .../query/functional/TestNewFunctionSSorRS.java |   129 +
 .../CompiledAggregateFunctionJUnitTest.java     |   200 +
 .../CompiledGroupBySelectJUnitTest.java         |   161 +
 .../query/internal/CompiledInJUnitTest.java     |   460 +
 .../CompiledJunctionInternalsJUnitTest.java     |  3481 ++++
 .../internal/CopyOnReadQueryJUnitTest.java      |   418 +
 .../internal/ExecutionContextJUnitTest.java     |   405 +
 .../query/internal/IndexManagerJUnitTest.java   |   182 +
 .../internal/NWayMergeResultsJUnitTest.java     |   551 +
 .../internal/OrderByComparatorJUnitTest.java    |   206 +
 .../internal/ProjectionAttributeJUnitTest.java  |   241 +
 .../query/internal/QCompilerJUnitTest.java      |   452 +
 .../QueryExecutionContextJUnitTest.java         |    67 +
 ...ueryFromClauseCanonicalizationJUnitTest.java |   257 +
 .../QueryObjectSerializationJUnitTest.java      |   151 +
 .../QueryObserverCallbackJUnitTest.java         |   424 +
 .../query/internal/QueryTraceJUnitTest.java     |   449 +
 .../query/internal/QueryUtilsJUnitTest.java     |   308 +
 .../query/internal/ResultsBagJUnitTest.java     |   307 +
 .../ResultsBagLimitBehaviourJUnitTest.java      |   585 +
 .../ResultsCollectionWrapperLimitJUnitTest.java |   367 +
 .../SelectResultsComparatorJUnitTest.java       |    91 +
 .../StructBagLimitBehaviourJUnitTest.java       |   129 +
 .../query/internal/StructSetJUnitTest.java      |    77 +
 .../internal/aggregate/AggregatorJUnitTest.java |   215 +
 ...syncIndexUpdaterThreadShutdownJUnitTest.java |   123 +
 .../index/AsynchIndexMaintenanceJUnitTest.java  |   261 +
 .../CompactRangeIndexIndexMapJUnitTest.java     |   187 +
 .../index/CompactRangeIndexJUnitTest.java       |   506 +
 ...rrentIndexInitOnOverflowRegionDUnitTest.java |   467 +
 ...ndexOperationsOnOverflowRegionDUnitTest.java |   724 +
 ...pdateWithInplaceObjectModFalseDUnitTest.java |   714 +
 ...ConcurrentIndexUpdateWithoutWLDUnitTest.java |   800 +
 .../index/CopyOnReadIndexDUnitTest.java         |   652 +
 .../index/CopyOnReadIndexJUnitTest.java         |   457 +
 .../DeclarativeIndexCreationJUnitTest.java      |   123 +
 .../query/internal/index/EquijoinDUnitTest.java |   437 +
 .../internal/index/HashIndexJUnitTest.java      |  1592 ++
 .../internal/index/HashIndexSetJUnitTest.java   |   504 +
 .../index/IndexCreationInternalsJUnitTest.java  |   214 +
 .../internal/index/IndexElemArrayJUnitTest.java |   137 +
 .../internal/index/IndexHintJUnitTest.java      |   506 +
 .../query/internal/index/IndexJUnitTest.java    |    97 +
 .../index/IndexMaintainceJUnitTest.java         |   513 +
 .../index/IndexMaintenanceJUnitTest.java        |  1439 ++
 .../index/IndexStatisticsJUnitTest.java         |   862 +
 .../IndexTrackingQueryObserverDUnitTest.java    |   329 +
 .../IndexTrackingQueryObserverJUnitTest.java    |   172 +
 .../query/internal/index/IndexUseJUnitTest.java |  1654 ++
 .../IndexedMergeEquiJoinScenariosJUnitTest.java |   604 +
 ...itializeIndexEntryDestroyQueryDUnitTest.java |   455 +
 .../internal/index/MapIndexStoreJUnitTest.java  |   339 +
 .../MapRangeIndexMaintenanceJUnitTest.java      |   389 +
 .../index/MemoryIndexStoreJUnitTest.java        |   396 +
 ...exStoreWithInplaceModificationJUnitTest.java |    54 +
 .../index/MultiIndexCreationDUnitTest.java      |   201 +
 .../NewDeclarativeIndexCreationJUnitTest.java   |   173 +
 .../PartitionedRegionEquijoinDUnitTest.java     |   130 +
 .../index/PdxCopyOnReadQueryJUnitTest.java      |    77 +
 ...gRegionCreationIndexUpdateTypeJUnitTest.java |    98 +
 .../index/PutAllWithIndexPerfDUnitTest.java     |   216 +
 .../internal/index/RangeIndexAPIJUnitTest.java  |   422 +
 .../PRBasicIndexCreationDUnitTest.java          |  1050 +
 .../PRBasicIndexCreationDeadlockDUnitTest.java  |   235 +
 .../PRBasicMultiIndexCreationDUnitTest.java     |  1065 +
 .../partitioned/PRBasicQueryDUnitTest.java      |   273 +
 .../PRBasicRemoveIndexDUnitTest.java            |   142 +
 .../PRColocatedEquiJoinDUnitTest.java           |  1722 ++
 .../partitioned/PRIndexStatisticsJUnitTest.java |   704 +
 .../partitioned/PRInvalidQueryDUnitTest.java    |   133 +
 .../partitioned/PRInvalidQueryJUnitTest.java    |   127 +
 .../partitioned/PRQueryCacheCloseDUnitTest.java |   341 +
 .../PRQueryCacheClosedJUnitTest.java            |   260 +
 .../query/partitioned/PRQueryDUnitHelper.java   |  3048 +++
 .../query/partitioned/PRQueryDUnitTest.java     |  1228 ++
 .../query/partitioned/PRQueryJUnitTest.java     |   188 +
 .../partitioned/PRQueryNumThreadsJUnitTest.java |   165 +
 .../query/partitioned/PRQueryPerfDUnitTest.java |   505 +
 .../PRQueryRegionCloseDUnitTest.java            |   211 +
 .../PRQueryRegionClosedJUnitTest.java           |   257 +
 .../PRQueryRegionDestroyedDUnitTest.java        |   225 +
 .../PRQueryRegionDestroyedJUnitTest.java        |   254 +
 .../PRQueryRemoteNodeExceptionDUnitTest.java    |   786 +
 .../gemfire/cache/query/transaction/Person.java |    57 +
 .../query/transaction/QueryAndJtaJUnitTest.java |   479 +
 .../internal/ConnectionCountProbeJUnitTest.java |    51 +
 .../cache/snapshot/CacheSnapshotJUnitTest.java  |   128 +
 .../snapshot/ParallelSnapshotDUnitTest.java     |   197 +
 .../gemfire/cache/snapshot/RegionGenerator.java |   125 +
 .../cache/snapshot/RegionSnapshotJUnitTest.java |   294 +
 .../snapshot/SnapshotByteArrayDUnitTest.java    |   138 +
 .../cache/snapshot/SnapshotDUnitTest.java       |   224 +
 .../snapshot/SnapshotPerformanceDUnitTest.java  |   167 +
 .../cache/snapshot/SnapshotTestCase.java        |    92 +
 .../cache/snapshot/WanSnapshotJUnitTest.java    |    98 +
 .../cache/util/PasswordUtilJUnitTest.java       |    41 +
 .../gemfire/cache30/Bug34387DUnitTest.java      |   174 +
 .../gemfire/cache30/Bug34948DUnitTest.java      |   148 +
 .../gemfire/cache30/Bug35214DUnitTest.java      |   214 +
 .../gemfire/cache30/Bug38013DUnitTest.java      |   141 +
 .../gemfire/cache30/Bug38741DUnitTest.java      |   414 +
 .../gemfire/cache30/Bug40255JUnitTest.java      |   143 +
 .../gemfire/cache30/Bug40662JUnitTest.java      |    90 +
 .../gemfire/cache30/Bug44418JUnitTest.java      |   173 +
 .../gemfire/cache30/CacheCloseDUnitTest.java    |   104 +
 .../gemfire/cache30/CacheListenerTestCase.java  |   428 +
 .../gemfire/cache30/CacheLoaderTestCase.java    |   330 +
 .../gemfire/cache30/CacheLogRollDUnitTest.java  |   455 +
 .../gemfire/cache30/CacheMapTxnDUnitTest.java   |   534 +
 ...cheRegionsReliablityStatsCheckDUnitTest.java |   136 +
 .../cache30/CacheSerializableRunnable.java      |   114 +
 .../cache30/CacheStatisticsDUnitTest.java       |   515 +
 .../gemstone/gemfire/cache30/CacheTestCase.java |   653 +
 .../gemfire/cache30/CacheWriterTestCase.java    |   507 +
 .../cache30/CacheXMLPartitionResolver.java      |    78 +
 .../gemfire/cache30/CacheXml30DUnitTest.java    |   827 +
 .../gemfire/cache30/CacheXml40DUnitTest.java    |   150 +
 .../gemfire/cache30/CacheXml41DUnitTest.java    |   643 +
 .../gemfire/cache30/CacheXml45DUnitTest.java    |   398 +
 .../gemfire/cache30/CacheXml51DUnitTest.java    |   351 +
 .../gemfire/cache30/CacheXml55DUnitTest.java    |    53 +
 .../gemfire/cache30/CacheXml57DUnitTest.java    |   658 +
 .../gemfire/cache30/CacheXml58DUnitTest.java    |   505 +
 .../gemfire/cache30/CacheXml60DUnitTest.java    |   336 +
 .../gemfire/cache30/CacheXml61DUnitTest.java    |   125 +
 .../gemfire/cache30/CacheXml65DUnitTest.java    |  1159 ++
 .../gemfire/cache30/CacheXml66DUnitTest.java    |   376 +
 .../gemfire/cache30/CacheXml70DUnitTest.java    |   289 +
 .../gemfire/cache30/CacheXml80DUnitTest.java    |   297 +
 .../gemfire/cache30/CacheXml81DUnitTest.java    |   158 +
 .../gemfire/cache30/CacheXml90DUnitTest.java    |   234 +
 .../gemfire/cache30/CacheXmlTestCase.java       |   157 +
 .../cache30/CachedAllEventsDUnitTest.java       |   111 +
 .../gemfire/cache30/CallbackArgDUnitTest.java   |   185 +
 .../cache30/CertifiableTestCacheListener.java   |   148 +
 .../cache30/ClearMultiVmCallBkDUnitTest.java    |   249 +
 .../gemfire/cache30/ClearMultiVmDUnitTest.java  |   467 +
 .../cache30/ClientMembershipDUnitTest.java      |  1659 ++
 .../ClientMembershipSelectorDUnitTest.java      |    32 +
 .../ClientRegisterInterestDUnitTest.java        |   426 +
 ...ClientRegisterInterestSelectorDUnitTest.java |    32 +
 .../cache30/ClientServerCCEDUnitTest.java       |   633 +
 .../gemfire/cache30/ClientServerTestCase.java   |   391 +
 .../ConcurrentLeaveDuringGIIDUnitTest.java      |   216 +
 ...ibutedNoAckAsyncOverflowRegionDUnitTest.java |    61 +
 ...iskDistributedNoAckAsyncRegionDUnitTest.java |    53 +
 .../DiskDistributedNoAckRegionTestCase.java     |    42 +
 ...ributedNoAckSyncOverflowRegionDUnitTest.java |    63 +
 .../gemfire/cache30/DiskRegionDUnitTest.java    |  1636 ++
 .../gemfire/cache30/DiskRegionTestImpl.java     |   247 +
 .../cache30/DistAckMapMethodsDUnitTest.java     |   705 +
 ...istributedAckOverflowRegionCCEDUnitTest.java |    82 +
 ...tedAckOverflowRegionCCEOffHeapDUnitTest.java |    82 +
 ...tributedAckPersistentRegionCCEDUnitTest.java |   228 +
 ...dAckPersistentRegionCCEOffHeapDUnitTest.java |    82 +
 .../DistributedAckRegionCCEDUnitTest.java       |   694 +
 ...DistributedAckRegionCCEOffHeapDUnitTest.java |    82 +
 ...istributedAckRegionCompressionDUnitTest.java |    72 +
 .../cache30/DistributedAckRegionDUnitTest.java  |   140 +
 .../DistributedAckRegionOffHeapDUnitTest.java   |    82 +
 .../DistributedMulticastRegionDUnitTest.java    |   212 +
 .../DistributedNoAckRegionCCEDUnitTest.java     |   586 +
 ...stributedNoAckRegionCCEOffHeapDUnitTest.java |    82 +
 .../DistributedNoAckRegionDUnitTest.java        |   311 +
 .../DistributedNoAckRegionOffHeapDUnitTest.java |    82 +
 .../gemfire/cache30/DynamicRegionDUnitTest.java |   288 +
 .../gemfire/cache30/GlobalLockingDUnitTest.java |   391 +
 .../cache30/GlobalRegionCCEDUnitTest.java       |   245 +
 .../GlobalRegionCCEOffHeapDUnitTest.java        |    82 +
 .../gemfire/cache30/GlobalRegionDUnitTest.java  |   417 +
 .../cache30/GlobalRegionOffHeapDUnitTest.java   |    89 +
 .../cache30/LRUEvictionControllerDUnitTest.java |   488 +
 .../gemfire/cache30/LocalRegionDUnitTest.java   |   264 +
 .../MemLRUEvictionControllerDUnitTest.java      |   276 +
 .../gemfire/cache30/MultiVMRegionTestCase.java  |  9177 +++++++++
 .../gemfire/cache30/MyGatewayEventFilter1.java  |    61 +
 .../gemfire/cache30/MyGatewayEventFilter2.java  |    66 +
 .../cache30/MyGatewayTransportFilter1.java      |    53 +
 .../cache30/MyGatewayTransportFilter2.java      |    55 +
 .../OffHeapLRUEvictionControllerDUnitTest.java  |    80 +
 .../PRBucketSynchronizationDUnitTest.java       |   306 +
 .../PartitionedRegionCompressionDUnitTest.java  |    70 +
 .../cache30/PartitionedRegionDUnitTest.java     |   554 +
 ...tionedRegionMembershipListenerDUnitTest.java |   150 +
 .../PartitionedRegionOffHeapDUnitTest.java      |    81 +
 .../cache30/PreloadedRegionTestCase.java        |   102 +
 .../gemfire/cache30/ProxyDUnitTest.java         |   546 +
 .../cache30/PutAllCallBkRemoteVMDUnitTest.java  |   401 +
 .../cache30/PutAllCallBkSingleVMDUnitTest.java  |   321 +
 .../gemfire/cache30/PutAllMultiVmDUnitTest.java |   366 +
 .../gemfire/cache30/QueueMsgDUnitTest.java      |   312 +
 .../cache30/RRSynchronizationDUnitTest.java     |   269 +
 .../gemfire/cache30/ReconnectDUnitTest.java     |  1173 ++
 .../ReconnectedCacheServerDUnitTest.java        |    95 +
 .../cache30/RegionAttributesTestCase.java       |   266 +
 .../cache30/RegionExpirationDUnitTest.java      |   276 +
 .../RegionMembershipListenerDUnitTest.java      |   420 +
 .../RegionReliabilityDistAckDUnitTest.java      |    39 +
 .../RegionReliabilityDistNoAckDUnitTest.java    |    39 +
 .../RegionReliabilityGlobalDUnitTest.java       |    39 +
 .../RegionReliabilityListenerDUnitTest.java     |   209 +
 .../cache30/RegionReliabilityTestCase.java      |  1463 ++
 .../gemfire/cache30/RegionTestCase.java         |  4101 ++++
 .../gemfire/cache30/ReliabilityTestCase.java    |    59 +
 .../cache30/RemoveAllMultiVmDUnitTest.java      |   300 +
 .../gemfire/cache30/RequiredRolesDUnitTest.java |   440 +
 .../cache30/RolePerformanceDUnitTest.java       |   188 +
 .../gemfire/cache30/SearchAndLoadDUnitTest.java |  1017 +
 .../gemfire/cache30/SlowRecDUnitTest.java       |  1467 ++
 .../gemfire/cache30/TXDistributedDUnitTest.java |  1527 ++
 .../gemfire/cache30/TXOrderDUnitTest.java       |   434 +
 .../cache30/TXRestrictionsDUnitTest.java        |   100 +
 .../gemfire/cache30/TestCacheCallback.java      |   102 +
 .../gemfire/cache30/TestCacheListener.java      |   222 +
 .../gemfire/cache30/TestCacheLoader.java        |    45 +
 .../gemfire/cache30/TestCacheWriter.java        |   131 +
 .../gemfire/cache30/TestDiskRegion.java         |   257 +
 .../gemstone/gemfire/cache30/TestHeapLRU.java   |    90 +
 .../gemfire/cache30/TestPdxSerializer.java      |    69 +
 .../cache30/TestTransactionListener.java        |    93 +
 .../gemfire/cache30/TestTransactionWriter.java  |    44 +
 .../AnalyzeSerializablesJUnitTest.java          |   325 +
 .../codeAnalysis/ClassAndMethodDetails.java     |   154 +
 .../gemfire/codeAnalysis/ClassAndMethods.java   |    50 +
 .../codeAnalysis/ClassAndVariableDetails.java   |   108 +
 .../gemfire/codeAnalysis/ClassAndVariables.java |    64 +
 .../codeAnalysis/CompiledClassUtils.java        |   433 +
 .../codeAnalysis/decode/CompiledAttribute.java  |    46 +
 .../codeAnalysis/decode/CompiledClass.java      |   276 +
 .../codeAnalysis/decode/CompiledCode.java       |    70 +
 .../codeAnalysis/decode/CompiledField.java      |   116 +
 .../codeAnalysis/decode/CompiledMethod.java     |   153 +
 .../gemfire/codeAnalysis/decode/cp/Cp.java      |    78 +
 .../gemfire/codeAnalysis/decode/cp/CpClass.java |    42 +
 .../codeAnalysis/decode/cp/CpDouble.java        |    40 +
 .../codeAnalysis/decode/cp/CpFieldref.java      |    33 +
 .../gemfire/codeAnalysis/decode/cp/CpFloat.java |    31 +
 .../codeAnalysis/decode/cp/CpInteger.java       |    31 +
 .../decode/cp/CpInterfaceMethodref.java         |    24 +
 .../codeAnalysis/decode/cp/CpInvokeDynamic.java |    33 +
 .../gemfire/codeAnalysis/decode/cp/CpLong.java  |    39 +
 .../codeAnalysis/decode/cp/CpMethodHandle.java  |    33 +
 .../codeAnalysis/decode/cp/CpMethodType.java    |    31 +
 .../codeAnalysis/decode/cp/CpMethodref.java     |    25 +
 .../codeAnalysis/decode/cp/CpNameAndType.java   |    27 +
 .../codeAnalysis/decode/cp/CpString.java        |    25 +
 .../gemfire/codeAnalysis/decode/cp/CpUtf8.java  |   133 +
 .../AbstractLauncherIntegrationJUnitTest.java   |    71 +
 .../distributed/AbstractLauncherJUnitTest.java  |   300 +
 .../AbstractLauncherJUnitTestCase.java          |   255 +
 .../AbstractLauncherServiceStatusJUnitTest.java |   265 +
 .../AbstractLocatorLauncherJUnitTestCase.java   |   106 +
 .../AbstractServerLauncherJUnitTestCase.java    |    94 +
 .../gemfire/distributed/AuthInitializer.java    |    45 +
 .../distributed/DistributedMemberDUnitTest.java |   432 +
 .../DistributedSystemConnectPerf.java           |   135 +
 .../distributed/DistributedSystemDUnitTest.java |   406 +
 .../DistributedSystemIntegrationJUnitTest.java  |    91 +
 .../distributed/DistributedSystemJUnitTest.java |    78 +
 .../distributed/DistributedTestSuite.java       |    36 +
 .../distributed/HostedLocatorsDUnitTest.java    |   195 +
 .../LauncherMemberMXBeanJUnitTest.java          |   153 +
 .../gemfire/distributed/LauncherTestSuite.java  |    48 +
 .../gemfire/distributed/LocatorDUnitTest.java   |  1922 ++
 .../gemfire/distributed/LocatorJUnitTest.java   |   200 +
 .../LocatorLauncherIntegrationJUnitTest.java    |   248 +
 .../distributed/LocatorLauncherJUnitTest.java   |   343 +
 .../LocatorLauncherLocalFileJUnitTest.java      |    52 +
 .../LocatorLauncherLocalJUnitTest.java          |   843 +
 .../LocatorLauncherRemoteFileJUnitTest.java     |   219 +
 .../LocatorLauncherRemoteJUnitTest.java         |  1005 +
 .../distributed/LocatorStateJUnitTest.java      |   208 +
 .../gemfire/distributed/MyAuthenticator.java    |    54 +
 .../gemfire/distributed/MyPrincipal.java        |    29 +
 .../gemfire/distributed/RoleDUnitTest.java      |   170 +
 .../ServerLauncherIntegrationJUnitTest.java     |   312 +
 .../distributed/ServerLauncherJUnitTest.java    |   831 +
 .../ServerLauncherLocalFileJUnitTest.java       |    55 +
 .../ServerLauncherLocalJUnitTest.java           |  1076 ++
 .../ServerLauncherRemoteFileJUnitTest.java      |   223 +
 .../ServerLauncherRemoteJUnitTest.java          |  1428 ++
 .../ServerLauncherWithSpringJUnitTest.java      |    99 +
 .../distributed/SystemAdminDUnitTest.java       |   125 +
 .../AtomicLongWithTerminalStateJUnitTest.java   |    41 +
 .../distributed/internal/Bug40751DUnitTest.java |   138 +
 .../ConsoleDistributionManagerDUnitTest.java    |   441 +
 .../distributed/internal/DateMessage.java       |    98 +
 .../internal/DistributionAdvisorDUnitTest.java  |    98 +
 .../internal/DistributionConfigJUnitTest.java   |   313 +
 .../internal/DistributionManagerDUnitTest.java  |   579 +
 .../InternalDistributedSystemJUnitTest.java     |   831 +
 .../gemfire/distributed/internal/LDM.java       |    71 +
 .../internal/LocatorLoadSnapshotJUnitTest.java  |   384 +
 .../internal/ProduceDateMessages.java           |    53 +
 .../internal/ProductUseLogDUnitTest.java        |   108 +
 .../internal/ProductUseLogJUnitTest.java        |    86 +
 .../internal/ServerLocatorJUnitTest.java        |    74 +
 .../internal/SharedConfigurationJUnitTest.java  |    57 +
 .../internal/StartupMessageDataJUnitTest.java   |   296 +
 .../deadlock/DeadlockDetectorJUnitTest.java     |   333 +
 .../deadlock/DependencyGraphJUnitTest.java      |    87 +
 .../GemFireDeadlockDetectorDUnitTest.java       |   243 +
 .../deadlock/UnsafeThreadLocalJUnitTest.java    |    61 +
 .../internal/locks/CollaborationJUnitTest.java  |   617 +
 .../internal/locks/DLockGrantorHelper.java      |    98 +
 .../locks/DLockReentrantLockJUnitTest.java      |    84 +
 .../membership/MembershipJUnitTest.java         |   364 +
 .../internal/membership/NetViewJUnitTest.java   |   269 +
 .../membership/gms/GMSMemberJUnitTest.java      |   164 +
 .../membership/gms/MembershipManagerHelper.java |   171 +
 .../gms/auth/GMSAuthenticatorJUnitTest.java     |   316 +
 .../gms/fd/GMSHealthMonitorJUnitTest.java       |   638 +
 .../locator/GMSLocatorRecoveryJUnitTest.java    |   186 +
 .../gms/membership/GMSJoinLeaveJUnitTest.java   |  1231 ++
 .../gms/membership/StatRecorderJUnitTest.java   |   227 +
 .../messenger/GMSQuorumCheckerJUnitTest.java    |   359 +
 .../membership/gms/messenger/InterceptUDP.java  |   109 +
 .../messenger/JGroupsMessengerJUnitTest.java    |   895 +
 .../gms/mgr/GMSMembershipManagerJUnitTest.java  |   436 +
 .../StreamingOperationManyDUnitTest.java        |   223 +
 .../StreamingOperationOneDUnitTest.java         |   182 +
 .../TcpServerBackwardCompatDUnitTest.java       |   257 +
 .../internal/tcpserver/TcpServerJUnitTest.java  |   221 +
 .../support/DistributedSystemAdapter.java       |   258 +
 .../gemfire/disttx/CacheMapDistTXDUnitTest.java |    65 +
 .../gemfire/disttx/DistTXDebugDUnitTest.java    |  1014 +
 .../disttx/DistTXDistributedTestSuite.java      |    42 +
 .../gemfire/disttx/DistTXExpiryJUnitTest.java   |    57 +
 .../gemfire/disttx/DistTXJUnitTest.java         |    96 +
 .../disttx/DistTXManagerImplJUnitTest.java      |    54 +
 .../gemfire/disttx/DistTXOrderDUnitTest.java    |    55 +
 .../disttx/DistTXPersistentDebugDUnitTest.java  |   132 +
 .../DistTXReleasesOffHeapOnCloseJUnitTest.java  |    53 +
 .../disttx/DistTXRestrictionsDUnitTest.java     |    46 +
 .../disttx/DistTXWithDeltaDUnitTest.java        |    38 +
 .../gemfire/disttx/DistTXWriterJUnitTest.java   |    56 +
 .../disttx/DistTXWriterOOMEJUnitTest.java       |    57 +
 .../disttx/DistributedTransactionDUnitTest.java |  2203 +++
 .../gemfire/disttx/PRDistTXDUnitTest.java       |    65 +
 .../gemfire/disttx/PRDistTXJUnitTest.java       |    92 +
 .../disttx/PRDistTXWithVersionsDUnitTest.java   |    66 +
 ...entPartitionedRegionWithDistTXDUnitTest.java |    46 +
 .../internal/AbstractConfigJUnitTest.java       |   114 +
 .../gemfire/internal/ArrayEqualsJUnitTest.java  |   193 +
 .../gemfire/internal/AvailablePortHelper.java   |   133 +
 .../internal/AvailablePortJUnitTest.java        |    75 +
 ...wardCompatibilitySerializationDUnitTest.java |   300 +
 .../gemfire/internal/Bug49856JUnitTest.java     |    85 +
 .../gemfire/internal/Bug51616JUnitTest.java     |    61 +
 .../gemfire/internal/ByteArrayData.java         |    73 +
 .../gemstone/gemfire/internal/ClassBuilder.java |   291 +
 .../ClassNotFoundExceptionDUnitTest.java        |   244 +
 .../internal/ClassPathLoaderJUnitTest.java      |  1262 ++
 .../gemfire/internal/ConfigSourceJUnitTest.java |    89 +
 .../internal/CopyOnWriteHashSetJUnitTest.java   |   103 +
 .../internal/DataSerializableJUnitTest.java     |  3671 ++++
 .../gemfire/internal/FileUtilJUnitTest.java     |    87 +
 .../internal/GemFireStatSamplerJUnitTest.java   |   618 +
 .../GemFireVersionIntegrationJUnitTest.java     |    54 +
 .../internal/GemFireVersionJUnitTest.java       |   102 +
 .../internal/HeapDataOutputStreamJUnitTest.java |   154 +
 .../gemfire/internal/InlineKeyJUnitTest.java    |   173 +
 .../gemfire/internal/JSSESocketJUnitTest.java   |   247 +
 .../internal/JarClassLoaderJUnitTest.java       |   828 +
 .../gemfire/internal/JarDeployerDUnitTest.java  |   747 +
 .../com/gemstone/gemfire/internal/JavaExec.java |    69 +
 .../gemfire/internal/LineWrapUnitJUnitTest.java |    52 +
 .../gemstone/gemfire/internal/LongBuffer.java   |    96 +
 .../gemfire/internal/NanoTimerJUnitTest.java    |   134 +
 .../gemfire/internal/ObjIdMapJUnitTest.java     |   256 +
 .../internal/OneTaskOnlyDecoratorJUnitTest.java |   165 +
 .../internal/PdxDeleteFieldDUnitTest.java       |   213 +
 .../internal/PdxDeleteFieldJUnitTest.java       |   214 +
 .../gemfire/internal/PdxRenameDUnitTest.java    |   217 +
 .../gemfire/internal/PdxRenameJUnitTest.java    |   164 +
 .../PutAllOperationContextJUnitTest.java        |   197 +
 .../internal/SSLConfigIntegrationJUnitTest.java |    51 +
 .../gemfire/internal/SSLConfigJUnitTest.java    |  1233 ++
 ...hreadPoolExecutorWithKeepAliveJUnitTest.java |   342 +
 .../internal/SimpleStatSamplerJUnitTest.java    |   358 +
 .../gemfire/internal/SocketCloserJUnitTest.java |   195 +
 .../internal/SocketCloserWithWaitJUnitTest.java |    38 +
 .../StatArchiveWriterReaderJUnitTest.java       |  1735 ++
 .../gemfire/internal/StatSamplerJUnitTest.java  |   361 +
 .../gemfire/internal/StatSamplerTestCase.java   |   185 +
 .../internal/UniqueIdGeneratorJUnitTest.java    |    68 +
 .../internal/cache/AbstractRegionJUnitTest.java |   513 +
 .../internal/cache/AbstractRegionMapTest.java   |   186 +
 .../gemfire/internal/cache/BackupDUnitTest.java |   800 +
 .../gemfire/internal/cache/BackupJUnitTest.java |   435 +
 .../internal/cache/BucketRegionJUnitTest.java   |   208 +
 .../internal/cache/Bug33359DUnitTest.java       |   160 +
 .../internal/cache/Bug33726DUnitTest.java       |   161 +
 .../internal/cache/Bug33726JUnitTest.java       |   134 +
 .../Bug34179TooManyFilesOpenJUnitTest.java      |   130 +
 .../internal/cache/Bug34583JUnitTest.java       |   101 +
 .../internal/cache/Bug37241DUnitTest.java       |   231 +
 .../internal/cache/Bug37244JUnitTest.java       |   279 +
 .../internal/cache/Bug37377DUnitTest.java       |   380 +
 .../internal/cache/Bug37500JUnitTest.java       |   184 +
 .../internal/cache/Bug39079DUnitTest.java       |   410 +
 .../internal/cache/Bug40299DUnitTest.java       |   304 +
 .../internal/cache/Bug40632DUnitTest.java       |   148 +
 .../internal/cache/Bug41091DUnitTest.java       |   174 +
 .../internal/cache/Bug41733DUnitTest.java       |   216 +
 .../internal/cache/Bug41957DUnitTest.java       |   161 +
 .../internal/cache/Bug42055DUnitTest.java       |    88 +
 .../internal/cache/Bug45164DUnitTest.java       |   104 +
 .../internal/cache/Bug45934DUnitTest.java       |   134 +
 .../internal/cache/Bug47667DUnitTest.java       |    87 +
 .../internal/cache/Bug48182JUnitTest.java       |   200 +
 .../internal/cache/CacheAdvisorDUnitTest.java   |   281 +
 .../cache/CacheLifecycleListenerJUnitTest.java  |   324 +
 .../internal/cache/CacheServiceJUnitTest.java   |    59 +
 .../cache/ChunkValueWrapperJUnitTest.java       |   188 +
 .../internal/cache/ClearDAckDUnitTest.java      |   286 +
 .../internal/cache/ClearGlobalDUnitTest.java    |   214 +
 ...ssagesRegionCreationAndDestroyJUnitTest.java |   173 +
 .../cache/ClientServerGetAllDUnitTest.java      |   817 +
 ...ServerInvalidAndDestroyedEntryDUnitTest.java |   514 +
 .../ClientServerTransactionCCEDUnitTest.java    |   108 +
 .../cache/ClientServerTransactionDUnitTest.java |  3389 ++++
 .../cache/ComplexDiskRegionJUnitTest.java       |   169 +
 .../ConcurrentDestroySubRegionDUnitTest.java    |   173 +
 ...entFlushingAndRegionOperationsJUnitTest.java |   641 +
 .../cache/ConcurrentMapLocalJUnitTest.java      |   105 +
 .../cache/ConcurrentMapOpsDUnitTest.java        |  1238 ++
 .../ConcurrentRegionOperationsJUnitTest.java    |   925 +
 ...rentRollingAndRegionOperationsJUnitTest.java |   996 +
 .../internal/cache/ConflationJUnitTest.java     |   409 +
 .../cache/ConnectDisconnectDUnitTest.java       |   185 +
 .../cache/CustomerIDPartitionResolver.java      |    86 +
 .../internal/cache/DeltaFaultInDUnitTest.java   |   145 +
 .../cache/DeltaPropagationDUnitTest.java        |  1463 ++
 .../cache/DeltaPropagationStatsDUnitTest.java   |   608 +
 .../internal/cache/DeltaSizingDUnitTest.java    |   265 +
 .../gemfire/internal/cache/DiskIFJUnitTest.java |   796 +
 .../gemfire/internal/cache/DiskIdJUnitTest.java |   238 +
 .../internal/cache/DiskInitFileJUnitTest.java   |   113 +
 .../cache/DiskOfflineCompactionJUnitTest.java   |   826 +
 .../internal/cache/DiskOldAPIsJUnitTest.java    |   437 +
 ...iskRandomOperationsAndRecoveryJUnitTest.java |   715 +
 .../cache/DiskRegByteArrayDUnitTest.java        |   270 +
 .../cache/DiskRegCacheXmlJUnitTest.java         |   299 +
 .../DiskRegCachexmlGeneratorJUnitTest.java      |   302 +
 .../internal/cache/DiskRegCbkChkJUnitTest.java  |   118 +
 .../DiskRegOplogSwtchingAndRollerJUnitTest.java |  1021 +
 .../cache/DiskRegRecoveryJUnitTest.java         |  1495 ++
 .../cache/DiskRegionAsyncRecoveryJUnitTest.java |   538 +
 ...RegionChangingRegionAttributesJUnitTest.java |   143 +
 .../cache/DiskRegionClearJUnitTest.java         |   288 +
 .../internal/cache/DiskRegionHelperFactory.java |   263 +
 .../DiskRegionIllegalArguementsJUnitTest.java   |   281 +
 ...iskRegionIllegalCacheXMLvaluesJUnitTest.java |   146 +
 .../internal/cache/DiskRegionJUnitTest.java     |  3141 +++
 .../internal/cache/DiskRegionProperties.java    |   222 +
 .../internal/cache/DiskRegionTestingBase.java   |   404 +
 .../cache/DiskStoreFactoryJUnitTest.java        |   450 +
 .../cache/DiskWriteAttributesJUnitTest.java     |   223 +
 ...DistrbutedRegionProfileOffHeapDUnitTest.java |   252 +
 .../cache/DistributedCacheTestCase.java         |   472 +
 .../cache/EnumListenerEventJUnitTest.java       |    73 +
 .../internal/cache/EventTrackerDUnitTest.java   |   418 +
 .../internal/cache/EvictionDUnitTest.java       |   247 +
 .../cache/EvictionObjectSizerDUnitTest.java     |   358 +
 .../internal/cache/EvictionStatsDUnitTest.java  |   553 +
 .../internal/cache/EvictionTestBase.java        |   577 +
 .../internal/cache/FaultingInJUnitTest.java     |   236 +
 .../cache/FixedPRSinglehopDUnitTest.java        |   876 +
 .../internal/cache/GIIDeltaDUnitTest.java       |  2632 +++
 .../internal/cache/GIIFlowControlDUnitTest.java |   455 +
 .../internal/cache/GridAdvisorDUnitTest.java    |  1081 ++
 .../HAOverflowMemObjectSizerDUnitTest.java      |   288 +
 .../cache/IncrementalBackupDUnitTest.java       |  1104 ++
 .../cache/InterruptClientServerDUnitTest.java   |   252 +
 .../internal/cache/InterruptDiskJUnitTest.java  |   135 +
 ...InterruptsConserveSocketsFalseDUnitTest.java |    37 +
 .../internal/cache/InterruptsDUnitTest.java     |   213 +
 .../internal/cache/IteratorDUnitTest.java       |   104 +
 .../LIFOEvictionAlgoEnabledRegionJUnitTest.java |   343 +
 ...victionAlgoMemoryEnabledRegionJUnitTest.java |   436 +
 .../internal/cache/MapClearGIIDUnitTest.java    |   285 +
 .../internal/cache/MapInterface2JUnitTest.java  |   281 +
 .../internal/cache/MapInterfaceJUnitTest.java   |   301 +
 .../internal/cache/MockCacheService.java        |    24 +
 .../internal/cache/MockCacheServiceImpl.java    |    39 +
 .../MultipleOplogsRollingFeatureJUnitTest.java  |   257 +
 .../cache/NetSearchMessagingDUnitTest.java      |   442 +
 .../cache/OffHeapEvictionDUnitTest.java         |   135 +
 .../cache/OffHeapEvictionStatsDUnitTest.java    |    88 +
 .../gemfire/internal/cache/OffHeapTestUtil.java |    64 +
 .../cache/OfflineSnapshotJUnitTest.java         |   137 +
 .../gemfire/internal/cache/OldVLJUnitTest.java  |    92 +
 .../cache/OldValueImporterTestBase.java         |   181 +
 .../cache/OplogEntryIdMapJUnitTest.java         |    99 +
 .../cache/OplogEntryIdSetJUnitTest.java         |    83 +
 .../gemfire/internal/cache/OplogJUnitTest.java  |  4034 ++++
 .../internal/cache/OplogRVVJUnitTest.java       |   173 +
 .../cache/OrderedTombstoneMapJUnitTest.java     |    59 +
 .../cache/P2PDeltaPropagationDUnitTest.java     |   599 +
 .../internal/cache/PRBadToDataDUnitTest.java    |   109 +
 .../cache/PRConcurrentMapOpsJUnitTest.java      |   231 +
 .../cache/PRDataStoreMemoryJUnitTest.java       |   154 +
 .../PRDataStoreMemoryOffHeapJUnitTest.java      |    51 +
 .../gemfire/internal/cache/PRTXJUnitTest.java   |   150 +
 .../cache/PartitionAttributesImplJUnitTest.java |   543 +
 .../cache/PartitionListenerDUnitTest.java       |   203 +
 ...dRegionAPIConserveSocketsFalseDUnitTest.java |    45 +
 .../cache/PartitionedRegionAPIDUnitTest.java    |  1512 ++
 .../PartitionedRegionAsSubRegionDUnitTest.java  |   337 +
 ...gionBucketCreationDistributionDUnitTest.java |  1543 ++
 .../PartitionedRegionCacheCloseDUnitTest.java   |   297 +
 ...rtitionedRegionCacheLoaderForRootRegion.java |    62 +
 ...artitionedRegionCacheLoaderForSubRegion.java |    65 +
 ...rtitionedRegionCacheXMLExampleDUnitTest.java |   134 +
 .../PartitionedRegionCreationDUnitTest.java     |   914 +
 .../PartitionedRegionCreationJUnitTest.java     |   548 +
 .../cache/PartitionedRegionDUnitTestCase.java   |   531 +
 .../PartitionedRegionDataStoreJUnitTest.java    |   260 +
 ...rtitionedRegionDelayedRecoveryDUnitTest.java |   310 +
 .../PartitionedRegionDestroyDUnitTest.java      |   309 +
 .../PartitionedRegionEntryCountDUnitTest.java   |   149 +
 .../PartitionedRegionEvictionDUnitTest.java     |  1762 ++
 .../cache/PartitionedRegionHADUnitTest.java     |   506 +
 ...onedRegionHAFailureAndRecoveryDUnitTest.java |   535 +
 .../cache/PartitionedRegionHelperJUnitTest.java |    48 +
 .../PartitionedRegionInvalidateDUnitTest.java   |   212 +
 ...artitionedRegionLocalMaxMemoryDUnitTest.java |   318 +
 ...nedRegionLocalMaxMemoryOffHeapDUnitTest.java |    73 +
 .../PartitionedRegionMultipleDUnitTest.java     |   600 +
 ...rtitionedRegionOffHeapEvictionDUnitTest.java |    94 +
 .../cache/PartitionedRegionPRIDDUnitTest.java   |   270 +
 .../cache/PartitionedRegionQueryDUnitTest.java  |  1160 ++
 ...artitionedRegionQueryEvaluatorJUnitTest.java |   307 +
 ...artitionedRegionRedundancyZoneDUnitTest.java |   165 +
 ...tionedRegionSerializableObjectJUnitTest.java |   178 +
 .../PartitionedRegionSingleHopDUnitTest.java    |  2258 +++
 ...RegionSingleHopWithServerGroupDUnitTest.java |  1665 ++
 ...onedRegionSingleNodeOperationsJUnitTest.java |  1542 ++
 .../cache/PartitionedRegionSizeDUnitTest.java   |   609 +
 .../cache/PartitionedRegionStatsDUnitTest.java  |   649 +
 .../cache/PartitionedRegionStatsJUnitTest.java  |   534 +
 .../cache/PartitionedRegionTestHelper.java      |   337 +
 .../PartitionedRegionTestUtilsDUnitTest.java    |   576 +
 .../PartitionedRegionWithSameNameDUnitTest.java |   924 +
 .../PersistentPartitionedRegionJUnitTest.java   |   225 +
 .../internal/cache/PutAllDAckDUnitTest.java     |   228 +
 .../internal/cache/PutAllGlobalDUnitTest.java   |   296 +
 .../cache/RegionEntryFlagsJUnitTest.java        |    97 +
 .../internal/cache/RegionListenerJUnitTest.java |    63 +
 .../cache/RemotePutReplyMessageJUnitTest.java   |    53 +
 .../cache/RemoteTransactionCCEDUnitTest.java    |    35 +
 .../cache/RemoteTransactionDUnitTest.java       |  4322 +++++
 .../internal/cache/RemoveAllDAckDUnitTest.java  |   173 +
 .../internal/cache/RemoveDAckDUnitTest.java     |   201 +
 .../internal/cache/RemoveGlobalDUnitTest.java   |   250 +
 .../internal/cache/RunCacheInOldGemfire.java    |   188 +
 .../cache/SimpleDiskRegionJUnitTest.java        |   390 +
 .../internal/cache/SingleHopStatsDUnitTest.java |   523 +
 .../internal/cache/SizingFlagDUnitTest.java     |  1039 +
 .../internal/cache/SnapshotTestUtil.java        |    47 +
 .../internal/cache/SystemFailureDUnitTest.java  |   877 +
 .../internal/cache/TXManagerImplJUnitTest.java  |   334 +
 .../cache/TXReservationMgrJUnitTest.java        |   150 +
 .../gemfire/internal/cache/TestDelta.java       |    96 +
 .../internal/cache/TestHelperForHydraTests.java |    32 +
 .../internal/cache/TestNonSizerObject.java      |    63 +
 .../internal/cache/TestObjectSizerImpl.java     |    72 +
 .../gemfire/internal/cache/TestUtils.java       |    32 +
 .../cache/TombstoneCreationJUnitTest.java       |   231 +
 .../cache/TransactionsWithDeltaDUnitTest.java   |   376 +
 .../internal/cache/UnitTestValueHolder.java     |    43 +
 .../gemfire/internal/cache/UnzipUtil.java       |    84 +
 .../internal/cache/UpdateVersionJUnitTest.java  |   407 +
 .../gemfire/internal/cache/VLJUnitTest.java     |   130 +
 .../cache/control/FilterByPathJUnitTest.java    |    96 +
 .../cache/control/MemoryMonitorJUnitTest.java   |   762 +
 .../control/MemoryMonitorOffHeapJUnitTest.java  |   338 +
 .../control/MemoryThresholdsJUnitTest.java      |   152 +
 .../control/RebalanceOperationDUnitTest.java    |  3267 ++++
 .../control/TestMemoryThresholdListener.java    |   169 +
 ...skRegOverflowAsyncGetInMemPerfJUnitTest.java |   136 +
 ...iskRegOverflowAsyncJUnitPerformanceTest.java |   167 +
 ...lowSyncGetInMemPerfJUnitPerformanceTest.java |   129 +
 ...DiskRegOverflowSyncJUnitPerformanceTest.java |   169 +
 ...egionOverflowAsyncRollingOpLogJUnitTest.java |   225 +
 ...RegionOverflowSyncRollingOpLogJUnitTest.java |   223 +
 .../DiskRegionPerfJUnitPerformanceTest.java     |   570 +
 .../DiskRegionPersistOnlySyncJUnitTest.java     |   234 +
 ...DiskRegionRollOpLogJUnitPerformanceTest.java |   638 +
 ...ltiThreadedOplogPerJUnitPerformanceTest.java |   216 +
 .../cache/execute/Bug51193DUnitTest.java        |   245 +
 .../ClientServerFunctionExecutionDUnitTest.java |   892 +
 .../execute/ColocationFailoverDUnitTest.java    |   528 +
 .../cache/execute/CustomResultCollector.java    |    50 +
 .../execute/CustomerIDPartitionResolver.java    |    82 +
 ...ributedRegionFunctionExecutionDUnitTest.java |  1356 ++
 .../FunctionExecution_ExceptionDUnitTest.java   |   646 +
 .../execute/FunctionServiceStatsDUnitTest.java  |  1364 ++
 .../cache/execute/LocalDataSetDUnitTest.java    |   390 +
 .../cache/execute/LocalDataSetFunction.java     |    90 +
 .../execute/LocalDataSetIndexingDUnitTest.java  |   303 +
 .../LocalFunctionExecutionDUnitTest.java        |   185 +
 .../MemberFunctionExecutionDUnitTest.java       |   673 +
 .../MultiRegionFunctionExecutionDUnitTest.java  |   298 +
 .../execute/MyFunctionExecutionException.java   |    59 +
 .../cache/execute/MyTransactionFunction.java    |   517 +
 .../OnGroupsFunctionExecutionDUnitTest.java     |  1246 ++
 ...ntServerFunctionExecutionNoAckDUnitTest.java |   250 +
 ...tServerRegionFunctionExecutionDUnitTest.java |  1638 ++
 ...egionFunctionExecutionFailoverDUnitTest.java |   499 +
 ...onFunctionExecutionNoSingleHopDUnitTest.java |  1189 ++
 ...onExecutionSelectorNoSingleHopDUnitTest.java |  1153 ++
 ...gionFunctionExecutionSingleHopDUnitTest.java |  1177 ++
 .../cache/execute/PRClientServerTestBase.java   |   819 +
 .../cache/execute/PRColocationDUnitTest.java    |  2652 +++
 .../execute/PRCustomPartitioningDUnitTest.java  |   575 +
 .../execute/PRFunctionExecutionDUnitTest.java   |  3213 +++
 .../PRFunctionExecutionTimeOutDUnitTest.java    |   885 +
 ...ctionExecutionWithResultSenderDUnitTest.java |   663 +
 .../execute/PRPerformanceTestDUnitTest.java     |   425 +
 .../cache/execute/PRTransactionDUnitTest.java   |   749 +
 .../PRTransactionWithVersionsDUnitTest.java     |    29 +
 .../internal/cache/execute/PerfFunction.java    |    69 +
 .../internal/cache/execute/PerfTxFunction.java  |    74 +
 .../cache/execute/PerformanceTestFunction.java  |    74 +
 .../execute/SingleHopGetAllPutAllDUnitTest.java |   198 +
 .../internal/cache/execute/TestFunction.java    |   150 +
 .../internal/cache/execute/data/CustId.java     |    72 +
 .../internal/cache/execute/data/Customer.java   |    77 +
 .../internal/cache/execute/data/Order.java      |    65 +
 .../internal/cache/execute/data/OrderId.java    |    82 +
 .../internal/cache/execute/data/Shipment.java   |    65 +
 .../internal/cache/execute/data/ShipmentId.java |    89 +
 .../SimpleExtensionPointJUnitTest.java          |   215 +
 .../extension/mock/AbstractMockExtension.java   |    61 +
 .../mock/AbstractMockExtensionXmlGenerator.java |    41 +
 .../mock/AlterMockCacheExtensionFunction.java   |    90 +
 .../mock/AlterMockRegionExtensionFunction.java  |   104 +
 .../mock/CreateMockCacheExtensionFunction.java  |    86 +
 .../mock/CreateMockRegionExtensionFunction.java |   101 +
 .../mock/DestroyMockCacheExtensionFunction.java |    89 +
 .../DestroyMockRegionExtensionFunction.java     |    99 +
 .../extension/mock/MockCacheExtension.java      |    53 +
 .../mock/MockCacheExtensionXmlGenerator.java    |    57 +
 .../extension/mock/MockExtensionCommands.java   |   219 +
 .../extension/mock/MockExtensionXmlParser.java  |   102 +
 .../extension/mock/MockRegionExtension.java     |    47 +
 .../mock/MockRegionExtensionXmlGenerator.java   |    57 +
 ...gionFunctionFunctionInvocationException.java |    60 +
 .../functions/DistributedRegionFunction.java    |    97 +
 .../cache/functions/LocalDataSetFunction.java   |    89 +
 .../internal/cache/functions/TestFunction.java  |  1148 ++
 .../ha/BlockingHARQAddOperationJUnitTest.java   |   239 +
 .../cache/ha/BlockingHARQStatsJUnitTest.java    |    77 +
 .../cache/ha/BlockingHARegionJUnitTest.java     |   480 +
 .../ha/BlockingHARegionQueueJUnitTest.java      |   213 +
 .../cache/ha/Bug36853EventsExpiryDUnitTest.java |   304 +
 .../internal/cache/ha/Bug48571DUnitTest.java    |   262 +
 .../internal/cache/ha/Bug48879DUnitTest.java    |   219 +
 .../internal/cache/ha/ConflatableObject.java    |   221 +
 .../cache/ha/EventIdOptimizationDUnitTest.java  |   583 +
 .../cache/ha/EventIdOptimizationJUnitTest.java  |   253 +
 .../internal/cache/ha/FailoverDUnitTest.java    |   345 +
 .../internal/cache/ha/HABugInPutDUnitTest.java  |   181 +
 .../internal/cache/ha/HAClearDUnitTest.java     |   657 +
 .../cache/ha/HAConflationDUnitTest.java         |   443 +
 .../internal/cache/ha/HADuplicateDUnitTest.java |   327 +
 .../cache/ha/HAEventIdPropagationDUnitTest.java |   851 +
 .../internal/cache/ha/HAExpiryDUnitTest.java    |   285 +
 .../internal/cache/ha/HAGIIBugDUnitTest.java    |   418 +
 .../internal/cache/ha/HAGIIDUnitTest.java       |   470 +
 .../gemfire/internal/cache/ha/HAHelper.java     |    51 +
 .../cache/ha/HARQAddOperationJUnitTest.java     |  1203 ++
 .../cache/ha/HARQueueNewImplDUnitTest.java      |  1276 ++
 .../internal/cache/ha/HARegionDUnitTest.java    |   406 +
 .../internal/cache/ha/HARegionJUnitTest.java    |   222 +
 .../cache/ha/HARegionQueueDUnitTest.java        |  1149 ++
 .../cache/ha/HARegionQueueJUnitTest.java        |  2153 +++
 .../ha/HARegionQueueStartStopJUnitTest.java     |   133 +
 .../cache/ha/HARegionQueueStatsJUnitTest.java   |   504 +
 .../cache/ha/HASlowReceiverDUnitTest.java       |   290 +
 .../ha/OperationsPropagationDUnitTest.java      |   498 +
 .../internal/cache/ha/PutAllDUnitTest.java      |   585 +
 .../internal/cache/ha/StatsBugDUnitTest.java    |   371 +
 .../cache/ha/TestBlockingHARegionQueue.java     |   129 +
 .../cache/ha/ThreadIdentifierJUnitTest.java     |   116 +
 .../cache/locks/TXLockServiceDUnitTest.java     |   726 +
 .../internal/cache/lru/LRUClockJUnitTest.java   |   519 +
 .../cache/partitioned/Bug39356DUnitTest.java    |   236 +
 .../cache/partitioned/Bug43684DUnitTest.java    |   343 +
 .../cache/partitioned/Bug47388DUnitTest.java    |   287 +
 .../cache/partitioned/Bug51400DUnitTest.java    |   207 +
 .../partitioned/ElidedPutAllDUnitTest.java      |   123 +
 .../OfflineMembersDetailsJUnitTest.java         |    59 +
 .../partitioned/PartitionResolverDUnitTest.java |   411 +
 .../PartitionedRegionLoadModelJUnitTest.java    |  1560 ++
 .../PartitionedRegionLoaderWriterDUnitTest.java |   210 +
 ...rtitionedRegionMetaDataCleanupDUnitTest.java |   193 +
 .../partitioned/PersistPRKRFDUnitTest.java      |   234 +
 ...tentColocatedPartitionedRegionDUnitTest.java |  1597 ++
 .../PersistentPartitionedRegionDUnitTest.java   |  2227 +++
 ...tentPartitionedRegionOldConfigDUnitTest.java |    51 +
 .../PersistentPartitionedRegionTestBase.java    |   807 +
 ...rtitionedRegionWithTransactionDUnitTest.java |   185 +
 .../PutPutReplyMessageJUnitTest.java            |    54 +
 .../cache/partitioned/ShutdownAllDUnitTest.java |   847 +
 ...treamingPartitionOperationManyDUnitTest.java |   250 +
 ...StreamingPartitionOperationOneDUnitTest.java |   233 +
 .../fixed/CustomerFixedPartitionResolver.java   |   113 +
 .../fixed/FixedPartitioningDUnitTest.java       |  1482 ++
 .../fixed/FixedPartitioningTestBase.java        |  1407 ++
 ...ngWithColocationAndPersistenceDUnitTest.java |  1170 ++
 .../cache/partitioned/fixed/MyDate1.java        |    72 +
 .../cache/partitioned/fixed/MyDate2.java        |    52 +
 .../cache/partitioned/fixed/MyDate3.java        |    72 +
 .../fixed/QuarterPartitionResolver.java         |   142 +
 .../SingleHopQuarterPartitionResolver.java      |   173 +
 .../persistence/BackupInspectorJUnitTest.java   |   236 +
 .../PersistentRVVRecoveryDUnitTest.java         |  1006 +
 .../PersistentRecoveryOrderDUnitTest.java       |  1843 ++
 ...rsistentRecoveryOrderOldConfigDUnitTest.java |    66 +
 .../PersistentReplicatedTestBase.java           |   240 +
 .../TemporaryResultSetFactoryJUnitTest.java     |   136 +
 .../RegionEntryFactoryBuilderJUnitTest.java     |    85 +
 .../GFSnapshotJUnitPerformanceTest.java         |   158 +
 .../internal/cache/tier/Bug40396DUnitTest.java  |   213 +
 .../tier/sockets/AcceptorImplJUnitTest.java     |   276 +
 ...mpatibilityHigherVersionClientDUnitTest.java |   249 +
 .../cache/tier/sockets/Bug36269DUnitTest.java   |   226 +
 .../cache/tier/sockets/Bug36457DUnitTest.java   |   213 +
 .../cache/tier/sockets/Bug36805DUnitTest.java   |   244 +
 .../cache/tier/sockets/Bug36829DUnitTest.java   |   170 +
 .../cache/tier/sockets/Bug36995DUnitTest.java   |   256 +
 .../cache/tier/sockets/Bug37210DUnitTest.java   |   294 +
 .../cache/tier/sockets/Bug37805DUnitTest.java   |   139 +
 .../CacheServerMaxConnectionsJUnitTest.java     |   225 +
 ...heServerSelectorMaxConnectionsJUnitTest.java |    35 +
 .../cache/tier/sockets/CacheServerTestUtil.java |   646 +
 .../CacheServerTransactionsDUnitTest.java       |   817 +
 ...acheServerTransactionsSelectorDUnitTest.java |    35 +
 .../tier/sockets/ClearPropagationDUnitTest.java |   480 +
 .../tier/sockets/ClientConflationDUnitTest.java |   540 +
 .../sockets/ClientHealthMonitorJUnitTest.java   |   261 +
 .../ClientHealthMonitorSelectorJUnitTest.java   |    35 +
 .../sockets/ClientInterestNotifyDUnitTest.java  |   639 +
 .../tier/sockets/ClientServerMiscDUnitTest.java |  1389 ++
 .../ClientServerMiscSelectorDUnitTest.java      |    36 +
 .../cache/tier/sockets/ConflationDUnitTest.java |   910 +
 .../tier/sockets/ConnectionProxyJUnitTest.java  |   857 +
 .../DataSerializerPropogationDUnitTest.java     |  1325 ++
 .../cache/tier/sockets/DeltaEOFException.java   |   113 +
 .../DestroyEntryPropagationDUnitTest.java       |   497 +
 .../sockets/DurableClientBug39997DUnitTest.java |   126 +
 .../DurableClientQueueSizeDUnitTest.java        |   416 +
 .../DurableClientReconnectAutoDUnitTest.java    |    59 +
 .../DurableClientReconnectDUnitTest.java        |   763 +
 .../sockets/DurableClientStatsDUnitTest.java    |   381 +
 .../sockets/DurableRegistrationDUnitTest.java   |   777 +
 .../sockets/DurableResponseMatrixDUnitTest.java |   498 +
 .../sockets/EventIDVerificationDUnitTest.java   |   491 +
 .../EventIDVerificationInP2PDUnitTest.java      |   325 +
 .../cache/tier/sockets/FaultyDelta.java         |   162 +
 .../FilterProfileIntegrationJUnitTest.java      |   110 +
 .../tier/sockets/FilterProfileJUnitTest.java    |   412 +
 .../ForceInvalidateEvictionDUnitTest.java       |   401 +
 ...ForceInvalidateOffHeapEvictionDUnitTest.java |    65 +
 .../cache/tier/sockets/HABug36738DUnitTest.java |   194 +
 .../sockets/HAInterestDistributedTestCase.java  |    31 +
 .../tier/sockets/HAInterestPart1DUnitTest.java  |   213 +
 .../tier/sockets/HAInterestPart2DUnitTest.java  |   376 +
 .../cache/tier/sockets/HAInterestTestCase.java  |  1021 +
 .../sockets/HAStartupAndFailoverDUnitTest.java  |   742 +
 .../internal/cache/tier/sockets/HaHelper.java   |    33 +
 .../InstantiatorPropagationDUnitTest.java       |  1723 ++
 .../tier/sockets/InterestListDUnitTest.java     |  1165 ++
 .../sockets/InterestListEndpointDUnitTest.java  |   503 +
 .../InterestListEndpointPRDUnitTest.java        |    42 +
 .../InterestListEndpointSelectorDUnitTest.java  |    35 +
 .../sockets/InterestListFailoverDUnitTest.java  |   318 +
 .../sockets/InterestListRecoveryDUnitTest.java  |   519 +
 .../sockets/InterestRegrListenerDUnitTest.java  |   469 +
 .../sockets/InterestResultPolicyDUnitTest.java  |   398 +
 .../cache/tier/sockets/MessageJUnitTest.java    |   112 +
 .../sockets/NewRegionAttributesDUnitTest.java   |   489 +
 .../tier/sockets/ObjectPartListJUnitTest.java   |   130 +
 .../tier/sockets/RedundancyLevelJUnitTest.java  |   130 +
 .../sockets/RedundancyLevelPart1DUnitTest.java  |   538 +
 .../sockets/RedundancyLevelPart2DUnitTest.java  |   535 +
 .../sockets/RedundancyLevelPart3DUnitTest.java  |   249 +
 .../tier/sockets/RedundancyLevelTestBase.java   |   653 +
 .../tier/sockets/RegionCloseDUnitTest.java      |   246 +
 ...erInterestBeforeRegionCreationDUnitTest.java |   276 +
 .../sockets/RegisterInterestKeysDUnitTest.java  |   248 +
 .../RegisterInterestKeysPRDUnitTest.java        |    41 +
 .../sockets/ReliableMessagingDUnitTest.java     |   438 +
 .../internal/cache/tier/sockets/TestFilter.java |    58 +
 .../sockets/UnregisterInterestDUnitTest.java    |   342 +
 .../sockets/UpdatePropagationDUnitTest.java     |   586 +
 .../sockets/UpdatePropagationPRDUnitTest.java   |    37 +
 .../VerifyEventIDGenerationInP2PDUnitTest.java  |   185 +
 ...UpdatesFromNonInterestEndPointDUnitTest.java |   256 +
 .../tier/sockets/command/CommitCommandTest.java |    61 +
 .../cache/versions/RVVExceptionJUnitTest.java   |    48 +
 .../versions/RegionVersionHolder2JUnitTest.java |   178 +
 .../versions/RegionVersionHolderJUnitTest.java  |  1894 ++
 .../RegionVersionHolderRandomJUnitTest.java     |   191 +
 ...RegionVersionHolderSmallBitSetJUnitTest.java |    46 +
 .../versions/RegionVersionVectorJUnitTest.java  |   546 +
 .../cache/wan/AsyncEventQueueTestBase.java      |  1672 ++
 .../cache/wan/CustomAsyncEventListener.java     |    57 +
 .../gemfire/internal/cache/wan/Filter70.java    |    63 +
 .../cache/wan/MyAsyncEventListener.java         |    53 +
 .../cache/wan/MyAsyncEventListener2.java        |    98 +
 .../cache/wan/MyDistributedSystemListener.java  |    65 +
 .../cache/wan/MyGatewaySenderEventListener.java |    77 +
 .../wan/MyGatewaySenderEventListener2.java      |    77 +
 .../cache/wan/MyGatewayTransportFilter1.java    |    57 +
 .../cache/wan/MyGatewayTransportFilter2.java    |    56 +
 .../cache/wan/MyGatewayTransportFilter3.java    |    56 +
 .../cache/wan/MyGatewayTransportFilter4.java    |    56 +
 .../internal/cache/wan/QueueListener.java       |    79 +
 .../asyncqueue/AsyncEventListenerDUnitTest.java |  1529 ++
 .../AsyncEventListenerOffHeapDUnitTest.java     |    33 +
 .../AsyncEventQueueStatsDUnitTest.java          |   289 +
 .../AsyncEventQueueValidationsJUnitTest.java    |    82 +
 .../ConcurrentAsyncEventQueueDUnitTest.java     |   274 +
 ...ncurrentAsyncEventQueueOffHeapDUnitTest.java |    32 +
 .../CommonParallelAsyncEventQueueDUnitTest.java |    58 +
 ...ParallelAsyncEventQueueOffHeapDUnitTest.java |    32 +
 .../ParallelGatewaySenderQueueJUnitTest.java    |    87 +
 ...ialGatewaySenderEventProcessorJUnitTest.java |    42 +
 .../xmlcache/AbstractXmlParserJUnitTest.java    |   168 +
 .../cache/xmlcache/CacheCreationJUnitTest.java  |   209 +
 .../cache/xmlcache/CacheXmlParserJUnitTest.java |   169 +
 .../xmlcache/CacheXmlVersionJUnitTest.java      |    75 +
 .../PivotalEntityResolverJUnitTest.java         |   145 +
 .../cache/xmlcache/RegionCreationJUnitTest.java |    57 +
 .../xmlcache/XmlGeneratorUtilsJUnitTest.java    |   250 +
 .../classpathloaderjunittest/DoesExist.java     |    21 +
 .../CompressionCacheConfigDUnitTest.java        |   190 +
 .../CompressionCacheListenerDUnitTest.java      |   362 +
 ...ompressionCacheListenerOffHeapDUnitTest.java |    76 +
 .../CompressionRegionConfigDUnitTest.java       |   527 +
 .../CompressionRegionFactoryDUnitTest.java      |   148 +
 .../CompressionRegionOperationsDUnitTest.java   |   541 +
 ...ressionRegionOperationsOffHeapDUnitTest.java |    69 +
 .../compression/CompressionStatsDUnitTest.java  |   681 +
 .../compression/SnappyCompressorJUnitTest.java  |    76 +
 .../datasource/AbstractPoolCacheJUnitTest.java  |   251 +
 .../internal/datasource/CleanUpJUnitTest.java   |   126 +
 .../ConnectionPoolCacheImplJUnitTest.java       |   213 +
 .../datasource/ConnectionPoolingJUnitTest.java  |   339 +
 .../datasource/DataSourceFactoryJUnitTest.java  |   115 +
 .../internal/datasource/RestartJUnitTest.java   |    82 +
 .../internal/i18n/BasicI18nJUnitTest.java       |   407 +
 .../io/CompositeOutputStreamJUnitTest.java      |   453 +
 .../gemfire/internal/jndi/ContextJUnitTest.java |   440 +
 .../internal/jta/BlockingTimeOutJUnitTest.java  |   311 +
 .../gemfire/internal/jta/CacheUtils.java        |   226 +
 .../internal/jta/DataSourceJTAJUnitTest.java    |  1024 +
 .../internal/jta/ExceptionJUnitTest.java        |   126 +
 .../jta/GlobalTransactionJUnitTest.java         |   254 +
 .../gemstone/gemfire/internal/jta/JTAUtils.java |   386 +
 .../internal/jta/JtaIntegrationJUnitTest.java   |   134 +
 .../gemstone/gemfire/internal/jta/SyncImpl.java |    39 +
 .../internal/jta/TransactionImplJUnitTest.java  |   109 +
 .../jta/TransactionManagerImplJUnitTest.java    |   298 +
 .../jta/TransactionTimeOutJUnitTest.java        |   333 +
 .../jta/UserTransactionImplJUnitTest.java       |   130 +
 .../internal/jta/dunit/CommitThread.java        |   176 +
 .../internal/jta/dunit/ExceptionsDUnitTest.java |   316 +
 .../jta/dunit/IdleTimeOutDUnitTest.java         |   344 +
 .../jta/dunit/LoginTimeOutDUnitTest.java        |   348 +
 .../jta/dunit/MaxPoolSizeDUnitTest.java         |   314 +
 .../internal/jta/dunit/RollbackThread.java      |   176 +
 .../jta/dunit/TransactionTimeOutDUnitTest.java  |   502 +
 .../dunit/TxnManagerMultiThreadDUnitTest.java   |   520 +
 .../internal/jta/dunit/TxnTimeOutDUnitTest.java |   310 +
 .../internal/jta/functional/CacheJUnitTest.java |  1199 ++
 .../jta/functional/TestXACacheLoader.java       |   104 +
 .../internal/lang/ClassUtilsJUnitTest.java      |   165 +
 .../internal/lang/InOutParameterJUnitTest.java  |    74 +
 .../internal/lang/InitializerJUnitTest.java     |    75 +
 .../internal/lang/ObjectUtilsJUnitTest.java     |   189 +
 .../internal/lang/StringUtilsJUnitTest.java     |   351 +
 .../internal/lang/SystemUtilsJUnitTest.java     |   101 +
 .../internal/lang/ThreadUtilsJUnitTest.java     |   214 +
 .../DistributedSystemLogFileJUnitTest.java      |  1505 ++
 .../logging/LocatorLogFileJUnitTest.java        |   125 +
 .../logging/LogServiceIntegrationJUnitTest.java |   223 +
 .../LogServiceIntegrationTestSupport.java       |    40 +
 .../internal/logging/LogServiceJUnitTest.java   |   120 +
 .../LogWriterDisabledPerformanceTest.java       |    64 +
 .../logging/LogWriterImplJUnitTest.java         |    83 +
 .../logging/LogWriterPerformanceTest.java       |   127 +
 .../logging/LoggingIntegrationTestSuite.java    |    35 +
 .../logging/LoggingPerformanceTestCase.java     |   200 +
 .../internal/logging/LoggingUnitTestSuite.java  |    42 +
 .../logging/MergeLogFilesJUnitTest.java         |   247 +
 .../gemfire/internal/logging/NullLogWriter.java |   146 +
 .../internal/logging/SortLogFileJUnitTest.java  |   115 +
 .../internal/logging/TestLogWriterFactory.java  |   134 +
 .../logging/log4j/AlertAppenderJUnitTest.java   |   257 +
 .../logging/log4j/ConfigLocatorJUnitTest.java   |   222 +
 .../log4j/FastLoggerIntegrationJUnitTest.java   |   575 +
 .../logging/log4j/FastLoggerJUnitTest.java      |   178 +
 .../FastLoggerWithDefaultConfigJUnitTest.java   |    90 +
 .../log4j/LocalizedMessageJUnitTest.java        |    64 +
 .../log4j/Log4J2DisabledPerformanceTest.java    |    73 +
 .../logging/log4j/Log4J2PerformanceTest.java    |   151 +
 .../log4j/Log4jIntegrationTestSuite.java        |    28 +
 .../logging/log4j/Log4jUnitTestSuite.java       |    32 +
 .../log4j/LogWriterAppenderJUnitTest.java       |   224 +
 .../LogWriterLoggerDisabledPerformanceTest.java |    72 +
 .../log4j/LogWriterLoggerPerformanceTest.java   |   150 +
 .../internal/net/SocketUtilsJUnitTest.java      |   130 +
 .../offheap/AbstractStoredObjectTestBase.java   |   203 +
 .../offheap/ByteArrayMemoryChunkJUnitTest.java  |    30 +
 .../offheap/DataAsAddressJUnitTest.java         |   368 +
 .../internal/offheap/DataTypeJUnitTest.java     |   913 +
 .../DirectByteBufferMemoryChunkJUnitTest.java   |    33 +
 ...tingOutOfOffHeapMemoryListenerJUnitTest.java |   100 +
 .../internal/offheap/FragmentJUnitTest.java     |   238 +
 .../offheap/FreeListOffHeapRegionJUnitTest.java |    46 +
 .../HeapByteBufferMemoryChunkJUnitTest.java     |    33 +
 .../internal/offheap/InlineKeyJUnitTest.java    |   185 +
 .../offheap/LifecycleListenerJUnitTest.java     |   230 +
 .../offheap/MemoryChunkJUnitTestBase.java       |   290 +
 .../internal/offheap/MemoryChunkTestSuite.java  |    32 +
 .../offheap/MemoryInspectorImplJUnitTest.java   |   142 +
 .../offheap/NullOffHeapMemoryStats.java         |   114 +
 .../offheap/NullOutOfOffHeapMemoryListener.java |    39 +
 .../internal/offheap/ObjectChunkJUnitTest.java  |   902 +
 .../offheap/ObjectChunkSliceJUnitTest.java      |    72 +
 .../ObjectChunkWithHeapFormJUnitTest.java       |    64 +
 .../offheap/OffHeapHelperJUnitTest.java         |   314 +
 .../internal/offheap/OffHeapIndexJUnitTest.java |    92 +
 .../internal/offheap/OffHeapRegionBase.java     |   593 +
 .../OffHeapRegionEntryHelperJUnitTest.java      |   870 +
 .../offheap/OffHeapStorageJUnitTest.java        |   285 +
 .../offheap/OffHeapValidationJUnitTest.java     |   540 +
 .../OffHeapWriteObjectAsByteArrayJUnitTest.java |   115 +
 .../OldFreeListOffHeapRegionJUnitTest.java      |    47 +
 .../offheap/OutOfOffHeapMemoryDUnitTest.java    |   304 +
 .../offheap/RefCountChangeInfoJUnitTest.java    |   207 +
 ...moryAllocatorFillPatternIntegrationTest.java |   246 +
 ...mpleMemoryAllocatorFillPatternJUnitTest.java |   183 +
 .../offheap/SimpleMemoryAllocatorJUnitTest.java |   631 +
 .../internal/offheap/StoredObjectTestSuite.java |    32 +
 .../offheap/SyncChunkStackJUnitTest.java        |   289 +
 .../TxReleasesOffHeapOnCloseJUnitTest.java      |    63 +
 .../offheap/UnsafeMemoryChunkJUnitTest.java     |    87 +
 .../BlockingProcessStreamReaderJUnitTest.java   |   480 +
 ...leProcessControllerIntegrationJUnitTest.java |   155 +
 .../LocalProcessControllerJUnitTest.java        |   119 +
 .../process/LocalProcessLauncherDUnitTest.java  |   148 +
 .../process/LocalProcessLauncherJUnitTest.java  |   182 +
 ...NonBlockingProcessStreamReaderJUnitTest.java |   411 +
 .../internal/process/PidFileJUnitTest.java      |   274 +
 .../ProcessControllerFactoryJUnitTest.java      |   159 +
 .../process/ProcessStreamReaderTestCase.java    |   238 +
 .../gemfire/internal/process/mbean/Process.java |    60 +
 .../internal/process/mbean/ProcessMBean.java    |    28 +
 ...tractSignalNotificationHandlerJUnitTest.java |   460 +
 .../internal/size/ObjectSizerJUnitTest.java     |    89 +
 .../internal/size/ObjectTraverserJUnitTest.java |   122 +
 .../internal/size/ObjectTraverserPerf.java      |   100 +
 .../size/SizeClassOnceObjectSizerJUnitTest.java |    70 +
 .../gemfire/internal/size/SizeTestUtil.java     |    33 +
 .../size/WellKnownClassSizerJUnitTest.java      |    62 +
 .../internal/statistics/DummyStatistics.java    |   209 +
 .../statistics/SampleCollectorJUnitTest.java    |   347 +
 .../statistics/StatMonitorHandlerJUnitTest.java |   256 +
 .../statistics/StatisticsDUnitTest.java         |   948 +
 .../statistics/StatisticsMonitorJUnitTest.java  |   227 +
 .../internal/statistics/TestSampleHandler.java  |   177 +
 .../statistics/TestStatArchiveWriter.java       |    60 +
 .../statistics/TestStatisticsManager.java       |    42 +
 .../statistics/TestStatisticsSampler.java       |    59 +
 .../statistics/ValueMonitorJUnitTest.java       |   374 +
 .../internal/stats50/AtomicStatsJUnitTest.java  |   128 +
 .../internal/tcp/ConnectionJUnitTest.java       |    88 +
 .../util/AbortableTaskServiceJUnitTest.java     |   199 +
 .../internal/util/ArrayUtilsJUnitTest.java      |   179 +
 .../gemfire/internal/util/BytesJUnitTest.java   |   116 +
 .../internal/util/CollectionUtilsJUnitTest.java |   487 +
 .../internal/util/DelayedActionJUnitTest.java   |    56 +
 .../gemfire/internal/util/IOUtilsJUnitTest.java |   315 +
 .../gemfire/internal/util/SerializableImpl.java |    38 +
 .../util/SerializableImplWithValue.java         |    57 +
 .../gemfire/internal/util/Valuable.java         |    40 +
 .../CompactConcurrentHashSetJUnitTest.java      |   103 +
 .../ConcurrentHashMapIteratorJUnitTest.java     |   124 +
 .../concurrent/CopyOnWriteHashMapJUnitTest.java |   505 +
 .../concurrent/ReentrantSemaphoreJUnitTest.java |   112 +
 .../SemaphoreReadWriteLockJUnitTest.java        |   185 +
 .../cm/ConcurrentHashMapJUnitTest.java          |   631 +
 .../concurrent/cm/CountedMapLoopsJUnitTest.java |   225 +
 .../concurrent/cm/IntMapCheckJUnitTest.java     |   618 +
 .../util/concurrent/cm/LoopHelpers.java         |   219 +
 .../util/concurrent/cm/MapCheckJUnitTest.java   |   631 +
 .../util/concurrent/cm/MapLoopsJUnitTest.java   |   230 +
 .../util/concurrent/cm/RLJBarJUnitTest.java     |   197 +
 .../concurrent/cm/StringMapLoopsJUnitTest.java  |   240 +
 .../management/CacheManagementDUnitTest.java    |   947 +
 .../management/ClientHealthStatsDUnitTest.java  |   446 +
 .../gemfire/management/CompositeStats.java      |   103 +
 .../gemfire/management/CompositeTestMBean.java  |    65 +
 .../gemfire/management/CompositeTestMXBean.java |    33 +
 .../management/CompositeTypeTestDUnitTest.java  |   170 +
 .../gemfire/management/CustomMBean.java         |    76 +
 .../gemfire/management/CustomMXBean.java        |    36 +
 .../management/DLockManagementDUnitTest.java    |   473 +
 .../DataBrowserJSONValidationJUnitTest.java     |   350 +
 .../management/DiskManagementDUnitTest.java     |   728 +
 .../management/DistributedSystemDUnitTest.java  |   894 +
 .../management/LocatorManagementDUnitTest.java  |   353 +
 .../gemstone/gemfire/management/MBeanUtil.java  |   550 +
 .../gemfire/management/ManagementTestBase.java  |   760 +
 .../MemberMBeanAttributesDUnitTest.java         |   270 +
 .../management/OffHeapManagementDUnitTest.java  |   978 +
 .../gemfire/management/QueryDataDUnitTest.java  |   873 +
 .../management/RegionManagementDUnitTest.java   |  1450 ++
 .../gemfire/management/TypedJsonJUnitTest.java  |   288 +
 ...ersalMembershipListenerAdapterDUnitTest.java |  2153 +++
 .../stats/AsyncEventQueueStatsJUnitTest.java    |    66 +
 .../bean/stats/CacheServerStatsJUnitTest.java   |   167 +
 .../bean/stats/DiskStatsJUnitTest.java          |   122 +
 .../stats/DistributedSystemStatsDUnitTest.java  |   108 +
 .../stats/DistributedSystemStatsJUnitTest.java  |   122 +
 .../bean/stats/GatewayMBeanBridgeJUnitTest.java |   108 +
 .../stats/GatewayReceiverStatsJUnitTest.java    |   207 +
 .../bean/stats/MBeanStatsTestCase.java          |    86 +
 .../bean/stats/MemberLevelStatsJUnitTest.java   |   581 +
 .../bean/stats/RegionStatsJUnitTest.java        |   271 +
 .../bean/stats/StatsRateJUnitTest.java          |   191 +
 .../internal/JettyHelperJUnitTest.java          |    80 +
 .../beans/DistributedSystemBridgeJUnitTest.java |   106 +
 .../cli/ClasspathScanLoadHelperJUnitTest.java   |    92 +
 .../internal/cli/CliUtilDUnitTest.java          |   435 +
 .../internal/cli/CommandManagerJUnitTest.java   |   330 +
 .../cli/CommandSeparatorEscapeJUnitTest.java    |   138 +
 .../internal/cli/DataCommandJsonJUnitTest.java  |    61 +
 .../internal/cli/GfshParserJUnitTest.java       |  1154 ++
 .../management/internal/cli/HeadlessGfsh.java   |   374 +
 .../internal/cli/HeadlessGfshJUnitTest.java     |    86 +
 .../management/internal/cli/ResultHandler.java  |    23 +
 .../internal/cli/TableBuilderJUnitTest.java     |   314 +
 .../cli/annotations/CliArgumentJUnitTest.java   |   214 +
 .../AbstractCommandsSupportJUnitTest.java       |   404 +
 .../cli/commands/CliCommandTestBase.java        |   565 +
 .../cli/commands/ConfigCommandsDUnitTest.java   |   502 +
 ...eateAlterDestroyRegionCommandsDUnitTest.java |  1150 ++
 .../cli/commands/DeployCommandsDUnitTest.java   |   480 +
 .../commands/DiskStoreCommandsDUnitTest.java    |  1157 ++
 .../commands/DiskStoreCommandsJUnitTest.java    |   405 +
 .../cli/commands/FunctionCommandsDUnitTest.java |   595 +
 .../commands/GemfireDataCommandsDUnitTest.java  |  2088 ++
 ...WithCacheLoaderDuringCacheMissDUnitTest.java |   374 +
 .../HTTPServiceSSLSupportJUnitTest.java         |   158 +
 .../cli/commands/IndexCommandsDUnitTest.java    |   815 +
 .../cli/commands/IndexCommandsJUnitTest.java    |   208 +
 ...stAndDescribeDiskStoreCommandsDUnitTest.java |   194 +
 .../ListAndDescribeRegionDUnitTest.java         |   321 +
 .../cli/commands/ListIndexCommandDUnitTest.java |   669 +
 .../cli/commands/MemberCommandsDUnitTest.java   |   288 +
 .../MiscellaneousCommandsDUnitTest.java         |   498 +
 ...laneousCommandsExportLogsPart1DUnitTest.java |   140 +
 ...laneousCommandsExportLogsPart2DUnitTest.java |   144 +
 ...laneousCommandsExportLogsPart3DUnitTest.java |   151 +
 ...laneousCommandsExportLogsPart4DUnitTest.java |   137 +
 .../cli/commands/QueueCommandsDUnitTest.java    |   392 +
 .../SharedConfigurationCommandsDUnitTest.java   |   341 +
 .../cli/commands/ShellCommandsDUnitTest.java    |   367 +
 .../cli/commands/ShowDeadlockDUnitTest.java     |   274 +
 .../cli/commands/ShowMetricsDUnitTest.java      |   345 +
 .../cli/commands/ShowStackTraceDUnitTest.java   |   150 +
 .../cli/commands/UserCommandsDUnitTest.java     |   164 +
 .../RegionPathConverterJUnitTest.java           |    82 +
 .../internal/cli/domain/AbstractImpl.java       |    21 +
 .../management/internal/cli/domain/Impl1.java   |    21 +
 .../management/internal/cli/domain/Impl12.java  |    21 +
 .../internal/cli/domain/Interface1.java         |    21 +
 .../internal/cli/domain/Interface2.java         |    21 +
 .../management/internal/cli/domain/Stock.java   |    37 +
 .../management/internal/cli/dto/Car.java        |    75 +
 .../management/internal/cli/dto/Key1.java       |    67 +
 .../management/internal/cli/dto/Key2.java       |    64 +
 .../internal/cli/dto/ObjectWithCharAttr.java    |    60 +
 .../management/internal/cli/dto/Value1.java     |    97 +
 .../management/internal/cli/dto/Value2.java     |    90 +
 .../functions/DataCommandFunctionJUnitTest.java |   132 +
 .../DescribeDiskStoreFunctionJUnitTest.java     |  1676 ++
 .../ListDiskStoresFunctionJUnitTest.java        |   328 +
 .../functions/ListIndexFunctionJUnitTest.java   |   435 +
 .../cli/parser/ParserUtilsJUnitTest.java        |    82 +
 .../preprocessor/PreprocessorJUnitTest.java     |   302 +
 .../PreprocessorUtilsJUnitTest.java             |   127 +
 .../cli/shell/GfshConfigInitFileJUnitTest.java  |   186 +
 .../shell/GfshExecutionStrategyJUnitTest.java   |   137 +
 .../cli/shell/GfshHistoryJUnitTest.java         |    89 +
 .../cli/shell/GfshInitFileJUnitTest.java        |   476 +
 .../SharedConfigurationDUnitTest.java           |   443 +
 .../configuration/ZipUtilsJUnitTest.java        |    96 +
 .../domain/CacheElementJUnitTest.java           |   144 +
 .../utils/XmlUtilsAddNewNodeJUnitTest.java      |   415 +
 .../configuration/utils/XmlUtilsJUnitTest.java  |   248 +
 .../internal/pulse/TestClientIdsDUnitTest.java  |   301 +
 .../internal/pulse/TestFunctionsDUnitTest.java  |   112 +
 .../internal/pulse/TestHeapDUnitTest.java       |   108 +
 .../internal/pulse/TestLocatorsDUnitTest.java   |    87 +
 .../pulse/TestSubscriptionsDUnitTest.java       |   307 +
 ...rDistributedSystemMXBeanIntegrationTest.java |    50 +
 ...horizeOperationForMBeansIntegrationTest.java |   323 +
 ...erationForRegionCommandsIntegrationTest.java |   136 +
 ...JSONAuthorizationDetailsIntegrationTest.java |   163 +
 ...tionCodesForDataCommandsIntegrationTest.java |   101 +
 ...tionCodesForDistributedSystemMXBeanTest.java |    76 +
 .../ReadOpFileAccessControllerJUnitTest.java    |   201 +
 .../WanCommandsControllerJUnitTest.java         |   140 +
 .../gemfire/management/model/EmptyObject.java   |    24 +
 .../gemstone/gemfire/management/model/Item.java |    95 +
 .../gemfire/management/model/Order.java         |    88 +
 .../gemfire/management/model/SubOrder.java      |    30 +
 .../DomainObjectsAsValuesJUnitTest.java         |   129 +
 .../GemcachedBinaryClientJUnitTest.java         |   148 +
 .../GemcachedDevelopmentJUnitTest.java          |   265 +
 .../gemfire/memcached/IntegrationJUnitTest.java |    94 +
 .../gemfire/pdx/AutoSerializableJUnitTest.java  |  1401 ++
 .../gemfire/pdx/ByteSourceJUnitTest.java        |   752 +
 .../ClientsWithVersioningRetryDUnitTest.java    |   513 +
 .../com/gemstone/gemfire/pdx/DSInsidePdx.java   |   109 +
 .../pdx/DistributedSystemIdDUnitTest.java       |   157 +
 .../com/gemstone/gemfire/pdx/DomainObject.java  |   106 +
 .../gemstone/gemfire/pdx/DomainObjectBad.java   |    25 +
 .../gemfire/pdx/DomainObjectClassLoadable.java  |    27 +
 .../gemfire/pdx/DomainObjectPdxAuto.java        |   192 +
 ...DomainObjectPdxAutoNoDefaultConstructor.java |    63 +
 .../java/com/gemstone/gemfire/pdx/Employee.java |    92 +
 .../pdx/JSONPdxClientServerDUnitTest.java       |   629 +
 .../com/gemstone/gemfire/pdx/NestedPdx.java     |   114 +
 .../gemfire/pdx/NonDelegatingLoader.java        |    66 +
 .../OffHeapByteBufferByteSourceJUnitTest.java   |    52 +
 .../gemfire/pdx/OffHeapByteSourceJUnitTest.java |    65 +
 .../pdx/PDXAsyncEventQueueDUnitTest.java        |   154 +
 .../gemfire/pdx/PdxAttributesJUnitTest.java     |   250 +
 .../gemfire/pdx/PdxClientServerDUnitTest.java   |   799 +
 .../pdx/PdxDeserializationDUnitTest.java        |   413 +
 .../pdx/PdxFormatterPutGetJUnitTest.java        |   208 +
 .../com/gemstone/gemfire/pdx/PdxInsideDS.java   |   107 +
 .../pdx/PdxInstanceFactoryJUnitTest.java        |  1210 ++
 .../gemfire/pdx/PdxInstanceJUnitTest.java       |   396 +
 .../gemfire/pdx/PdxSerializableDUnitTest.java   |   196 +
 .../gemfire/pdx/PdxSerializableJUnitTest.java   |  2171 +++
 .../gemfire/pdx/PdxStringJUnitTest.java         |   167 +
 .../gemfire/pdx/PdxTypeExportDUnitTest.java     |   130 +
 .../gemfire/pdx/SeparateClassloaderPdx.java     |    43 +
 .../com/gemstone/gemfire/pdx/SimpleClass.java   |    83 +
 .../com/gemstone/gemfire/pdx/SimpleClass1.java  |   151 +
 .../com/gemstone/gemfire/pdx/SimpleClass2.java  |    32 +
 .../gemfire/pdx/TestObjectForPdxFormatter.java  |  1003 +
 .../gemfire/pdx/VersionClassLoader.java         |    98 +
 .../gemstone/gemfire/redis/AuthJUnitTest.java   |   160 +
 .../gemfire/redis/ConcurrentStartTest.java      |    98 +
 .../gemstone/gemfire/redis/HashesJUnitTest.java |   191 +
 .../gemstone/gemfire/redis/ListsJUnitTest.java  |   254 +
 .../gemfire/redis/RedisDistDUnitTest.java       |   258 +
 .../gemstone/gemfire/redis/SetsJUnitTest.java   |   258 +
 .../gemfire/redis/SortedSetsJUnitTest.java      |   430 +
 .../gemfire/redis/StringsJunitTest.java         |   312 +
 .../web/controllers/AddFreeItemToOrders.java    |   153 +
 .../rest/internal/web/controllers/Customer.java |   109 +
 .../internal/web/controllers/DateTimeUtils.java |    40 +
 .../rest/internal/web/controllers/Gender.java   |    30 +
 .../internal/web/controllers/GetAllEntries.java |    68 +
 .../web/controllers/GetDeliveredOrders.java     |   106 +
 .../internal/web/controllers/GetRegions.java    |    76 +
 .../web/controllers/GetValueForKey.java         |    77 +
 .../rest/internal/web/controllers/Item.java     |   160 +
 .../rest/internal/web/controllers/Order.java    |   189 +
 .../rest/internal/web/controllers/Person.java   |   185 +
 .../web/controllers/PutKeyFunction.java         |    63 +
 .../web/controllers/RestAPITestBase.java        |   123 +
 .../internal/web/controllers/RestTestUtils.java |   110 +
 .../security/ClientAuthenticationDUnitTest.java |   905 +
 .../ClientAuthenticationPart2DUnitTest.java     |    88 +
 .../security/ClientAuthorizationDUnitTest.java  |   785 +
 .../security/ClientAuthorizationTestBase.java   |  1387 ++
 .../security/ClientMultiUserAuthzDUnitTest.java |   523 +
 .../DeltaClientAuthorizationDUnitTest.java      |   352 +
 .../DeltaClientPostAuthorizationDUnitTest.java  |   538 +
 .../security/P2PAuthenticationDUnitTest.java    |   604 +
 .../gemfire/security/SecurityTestUtil.java      |  1875 ++
 .../com/gemstone/gemfire/test/dunit/Assert.java |    66 +
 .../gemfire/test/dunit/AsyncInvocation.java     |   216 +
 .../gemstone/gemfire/test/dunit/DUnitEnv.java   |    78 +
 .../gemfire/test/dunit/DebuggerUtils.java       |    52 +
 .../gemfire/test/dunit/DistributedTestCase.java |   532 +
 .../test/dunit/DistributedTestUtils.java        |   167 +
 .../com/gemstone/gemfire/test/dunit/Host.java   |   213 +
 .../gemfire/test/dunit/IgnoredException.java    |   208 +
 .../com/gemstone/gemfire/test/dunit/Invoke.java |   160 +
 .../com/gemstone/gemfire/test/dunit/Jitter.java |    87 +
 .../gemfire/test/dunit/LogWriterUtils.java      |   111 +
 .../gemfire/test/dunit/NetworkUtils.java        |    69 +
 .../gemfire/test/dunit/RMIException.java        |   170 +
 .../gemfire/test/dunit/RepeatableRunnable.java  |    31 +
 .../test/dunit/SerializableCallable.java        |    70 +
 .../test/dunit/SerializableCallableIF.java      |    26 +
 .../test/dunit/SerializableRunnable.java        |    91 +
 .../test/dunit/SerializableRunnableIF.java      |    26 +
 .../test/dunit/StoppableWaitCriterion.java      |    35 +
 .../gemfire/test/dunit/ThreadUtils.java         |   155 +
 .../com/gemstone/gemfire/test/dunit/VM.java     |   450 +
 .../com/gemstone/gemfire/test/dunit/Wait.java   |   204 +
 .../gemfire/test/dunit/WaitCriterion.java       |    33 +
 .../dunit/rules/DistributedDisconnectRule.java  |   121 +
 .../rules/DistributedExternalResource.java      |    58 +
 .../DistributedRestoreSystemProperties.java     |    74 +
 .../gemfire/test/dunit/rules/RemoteInvoker.java |    43 +
 .../test/dunit/standalone/BounceResult.java     |    36 +
 .../gemfire/test/dunit/standalone/ChildVM.java  |    81 +
 .../test/dunit/standalone/DUnitLauncher.java    |   464 +
 .../test/dunit/standalone/ProcessManager.java   |   259 +
 .../test/dunit/standalone/RemoteDUnitVM.java    |   143 +
 .../test/dunit/standalone/RemoteDUnitVMIF.java  |    36 +
 .../dunit/standalone/StandAloneDUnitEnv.java    |    74 +
 .../test/dunit/tests/BasicDUnitTest.java        |   156 +
 .../tests/GetDefaultDiskStoreNameDUnitTest.java |    67 +
 .../dunit/tests/GetTestMethodNameDUnitTest.java |    54 +
 .../gemfire/test/dunit/tests/VMDUnitTest.java   |   206 +
 .../com/gemstone/gemfire/test/fake/Fakes.java   |    99 +
 .../gemfire/test/golden/ExecutableProcess.java  |    24 +
 .../gemfire/test/golden/FailOutputTestCase.java |    52 +
 .../golden/FailWithErrorInOutputJUnitTest.java  |    47 +
 .../FailWithExtraLineInOutputJUnitTest.java     |    76 +
 ...WithLineMissingFromEndOfOutputJUnitTest.java |    75 +
 ...hLineMissingFromMiddleOfOutputJUnitTest.java |    74 +
 .../FailWithLoggerErrorInOutputJUnitTest.java   |    46 +
 .../FailWithLoggerFatalInOutputJUnitTest.java   |    46 +
 .../FailWithLoggerWarnInOutputJUnitTest.java    |    46 +
 .../golden/FailWithProblemInOutputTestCase.java |    61 +
 .../golden/FailWithSevereInOutputJUnitTest.java |    47 +
 ...hTimeoutOfWaitForOutputToMatchJUnitTest.java |    68 +
 .../FailWithWarningInOutputJUnitTest.java       |    47 +
 .../gemfire/test/golden/GoldenComparator.java   |   142 +
 .../test/golden/GoldenStringComparator.java     |    39 +
 .../gemfire/test/golden/GoldenTestCase.java     |   157 +
 .../golden/GoldenTestFrameworkTestSuite.java    |    43 +
 .../gemfire/test/golden/PassJUnitTest.java      |    86 +
 .../golden/PassWithExpectedErrorJUnitTest.java  |    47 +
 .../golden/PassWithExpectedProblemTestCase.java |    91 +
 .../golden/PassWithExpectedSevereJUnitTest.java |    47 +
 .../PassWithExpectedWarningJUnitTest.java       |    47 +
 .../test/golden/RegexGoldenComparator.java      |    37 +
 .../test/golden/StringGoldenComparator.java     |    37 +
 .../gemfire/test/golden/log4j2-test.xml         |    18 +
 .../gemfire/test/process/MainLauncher.java      |    48 +
 .../test/process/MainLauncherJUnitTest.java     |   159 +
 .../gemfire/test/process/OutputFormatter.java   |    37 +
 .../test/process/ProcessOutputReader.java       |    89 +
 .../test/process/ProcessStreamReader.java       |    74 +
 .../process/ProcessTestFrameworkTestSuite.java  |    28 +
 .../gemfire/test/process/ProcessWrapper.java    |   464 +
 .../test/process/ProcessWrapperJUnitTest.java   |    72 +
 .../gemstone/gemfire/util/JSR166TestCase.java   |   482 +
 .../gemstone/gemfire/util/test/TestUtil.java    |    65 +
 .../com/gemstone/persistence/admin/Logger.java  |   278 +
 .../gemstone/persistence/logging/Formatter.java |    41 +
 .../gemstone/persistence/logging/Handler.java   |    98 +
 .../com/gemstone/persistence/logging/Level.java |   128 +
 .../gemstone/persistence/logging/LogRecord.java |   185 +
 .../gemstone/persistence/logging/Logger.java    |   566 +
 .../persistence/logging/SimpleFormatter.java    |    77 +
 .../persistence/logging/StreamHandler.java      |    61 +
 .../test/java/com/gemstone/sequence/Arrow.java  |   124 +
 .../java/com/gemstone/sequence/Lifeline.java    |    98 +
 .../com/gemstone/sequence/LifelineState.java    |   114 +
 .../java/com/gemstone/sequence/LineMapper.java  |    36 +
 .../com/gemstone/sequence/SequenceDiagram.java  |   315 +
 .../com/gemstone/sequence/SequencePanel.java    |    83 +
 .../com/gemstone/sequence/StateColorMap.java    |    66 +
 .../java/com/gemstone/sequence/TimeAxis.java    |   122 +
 .../com/gemstone/sequence/ZoomingPanel.java     |   188 +
 .../sequence/gemfire/DefaultLineMapper.java     |    42 +
 .../gemfire/GemfireSequenceDisplay.java         |   336 +
 .../sequence/gemfire/HydraLineMapper.java       |   135 +
 .../sequence/gemfire/SelectGraphDialog.java     |   155 +
 .../com/main/MyDistributedSystemListener.java   |   115 +
 .../com/main/WANBootStrapping_Site1_Add.java    |   122 +
 .../com/main/WANBootStrapping_Site1_Remove.java |    75 +
 .../com/main/WANBootStrapping_Site2_Add.java    |   107 +
 .../com/main/WANBootStrapping_Site2_Remove.java |    73 +
 geode-core/src/test/java/hydra/GsRandom.java    |   311 +
 .../test/java/hydra/HydraRuntimeException.java  |    33 +
 geode-core/src/test/java/hydra/Log.java         |   219 +
 .../src/test/java/hydra/LogVersionHelper.java   |    45 +
 .../src/test/java/hydra/MethExecutor.java       |   393 +
 .../src/test/java/hydra/MethExecutorResult.java |   186 +
 .../src/test/java/hydra/SchedulingOrder.java    |    36 +
 .../src/test/java/hydra/log/AnyLogWriter.java   |   555 +
 .../java/hydra/log/CircularOutputStream.java    |   131 +
 .../parReg/query/unittest/NewPortfolio.java     |   272 +
 .../java/parReg/query/unittest/Position.java    |   162 +
 .../src/test/java/perffmwk/Formatter.java       |   147 +
 .../java/security/AuthzCredentialGenerator.java |   462 +
 .../test/java/security/CredentialGenerator.java |   343 +
 .../security/DummyAuthzCredentialGenerator.java |   145 +
 .../java/security/DummyCredentialGenerator.java |    94 +
 .../security/LdapUserCredentialGenerator.java   |   160 +
 .../java/security/PKCSCredentialGenerator.java  |   112 +
 .../java/security/SSLCredentialGenerator.java   |   117 +
 .../UserPasswordWithExtraPropsAuthInit.java     |    77 +
 .../security/XmlAuthzCredentialGenerator.java   |   264 +
 .../templates/security/DummyAuthenticator.java  |    87 +
 .../templates/security/DummyAuthorization.java  |   118 +
 .../security/FunctionSecurityPrmsHolder.java    |    55 +
 .../security/LdapUserAuthenticator.java         |   117 +
 .../java/templates/security/PKCSAuthInit.java   |   133 +
 .../templates/security/PKCSAuthenticator.java   |   167 +
 .../java/templates/security/PKCSPrincipal.java  |    42 +
 .../security/UserPasswordAuthInit.java          |    84 +
 .../templates/security/UsernamePrincipal.java   |    46 +
 .../templates/security/XmlAuthorization.java    |   675 +
 .../templates/security/XmlErrorHandler.java     |    82 +
 .../src/test/java/util/TestException.java       |    35 +
 ...gemstone.gemfire.internal.cache.CacheService |     1 +
 ...ne.gemfire.internal.cache.xmlcache.XmlParser |     5 +
 ...org.springframework.shell.core.CommandMarker |     8 +
 .../ClientCacheFactoryJUnitTest_single_pool.xml |    30 +
 .../cache/client/internal/cacheserver.cer       |   Bin 0 -> 782 bytes
 .../cache/client/internal/cacheserver.keystore  |   Bin 0 -> 1253 bytes
 .../client/internal/cacheserver.truststore      |   Bin 0 -> 844 bytes
 .../gemfire/cache/client/internal/client.cer    |   Bin 0 -> 782 bytes
 .../cache/client/internal/client.keystore       |   Bin 0 -> 1251 bytes
 .../cache/client/internal/client.truststore     |   Bin 0 -> 846 bytes
 .../cache/client/internal/default.keystore      |   Bin 0 -> 1115 bytes
 .../cache/client/internal/trusted.keystore      |   Bin 0 -> 1078 bytes
 .../gemfire/cache/query/dunit/IndexCreation.xml |   131 +
 .../functional/index-creation-with-eviction.xml |    56 +
 .../index-creation-without-eviction.xml         |    67 +
 .../functional/index-recovery-overflow.xml      |    57 +
 .../query/internal/index/cachequeryindex.xml    |   125 +
 .../internal/index/cachequeryindexwitherror.xml |   134 +
 .../cache/query/partitioned/PRIndexCreation.xml |    44 +
 .../gemfire/cache30/attributesUnordered.xml     |    39 +
 .../com/gemstone/gemfire/cache30/badFloat.xml   |    30 +
 .../com/gemstone/gemfire/cache30/badInt.xml     |    33 +
 .../gemfire/cache30/badKeyConstraintClass.xml   |    31 +
 .../com/gemstone/gemfire/cache30/badScope.xml   |    30 +
 .../com/gemstone/gemfire/cache30/bug44710.xml   |    31 +
 .../gemfire/cache30/callbackNotDeclarable.xml   |    34 +
 .../gemfire/cache30/callbackWithException.xml   |    34 +
 .../com/gemstone/gemfire/cache30/coLocation.xml |    31 +
 .../gemstone/gemfire/cache30/coLocation3.xml    |    31 +
 .../com/gemstone/gemfire/cache30/ewtest.xml     |    68 +
 .../cache30/examples_3_0/example-cache.xml      |    87 +
 .../cache30/examples_4_0/example-cache.xml      |    94 +
 .../gemfire/cache30/loaderNotLoader.xml         |    33 +
 .../com/gemstone/gemfire/cache30/malformed.xml  |    29 +
 .../gemfire/cache30/namedAttributes.xml         |    59 +
 .../gemfire/cache30/partitionedRegion.xml       |    39 +
 .../gemfire/cache30/partitionedRegion51.xml     |    31 +
 .../gemstone/gemfire/cache30/sameRootRegion.xml |    37 +
 .../gemstone/gemfire/cache30/sameSubregion.xml  |    42 +
 .../gemfire/cache30/unknownNamedAttributes.xml  |    30 +
 .../gemfire/codeAnalysis/excludedClasses.txt    |   118 +
 .../gemstone/gemfire/codeAnalysis/openBugs.txt  |    23 +
 .../sanctionedDataSerializables.txt             |  2172 +++
 .../codeAnalysis/sanctionedSerializables.txt    |   827 +
 .../internal/SharedConfigurationJUnitTest.xml   |    23 +
 ...st_testWriteAfterSamplingBegins_expected.gfs |   Bin 0 -> 1970 bytes
 ...est_testWriteWhenSamplingBegins_expected.gfs |   Bin 0 -> 1933 bytes
 .../internal/cache/BackupJUnitTest.cache.xml    |    23 +
 .../internal/cache/DiskRegCacheXmlJUnitTest.xml |   233 +
 .../cache/PartitionRegionCacheExample1.xml      |    43 +
 .../cache/PartitionRegionCacheExample2.xml      |    42 +
 .../incorrect_bytes_threshold.xml               |    35 +
 .../faultyDiskXMLsForTesting/incorrect_dir.xml  |    35 +
 .../incorrect_dir_size.xml                      |    35 +
 .../incorrect_max_oplog_size.xml                |    35 +
 .../incorrect_roll_oplogs_value.xml             |    35 +
 .../incorrect_sync_value.xml                    |    35 +
 .../incorrect_time_interval.xml                 |    35 +
 .../mixed_diskstore_diskdir.xml                 |    38 +
 .../mixed_diskstore_diskwriteattrs.xml          |    38 +
 .../tier/sockets/RedundancyLevelJUnitTest.xml   |    38 +
 ...testDTDFallbackWithNonEnglishLocal.cache.xml |    23 +
 .../gemstone/gemfire/internal/jta/cachejta.xml  |   273 +
 .../domain/CacheElementJUnitTest.xml            |     7 +
 ...dNewNodeJUnitTest.testAddNewNodeNewNamed.xml |    25 +
 ...ewNodeJUnitTest.testAddNewNodeNewUnnamed.xml |    27 +
 ...itTest.testAddNewNodeNewUnnamedExtension.xml |    25 +
 ...NodeJUnitTest.testAddNewNodeReplaceNamed.xml |    22 +
 ...deJUnitTest.testAddNewNodeReplaceUnnamed.xml |    24 +
 ...st.testAddNewNodeReplaceUnnamedExtension.xml |    24 +
 ...sAddNewNodeJUnitTest.testDeleteNodeNamed.xml |    21 +
 ...ddNewNodeJUnitTest.testDeleteNodeUnnamed.xml |    23 +
 ...JUnitTest.testDeleteNodeUnnamedExtension.xml |    23 +
 .../utils/XmlUtilsAddNewNodeJUnitTest.xml       |    24 +
 ...Test.testBuildSchemaLocationMapAttribute.xml |    10 +
 ...testBuildSchemaLocationMapEmptyAttribute.xml |     8 +
 ...ationMapMapOfStringListOfStringAttribute.xml |    10 +
 ....testBuildSchemaLocationMapNullAttribute.xml |     7 +
 ...XmlUtilsJUnitTest.testQuerySingleElement.xml |    24 +
 .../management/internal/security/auth1.json     |    14 +
 .../management/internal/security/auth2.json     |    21 +
 .../management/internal/security/auth3.json     |    25 +
 .../internal/security/testInheritRole.json      |    40 +
 .../security/testSimpleUserAndRole.json         |    14 +
 .../testUserAndRoleRegionServerGroup.json       |    16 +
 .../internal/security/testUserMultipleRole.json |    20 +
 .../gemstone/gemfire/pdx/jsonStrings/array.txt  |    22 +
 .../gemfire/pdx/jsonStrings/attachment.txt      |    11 +
 .../gemfire/pdx/jsonStrings/attachment2.txt     |    13 +
 .../gemstone/gemfire/pdx/jsonStrings/book.txt   |    17 +
 .../gemstone/gemfire/pdx/jsonStrings/image.txt  |    13 +
 .../gemstone/gemfire/pdx/jsonStrings/json1.txt  |    22 +
 .../gemstone/gemfire/pdx/jsonStrings/json10.txt |    20 +
 .../gemstone/gemfire/pdx/jsonStrings/json11.txt |    33 +
 .../gemstone/gemfire/pdx/jsonStrings/json12.txt |    32 +
 .../gemstone/gemfire/pdx/jsonStrings/json13.txt |    42 +
 .../gemstone/gemfire/pdx/jsonStrings/json14.txt |    15 +
 .../gemstone/gemfire/pdx/jsonStrings/json15.txt |     1 +
 .../gemstone/gemfire/pdx/jsonStrings/json16.txt |    31 +
 .../gemfire/pdx/jsonStrings/json16_2.txt        |    31 +
 .../gemstone/gemfire/pdx/jsonStrings/json17.txt |    27 +
 .../gemstone/gemfire/pdx/jsonStrings/json18.txt |    71 +
 .../gemstone/gemfire/pdx/jsonStrings/json19.txt |    18 +
 .../gemstone/gemfire/pdx/jsonStrings/json2.txt  |    11 +
 .../gemstone/gemfire/pdx/jsonStrings/json20.txt |    36 +
 .../gemstone/gemfire/pdx/jsonStrings/json21.txt |    36 +
 .../gemstone/gemfire/pdx/jsonStrings/json22.txt |    36 +
 .../gemstone/gemfire/pdx/jsonStrings/json23.txt |    23 +
 .../gemstone/gemfire/pdx/jsonStrings/json24.txt |    15 +
 .../gemstone/gemfire/pdx/jsonStrings/json25.txt |    33 +
 .../gemstone/gemfire/pdx/jsonStrings/json26.txt |    13 +
 .../gemstone/gemfire/pdx/jsonStrings/json27.txt |    25 +
 .../gemstone/gemfire/pdx/jsonStrings/json28.txt |    84 +
 .../gemstone/gemfire/pdx/jsonStrings/json29.txt |    11 +
 .../gemstone/gemfire/pdx/jsonStrings/json3.txt  |    26 +
 .../gemstone/gemfire/pdx/jsonStrings/json31.txt |     9 +
 .../gemstone/gemfire/pdx/jsonStrings/json4.txt  |    88 +
 .../gemstone/gemfire/pdx/jsonStrings/json5.txt  |    27 +
 .../gemstone/gemfire/pdx/jsonStrings/json6.txt  |    11 +
 .../gemstone/gemfire/pdx/jsonStrings/json7.txt  |    32 +
 .../gemstone/gemfire/pdx/jsonStrings/json8.txt  |    53 +
 .../gemstone/gemfire/pdx/jsonStrings/json9.txt  |    77 +
 .../gemfire/pdx/jsonStrings/jsonMongo.txt       |    10 +
 .../pdx/jsonStrings/jsonMongoSingleQuote.tx0    |    10 +
 .../gemfire/pdx/jsonStrings/jsonProductdb.txt   |    33 +
 .../gemfire/pdx/jsonStrings/json_google.txt     |    33 +
 .../gemfire/pdx/jsonStrings/jsoncustomer.txt    |    24 +
 .../gemfire/pdx/jsonStrings/jsonemptyobject.txo |    44 +
 .../gemfire/pdx/jsonStrings/jsonemptyobject.txt |    23 +
 .../gemfire/pdx/jsonStrings/jsonfacebook.txt    |    45 +
 .../gemfire/pdx/jsonStrings/jsonfeed.txt        |    33 +
 .../gemfire/pdx/jsonStrings/jsonfeed2.txt       |    47 +
 .../gemfire/pdx/jsonStrings/jsonflicker.txt     |    21 +
 .../gemfire/pdx/jsonStrings/jsoniphone.txt      |    78 +
 .../pdx/jsonStrings/jsonsolrwithcomment.tx0     |    29 +
 .../pdx/jsonStrings/jsonsolrwithcomment.txt     |    29 +
 .../gemfire/pdx/jsonStrings/jsontwitter1.txt    |   430 +
 .../gemfire/pdx/jsonStrings/jsontwitter2.txt    |   574 +
 .../gemfire/pdx/jsonStrings/jsontwitter3.txt    |    70 +
 .../gemfire/pdx/jsonStrings/jsonutf.tx0         |     2 +
 .../gemfire/pdx/jsonStrings/jsonyahoo.txt       |    11 +
 .../gemfire/pdx/jsonStrings/jsonyoutube.txt     |    54 +
 .../gemfire/pdx/jsonStrings/linkden1.txt        |    16 +
 .../gemstone/gemfire/pdx/jsonStrings/odata.txt  |    16 +
 .../gemstone/gemfire/pdx/jsonStrings/odata2.txt |    18 +
 .../jsonStrings/unquoteJsonStrings/json1.txt    |    31 +
 .../gemfire/pdx/jsonStrings/weather.txt         |     1 +
 .../gemfire/test/golden/log4j2-test.xml         |    18 +
 geode-core/src/test/resources/jta/cachejta.xml  |   273 +
 .../src/test/resources/lib/authz-dummy.xml      |   126 +
 .../src/test/resources/lib/authz-ldap.xml       |    85 +
 .../resources/lib/authz-multiUser-dummy.xml     |   106 +
 .../test/resources/lib/authz-multiUser-ldap.xml |    83 +
 .../test/resources/lib/keys/gemfire1.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire10.keystore  |   Bin 0 -> 1546 bytes
 .../test/resources/lib/keys/gemfire11.keystore  |   Bin 0 -> 1546 bytes
 .../test/resources/lib/keys/gemfire2.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire3.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire4.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire5.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire6.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire7.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire8.keystore   |   Bin 0 -> 1536 bytes
 .../test/resources/lib/keys/gemfire9.keystore   |   Bin 0 -> 1536 bytes
 .../resources/lib/keys/ibm/gemfire1.keystore    |   Bin 0 -> 1426 bytes
 .../resources/lib/keys/ibm/gemfire10.keystore   |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire11.keystore   |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire2.keystore    |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire3.keystore    |   Bin 0 -> 1426 bytes
 .../resources/lib/keys/ibm/gemfire4.keystore    |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire5.keystore    |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire6.keystore    |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire7.keystore    |   Bin 0 -> 1426 bytes
 .../resources/lib/keys/ibm/gemfire8.keystore    |   Bin 0 -> 1434 bytes
 .../resources/lib/keys/ibm/gemfire9.keystore    |   Bin 0 -> 1426 bytes
 .../test/resources/lib/keys/ibm/publickeyfile   |   Bin 0 -> 4535 bytes
 .../src/test/resources/lib/keys/publickeyfile   |   Bin 0 -> 4535 bytes
 .../resources/spring/spring-gemfire-context.xml |    42 +
 .../src/test/resources/ssl/trusted.keystore     |   Bin 0 -> 1176 bytes
 .../src/test/resources/ssl/untrusted.keystore   |   Bin 0 -> 1181 bytes
 .../resources/templates/security/authz5_5.dtd   |   105 +
 .../resources/templates/security/authz6_0.dtd   |   110 +
 geode-cq/build.gradle                           |    23 +
 .../cache/client/internal/CloseCQOp.java        |    72 +
 .../cache/client/internal/CreateCQOp.java       |   163 +
 .../cache/client/internal/CreateCQWithIROp.java |    92 +
 .../cache/client/internal/GetDurableCQsOp.java  |   135 +
 .../client/internal/ServerCQProxyImpl.java      |   111 +
 .../gemfire/cache/client/internal/StopCQOp.java |    72 +
 .../cache/query/internal/cq/ClientCQImpl.java   |   615 +
 .../internal/cq/CqAttributesMutatorImpl.java    |    68 +
 .../cache/query/internal/cq/CqConflatable.java  |   223 +
 .../cache/query/internal/cq/CqEventImpl.java    |   162 +
 .../cache/query/internal/cq/CqListenerImpl.java |    56 +
 .../cache/query/internal/cq/CqQueryImpl.java    |   383 +
 .../query/internal/cq/CqServiceFactoryImpl.java |    69 +
 .../cache/query/internal/cq/CqServiceImpl.java  |  2087 ++
 .../internal/cq/CqServiceStatisticsImpl.java    |   100 +
 .../query/internal/cq/CqServiceVsdStats.java    |   411 +
 .../query/internal/cq/CqStatisticsImpl.java     |    75 +
 .../cache/query/internal/cq/ServerCQImpl.java   |   655 +
 .../tier/sockets/command/BaseCQCommand.java     |    59 +
 .../cache/tier/sockets/command/CloseCQ.java     |   131 +
 .../cache/tier/sockets/command/ExecuteCQ.java   |   168 +
 .../cache/tier/sockets/command/ExecuteCQ61.java |   220 +
 .../cache/tier/sockets/command/GetCQStats.java  |   100 +
 .../tier/sockets/command/GetDurableCQs.java     |   143 +
 .../cache/tier/sockets/command/MonitorCQ.java   |   100 +
 .../cache/tier/sockets/command/StopCQ.java      |   135 +
 ...cache.query.internal.cq.spi.CqServiceFactory |    15 +
 .../gemfire/cache/query/cq/CQJUnitTest.java     |   150 +
 .../cache/query/cq/dunit/CqDataDUnitTest.java   |  1165 ++
 .../dunit/CqDataOptimizedExecuteDUnitTest.java  |    55 +
 .../cq/dunit/CqDataUsingPoolDUnitTest.java      |  1559 ++
 ...qDataUsingPoolOptimizedExecuteDUnitTest.java |    54 +
 .../cache/query/cq/dunit/CqPerfDUnitTest.java   |  1048 +
 .../cq/dunit/CqPerfUsingPoolDUnitTest.java      |  1008 +
 .../cache/query/cq/dunit/CqQueryDUnitTest.java  |  3995 ++++
 .../dunit/CqQueryOptimizedExecuteDUnitTest.java |   310 +
 .../cq/dunit/CqQueryUsingPoolDUnitTest.java     |  3325 ++++
 ...QueryUsingPoolOptimizedExecuteDUnitTest.java |    50 +
 .../cq/dunit/CqResultSetUsingPoolDUnitTest.java |  1134 ++
 ...ltSetUsingPoolOptimizedExecuteDUnitTest.java |   235 +
 .../cache/query/cq/dunit/CqStateDUnitTest.java  |   138 +
 .../cache/query/cq/dunit/CqStatsDUnitTest.java  |   445 +
 .../dunit/CqStatsOptimizedExecuteDUnitTest.java |    50 +
 .../cq/dunit/CqStatsUsingPoolDUnitTest.java     |   456 +
 ...StatsUsingPoolOptimizedExecuteDUnitTest.java |    50 +
 .../query/cq/dunit/CqTimeTestListener.java      |   266 +
 .../PartitionedRegionCqQueryDUnitTest.java      |  1792 ++
 ...dRegionCqQueryOptimizedExecuteDUnitTest.java |   246 +
 .../query/cq/dunit/PrCqUsingPoolDUnitTest.java  |  2033 ++
 .../PrCqUsingPoolOptimizedExecuteDUnitTest.java |    50 +
 .../cache/query/dunit/PdxQueryCQDUnitTest.java  |   706 +
 .../cache/query/dunit/PdxQueryCQTestBase.java   |   496 +
 .../dunit/QueryIndexUpdateRIDUnitTest.java      |   815 +
 .../query/dunit/QueryMonitorDUnitTest.java      |  1299 ++
 .../cache/snapshot/ClientSnapshotDUnitTest.java |   286 +
 .../AnalyzeCQSerializablesJUnitTest.java        |    79 +
 .../cache/PRDeltaPropagationDUnitTest.java      |  1183 ++
 .../internal/cache/PutAllCSDUnitTest.java       |  4426 +++++
 .../cache/RemoteCQTransactionDUnitTest.java     |  1119 ++
 .../internal/cache/ha/CQListGIIDUnitTest.java   |   812 +
 .../cache/ha/HADispatcherDUnitTest.java         |   692 +
 .../sockets/ClientToServerDeltaDUnitTest.java   |   984 +
 .../DeltaPropagationWithCQDUnitTest.java        |   337 +
 ...ToRegionRelationCQRegistrationDUnitTest.java |   754 +
 .../sockets/DurableClientCrashDUnitTest.java    |    99 +
 .../sockets/DurableClientNetDownDUnitTest.java  |    79 +
 .../sockets/DurableClientSimpleDUnitTest.java   |  3343 ++++
 .../tier/sockets/DurableClientTestCase.java     |  2058 ++
 .../CacheServerManagementDUnitTest.java         |   574 +
 .../cli/commands/ClientCommandsDUnitTest.java   |  1446 ++
 .../DurableClientCommandsDUnitTest.java         |   436 +
 .../internal/pulse/TestCQDUnitTest.java         |   145 +
 .../internal/pulse/TestClientsDUnitTest.java    |   106 +
 .../internal/pulse/TestServerDUnitTest.java     |    97 +
 .../ClientAuthorizationTwoDUnitTest.java        |   239 +
 .../security/ClientAuthzObjectModDUnitTest.java |   412 +
 .../ClientCQPostAuthorizationDUnitTest.java     |   511 +
 .../ClientPostAuthorizationDUnitTest.java       |   390 +
 .../gemfire/security/MultiuserAPIDUnitTest.java |   383 +
 .../MultiuserDurableCQAuthzDUnitTest.java       |   477 +
 .../gemfire/codeAnalysis/excludedClasses.txt    |     2 +
 .../gemstone/gemfire/codeAnalysis/openBugs.txt  |    21 +
 .../sanctionedDataSerializables.txt             |     4 +
 .../codeAnalysis/sanctionedSerializables.txt    |     1 +
 .../tier/sockets/durablecq-client-cache.xml     |    37 +
 .../tier/sockets/durablecq-server-cache.xml     |    32 +
 .../java/joptsimple/AbstractOptionSpec.java     |   127 +
 .../joptsimple/AlternativeLongOptionSpec.java   |    54 +
 .../joptsimple/ArgumentAcceptingOptionSpec.java |   349 +
 .../src/main/java/joptsimple/ArgumentList.java  |    59 +
 .../java/joptsimple/BuiltinHelpFormatter.java   |   149 +
 .../src/main/java/joptsimple/HelpFormatter.java |    45 +
 .../IllegalOptionSpecificationException.java    |    52 +
 .../MissingRequiredOptionException.java         |    52 +
 .../MultipleArgumentsForOptionException.java    |    52 +
 .../java/joptsimple/NoArgumentOptionSpec.java   |    82 +
 .../OptionArgumentConversionException.java      |    63 +
 .../main/java/joptsimple/OptionDescriptor.java  |    94 +
 .../main/java/joptsimple/OptionException.java   |   111 +
 .../OptionMissingRequiredArgumentException.java |    52 +
 .../src/main/java/joptsimple/OptionParser.java  |   568 +
 .../main/java/joptsimple/OptionParserState.java |    81 +
 .../src/main/java/joptsimple/OptionSet.java     |   309 +
 .../src/main/java/joptsimple/OptionSpec.java    |    98 +
 .../main/java/joptsimple/OptionSpecBuilder.java |    96 +
 .../java/joptsimple/OptionSpecTokenizer.java    |   127 +
 .../joptsimple/OptionalArgumentOptionSpec.java  |    69 +
 .../src/main/java/joptsimple/ParserRules.java   |    84 +
 .../joptsimple/RequiredArgumentOptionSpec.java  |    54 +
 .../joptsimple/UnrecognizedOptionException.java |    52 +
 .../joptsimple/ValueConversionException.java    |    54 +
 .../main/java/joptsimple/ValueConverter.java    |    58 +
 .../joptsimple/internal/AbbreviationMap.java    |   233 +
 .../main/java/joptsimple/internal/Classes.java  |    74 +
 .../main/java/joptsimple/internal/Column.java   |   133 +
 .../internal/ColumnWidthCalculator.java         |    41 +
 .../java/joptsimple/internal/ColumnarData.java  |   163 +
 .../ConstructorInvokingValueConverter.java      |    58 +
 .../internal/MethodInvokingValueConverter.java  |    60 +
 .../main/java/joptsimple/internal/Objects.java  |    46 +
 .../java/joptsimple/internal/Reflection.java    |   143 +
 .../internal/ReflectionException.java           |    39 +
 .../main/java/joptsimple/internal/Strings.java  |   117 +
 .../java/joptsimple/util/DateConverter.java     |   104 +
 .../main/java/joptsimple/util/KeyValuePair.java |    83 +
 .../main/java/joptsimple/util/RegexMatcher.java |    88 +
 geode-json/src/main/java/org/json/CDL.java      |   279 +
 geode-json/src/main/java/org/json/Cookie.java   |   169 +
 .../src/main/java/org/json/CookieList.java      |    90 +
 geode-json/src/main/java/org/json/HTTP.java     |   163 +
 .../src/main/java/org/json/HTTPTokener.java     |    77 +
 .../src/main/java/org/json/JSONArray.java       |   906 +
 .../src/main/java/org/json/JSONException.java   |    28 +
 geode-json/src/main/java/org/json/JSONML.java   |   467 +
 .../src/main/java/org/json/JSONObject.java      |  1611 ++
 .../src/main/java/org/json/JSONString.java      |    18 +
 .../src/main/java/org/json/JSONStringer.java    |    78 +
 .../src/main/java/org/json/JSONTokener.java     |   446 +
 .../src/main/java/org/json/JSONWriter.java      |   327 +
 geode-json/src/main/java/org/json/XML.java      |   508 +
 .../src/main/java/org/json/XMLTokener.java      |   365 +
 geode-junit/build.gradle                        |    21 +
 .../gemfire/test/junit/ConditionalIgnore.java   |    49 +
 .../gemfire/test/junit/IgnoreCondition.java     |    32 +
 .../gemfire/test/junit/IgnoreUntil.java         |    49 +
 .../com/gemstone/gemfire/test/junit/Repeat.java |    43 +
 .../com/gemstone/gemfire/test/junit/Retry.java  |    38 +
 .../test/junit/categories/ContainerTest.java    |    25 +
 .../test/junit/categories/DistributedTest.java  |    25 +
 .../categories/DistributedTransactionsTest.java |    26 +
 .../test/junit/categories/HydraTest.java        |    24 +
 .../test/junit/categories/IntegrationTest.java  |    25 +
 .../test/junit/categories/PerformanceTest.java  |    25 +
 .../gemfire/test/junit/categories/UITest.java   |    24 +
 .../gemfire/test/junit/categories/UnitTest.java |    25 +
 .../gemfire/test/junit/categories/WanTest.java  |    24 +
 .../test/junit/rules/ConditionalIgnoreRule.java |   123 +
 .../test/junit/rules/ExpectedTimeout.java       |   180 +
 .../test/junit/rules/ExpectedTimeoutRule.java   |   180 +
 .../test/junit/rules/IgnoreUntilRule.java       |   123 +
 .../gemfire/test/junit/rules/RepeatRule.java    |    81 +
 .../gemfire/test/junit/rules/RetryRule.java     |   181 +
 .../rules/SerializableExternalResource.java     |   107 +
 .../test/junit/rules/SerializableRuleChain.java |   119 +
 .../rules/SerializableTemporaryFolder.java      |    70 +
 .../test/junit/rules/SerializableTestName.java  |    54 +
 .../test/junit/rules/SerializableTestRule.java  |    33 +
 .../junit/rules/SerializableTestWatcher.java    |    29 +
 .../test/junit/rules/SerializableTimeout.java   |   119 +
 .../junit/support/DefaultIgnoreCondition.java   |    57 +
 .../IgnoreConditionEvaluationException.java     |    43 +
 .../junit/rules/ExpectedTimeoutJUnitTest.java   |   204 +
 .../examples/RepeatingTestCasesExampleTest.java |    94 +
 .../rules/examples/RetryRuleExampleTest.java    |    43 +
 .../rules/tests/ExpectedTimeoutRuleTest.java    |   214 +
 .../junit/rules/tests/IgnoreUntilRuleTest.java  |   121 +
 .../junit/rules/tests/JUnitRuleTestSuite.java   |    33 +
 .../test/junit/rules/tests/RepeatRuleTest.java  |   304 +
 .../tests/RetryRuleGlobalWithErrorTest.java     |   250 +
 .../tests/RetryRuleGlobalWithExceptionTest.java |   254 +
 .../tests/RetryRuleLocalWithErrorTest.java      |   207 +
 .../tests/RetryRuleLocalWithExceptionTest.java  |   213 +
 .../junit/rules/tests/RuleAndClassRuleTest.java |   138 +
 .../test/junit/rules/tests/TestRunner.java      |    37 +
 geode-lucene/build.gradle                       |    40 +
 .../gemfire/cache/lucene/LuceneIndex.java       |    60 +
 .../gemfire/cache/lucene/LuceneQuery.java       |    48 +
 .../cache/lucene/LuceneQueryFactory.java        |   100 +
 .../cache/lucene/LuceneQueryProvider.java       |    45 +
 .../cache/lucene/LuceneQueryResults.java        |    58 +
 .../cache/lucene/LuceneResultStruct.java        |    62 +
 .../gemfire/cache/lucene/LuceneService.java     |   118 +
 .../cache/lucene/LuceneServiceProvider.java     |    46 +
 .../lucene/internal/InternalLuceneIndex.java    |    29 +
 .../lucene/internal/InternalLuceneService.java  |    29 +
 .../lucene/internal/LuceneEventListener.java    |    99 +
 .../LuceneIndexForPartitionedRegion.java        |   136 +
 .../LuceneIndexForReplicatedRegion.java         |    48 +
 .../cache/lucene/internal/LuceneIndexImpl.java  |   107 +
 .../lucene/internal/LuceneQueryFactoryImpl.java |    67 +
 .../cache/lucene/internal/LuceneQueryImpl.java  |    87 +
 .../lucene/internal/LuceneQueryResultsImpl.java |   120 +
 .../lucene/internal/LuceneResultStructImpl.java |    94 +
 .../lucene/internal/LuceneServiceImpl.java      |   273 +
 .../internal/PartitionedRepositoryManager.java  |   163 +
 .../lucene/internal/StringQueryProvider.java    |   106 +
 .../internal/directory/FileIndexInput.java      |   131 +
 .../internal/directory/RegionDirectory.java     |   119 +
 .../internal/distributed/CollectorManager.java  |    55 +
 .../lucene/internal/distributed/EntryScore.java |    82 +
 .../internal/distributed/LuceneFunction.java    |   137 +
 .../distributed/LuceneFunctionContext.java      |   115 +
 .../lucene/internal/distributed/TopEntries.java |   133 +
 .../distributed/TopEntriesCollector.java        |   102 +
 .../distributed/TopEntriesCollectorManager.java |   178 +
 .../TopEntriesFunctionCollector.java            |   163 +
 .../lucene/internal/filesystem/ChunkKey.java    |   123 +
 .../cache/lucene/internal/filesystem/File.java  |   155 +
 .../internal/filesystem/FileInputStream.java    |   166 +
 .../internal/filesystem/FileOutputStream.java   |   103 +
 .../lucene/internal/filesystem/FileSystem.java  |   156 +
 .../filesystem/SeekableInputStream.java         |    43 +
 .../internal/repository/IndexRepository.java    |    74 +
 .../repository/IndexRepositoryImpl.java         |   113 +
 .../repository/IndexResultCollector.java        |    47 +
 .../internal/repository/RepositoryManager.java  |    44 +
 .../HeterogenousLuceneSerializer.java           |    83 +
 .../repository/serializer/LuceneSerializer.java |    35 +
 .../serializer/PdxLuceneSerializer.java         |    47 +
 .../serializer/ReflectionLuceneSerializer.java  |    74 +
 .../repository/serializer/SerializerUtil.java   |   168 +
 .../internal/xml/LuceneIndexCreation.java       |   111 +
 .../internal/xml/LuceneIndexXmlGenerator.java   |    65 +
 .../internal/xml/LuceneServiceXmlGenerator.java |    39 +
 .../lucene/internal/xml/LuceneXmlConstants.java |    31 +
 .../lucene/internal/xml/LuceneXmlParser.java    |    97 +
 .../geode.apache.org/lucene/lucene-1.0.xsd      |    57 +
 ...gemstone.gemfire.internal.cache.CacheService |     1 +
 ...ne.gemfire.internal.cache.xmlcache.XmlParser |     1 +
 .../internal/LuceneEventListenerJUnitTest.java  |   109 +
 .../LuceneIndexRecoveryHAJUnitTest.java         |   201 +
 .../LuceneQueryFactoryImplJUnitTest.java        |    50 +
 .../internal/LuceneQueryImplJUnitTest.java      |   123 +
 .../LuceneQueryResultsImplJUnitTest.java        |   126 +
 .../LuceneResultStructImpJUnitTest.java         |    51 +
 .../internal/LuceneServiceImplJUnitTest.java    |   226 +
 .../PartitionedRepositoryManagerJUnitTest.java  |   230 +
 .../internal/StringQueryProviderJUnitTest.java  |    90 +
 .../directory/RegionDirectoryJUnitTest.java     |    56 +
 .../DistributedScoringJUnitTest.java            |   155 +
 .../distributed/EntryScoreJUnitTest.java        |    40 +
 .../LuceneFunctionContextJUnitTest.java         |    64 +
 .../distributed/LuceneFunctionJUnitTest.java    |   423 +
 .../LuceneFunctionReadPathDUnitTest.java        |   240 +
 .../TopEntriesCollectorJUnitTest.java           |   139 +
 .../TopEntriesFunctionCollectorJUnitTest.java   |   323 +
 .../distributed/TopEntriesJUnitTest.java        |   146 +
 .../internal/filesystem/ChunkKeyJUnitTest.java  |    48 +
 .../internal/filesystem/FileJUnitTest.java      |    53 +
 .../filesystem/FileSystemJUnitTest.java         |   578 +
 .../IndexRepositoryImplJUnitTest.java           |   208 +
 .../IndexRepositoryImplPerformanceTest.java     |   439 +
 .../HeterogenousLuceneSerializerJUnitTest.java  |    90 +
 .../serializer/PdxFieldMapperJUnitTest.java     |    85 +
 .../ReflectionFieldMapperJUnitTest.java         |    85 +
 .../internal/repository/serializer/Type1.java   |    48 +
 .../internal/repository/serializer/Type2.java   |    34 +
 ...neIndexXmlGeneratorIntegrationJUnitTest.java |    78 +
 .../xml/LuceneIndexXmlGeneratorJUnitTest.java   |    80 +
 ...uceneIndexXmlParserIntegrationJUnitTest.java |   107 +
 .../xml/LuceneIndexXmlParserJUnitTest.java      |    72 +
 ...erIntegrationJUnitTest.createIndex.cache.xml |    41 +
 ...serIntegrationJUnitTest.parseIndex.cache.xml |    41 +
 geode-pulse/build.gradle                        |    98 +
 .../tools/pulse/internal/PulseAppListener.java  |   703 +
 .../controllers/ExceptionHandlingAdvice.java    |    52 +
 .../internal/controllers/PulseController.java   |   587 +
 .../tools/pulse/internal/data/Cluster.java      |  3826 ++++
 .../tools/pulse/internal/data/DataBrowser.java  |   281 +
 .../pulse/internal/data/IClusterUpdater.java    |    37 +
 .../pulse/internal/data/JMXDataUpdater.java     |  2455 +++
 .../pulse/internal/data/JmxManagerFinder.java   |   171 +
 .../tools/pulse/internal/data/PulseConfig.java  |   126 +
 .../pulse/internal/data/PulseConstants.java     |   421 +
 .../tools/pulse/internal/data/PulseVersion.java |   104 +
 .../tools/pulse/internal/data/Repository.java   |   215 +
 .../gemfire/tools/pulse/internal/json/CDL.java  |   274 +
 .../tools/pulse/internal/json/Cookie.java       |   164 +
 .../tools/pulse/internal/json/CookieList.java   |    85 +
 .../gemfire/tools/pulse/internal/json/HTTP.java |   158 +
 .../tools/pulse/internal/json/HTTPTokener.java  |    72 +
 .../tools/pulse/internal/json/JSONArray.java    |   901 +
 .../pulse/internal/json/JSONException.java      |    47 +
 .../tools/pulse/internal/json/JSONML.java       |   462 +
 .../tools/pulse/internal/json/JSONObject.java   |  1585 ++
 .../tools/pulse/internal/json/JSONString.java   |    37 +
 .../tools/pulse/internal/json/JSONStringer.java |    73 +
 .../tools/pulse/internal/json/JSONTokener.java  |   441 +
 .../tools/pulse/internal/json/JSONWriter.java   |   322 +
 .../gemfire/tools/pulse/internal/json/README    |    68 +
 .../gemfire/tools/pulse/internal/json/XML.java  |   503 +
 .../tools/pulse/internal/json/XMLTokener.java   |   360 +
 .../tools/pulse/internal/log/LogWriter.java     |   266 +
 .../pulse/internal/log/MessageFormatter.java    |   103 +
 .../pulse/internal/log/PulseLogWriter.java      |   306 +
 .../tools/pulse/internal/log/PulseLogger.java   |   144 +
 .../internal/service/ClusterDetailsService.java |   109 +
 .../service/ClusterDiskThroughputService.java   |    79 +
 .../service/ClusterGCPausesService.java         |    71 +
 .../service/ClusterKeyStatisticsService.java    |    79 +
 .../internal/service/ClusterMemberService.java  |   132 +
 .../service/ClusterMembersRGraphService.java    |   372 +
 .../service/ClusterMemoryUsageService.java      |    70 +
 .../internal/service/ClusterRegionService.java  |   241 +
 .../internal/service/ClusterRegionsService.java |   243 +
 .../service/ClusterSelectedRegionService.java   |   278 +
 .../ClusterSelectedRegionsMemberService.java    |   146 +
 .../internal/service/ClusterWANInfoService.java |    82 +
 .../service/MemberAsynchEventQueuesService.java |   107 +
 .../internal/service/MemberClientsService.java  |   123 +
 .../internal/service/MemberDetailsService.java  |   128 +
 .../service/MemberDiskThroughputService.java    |    93 +
 .../internal/service/MemberGCPausesService.java |    85 +
 .../service/MemberGatewayHubService.java        |   163 +
 .../service/MemberHeapUsageService.java         |    85 +
 .../service/MemberKeyStatisticsService.java     |    98 +
 .../internal/service/MemberRegionsService.java  |   140 +
 .../internal/service/MembersListService.java    |    77 +
 .../pulse/internal/service/PulseService.java    |    42 +
 .../internal/service/PulseServiceFactory.java   |    56 +
 .../internal/service/PulseVersionService.java   |    74 +
 .../service/QueryStatisticsService.java         |   152 +
 .../internal/service/SystemAlertsService.java   |   134 +
 .../pulse/internal/util/ConnectionUtil.java     |    47 +
 .../pulse/internal/util/IPAddressUtil.java      |    66 +
 .../tools/pulse/internal/util/StringUtils.java  |    86 +
 .../tools/pulse/internal/util/TimeUtils.java    |   121 +
 .../main/resources/LogMessages_en_US.properties |    97 +
 .../main/resources/LogMessages_fr_FR.properties |    91 +
 .../src/main/resources/default.properties       |    23 +
 .../src/main/resources/gemfire.properties       |    47 +
 .../src/main/resources/pulse-users.properties   |    30 +
 geode-pulse/src/main/resources/pulse.properties |    54 +
 .../src/main/resources/pulsesecurity.properties |    26 +
 .../src/main/resources/sqlfire.properties       |    47 +
 geode-pulse/src/main/webapp/DataBrowser.html    |   345 +
 geode-pulse/src/main/webapp/Login.html          |   114 +
 .../src/main/webapp/META-INF/MANIFEST.MF        |     3 +
 geode-pulse/src/main/webapp/MemberDetails.html  |   603 +
 .../src/main/webapp/QueryStatistics.html        |   308 +
 .../webapp/WEB-INF/mvc-dispatcher-servlet.xml   |    35 +
 .../src/main/webapp/WEB-INF/spring-security.xml |    83 +
 geode-pulse/src/main/webapp/WEB-INF/web.xml     |    62 +
 geode-pulse/src/main/webapp/clusterDetail.html  |   662 +
 .../src/main/webapp/css/ForceDirected.css       |    46 +
 geode-pulse/src/main/webapp/css/Treemap.css     |   134 +
 geode-pulse/src/main/webapp/css/base.css        |    74 +
 geode-pulse/src/main/webapp/css/common.css      |   240 +
 .../webapp/css/fonts/DroidSans-Bold-webfont.eot |   Bin 0 -> 43462 bytes
 .../webapp/css/fonts/DroidSans-Bold-webfont.svg |   271 +
 .../webapp/css/fonts/DroidSans-Bold-webfont.ttf |   Bin 0 -> 43260 bytes
 .../css/fonts/DroidSans-Bold-webfont.woff       |   Bin 0 -> 27120 bytes
 .../main/webapp/css/fonts/DroidSans-webfont.eot |   Bin 0 -> 44926 bytes
 .../main/webapp/css/fonts/DroidSans-webfont.svg |   271 +
 .../main/webapp/css/fonts/DroidSans-webfont.ttf |   Bin 0 -> 44712 bytes
 .../webapp/css/fonts/DroidSans-webfont.woff     |   Bin 0 -> 27672 bytes
 .../src/main/webapp/css/grid/ui.jqgrid.css      |   850 +
 .../src/main/webapp/css/grips/horizontal.png    |   Bin 0 -> 2753 bytes
 .../src/main/webapp/css/grips/vertical.png      |   Bin 0 -> 91 bytes
 geode-pulse/src/main/webapp/css/ie/ie.css       |    19 +
 geode-pulse/src/main/webapp/css/ie/ie7.css      |    21 +
 geode-pulse/src/main/webapp/css/ie/ie8.css      |    20 +
 geode-pulse/src/main/webapp/css/ie/ie9.css      |    20 +
 geode-pulse/src/main/webapp/css/jquery-ui.css   |   566 +
 .../src/main/webapp/css/jquery.jscrollpane.css  |   121 +
 .../src/main/webapp/css/jquery.ui.all.css       |    11 +
 .../src/main/webapp/css/jquery.ui.core.css      |    41 +
 .../src/main/webapp/css/jquery.ui.theme.css     |   248 +
 .../src/main/webapp/css/jquery.ztreestyle.css   |    90 +
 .../css/multiselect/jquery.multiselect.css      |   301 +
 .../main/webapp/css/multiselect/prettify.css    |    46 +
 .../src/main/webapp/css/multiselect/style.css   |    35 +
 geode-pulse/src/main/webapp/css/popup.css       |    55 +
 geode-pulse/src/main/webapp/css/style.css       |  3105 +++
 .../src/main/webapp/css/treeView/Treemap.css    |   134 +
 .../src/main/webapp/images/about-gemfirexd.png  |   Bin 0 -> 4440 bytes
 .../src/main/webapp/images/about-geode.png      |   Bin 0 -> 7640 bytes
 .../src/main/webapp/images/about-sqlfire.png    |   Bin 0 -> 6277 bytes
 geode-pulse/src/main/webapp/images/about.png    |   Bin 0 -> 4421 bytes
 .../src/main/webapp/images/acc-minus.png        |   Bin 0 -> 1049 bytes
 .../src/main/webapp/images/acc-n-minus.png      |   Bin 0 -> 961 bytes
 .../src/main/webapp/images/acc-n-plus.png       |   Bin 0 -> 988 bytes
 geode-pulse/src/main/webapp/images/acc-plus.png |   Bin 0 -> 1047 bytes
 .../src/main/webapp/images/activeServer.png     |   Bin 0 -> 2846 bytes
 .../main/webapp/images/apache_geode_logo.png    |   Bin 0 -> 23616 bytes
 .../src/main/webapp/images/arrow-down.png       |   Bin 0 -> 986 bytes
 geode-pulse/src/main/webapp/images/arrow-up.png |   Bin 0 -> 988 bytes
 geode-pulse/src/main/webapp/images/bg-image.png |   Bin 0 -> 948 bytes
 .../src/main/webapp/images/bg-imageLogin.png    |   Bin 0 -> 946 bytes
 .../src/main/webapp/images/blue-msg-icon.png    |   Bin 0 -> 1194 bytes
 .../src/main/webapp/images/border-left-grid.png |   Bin 0 -> 927 bytes
 .../src/main/webapp/images/bread-crumb.png      |   Bin 0 -> 1182 bytes
 .../src/main/webapp/images/bubble_arrow.png     |   Bin 0 -> 1168 bytes
 .../src/main/webapp/images/chart-active.png     |   Bin 0 -> 1096 bytes
 geode-pulse/src/main/webapp/images/chart.png    |   Bin 0 -> 1095 bytes
 geode-pulse/src/main/webapp/images/checkbox.png |   Bin 0 -> 1630 bytes
 geode-pulse/src/main/webapp/images/chkbox.png   |   Bin 0 -> 1313 bytes
 .../src/main/webapp/images/copy_icon.png        |   Bin 0 -> 1172 bytes
 .../src/main/webapp/images/correct_icon.png     |   Bin 0 -> 1143 bytes
 .../main/webapp/images/correct_small_icon.png   |   Bin 0 -> 1065 bytes
 .../main/webapp/images/correct_white_icon.png   |   Bin 0 -> 1122 bytes
 geode-pulse/src/main/webapp/images/cross.png    |   Bin 0 -> 2954 bytes
 .../main/webapp/images/dataViewWanEnabled.png   |   Bin 0 -> 1204 bytes
 .../src/main/webapp/images/dd_active.png        |   Bin 0 -> 1065 bytes
 geode-pulse/src/main/webapp/images/dd_arrow.png |   Bin 0 -> 1058 bytes
 .../webapp/images/error-locators-others.png     |   Bin 0 -> 2052 bytes
 .../src/main/webapp/images/error-locators.png   |   Bin 0 -> 2023 bytes
 .../images/error-manager-locator-others.png     |   Bin 0 -> 2067 bytes
 .../webapp/images/error-manager-locator.png     |   Bin 0 -> 2047 bytes
 .../webapp/images/error-managers-others.png     |   Bin 0 -> 2051 bytes
 .../src/main/webapp/images/error-managers.png   |   Bin 0 -> 2025 bytes
 .../main/webapp/images/error-message-icon.png   |   Bin 0 -> 1193 bytes
 .../src/main/webapp/images/error-msg-icon.png   |   Bin 0 -> 1194 bytes
 .../src/main/webapp/images/error-others.png     |   Bin 0 -> 2066 bytes
 .../src/main/webapp/images/error-otheruser.png  |   Bin 0 -> 2002 bytes
 .../main/webapp/images/error-status-icon.png    |   Bin 0 -> 2024 bytes
 geode-pulse/src/main/webapp/images/error.png    |   Bin 0 -> 1110 bytes
 .../src/main/webapp/images/graph-active.png     |   Bin 0 -> 1360 bytes
 geode-pulse/src/main/webapp/images/graph.png    |   Bin 0 -> 1374 bytes
 .../images/graph/key-statistics-graph.png       |   Bin 0 -> 1617 bytes
 .../webapp/images/graph/memory-usage-graph.png  |   Bin 0 -> 4366 bytes
 .../src/main/webapp/images/graph/reads.png      |   Bin 0 -> 3423 bytes
 .../images/graph/throughput-writes-graph.png    |   Bin 0 -> 4340 bytes
 .../src/main/webapp/images/graph/topology.png   |   Bin 0 -> 14997 bytes
 .../src/main/webapp/images/graph/treeview.png   |   Bin 0 -> 3386 bytes
 .../src/main/webapp/images/graph/writes.png     |   Bin 0 -> 3527 bytes
 .../src/main/webapp/images/grid-active.png      |   Bin 0 -> 1095 bytes
 geode-pulse/src/main/webapp/images/grid.png     |   Bin 0 -> 1094 bytes
 .../webapp/images/header-bg-bottom-border.png   |   Bin 0 -> 924 bytes
 geode-pulse/src/main/webapp/images/hide_ico.png |   Bin 0 -> 3281 bytes
 .../src/main/webapp/images/history-icon.png     |   Bin 0 -> 3533 bytes
 .../src/main/webapp/images/history-remove.png   |   Bin 0 -> 1185 bytes
 .../src/main/webapp/images/hor-spiltter-dot.png |   Bin 0 -> 990 bytes
 .../webapp/images/icons members/locators.png    |   Bin 0 -> 3106 bytes
 .../images/icons members/locators_others.png    |   Bin 0 -> 3118 bytes
 .../webapp/images/icons members/managers.png    |   Bin 0 -> 3103 bytes
 .../images/icons members/managers_locators.png  |   Bin 0 -> 3120 bytes
 .../images/icons members/managers_others.png    |   Bin 0 -> 3117 bytes
 .../main/webapp/images/icons members/others.png |   Bin 0 -> 3102 bytes
 .../src/main/webapp/images/info-msg-icon.png    |   Bin 0 -> 1194 bytes
 geode-pulse/src/main/webapp/images/lastLine.png |   Bin 0 -> 948 bytes
 geode-pulse/src/main/webapp/images/line.png     |   Bin 0 -> 929 bytes
 geode-pulse/src/main/webapp/images/mask-bg.png  |   Bin 0 -> 940 bytes
 .../webapp/images/membersName_arror-off.png     |   Bin 0 -> 1148 bytes
 .../main/webapp/images/membersName_arror-on.png |   Bin 0 -> 1170 bytes
 geode-pulse/src/main/webapp/images/minus.png    |   Bin 0 -> 2959 bytes
 .../webapp/images/normal-locators-others.png    |   Bin 0 -> 2025 bytes
 .../src/main/webapp/images/normal-locators.png  |   Bin 0 -> 1995 bytes
 .../images/normal-manager-locator-others.png    |   Bin 0 -> 2037 bytes
 .../webapp/images/normal-manager-locator.png    |   Bin 0 -> 2029 bytes
 .../webapp/images/normal-managers-others.png    |   Bin 0 -> 2027 bytes
 .../src/main/webapp/images/normal-managers.png  |   Bin 0 -> 1997 bytes
 .../src/main/webapp/images/normal-others.png    |   Bin 0 -> 1988 bytes
 .../src/main/webapp/images/normal-otheruser.png |   Bin 0 -> 1968 bytes
 .../main/webapp/images/normal-status-icon.png   |   Bin 0 -> 1955 bytes
 geode-pulse/src/main/webapp/images/normal.png   |   Bin 0 -> 1110 bytes
 .../src/main/webapp/images/orange-msg-icon.png  |   Bin 0 -> 1194 bytes
 .../src/main/webapp/images/pivotal-logo.png     |   Bin 0 -> 3500 bytes
 geode-pulse/src/main/webapp/images/plus.png     |   Bin 0 -> 1178 bytes
 .../src/main/webapp/images/plusMinusIcon.png    |   Bin 0 -> 1192 bytes
 .../src/main/webapp/images/popup-arrow.png      |   Bin 0 -> 1075 bytes
 .../main/webapp/images/popup-close-button.png   |   Bin 0 -> 1026 bytes
 .../images/pulse-monitoring-gemfirexd-old.png   |   Bin 0 -> 6606 bytes
 .../images/pulse-monitoring-gemfirexd.png       |   Bin 0 -> 4440 bytes
 .../webapp/images/pulse-monitoring-sqlfire.png  |   Bin 0 -> 6467 bytes
 .../src/main/webapp/images/pulse-monitoring.png |   Bin 0 -> 4741 bytes
 .../src/main/webapp/images/radio-off.png        |   Bin 0 -> 1252 bytes
 geode-pulse/src/main/webapp/images/radio-on.png |   Bin 0 -> 1306 bytes
 geode-pulse/src/main/webapp/images/radio.png    |   Bin 0 -> 2476 bytes
 .../src/main/webapp/images/regionIcons.png      |   Bin 0 -> 1495 bytes
 .../src/main/webapp/images/rightBorder.png      |   Bin 0 -> 927 bytes
 .../src/main/webapp/images/searchIcon.png       |   Bin 0 -> 1592 bytes
 .../src/main/webapp/images/seperator.png        |   Bin 0 -> 929 bytes
 geode-pulse/src/main/webapp/images/server.png   |   Bin 0 -> 1233 bytes
 .../webapp/images/severe-locators-others.png    |   Bin 0 -> 2026 bytes
 .../src/main/webapp/images/severe-locators.png  |   Bin 0 -> 1980 bytes
 .../images/severe-manager-locator-others.png    |   Bin 0 -> 2032 bytes
 .../webapp/images/severe-manager-locator.png    |   Bin 0 -> 2026 bytes
 .../webapp/images/severe-managers-others.png    |   Bin 0 -> 2026 bytes
 .../src/main/webapp/images/severe-managers.png  |   Bin 0 -> 1985 bytes
 .../src/main/webapp/images/severe-msg-icon.png  |   Bin 0 -> 1194 bytes
 .../src/main/webapp/images/severe-others.png    |   Bin 0 -> 2007 bytes
 .../src/main/webapp/images/severe-otheruser.png |   Bin 0 -> 1959 bytes
 .../main/webapp/images/severe-status-icon.png   |   Bin 0 -> 2218 bytes
 geode-pulse/src/main/webapp/images/severe.png   |   Bin 0 -> 1110 bytes
 geode-pulse/src/main/webapp/images/show_ico.png |   Bin 0 -> 3296 bytes
 geode-pulse/src/main/webapp/images/spacer.png   |   Bin 0 -> 922 bytes
 geode-pulse/src/main/webapp/images/sqlfire.png  |   Bin 0 -> 6467 bytes
 .../src/main/webapp/images/status-down.png      |   Bin 0 -> 1125 bytes
 .../src/main/webapp/images/status-up.png        |   Bin 0 -> 1104 bytes
 .../src/main/webapp/images/subServer.png        |   Bin 0 -> 2201 bytes
 .../src/main/webapp/images/tab-bottom-bg.png    |   Bin 0 -> 929 bytes
 .../src/main/webapp/images/treeView-img.png     |   Bin 0 -> 962 bytes
 .../main/webapp/images/ui-anim_basic_16x16.gif  |   Bin 0 -> 1459 bytes
 .../src/main/webapp/images/ver-spiltter-dot.png |   Bin 0 -> 979 bytes
 .../webapp/images/warning-locators-others.png   |   Bin 0 -> 2048 bytes
 .../src/main/webapp/images/warning-locators.png |   Bin 0 -> 2032 bytes
 .../images/warning-manager-locator-others.png   |   Bin 0 -> 2071 bytes
 .../webapp/images/warning-manager-locator.png   |   Bin 0 -> 2052 bytes
 .../webapp/images/warning-managers-others.png   |   Bin 0 -> 2023 bytes
 .../src/main/webapp/images/warning-managers.png |   Bin 0 -> 2030 bytes
 .../src/main/webapp/images/warning-msg-icon.png |   Bin 0 -> 1194 bytes
 .../src/main/webapp/images/warning-others.png   |   Bin 0 -> 2027 bytes
 .../main/webapp/images/warning-otheruser.png    |   Bin 0 -> 2010 bytes
 .../main/webapp/images/warning-status-icon.png  |   Bin 0 -> 1714 bytes
 geode-pulse/src/main/webapp/images/warning.png  |   Bin 0 -> 1107 bytes
 .../src/main/webapp/images/yellow-msg-icon.png  |   Bin 0 -> 1194 bytes
 geode-pulse/src/main/webapp/index.html          |    67 +
 .../main/webapp/properties/default.properties   |    21 +
 .../webapp/properties/default_en.properties     |    21 +
 .../main/webapp/properties/gemfire.properties   |    45 +
 .../webapp/properties/gemfire_en.properties     |    45 +
 .../main/webapp/properties/gemfirexd.properties |    45 +
 .../webapp/properties/gemfirexd_en.properties   |    45 +
 .../src/main/webapp/properties/index.properties |    18 +
 .../main/webapp/properties/index_fr.properties  |    19 +
 .../main/webapp/properties/sqlfire.properties   |    45 +
 geode-pulse/src/main/webapp/regionDetail.html   |   552 +
 .../src/main/webapp/scripts/lib/common.js       |   536 +
 .../src/main/webapp/scripts/lib/excanvas.js     |  1416 ++
 .../main/webapp/scripts/lib/grid.locale-en.js   |   169 +
 .../src/main/webapp/scripts/lib/html5.js        |     3 +
 geode-pulse/src/main/webapp/scripts/lib/jit.js  | 17208 +++++++++++++++++
 .../src/main/webapp/scripts/lib/jquery-1.7.2.js |  9404 +++++++++
 .../webapp/scripts/lib/jquery.generateFile.js   |    77 +
 .../scripts/lib/jquery.i18n.properties.js       |   336 +
 .../webapp/scripts/lib/jquery.jqGrid.src.js     | 12182 ++++++++++++
 .../webapp/scripts/lib/jquery.jscrollpane.js    |  1340 ++
 .../webapp/scripts/lib/jquery.mousewheel.js     |    84 +
 .../webapp/scripts/lib/jquery.placeholder.js    |   106 +
 .../main/webapp/scripts/lib/jquery.sparkline.js |  3001 +++
 .../main/webapp/scripts/lib/jquery.tablednd.js  |   383 +
 .../main/webapp/scripts/lib/jquery.timeago.js   |   193 +
 .../webapp/scripts/lib/jquery.ztree.core-3.5.js |  1650 ++
 .../scripts/lib/jquery.ztree.excheck-3.5.js     |   624 +
 .../src/main/webapp/scripts/lib/split.js        |   375 +
 .../src/main/webapp/scripts/lib/tooltip.js      |   357 +
 .../webapp/scripts/multiselect/jquery-ui.js     | 14988 ++++++++++++++
 .../scripts/multiselect/jquery.multiselect.js   |   816 +
 .../main/webapp/scripts/multiselect/prettify.js |  1522 ++
 .../webapp/scripts/pulsescript/MemberDetails.js |  1045 +
 .../scripts/pulsescript/PulseCallbacks.js       |  1735 ++
 .../scripts/pulsescript/PulseFunctions.js       |   227 +
 .../webapp/scripts/pulsescript/clusterDetail.js |  2370 +++
 .../scripts/pulsescript/clusterRGraphMembers.js |  1515 ++
 .../main/webapp/scripts/pulsescript/common.js   |  1626 ++
 .../scripts/pulsescript/pages/DataBrowser.js    |   667 +
 .../pulsescript/pages/DataBrowserQuery.js       |   964 +
 .../pages/DataBrowserQueryHistory.js            |    95 +
 .../webapp/scripts/pulsescript/pages/Login.js   |   170 +
 .../webapp/scripts/pulsescript/pages/index.js   |    26 +
 .../scripts/pulsescript/queryStatistics.js      |   315 +
 .../webapp/scripts/pulsescript/regionView.js    |   757 +
 .../pulse/testbed/GemFireDistributedSystem.java |   323 +
 .../tools/pulse/testbed/GemfireTopology.java    |    24 +
 .../tools/pulse/testbed/PropFileHelper.java     |   115 +
 .../pulse/testbed/PropMockDataUpdater.java      |   515 +
 .../gemfire/tools/pulse/testbed/TestBed.java    |    84 +
 .../tools/pulse/testbed/driver/PulseUITest.java |   284 +
 .../pulse/testbed/driver/TomcatHelper.java      |    77 +
 .../tools/pulse/tests/AggregateStatement.java   |   217 +
 .../pulse/tests/AggregateStatementMBean.java    |   168 +
 .../pulse/tests/DataBrowserResultLoader.java    |    84 +
 .../pulse/tests/GemFireXDAggregateTable.java    |    46 +
 .../tests/GemFireXDAggregateTableMBean.java     |    28 +
 .../tools/pulse/tests/GemFireXDCluster.java     |    95 +
 .../pulse/tests/GemFireXDClusterMBean.java      |    32 +
 .../tools/pulse/tests/GemFireXDMember.java      |    80 +
 .../tools/pulse/tests/GemFireXDMemberMBean.java |    31 +
 .../gemfire/tools/pulse/tests/JMXBaseBean.java  |    67 +
 .../tools/pulse/tests/JMXProperties.java        |    47 +
 .../gemfire/tools/pulse/tests/Member.java       |   193 +
 .../gemfire/tools/pulse/tests/MemberMBean.java  |    86 +
 .../tools/pulse/tests/PulseAutomatedTest.java   |   785 +
 .../tools/pulse/tests/PulseBaseTest.java        |   686 +
 .../gemfire/tools/pulse/tests/PulseTest.java    |  1056 +
 .../tools/pulse/tests/PulseTestData.java        |   106 +
 .../tools/pulse/tests/PulseTestLocators.java    |   225 +
 .../gemfire/tools/pulse/tests/Region.java       |   192 +
 .../gemfire/tools/pulse/tests/RegionMBean.java  |    59 +
 .../tools/pulse/tests/RegionOnMember.java       |    96 +
 .../tools/pulse/tests/RegionOnMemberMBean.java  |    50 +
 .../gemfire/tools/pulse/tests/Server.java       |   253 +
 .../gemfire/tools/pulse/tests/ServerObject.java |   264 +
 .../tools/pulse/tests/ServerObjectMBean.java    |    79 +
 .../gemfire/tools/pulse/tests/TomcatHelper.java |    97 +
 .../pulse/tests/junit/BaseServiceTest.java      |   250 +
 .../junit/ClusterSelectedRegionServiceTest.java |   350 +
 ...ClusterSelectedRegionsMemberServiceTest.java |   362 +
 .../junit/MemberGatewayHubServiceTest.java      |   423 +
 geode-pulse/src/test/resources/NoDataFound1.txt |     1 +
 geode-pulse/src/test/resources/NoDataFound2.txt |    35 +
 geode-pulse/src/test/resources/NoDataFound3.txt |     6 +
 geode-pulse/src/test/resources/message.txt      |     1 +
 geode-pulse/src/test/resources/test.properties  |   326 +
 geode-pulse/src/test/resources/test1.txt        |     5 +
 geode-pulse/src/test/resources/test2.txt        |     7 +
 geode-pulse/src/test/resources/test3.txt        |     5 +
 geode-pulse/src/test/resources/test4.txt        |     4 +
 geode-pulse/src/test/resources/test5.txt        |     7 +
 geode-pulse/src/test/resources/test6.txt        |    11 +
 geode-pulse/src/test/resources/test7.txt        |    13 +
 .../resources/testNullObjectsAtRootLevel1.txt   |    25 +
 .../resources/testNullObjectsAtRootLevel2.txt   |    30 +
 .../src/test/resources/testQueryResult.txt      |   198 +
 .../src/test/resources/testQueryResult1000.txt  |  1023 +
 .../testQueryResultArrayAndArrayList.txt        |     8 +
 .../test/resources/testQueryResultArrayList.txt |     6 +
 .../resources/testQueryResultArrayOfList.txt    |    15 +
 .../resources/testQueryResultClusterSmall.txt   |    23 +
 .../testQueryResultClusterWithStruct.txt        |    10 +
 .../test/resources/testQueryResultHashMap.txt   |     8 +
 .../resources/testQueryResultHashMapSmall.txt   |    12 +
 .../src/test/resources/testQueryResultSmall.txt |    12 +
 .../resources/testQueryResultWithStruct.txt     |  1744 ++
 .../testQueryResultWithStructSmall.txt          |    15 +
 geode-pulse/src/test/resources/test_pp.txt      |     7 +
 .../src/test/resources/testbed.properties       |   157 +
 geode-rebalancer/build.gradle                   |    28 +
 .../gemfire/cache/util/AutoBalancer.java        |   554 +
 .../util/AutoBalancerIntegrationJUnitTest.java  |   206 +
 .../cache/util/AutoBalancerJUnitTest.java       |   604 +
 geode-site/.gitignore                           |     1 +
 geode-site/website/.gitignore                   |     1 +
 geode-site/website/README.md                    |    54 +
 geode-site/website/Rules                        |    69 +
 geode-site/website/build.sh                     |    18 +
 .../website/content/bootstrap/bootstrap.min.css |     9 +
 geode-site/website/content/community/index.html |   291 +
 .../website/content/css/bootflat-extensions.css |   356 +
 .../website/content/css/bootflat-square.css     |    69 +
 geode-site/website/content/css/bootflat.css     |  1559 ++
 .../website/content/css/font-awesome.min.css    |   405 +
 geode-site/website/content/css/geode-site.css   |  1617 ++
 geode-site/website/content/favicon.ico          |   Bin 0 -> 20805 bytes
 geode-site/website/content/font/FontAwesome.otf |   Bin 0 -> 61896 bytes
 .../content/font/fontawesome-webfont-eot.eot    |   Bin 0 -> 37405 bytes
 .../content/font/fontawesome-webfont-svg.svg    |   399 +
 .../content/font/fontawesome-webfont-ttf.ttf    |   Bin 0 -> 79076 bytes
 .../content/font/fontawesome-webfont-woff.woff  |   Bin 0 -> 43572 bytes
 .../website/content/img/apache_geode_logo.png   |   Bin 0 -> 23616 bytes
 .../content/img/apache_geode_logo_white.png     |   Bin 0 -> 22695 bytes
 .../img/apache_geode_logo_white_small.png       |   Bin 0 -> 52948 bytes
 .../website/content/img/check_flat/default.png  |   Bin 0 -> 25851 bytes
 geode-site/website/content/img/egg-logo.png     |   Bin 0 -> 9938 bytes
 geode-site/website/content/img/github.png       |   Bin 0 -> 8936 bytes
 geode-site/website/content/index.html           |   142 +
 geode-site/website/content/js/bootstrap.min.js  |     8 +
 geode-site/website/content/js/head.js           |   708 +
 geode-site/website/content/js/html5shiv.js      |     8 +
 .../website/content/js/jquery-1.10.1.min.js     |     6 +
 geode-site/website/content/js/jquery.icheck.js  |   397 +
 geode-site/website/content/js/respond.min.js    |     6 +
 geode-site/website/content/js/usergrid-site.js  |    66 +
 geode-site/website/content/releases/index.html  |   129 +
 geode-site/website/layouts/community.html       |     1 +
 geode-site/website/layouts/default.html         |    44 +
 geode-site/website/layouts/docs.html            |     1 +
 geode-site/website/layouts/footer.html          |    96 +
 geode-site/website/layouts/header.html          |   248 +
 geode-site/website/lib/default.rb               |    60 +
 geode-site/website/lib/helpers_.rb              |    16 +
 geode-site/website/lib/pandoc.template          |     4 +
 geode-site/website/nanoc.yaml                   |    94 +
 geode-site/website/run.sh                       |    18 +
 geode-site/website/utilities/map-markers.rb     |    75 +
 geode-site/website/utilities/markers.txt        |   440 +
 geode-site/website/utilities/snapshot-apigee.rb |    88 +
 geode-spark-connector/.gitignore                |     1 +
 geode-spark-connector/README.md                 |    32 +
 geode-spark-connector/doc/10_demos.md           |    84 +
 geode-spark-connector/doc/1_building.md         |    36 +
 geode-spark-connector/doc/2_quick.md            |   178 +
 geode-spark-connector/doc/3_connecting.md       |    55 +
 geode-spark-connector/doc/4_loading.md          |   108 +
 geode-spark-connector/doc/5_rdd_join.md         |   237 +
 geode-spark-connector/doc/6_save_rdd.md         |    81 +
 geode-spark-connector/doc/7_save_dstream.md     |    68 +
 geode-spark-connector/doc/8_oql.md              |    58 +
 geode-spark-connector/doc/9_java_api.md         |   129 +
 .../connector/internal/RegionMetadata.java      |    93 +
 .../gemfirefunctions/QueryFunction.java         |    99 +
 .../RetrieveRegionFunction.java                 |   208 +
 .../RetrieveRegionMetadataFunction.java         |   118 +
 .../StructStreamingResultSender.java            |   219 +
 .../gemfire/spark/connector/Employee.java       |    54 +
 .../spark/connector/JavaApiIntegrationTest.java |   424 +
 .../gemfire/spark/connector/Portfolio.java      |   109 +
 .../gemfire/spark/connector/Position.java       |    73 +
 .../src/it/resources/test-regions.xml           |    49 +
 .../src/it/resources/test-retrieve-regions.xml  |    57 +
 .../spark/connector/BasicIntegrationTest.scala  |   598 +
 .../RDDJoinRegionIntegrationTest.scala          |   300 +
 .../RetrieveRegionIntegrationTest.scala         |   253 +
 .../gemfire/spark/connector/package.scala       |    29 +
 .../connector/testkit/GemFireCluster.scala      |    47 +
 .../spark/connector/testkit/GemFireRunner.scala |   148 +
 .../spark/connector/testkit/IOUtils.scala       |    94 +
 .../spark/streaming/ManualClockHelper.scala     |    28 +
 .../spark/streaming/TestInputDStream.scala      |    44 +
 .../javaapi/GemFireJavaDStreamFunctions.java    |    86 +
 .../GemFireJavaPairDStreamFunctions.java        |    77 +
 .../javaapi/GemFireJavaPairRDDFunctions.java    |   238 +
 .../javaapi/GemFireJavaRDDFunctions.java        |   178 +
 .../javaapi/GemFireJavaSQLContextFunctions.java |    49 +
 .../GemFireJavaSparkContextFunctions.java       |    87 +
 .../connector/javaapi/GemFireJavaUtil.java      |   122 +
 .../spark/connector/GemFireConnection.scala     |    67 +
 .../spark/connector/GemFireConnectionConf.scala |    73 +
 .../connector/GemFireConnectionManager.scala    |    31 +
 .../connector/GemFireFunctionDeployer.scala     |    81 +
 .../connector/GemFireKryoRegistrator.scala      |    29 +
 .../connector/GemFirePairRDDFunctions.scala     |   140 +
 .../spark/connector/GemFireRDDFunctions.scala   |   120 +
 .../connector/GemFireSQLContextFunctions.scala  |    42 +
 .../GemFireSparkContextFunctions.scala          |    39 +
 .../internal/DefaultGemFireConnection.scala     |   164 +
 .../DefaultGemFireConnectionManager.scala       |    77 +
 .../connector/internal/LocatorHelper.scala      |   135 +
 .../StructStreamingResultCollector.scala        |   152 +
 .../connector/internal/oql/QueryParser.scala    |    58 +
 .../spark/connector/internal/oql/QueryRDD.scala |    83 +
 .../internal/oql/QueryResultCollector.scala     |    69 +
 .../connector/internal/oql/RDDConverter.scala   |    40 +
 .../connector/internal/oql/RowBuilder.scala     |    38 +
 .../connector/internal/oql/SchemaBuilder.scala  |    73 +
 .../internal/oql/UndefinedSerializer.scala      |    46 +
 .../connector/internal/rdd/GemFireJoinRDD.scala |    67 +
 .../internal/rdd/GemFireOuterJoinRDD.scala      |    69 +
 .../internal/rdd/GemFireRDDPartition.scala      |    36 +
 .../internal/rdd/GemFireRDDPartitioner.scala    |    59 +
 .../rdd/GemFireRDDPartitionerImpl.scala         |    89 +
 .../internal/rdd/GemFireRDDWriter.scala         |    82 +
 .../internal/rdd/GemFireRegionRDD.scala         |   138 +
 .../javaapi/GemFireJavaRegionRDD.scala          |    26 +
 .../spark/connector/javaapi/JavaAPIHelper.scala |    53 +
 .../gemfire/spark/connector/package.scala       |    69 +
 .../streaming/GemFireDStreamFunctions.scala     |    89 +
 .../spark/connector/streaming/package.scala     |    32 +
 .../gemfire/spark/connector/JavaAPITest.java    |   163 +
 .../connector/GemFireFunctionDeployerTest.scala |    58 +
 .../DefaultGemFireConnectionManagerTest.scala   |    82 +
 ...tStreamingResultSenderAndCollectorTest.scala |   254 +
 .../internal/oql/QueryParserTest.scala          |    83 +
 .../connector/ConnectorImplicitsTest.scala      |    50 +
 .../connector/GemFireConnectionConfTest.scala   |   100 +
 .../connector/GemFireDStreamFunctionsTest.scala |    79 +
 .../connector/GemFireRDDFunctionsTest.scala     |   139 +
 .../spark/connector/LocatorHelperTest.scala     |   168 +
 .../rdd/GemFireRDDPartitionerTest.scala         |   190 +
 .../connector/rdd/GemFireRegionRDDTest.scala    |   117 +
 .../basic-demos/src/main/java/demo/Emp.java     |    95 +
 .../src/main/java/demo/OQLJavaDemo.java         |    59 +
 .../src/main/java/demo/PairRDDSaveJavaDemo.java |    86 +
 .../src/main/java/demo/RDDSaveJavaDemo.java     |    85 +
 .../src/main/java/demo/RegionToRDDJavaDemo.java |    57 +
 .../src/main/scala/demo/NetworkWordCount.scala  |    75 +
 .../project/Dependencies.scala                  |    45 +
 .../project/GemFireSparkBuild.scala             |    76 +
 geode-spark-connector/project/Settings.scala    |    57 +
 geode-spark-connector/project/build.properties  |     1 +
 geode-spark-connector/project/plugins.sbt       |     8 +
 geode-spark-connector/scalastyle-config.xml     |   117 +
 geode-wan/build.gradle                          |    23 +
 .../client/internal/GatewaySenderBatchOp.java   |   313 +
 .../cache/client/internal/SenderProxy.java      |    43 +
 .../internal/locator/wan/LocatorDiscovery.java  |   227 +
 .../internal/locator/wan/LocatorHelper.java     |   143 +
 .../locator/wan/LocatorJoinMessage.java         |   105 +
 .../wan/LocatorMembershipListenerImpl.java      |   230 +
 .../locator/wan/RemoteLocatorJoinRequest.java   |    87 +
 .../locator/wan/RemoteLocatorJoinResponse.java  |    89 +
 .../locator/wan/RemoteLocatorPingRequest.java   |    56 +
 .../locator/wan/RemoteLocatorPingResponse.java  |    55 +
 .../locator/wan/RemoteLocatorRequest.java       |    66 +
 .../locator/wan/RemoteLocatorResponse.java      |    74 +
 .../internal/locator/wan/WANFactoryImpl.java    |    74 +
 .../locator/wan/WanLocatorDiscovererImpl.java   |   138 +
 .../cache/wan/AbstractRemoteGatewaySender.java  |   169 +
 .../cache/wan/GatewayReceiverFactoryImpl.java   |   147 +
 .../internal/cache/wan/GatewayReceiverImpl.java |   253 +
 .../wan/GatewaySenderEventRemoteDispatcher.java |   766 +
 .../cache/wan/GatewaySenderFactoryImpl.java     |   389 +
 .../wan/parallel/ParallelGatewaySenderImpl.java |   267 +
 ...rentParallelGatewaySenderEventProcessor.java |    67 +
 ...moteParallelGatewaySenderEventProcessor.java |   122 +
 ...urrentSerialGatewaySenderEventProcessor.java |    45 +
 ...RemoteSerialGatewaySenderEventProcessor.java |    50 +
 .../wan/serial/SerialGatewaySenderImpl.java     |   260 +
 ...ternal.locator.wan.LocatorMembershipListener |    15 +
 ...ne.gemfire.internal.cache.wan.spi.WANFactory |    15 +
 .../cache/CacheXml70GatewayDUnitTest.java       |   243 +
 .../cache/CacheXml80GatewayDUnitTest.java       |   137 +
 .../AnalyzeWANSerializablesJUnitTest.java       |    91 +
 .../internal/cache/UpdateVersionDUnitTest.java  |   965 +
 .../gemfire/internal/cache/wan/WANTestBase.java |  5188 +++++
 ...oncurrentParallelGatewaySenderDUnitTest.java |   805 +
 ...ntParallelGatewaySenderOffHeapDUnitTest.java |    32 +
 ...allelGatewaySenderOperation_1_DUnitTest.java |   830 +
 ...allelGatewaySenderOperation_2_DUnitTest.java |   528 +
 ...tSerialGatewaySenderOperationsDUnitTest.java |   111 +
 ...GatewaySenderOperationsOffHeapDUnitTest.java |    32 +
 .../ConcurrentWANPropogation_1_DUnitTest.java   |   590 +
 .../ConcurrentWANPropogation_2_DUnitTest.java   |   466 +
 .../cache/wan/disttx/DistTXWANDUnitTest.java    |   205 +
 .../CommonParallelGatewaySenderDUnitTest.java   |   470 +
 ...onParallelGatewaySenderOffHeapDUnitTest.java |    32 +
 ...wWANConcurrencyCheckForDestroyDUnitTest.java |   514 +
 .../cache/wan/misc/PDXNewWanDUnitTest.java      |   753 +
 ...dRegion_ParallelWANPersistenceDUnitTest.java |   688 +
 ...dRegion_ParallelWANPropogationDUnitTest.java |  1074 +
 .../SenderWithTransportFilterDUnitTest.java     |   231 +
 ...downAllPersistentGatewaySenderDUnitTest.java |   199 +
 .../wan/misc/WANConfigurationJUnitTest.java     |   609 +
 .../wan/misc/WANLocatorServerDUnitTest.java     |   195 +
 .../cache/wan/misc/WANSSLDUnitTest.java         |   145 +
 .../wan/misc/WanAutoDiscoveryDUnitTest.java     |   469 +
 .../cache/wan/misc/WanValidationsDUnitTest.java |  1542 ++
 ...tewaySenderOperation_2_OffHeapDUnitTest.java |    32 +
 ...tewaySenderOperation_2_OffHeapDUnitTest.java |    32 +
 ...GatewaySenderOperationsOffHeapDUnitTest.java |    34 +
 ...ewaySenderQueueOverflowOffHeapDUnitTest.java |    34 +
 .../ParallelWANConflationOffHeapDUnitTest.java  |    34 +
 ...nceEnabledGatewaySenderOffHeapDUnitTest.java |    34 +
 ...ropogationConcurrentOpsOffHeapDUnitTest.java |    34 +
 .../ParallelWANPropogationOffHeapDUnitTest.java |    34 +
 ...erialGatewaySenderQueueOffHeapDUnitTest.java |    34 +
 ...nceEnabledGatewaySenderOffHeapDUnitTest.java |    34 +
 .../SerialWANPropogationOffHeapDUnitTest.java   |    34 +
 ...ation_PartitionedRegionOffHeapDUnitTest.java |    34 +
 ...allelGatewaySenderOperation_2_DUnitTest.java |    38 +
 ...arallelGatewaySenderOperationsDUnitTest.java |   634 +
 ...llelGatewaySenderQueueOverflowDUnitTest.java |   522 +
 .../ParallelWANConflationDUnitTest.java         |   497 +
 ...ersistenceEnabledGatewaySenderDUnitTest.java |  1731 ++
 ...llelWANPropagationClientServerDUnitTest.java |   108 +
 ...lelWANPropagationConcurrentOpsDUnitTest.java |   285 +
 .../ParallelWANPropagationDUnitTest.java        |  1358 ++
 ...ParallelWANPropagationLoopBackDUnitTest.java |   418 +
 .../wan/parallel/ParallelWANStatsDUnitTest.java |   486 +
 ...tewaySenderDistributedDeadlockDUnitTest.java |   395 +
 ...rialGatewaySenderEventListenerDUnitTest.java |   387 +
 .../SerialGatewaySenderOperationsDUnitTest.java |   654 +
 .../SerialGatewaySenderQueueDUnitTest.java      |   333 +
 ...ersistenceEnabledGatewaySenderDUnitTest.java |   563 +
 .../SerialWANPropagationLoopBackDUnitTest.java  |   494 +
 .../serial/SerialWANPropogationDUnitTest.java   |  1501 ++
 ...NPropogation_PartitionedRegionDUnitTest.java |   423 +
 .../SerialWANPropogationsFeatureDUnitTest.java  |   353 +
 .../wan/serial/SerialWANStatsDUnitTest.java     |   580 +
 .../wan/wancommand/WANCommandTestBase.java      |   513 +
 ...anCommandCreateGatewayReceiverDUnitTest.java |   623 +
 .../WanCommandCreateGatewaySenderDUnitTest.java |   700 +
 ...WanCommandGatewayReceiverStartDUnitTest.java |   273 +
 .../WanCommandGatewayReceiverStopDUnitTest.java |   278 +
 .../WanCommandGatewaySenderStartDUnitTest.java  |   399 +
 .../WanCommandGatewaySenderStopDUnitTest.java   |   352 +
 .../wan/wancommand/WanCommandListDUnitTest.java |   380 +
 .../WanCommandPauseResumeDUnitTest.java         |   683 +
 .../wancommand/WanCommandStatusDUnitTest.java   |   543 +
 .../management/WANManagementDUnitTest.java      |   501 +
 .../ClusterConfigurationDUnitTest.java          |  1057 +
 .../pulse/TestRemoteClusterDUnitTest.java       |   262 +
 .../gemfire/codeAnalysis/excludedClasses.txt    |     2 +
 .../gemstone/gemfire/codeAnalysis/openBugs.txt  |    21 +
 .../sanctionedDataSerializables.txt             |    28 +
 .../codeAnalysis/sanctionedSerializables.txt    |     0
 geode-web-api/build.gradle                      |    55 +
 .../web/controllers/AbstractBaseController.java |   841 +
 .../web/controllers/BaseControllerAdvice.java   |   147 +
 .../web/controllers/CommonCrudController.java   |   249 +
 .../controllers/FunctionAccessController.java   |   246 +
 .../web/controllers/PdxBasedCrudController.java |   354 +
 .../web/controllers/QueryAccessController.java  |   354 +
 .../web/controllers/support/JSONTypes.java      |    25 +
 .../controllers/support/QueryResultTypes.java   |    32 +
 .../web/controllers/support/RegionData.java     |   170 +
 .../controllers/support/RegionEntryData.java    |   105 +
 .../support/RestServersResultCollector.java     |    55 +
 .../web/controllers/support/UpdateOp.java       |    31 +
 .../DataTypeNotSupportedException.java          |    50 +
 .../web/exception/GemfireRestException.java     |    48 +
 .../web/exception/MalformedJsonException.java   |    51 +
 .../web/exception/RegionNotFoundException.java  |    44 +
 .../exception/ResourceNotFoundException.java    |    45 +
 ...stomMappingJackson2HttpMessageConverter.java |   161 +
 .../web/swagger/config/RestApiPathProvider.java |    77 +
 .../web/swagger/config/SwaggerConfig.java       |   181 +
 .../rest/internal/web/util/ArrayUtils.java      |    60 +
 .../rest/internal/web/util/DateTimeUtils.java   |    54 +
 .../internal/web/util/IdentifiableUtils.java    |   109 +
 .../rest/internal/web/util/JSONUtils.java       |   253 +
 .../rest/internal/web/util/JsonWriter.java      |   597 +
 .../rest/internal/web/util/NumberUtils.java     |   146 +
 .../rest/internal/web/util/ValidationUtils.java |    41 +
 .../main/webapp/WEB-INF/gemfire-api-servlet.xml |    85 +
 geode-web-api/src/main/webapp/WEB-INF/web.xml   |    65 +
 .../src/main/webapp/docs/css/reset.css          |   125 +
 .../src/main/webapp/docs/css/screen.css         |  1221 ++
 .../main/webapp/docs/images/explorer_icons.png  |   Bin 0 -> 5763 bytes
 .../src/main/webapp/docs/images/logo_small.png  |   Bin 0 -> 770 bytes
 .../main/webapp/docs/images/pet_store_api.png   |   Bin 0 -> 824 bytes
 .../src/main/webapp/docs/images/throbber.gif    |   Bin 0 -> 9257 bytes
 .../src/main/webapp/docs/images/wordnik_api.png |   Bin 0 -> 980 bytes
 geode-web-api/src/main/webapp/docs/index.html   |    81 +
 .../src/main/webapp/docs/lib/backbone-min.js    |    38 +
 .../main/webapp/docs/lib/handlebars-1.0.0.js    |  2278 +++
 .../main/webapp/docs/lib/highlight.7.3.pack.js  |     1 +
 .../main/webapp/docs/lib/jquery-1.8.0.min.js    |     2 +
 .../main/webapp/docs/lib/jquery.ba-bbq.min.js   |    18 +
 .../main/webapp/docs/lib/jquery.slideto.min.js  |     1 +
 .../main/webapp/docs/lib/jquery.wiggle.min.js   |     8 +
 .../src/main/webapp/docs/lib/shred.bundle.js    |  2765 +++
 .../src/main/webapp/docs/lib/shred/content.js   |   193 +
 .../src/main/webapp/docs/lib/swagger-oauth.js   |   211 +
 .../src/main/webapp/docs/lib/swagger.js         |  1527 ++
 .../src/main/webapp/docs/lib/underscore-min.js  |    32 +
 geode-web-api/src/main/webapp/docs/o2c.html     |    15 +
 .../src/main/webapp/docs/swagger-ui.js          |  2269 +++
 .../src/main/webapp/docs/swagger-ui.min.js      |     1 +
 geode-web/build.gradle                          |    55 +
 .../src/main/webapp/WEB-INF/gemfire-servlet.xml |    59 +
 geode-web/src/main/webapp/WEB-INF/web.xml       |    56 +
 .../internal/web/AbstractWebTestCase.java       |    97 +
 .../ShellCommandsControllerJUnitTest.java       |   240 +
 ...entVariablesHandlerInterceptorJUnitTest.java |   268 +
 .../internal/web/domain/LinkIndexJUnitTest.java |   237 +
 .../internal/web/domain/LinkJUnitTest.java      |   124 +
 .../domain/QueryParameterSourceJUnitTest.java   |    93 +
 .../web/http/ClientHttpRequestJUnitTest.java    |   510 +
 ...ableObjectHttpMessageConverterJUnitTest.java |   166 +
 .../RestHttpOperationInvokerJUnitTest.java      |   454 +
 .../SimpleHttpOperationInvokerJUnitTest.java    |   199 +
 .../web/util/ConvertUtilsJUnitTest.java         |   171 +
 .../internal/web/util/UriUtilsJUnitTest.java    |   119 +
 gradle/rat.gradle                               |   194 +-
 settings.gradle                                 |    38 +-
 12802 files changed, 1816313 insertions(+), 1817117 deletions(-)
----------------------------------------------------------------------



[021/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/Connection.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/Connection.java
index 74660da,0000000..988ca33
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/Connection.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/Connection.java
@@@ -1,4153 -1,0 +1,4154 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.tcp;
 +
 +import java.io.BufferedInputStream;
 +import java.io.ByteArrayOutputStream;
 +import java.io.DataInputStream;
 +import java.io.DataOutputStream;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.InterruptedIOException;
 +import java.io.OutputStream;
 +import java.net.ConnectException;
 +import java.net.Inet6Address;
 +import java.net.InetSocketAddress;
 +import java.net.Socket;
 +import java.net.SocketException;
 +import java.net.SocketTimeoutException;
 +import java.nio.ByteBuffer;
 +import java.nio.channels.CancelledKeyException;
 +import java.nio.channels.ClosedChannelException;
 +import java.nio.channels.ClosedSelectorException;
 +import java.nio.channels.SocketChannel;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.Iterator;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.concurrent.Semaphore;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +import java.util.concurrent.atomic.AtomicLong;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 +import com.gemstone.gemfire.distributed.internal.ConflationKey;
 +import com.gemstone.gemfire.distributed.internal.DM;
 +import com.gemstone.gemfire.distributed.internal.DMStats;
 +import com.gemstone.gemfire.distributed.internal.DirectReplyProcessor;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.distributed.internal.DistributionMessage;
 +import com.gemstone.gemfire.distributed.internal.DistributionStats;
 +import com.gemstone.gemfire.distributed.internal.ReplyException;
 +import com.gemstone.gemfire.distributed.internal.ReplyMessage;
 +import com.gemstone.gemfire.distributed.internal.ReplyProcessor21;
 +import com.gemstone.gemfire.distributed.internal.ReplySender;
 +import com.gemstone.gemfire.distributed.internal.direct.DirectChannel;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 +import com.gemstone.gemfire.i18n.StringId;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.ByteArrayDataInput;
 +import com.gemstone.gemfire.internal.DSFIDFactory;
 +import com.gemstone.gemfire.internal.InternalDataSerializer;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.SocketUtils;
 +import com.gemstone.gemfire.internal.SystemTimer;
 +import com.gemstone.gemfire.internal.SystemTimer.SystemTimerTask;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
 +import com.gemstone.gemfire.internal.logging.log4j.AlertAppender;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.tcp.MsgReader.Header;
 +import com.gemstone.gemfire.internal.util.concurrent.ReentrantSemaphore;
 +
 +/** <p>Connection is a socket holder that sends and receives serialized
 +    message objects.  A Connection may be closed to preserve system
 +    resources and will automatically be reopened when it's needed.</p>
 +
 +    @author Bruce Schuchardt
 +    @since 2.0
 +
 +*/
 +
 +public class Connection implements Runnable {
 +  private static final Logger logger = LogService.getLogger();
 +
 +  private static final int INITIAL_CAPACITY = Integer.getInteger("p2p.readerBufferSize", 32768).intValue();
 +  private static int P2P_CONNECT_TIMEOUT;
 +  private static boolean IS_P2P_CONNECT_TIMEOUT_INITIALIZED = false; 
 +  
 +  public final static int NORMAL_MSG_TYPE = 0x4c;
 +  public final static int CHUNKED_MSG_TYPE = 0x4d; // a chunk of one logical msg
 +  public final static int END_CHUNKED_MSG_TYPE = 0x4e; // last in a series of chunks
 +  public final static int DIRECT_ACK_BIT = 0x20;
 +  //We no longer support early ack
 +  //public final static int EARLY_ACK_BIT = 0x10;
 +
 +  public static final int MSG_HEADER_SIZE_OFFSET = 0;
 +  public static final int MSG_HEADER_TYPE_OFFSET = 4;
 +  public static final int MSG_HEADER_ID_OFFSET = 5;
 +  public static final int MSG_HEADER_BYTES = 7;
 +
 +  /**
 +   * Small buffer used for send socket buffer on receiver connections
 +   * and receive buffer on sender connections.
 +   */
 +  public final static int SMALL_BUFFER_SIZE = Integer.getInteger("gemfire.SMALL_BUFFER_SIZE",4096).intValue();
 +
 +  /** counter to give connections a unique id */
 +  private static AtomicLong idCounter = new AtomicLong(1);
 +
 +  /** string used as the reason for initiating suspect processing */
 +  public static final String INITIATING_SUSPECT_PROCESSING = "member unexpectedly shut down shared, unordered connection";
 +
 +  /** the table holding this connection */
 +  final ConnectionTable owner;
 +  
 +  /** Set to false once run() is terminating. Using this instead of Thread.isAlive  
 +    * as the reader thread may be a pooled thread.
 +    */ 
 +  private volatile boolean isRunning = false; 
 +
 +  /** true if connection is a shared resource that can be used by more than one thread */
 +  private boolean sharedResource;
 +
 +  public final boolean isSharedResource() {
 +    return this.sharedResource;
 +  }
 +  
 +  /** The idle timeout timer task for this connection */
 +  private SystemTimerTask idleTask;
 +  
 +  /**
 +   * Returns the depth of unshared reader threads from this thread to
 +   * the original non-reader-thread.
 +   * E.g., ServerConnection -> reader(domino=1) -> reader(domino=2) -> reader(domino=3)
 +   */
 +  public static int getDominoCount() {
 +    return dominoCount.get().intValue();
 +  }
 +
 +  private final static ThreadLocal isReaderThread = new ThreadLocal();
 +  public final static void makeReaderThread() {
 +    // mark this thread as a reader thread
 +    makeReaderThread(true);
 +  }
 +  private final static void makeReaderThread(boolean v) {
 +    isReaderThread.set(v);
 +  }
 +  // return true if this thread is a reader thread
 +  public final static boolean isReaderThread() {
 +    Object o = isReaderThread.get();
 +    if (o == null) {
 +      return false;
 +    } else {
 +      return ((Boolean)o).booleanValue();
 +    }
 +  }
 +
 +  private int getP2PConnectTimeout() {
 +    if(IS_P2P_CONNECT_TIMEOUT_INITIALIZED)
 +      return P2P_CONNECT_TIMEOUT;
 +    String connectTimeoutStr = System.getProperty("p2p.connectTimeout");
 +    if(connectTimeoutStr != null) {
 +      P2P_CONNECT_TIMEOUT =  Integer.parseInt(connectTimeoutStr);
 +    }
 +    else {      
 +      P2P_CONNECT_TIMEOUT = 6*this.owner.owner.getDM().getConfig().getMemberTimeout();
 +    }
 +    IS_P2P_CONNECT_TIMEOUT_INITIALIZED = true;
 +    return P2P_CONNECT_TIMEOUT;     
 +  }
 +  /**
 +   * If true then readers for thread owned sockets will send all messages on thread owned senders.
 +   * Even normally unordered msgs get send on TO socks.
 +   */
 +  private static final boolean DOMINO_THREAD_OWNED_SOCKETS = Boolean.getBoolean("p2p.ENABLE_DOMINO_THREAD_OWNED_SOCKETS");
 +  private final static ThreadLocal isDominoThread = new ThreadLocal();
 +  // return true if this thread is a reader thread
 +  public final static boolean tipDomino() {
 +    if (DOMINO_THREAD_OWNED_SOCKETS) {
 +      // mark this thread as one who wants to send ALL on TO sockets
 +      ConnectionTable.threadWantsOwnResources();
 +      isDominoThread.set(Boolean.TRUE);
 +      return true;
 +    } else {
 +      return false;
 +    }
 +  }
 +  public final static boolean isDominoThread() {
 +    Object o = isDominoThread.get();
 +    if (o == null) {
 +      return false;
 +    } else {
 +      return ((Boolean)o).booleanValue();
 +    }
 +  }
 +
 +  /** the socket entrusted to this connection */
 +  private final Socket socket;
 +
 +  /** the non-NIO output stream */
 +  OutputStream output;
 +
 +  /** output stream/channel lock */
 +  private final Object outLock = new Object();
 +
 +  /** the ID string of the conduit (for logging) */
 +  String conduitIdStr;
 +
 +  /** Identifies the java group member on the other side of the connection. */
 +  InternalDistributedMember remoteAddr;
 +
 +  /**
 +   * Identifies the version of the member on the other side of the connection.
 +   */
 +  Version remoteVersion;
 +
 +  /**
 +   * True if this connection was accepted by a listening socket.
 +   * This makes it a receiver.
 +   * False if this connection was explicitly created by a connect call.
 +   * This makes it a sender.
 +   */
 +  private final boolean isReceiver;
 +  
 +  /**
 +   * count of how many unshared p2p-readers removed from the original action this
 +   * thread is.  For instance, server-connection -> owned p2p reader (count 0)
 +   * -> owned p2p reader (count 1) -> owned p2p reader (count 2).  This shows
 +   * up in thread names as "DOM #x" (domino #x)
 +   */
 +  private static ThreadLocal<Integer> dominoCount = new ThreadLocal<Integer>() {
 +    @Override
 +    protected Integer initialValue() {
 +      return 0;
 +    }};
 +
 +//  /**
 +//   * name of sender thread thread.  Useful in finding out why a reader
 +//   * thread was created.  Add sending of the name in handshakes and
 +//   * add it to the name of the reader thread (the code is there but commented out)
 +//   */
 +//  private String senderName = null;
 +  
 +  // If we are a sender then we want to know if the receiver on the
 +  // other end is willing to have its messages queued. The following
 +  // four "async" inst vars come from his handshake response.
 +  /**
 +   * How long to wait if receiver will not accept a message before we
 +   * go into queue mode.
 +   * @since 4.2.2
 +   */
 +  private int asyncDistributionTimeout = 0;
 +  /**
 +   * How long to wait,
 +   * with the receiver not accepting any messages,
 +   * before kicking the receiver out of the distributed system.
 +   * Ignored if asyncDistributionTimeout is zero.
 +   * @since 4.2.2
 +   */
 +  private int asyncQueueTimeout = 0;
 +  /**
 +   * How much queued data we can have,
 +   * with the receiver not accepting any messages,
 +   * before kicking the receiver out of the distributed system.
 +   * Ignored if asyncDistributionTimeout is zero.
 +   * Canonicalized to bytes (property file has it as megabytes
 +   * @since 4.2.2
 +   */
 +  private long asyncMaxQueueSize = 0;
 +  /**
 +   * True if an async queue is already being filled.
 +   */
 +  private volatile boolean asyncQueuingInProgress = false;
 +
 +  /**
 +   * Maps ConflatedKey instances to ConflatedKey instance.
 +   * Note that even though the key and value for an entry is the map
 +   * will always be "equal" they will not always be "==".
 +   */
 +  private final Map conflatedKeys = new HashMap();
 +
 +  //private final Queue outgoingQueue = new LinkedBlockingQueue();
 +
 +
 +  // NOTE: LinkedBlockingQueue has a bug in which removes from the queue
 +  // cause future offer to increase the size without adding anything to the queue.
 +  // So I've changed from this backport class to a java.util.LinkedList
 +  private final LinkedList outgoingQueue = new LinkedList();
 +
 +  /**
 +   * Number of bytes in the outgoingQueue.
 +   * Used to control capacity.
 +   */
 +  private long queuedBytes = 0;
 +
 +  /** used for async writes */
 +  Thread pusherThread;
 +
 +  /**
 +   * The maximum number of concurrent senders sending a message to a single recipient.
 +   */
 +  private final static int MAX_SENDERS = Integer.getInteger("p2p.maxConnectionSenders", DirectChannel.DEFAULT_CONCURRENCY_LEVEL).intValue();
 +  /**
 +   * This semaphore is used to throttle how many threads will try to do sends on
 +   * this connection concurrently. A thread must acquire this semaphore before it
 +   * is allowed to start serializing its message.
 +   */
 +  private final Semaphore senderSem = new ReentrantSemaphore(MAX_SENDERS);
 +
 +  /** Set to true once the handshake has been read */
 +  volatile boolean handshakeRead = false;
 +  volatile boolean handshakeCancelled = false;
 +
 +  private volatile int replyCode = 0;
 +
 +  private static final byte REPLY_CODE_OK = (byte)69;
 +  private static final byte REPLY_CODE_OK_WITH_ASYNC_INFO = (byte)70;
 +
 +  private final Object handshakeSync = new Object();
 +
 +  /** message reader thread */
 +  private volatile Thread readerThread;
 +
 +//  /**
 +//   * When a thread owns the outLock and is writing to the socket, it must
 +//   * be placed in this variable so that it can be interrupted should the
 +//   * socket need to be closed.
 +//   */
 +//  private volatile Thread writerThread;
 +
 +  /** whether the reader thread is, or should be, running */
 +  volatile boolean stopped = true;
 +
 +  /** set to true once a close begins */
 +  private final AtomicBoolean closing = new AtomicBoolean(false);
 +
 +  volatile boolean readerShuttingDown = false;
 +
 +  /** whether the socket is connected */
 +  volatile boolean connected = false;
 +
 +  /**
 +   * Set to true once a connection finishes its constructor
 +   */
 +  volatile boolean finishedConnecting = false;
 +
 +  volatile boolean accessed = true;
 +  volatile boolean socketInUse = false;
 +  volatile boolean timedOut = false;
 +  
 +  /**
 +   * task for detecting ack timeouts and issuing alerts
 +   */
 +  private SystemTimer.SystemTimerTask ackTimeoutTask;
 +
 +  // State for ackTimeoutTask: transmissionStartTime, ackWaitTimeout, ackSATimeout, ackConnectionGroup, ackThreadName
 +  
 +  /** millisecond clock at the time message transmission started, if doing
 +   *  forced-disconnect processing */
 +  long transmissionStartTime;
 +  
 +  /** ack wait timeout - if socketInUse, use this to trigger SUSPECT processing */
 +  private long ackWaitTimeout;
 +
 +  /** ack severe alert timeout - if socketInUse, use this to send alert */
 +  private long ackSATimeout;
 +  
 +  /**
 +   * other connections participating in the current transmission.  we notify
 +   * them if ackSATimeout expires to keep all members from generating alerts
 +   * when only one is slow 
 +   */
 +  List ackConnectionGroup;
 +  
 +  /** name of thread that we're currently performing an operation in (may be null) */
 +  String ackThreadName;
 +  
 +
 +  /** the buffer used for NIO message receipt */
 +  ByteBuffer nioInputBuffer;
 +
 +  /** the position of the next message's content */
 +//  int nioMessageStart;
 +
 +  /** the length of the next message to be dispatched */
 +  int nioMessageLength;
 +//  byte nioMessageVersion;
 +
 +  /** the type of message being received */
 +  byte nioMessageType;
 +
 +  /** used to lock access to destreamer data */
 +  private final Object destreamerLock = new Object();
 +  /** caches a msg destreamer that is currently not being used */
 +  MsgDestreamer idleMsgDestreamer;
 +  /** used to map a msgId to a MsgDestreamer which are
 +    * used for destreaming chunked messages using nio */
 +  HashMap destreamerMap;
 +
 +  boolean directAck;
 +
 +  short nioMsgId;
 +
 +  /** whether the length of the next message has been established */
 +  boolean nioLengthSet = false;
 +
 +  /** is this connection used for serial message delivery? */
 +  boolean preserveOrder = false;
 +
 +  /** number of messages sent on this connection */
 +  private long messagesSent;
 +
 +  /** number of messages received on this connection */
 +  private long messagesReceived;
 +
 +  /** unique ID of this connection (remote if isReceiver==true) */
 +  private volatile long uniqueId;
 +
 +  private int sendBufferSize = -1;
 +  private int recvBufferSize = -1;
 +  
 +  private ReplySender replySender;
 +
 +  private void setSendBufferSize(Socket sock) {
 +    setSendBufferSize(sock, this.owner.getConduit().tcpBufferSize);
 +  }
 +  private void setReceiveBufferSize(Socket sock) {
 +    setReceiveBufferSize(sock, this.owner.getConduit().tcpBufferSize);
 +  }
 +  private void setSendBufferSize(Socket sock, int requestedSize) {
 +    setSocketBufferSize(sock, true, requestedSize);
 +  }
 +  private void setReceiveBufferSize(Socket sock, int requestedSize) {
 +    setSocketBufferSize(sock, false, requestedSize);
 +  }
 +  public int getReceiveBufferSize() {
 +    return recvBufferSize;
 +  }
 +  private void setSocketBufferSize(Socket sock, boolean send, int requestedSize) {
 +    setSocketBufferSize(sock, send, requestedSize, false);
 +  }
 +  private void setSocketBufferSize(Socket sock, boolean send, int requestedSize, boolean alreadySetInSocket) {
 +    if (requestedSize > 0) {
 +      try {
 +        int currentSize = send
 +          ? sock.getSendBufferSize()
 +          : sock.getReceiveBufferSize();
 +        if (currentSize == requestedSize) {
 +          if (send) {
 +            this.sendBufferSize = currentSize;
 +          }
 +          return;
 +        }
 +        if (!alreadySetInSocket) {
 +          if (send) {
 +            sock.setSendBufferSize(requestedSize);
 +          } else {
 +            sock.setReceiveBufferSize(requestedSize);
 +          }
 +        } else {
 +        }
 +      } catch (SocketException ignore) {
 +      }
 +      try {
 +        int actualSize = send
 +          ? sock.getSendBufferSize()
 +          : sock.getReceiveBufferSize();
 +        if (send) {
 +          this.sendBufferSize = actualSize;
 +        } else {
 +          this.recvBufferSize = actualSize;
 +        }
 +        if (actualSize < requestedSize) {
 +          logger.info(LocalizedMessage.create(LocalizedStrings.Connection_SOCKET_0_IS_1_INSTEAD_OF_THE_REQUESTED_2,
 +              new Object[] {(send ? "send buffer size" : "receive buffer size"), Integer.valueOf(actualSize), Integer.valueOf(requestedSize)}));
 +        } else if (actualSize > requestedSize) {
 +          if (logger.isTraceEnabled()) {
 +            logger.trace("Socket {} buffer size is {} instead of the requested {}",
 +                (send ? "send" : "receive"), actualSize, requestedSize);
 +          }
 +          // Remember the request size which is smaller.
 +          // This remembered value is used for allocating direct mem buffers.
 +          if (send) {
 +            this.sendBufferSize = requestedSize;
 +          } else {
 +            this.recvBufferSize = requestedSize;
 +          }
 +        }
 +      } catch (SocketException ignore) {
 +        if (send) {
 +          this.sendBufferSize = requestedSize;
 +        } else {
 +          this.recvBufferSize = requestedSize;
 +        }
 +      }
 +    }
 +  }
 +  /**
 +   * Returns the size of the send buffer on this connection's socket.
 +   */
 +  public int getSendBufferSize() {
 +    int result = this.sendBufferSize;
 +    if (result != -1) {
 +      return result;
 +    }
 +    try {
 +      result = getSocket().getSendBufferSize();
 +    } catch (SocketException ignore) {
 +      // just return a default
 +      result = this.owner.getConduit().tcpBufferSize;
 +    }
 +    this.sendBufferSize = result;
 +    return result;
 +  }
 +
 +  /** creates a connection that we accepted (it was initiated by
 +   * an explicit connect being done on the other side).
 +   * We will only receive data on this socket; never send.
 +   */
 +  protected static Connection createReceiver(ConnectionTable t, Socket s)
 +    throws IOException, ConnectionException
 +  {
 +    Connection c = new Connection(t, s);
 +    boolean readerStarted = false;
 +    try {
 +      c.startReader(t);
 +      readerStarted = true;
 +    } finally {
 +      if (!readerStarted) {
 +        c.closeForReconnect(LocalizedStrings.Connection_COULD_NOT_START_READER_THREAD.toLocalizedString());
 +      }
 +    }
 +    c.waitForHandshake();
 +    //sendHandshakeReplyOK();
 +    c.finishedConnecting = true;
 +    return c;
 +  }
 +  
 +  /** creates a connection that we accepted (it was initiated by
 +   * an explicit connect being done on the other side).
 +   */
 +  protected Connection(ConnectionTable t, Socket s)
 +    throws IOException, ConnectionException
 +  {
 +    if (t == null) {
 +      throw new IllegalArgumentException(LocalizedStrings.Connection_NULL_CONNECTIONTABLE.toLocalizedString());
 +    }
 +    this.isReceiver = true;
 +    this.owner = t;
 +    this.socket = s;
 +    this.conduitIdStr = owner.getConduit().getId().toString();
 +    this.handshakeRead = false;
 +    this.handshakeCancelled = false;
 +    this.connected = true;
 +
 +    try {
 +      s.setTcpNoDelay(true);
 +      s.setKeepAlive(true);
 +//      s.setSoLinger(true, (Integer.valueOf(System.getProperty("p2p.lingerTime", "5000"))).intValue());
 +      setSendBufferSize(s, SMALL_BUFFER_SIZE);
 +      setReceiveBufferSize(s);
 +    }
 +    catch (SocketException e) {
 +      // unable to get the settings we want.  Don't log an error because it will
 +      // likely happen a lot
 +    }
 +    if (!useNIO()) {
 +      try {
 +        //this.output = new BufferedOutputStream(s.getOutputStream(), SMALL_BUFFER_SIZE);
 +        this.output = s.getOutputStream();
 +      }
 +      catch (IOException io) {
 +        logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_UNABLE_TO_GET_P2P_CONNECTION_STREAMS), io);
 +        t.getSocketCloser().asyncClose(s, this.remoteAddr.toString(), null);
 +        throw io;
 +      }
 +    }
 +  }
 +  
 +  void setIdleTimeoutTask(SystemTimerTask task) {
 +    this.idleTask = task;
 +  }
 +
 +
 +  /**
 +   * Returns true if an idle connection was detected.
 +   */
 +  public boolean checkForIdleTimeout() {
 +    if (isSocketClosed()) {
 +      return true;
 +    }
 +    if (isSocketInUse()) {
 +      return false;
 +    }
 +    boolean isIdle = !this.accessed;
 +    this.accessed = false;
 +    if (isIdle) {
 +      this.timedOut = true;
 +      this.owner.getConduit().stats.incLostLease();
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Closing idle connection {} shared={} ordered={}", this, this.sharedResource, this.preserveOrder);
 +      }
 +      try {
 +        // Instead of calling requestClose
 +        // we call closeForReconnect.
 +        // We don't want this timeout close to close
 +        // any other connections. The problem with
 +        // requestClose has removeEndpoint set to true
 +        // which will close an receivers we have if this
 +        // connection is a shared one.
 +        closeForReconnect(LocalizedStrings.Connection_IDLE_CONNECTION_TIMED_OUT.toLocalizedString());
 +      } catch (Exception ignore) {}
 +    }
 +    return isIdle;
 +  }
 +
 +  static private byte[] okHandshakeBytes;
 +  static private ByteBuffer okHandshakeBuf;
 +  static {
 +    int msglen = 1; // one byte for reply code
 +    byte[] bytes = new byte[MSG_HEADER_BYTES + msglen];
 +    msglen = calcHdrSize(msglen);
 +    bytes[MSG_HEADER_SIZE_OFFSET] = (byte)((msglen/0x1000000) & 0xff);
 +    bytes[MSG_HEADER_SIZE_OFFSET+1] = (byte)((msglen/0x10000) & 0xff);
 +    bytes[MSG_HEADER_SIZE_OFFSET+2] = (byte)((msglen/0x100) & 0xff);
 +    bytes[MSG_HEADER_SIZE_OFFSET+3] = (byte)(msglen & 0xff);
 +    bytes[MSG_HEADER_TYPE_OFFSET] = (byte)NORMAL_MSG_TYPE; // message type
 +    bytes[MSG_HEADER_ID_OFFSET] = (byte)((MsgIdGenerator.NO_MSG_ID/0x100) & 0xff);
 +    bytes[MSG_HEADER_ID_OFFSET+1] = (byte)(MsgIdGenerator.NO_MSG_ID & 0xff);
 +    bytes[MSG_HEADER_BYTES] = REPLY_CODE_OK;
 +    int allocSize = bytes.length;
 +    ByteBuffer bb;
 +    if (TCPConduit.useDirectBuffers) {
 +      bb = ByteBuffer.allocateDirect(allocSize);
 +    } else {
 +      bb = ByteBuffer.allocate(allocSize);
 +    }
 +    bb.put(bytes);
 +    okHandshakeBuf = bb;
 +    okHandshakeBytes = bytes;
 +  }
 +
 +  /**
 +   * maximum message buffer size
 +   */
 +  public static final int MAX_MSG_SIZE = 0x00ffffff;
 +  public static int calcHdrSize(int byteSize) {
 +    if (byteSize > MAX_MSG_SIZE) {
 +      throw new IllegalStateException(LocalizedStrings.Connection_TCP_MESSAGE_EXCEEDED_MAX_SIZE_OF_0.toLocalizedString(Integer.valueOf(MAX_MSG_SIZE)));
 +    }
 +    int hdrSize = byteSize;
 +    hdrSize |= (HANDSHAKE_VERSION << 24);
 +    return hdrSize;
 +  }
 +  public static int calcMsgByteSize(int hdrSize) {
 +    return hdrSize & MAX_MSG_SIZE;
 +  }
 +  public static byte calcHdrVersion(int hdrSize) throws IOException {
 +    byte ver = (byte)(hdrSize >> 24);
 +    if (ver != HANDSHAKE_VERSION) {
 +      throw new IOException(LocalizedStrings.Connection_DETECTED_WRONG_VERSION_OF_GEMFIRE_PRODUCT_DURING_HANDSHAKE_EXPECTED_0_BUT_FOUND_1.toLocalizedString(new Object[] {new Byte(HANDSHAKE_VERSION), new Byte(ver)}));
 +    }
 +    return ver;
 +  }
 +  private void sendOKHandshakeReply() throws IOException, ConnectionException {
 +    byte[] my_okHandshakeBytes = null;
 +    ByteBuffer my_okHandshakeBuf = null;
 +    if (this.isReceiver) {
 +      DistributionConfig cfg = owner.getConduit().config;
 +      ByteBuffer bb;
 +      if (useNIO() && TCPConduit.useDirectBuffers) {
 +        bb = ByteBuffer.allocateDirect(128);
 +      } else {
 +        bb = ByteBuffer.allocate(128);
 +      }
 +      bb.putInt(0); // reserve first 4 bytes for packet length
 +      bb.put((byte)NORMAL_MSG_TYPE);
 +      bb.putShort(MsgIdGenerator.NO_MSG_ID);
 +      bb.put(REPLY_CODE_OK_WITH_ASYNC_INFO);
 +      bb.putInt(cfg.getAsyncDistributionTimeout());
 +      bb.putInt(cfg.getAsyncQueueTimeout());
 +      bb.putInt(cfg.getAsyncMaxQueueSize());
 +      // write own product version
 +      Version.writeOrdinal(bb, Version.CURRENT.ordinal(), true);
 +      // now set the msg length into position 0
 +      bb.putInt(0, calcHdrSize(bb.position()-MSG_HEADER_BYTES));
 +      if (useNIO()) {
 +        my_okHandshakeBuf = bb;
 +        bb.flip();
 +      } else {
 +        my_okHandshakeBytes = new byte[bb.position()];
 +        bb.flip();
 +        bb.get(my_okHandshakeBytes);
 +      }
 +    } else {
 +      my_okHandshakeBuf = okHandshakeBuf;
 +      my_okHandshakeBytes = okHandshakeBytes;
 +    }
 +    if (useNIO()) {
 +      synchronized (my_okHandshakeBuf) {
 +        my_okHandshakeBuf.position(0);
 +        nioWriteFully(getSocket().getChannel(), my_okHandshakeBuf, false, null);
 +      }
 +    } else {
 +      synchronized(outLock) {
 +        try {
 +//          this.writerThread = Thread.currentThread();
 +          this.output.write(my_okHandshakeBytes, 0, my_okHandshakeBytes.length);
 +          this.output.flush();
 +        }
 +        finally {
 +//          this.writerThread = null;
 +        }
 +      }
 +    }
 +  }
 +
 +  private static final int HANDSHAKE_TIMEOUT_MS = Integer.getInteger("p2p.handshakeTimeoutMs", 59000).intValue();
 +  //private static final byte HANDSHAKE_VERSION = 1; // 501
 +  //public static final byte HANDSHAKE_VERSION = 2; // cbb5x_PerfScale
 +  //public static final byte HANDSHAKE_VERSION = 3; // durable_client
 +  //public static final byte HANDSHAKE_VERSION = 4; // dataSerialMay19
 +//  public static final byte HANDSHAKE_VERSION = 5; // split-brain bits
 +  //public static final byte HANDSHAKE_VERSION = 6; // direct ack changes
 +  // NOTICE: handshake_version should not be changed anymore.  Use the gemfire
 +  //         version transmitted with the handshake bits and handle old handshakes
 +  //         based on that
 +  public static final byte HANDSHAKE_VERSION = 7; // product version exchange during handshake
 +
 +  /**
 +   * @throws ConnectionException if the conduit has stopped
 +   */
 +  private void waitForHandshake() throws ConnectionException {
 +    boolean needToClose = false;
 +    String reason = null;
 +    try {
 +    synchronized (this.handshakeSync) {
 +      if (!this.handshakeRead && !this.handshakeCancelled) {
 +        boolean success = false;
 +        reason = LocalizedStrings.Connection_UNKNOWN.toLocalizedString();
 +        boolean interrupted = Thread.interrupted();
 +        try {
 +          final long endTime = System.currentTimeMillis() + HANDSHAKE_TIMEOUT_MS;
 +          long msToWait = HANDSHAKE_TIMEOUT_MS;
 +          while (!this.handshakeRead && !this.handshakeCancelled && msToWait > 0) {
 +            this.handshakeSync.wait(msToWait); // spurious wakeup ok
 +            if (!this.handshakeRead && !this.handshakeCancelled) {
 +              msToWait = endTime - System.currentTimeMillis();
 +            }
 +          }
 +          if (!this.handshakeRead && !this.handshakeCancelled) {
 +            reason = LocalizedStrings.Connection_HANDSHAKE_TIMED_OUT.toLocalizedString();
 +            String peerName;
 +            if (this.remoteAddr != null) {
 +              peerName = this.remoteAddr.toString();
 +              // late in the life of jdk 1.7 we started seeing connections accepted
 +              // when accept() was not even being called.  This started causing timeouts
 +              // to occur in the handshake threads instead of causing failures in
 +              // connection-formation.  So, we need to initiate suspect processing here
 +              owner.getDM().getMembershipManager().suspectMember(this.remoteAddr,
 +                  LocalizedStrings.Connection_CONNECTION_HANDSHAKE_WITH_0_TIMED_OUT_AFTER_WAITING_1_MILLISECONDS.toLocalizedString(
 +                      new Object[] {peerName, Integer.valueOf(HANDSHAKE_TIMEOUT_MS)}));
 +            }
 +            else {
 +              peerName = "socket " + this.socket.getRemoteSocketAddress().toString()
 +                  + ":" + this.socket.getPort();
 +            }
 +            throw new ConnectionException(LocalizedStrings.Connection_CONNECTION_HANDSHAKE_WITH_0_TIMED_OUT_AFTER_WAITING_1_MILLISECONDS.toLocalizedString(
 +                  new Object[] {peerName, Integer.valueOf(HANDSHAKE_TIMEOUT_MS)}));
 +          } else {
 +            success = this.handshakeRead;
 +          }
 +        } catch (InterruptedException ex) {
 +          interrupted = true;
 +          this.owner.getConduit().getCancelCriterion().checkCancelInProgress(ex);
 +          reason = LocalizedStrings.Connection_INTERRUPTED.toLocalizedString();
 +        } finally {
 +          if (interrupted) {
 +            Thread.currentThread().interrupt();
 +          }
 +          if (success) {
 +            if (this.isReceiver) {
 +              needToClose = !owner.getConduit().getMembershipManager().addSurpriseMember(this.remoteAddr);
 +              if (needToClose) {
 +                reason = "this member is shunned";
 +              }
 +            }
 +          }
 +          else {
 +            needToClose = true; // for bug 42159
 +          }
 +        }
 +      } // !handshakeRead
 +    } // synchronized
 +
 +    } finally {
 +      if (needToClose) {
 +        // moved this call outside of the sync for bug 42159
 +        try {
 +          requestClose(reason); // fix for bug 31546
 +        } 
 +        catch (Exception ignore) {
 +        }
 +      }
 +    }
 +  }
 +
 +  private void notifyHandshakeWaiter(boolean success) {
 +    synchronized (this.handshakeSync) {
 +      if (success) {
 +        this.handshakeRead = true;
 +      } else {
 +        this.handshakeCancelled = true;
 +      }
 +      this.handshakeSync.notify();
 +    }
 +  }
 +  
 +  private final AtomicBoolean asyncCloseCalled = new AtomicBoolean();
 +  
 +  /**
 +   * asynchronously close this connection
 +   * 
 +   * @param beingSick
 +   */
 +  private void asyncClose(boolean beingSick) {
 +    // note: remoteAddr may be null if this is a receiver that hasn't finished its handshake
 +    
 +    // we do the close in a background thread because the operation may hang if 
 +    // there is a problem with the network.  See bug #46659
 +
 +    // if simulating sickness, sockets must be closed in-line so that tests know
 +    // that the vm is sick when the beSick operation completes
 +    if (beingSick) {
 +      prepareForAsyncClose();
 +    }
 +    else {
 +      if (this.asyncCloseCalled.compareAndSet(false, true)) {
 +        Socket s = this.socket;
 +        if (s != null && !s.isClosed()) {
 +          prepareForAsyncClose();
 +          this.owner.getSocketCloser().asyncClose(s, String.valueOf(this.remoteAddr), null);
 +        }
 +      }
 +    }
 +  }
 +  
 +  private void prepareForAsyncClose() {
 +    synchronized(stateLock) {
 +      if (readerThread != null && isRunning && !readerShuttingDown
 +          && (connectionState == STATE_READING || connectionState == STATE_READING_ACK)) {
 +        readerThread.interrupt();
 +      }
 +    }
 +  }
 +
 +  private static final int CONNECT_HANDSHAKE_SIZE = 4096;
 +
 +  /**
 +   * waits until we've joined the distributed system
 +   * before returning
 +   */
 +  private void waitForAddressCompletion() {
 +    InternalDistributedMember myAddr = this.owner.getConduit().getLocalAddress();
 +    synchronized (myAddr) {
 +      while ((owner.getConduit().getCancelCriterion().cancelInProgress() == null)
 +          && myAddr.getInetAddress() == null && myAddr.getVmViewId() < 0) {
 +        try {
 +          myAddr.wait(100); // spurious wakeup ok
 +        }
 +        catch (InterruptedException ie) {
 +          Thread.currentThread().interrupt();
 +          this.owner.getConduit().getCancelCriterion().checkCancelInProgress(ie);
 +        }
 +      }
 +      Assert.assertTrue(myAddr.getDirectChannelPort() == this.owner.getConduit().getPort());
 +    }
 +  }
 +
 +  private void handshakeNio() throws IOException {
 +    waitForAddressCompletion();
 +    
 +    InternalDistributedMember myAddr = this.owner.getConduit().getLocalAddress();
 +    final MsgOutputStream connectHandshake
 +      = new MsgOutputStream(CONNECT_HANDSHAKE_SIZE);
 +    //connectHandshake.reset();
 +    /**
 +     * Note a byte of zero is always written because old products
 +     * serialized a member id with always sends an ip address.
 +     * My reading of the ip-address specs indicated that the first byte
 +     * of a valid address would never be 0.
 +     */
 +    connectHandshake.writeByte(0);
 +    connectHandshake.writeByte(HANDSHAKE_VERSION);
 +    // NOTE: if you add or remove code in this section bump HANDSHAKE_VERSION
 +    InternalDataSerializer.invokeToData(myAddr, connectHandshake);
 +    connectHandshake.writeBoolean(this.sharedResource);
 +    connectHandshake.writeBoolean(this.preserveOrder);
 +    connectHandshake.writeLong(this.uniqueId);
 +    // write the product version ordinal
 +    Version.CURRENT.writeOrdinal(connectHandshake, true);
 +    connectHandshake.writeInt(dominoCount.get()+1);
 +// this writes the sending member + thread name that is stored in senderName
 +// on the receiver to show the cause of reader thread creation
 +//    if (dominoCount.get() > 0) {
 +//      connectHandshake.writeUTF(Thread.currentThread().getName());
 +//    } else {
 +//      String name = owner.getDM().getConfig().getName();
 +//      if (name == null) {
 +//        name = "pid="+OSProcess.getId();
 +//      }
 +//      connectHandshake.writeUTF("["+name+"] "+Thread.currentThread().getName());
 +//    }
 +    connectHandshake.setMessageHeader(NORMAL_MSG_TYPE, DistributionManager.STANDARD_EXECUTOR, MsgIdGenerator.NO_MSG_ID);
 +    nioWriteFully(getSocket().getChannel(), connectHandshake.getContentBuffer(), false, null);
 +  }
 +
 +  private void handshakeStream() throws IOException {
 +    waitForAddressCompletion();
 +
 +    //this.output = new BufferedOutputStream(getSocket().getOutputStream(), owner.getConduit().bufferSize);
 +    this.output = getSocket().getOutputStream();
 +    ByteArrayOutputStream baos = new ByteArrayOutputStream(CONNECT_HANDSHAKE_SIZE);
 +    DataOutputStream os = new DataOutputStream(baos);
 +    InternalDistributedMember myAddr = owner.getConduit().getLocalAddress();
 +    os.writeByte(0);
 +    os.writeByte(HANDSHAKE_VERSION);
 +    // NOTE: if you add or remove code in this section bump HANDSHAKE_VERSION
 +    InternalDataSerializer.invokeToData(myAddr, os);
 +    os.writeBoolean(this.sharedResource);
 +    os.writeBoolean(this.preserveOrder);
 +    os.writeLong(this.uniqueId);
 +    Version.CURRENT.writeOrdinal(os, true);
 +    os.writeInt(dominoCount.get()+1);
 + // this writes the sending member + thread name that is stored in senderName
 + // on the receiver to show the cause of reader thread creation
 +//    if (dominoCount.get() > 0) {
 +//      os.writeUTF(Thread.currentThread().getName());
 +//    } else {
 +//      String name = owner.getDM().getConfig().getName();
 +//      if (name == null) {
 +//        name = "pid="+OSProcess.getId();
 +//      }
 +//      os.writeUTF("["+name+"] "+Thread.currentThread().getName());
 +//    }
 +    os.flush();
 +
 +    byte[] msg = baos.toByteArray();
 +    int len = calcHdrSize(msg.length);
 +    byte[] lenbytes = new byte[MSG_HEADER_BYTES];
 +    lenbytes[MSG_HEADER_SIZE_OFFSET] = (byte)((len/0x1000000) & 0xff);
 +    lenbytes[MSG_HEADER_SIZE_OFFSET+1] = (byte)((len/0x10000) & 0xff);
 +    lenbytes[MSG_HEADER_SIZE_OFFSET+2] = (byte)((len/0x100) & 0xff);
 +    lenbytes[MSG_HEADER_SIZE_OFFSET+3] = (byte)(len & 0xff);
 +    lenbytes[MSG_HEADER_TYPE_OFFSET] = (byte)NORMAL_MSG_TYPE;
 +    lenbytes[MSG_HEADER_ID_OFFSET] = (byte)((MsgIdGenerator.NO_MSG_ID/0x100) & 0xff);
 +    lenbytes[MSG_HEADER_ID_OFFSET+1] = (byte)(MsgIdGenerator.NO_MSG_ID & 0xff);
 +    synchronized(outLock) {
 +      try {
 +//        this.writerThread = Thread.currentThread();
 +        this.output.write(lenbytes, 0, lenbytes.length);
 +        this.output.write(msg, 0, msg.length);
 +        this.output.flush();
 +      }
 +      finally {
 +//        this.writerThread = null;
 +      }
 +    }
 +  }
 +
 +  /**
 +   *
 +   * @throws IOException if handshake fails
 +   */
 +  private void attemptHandshake(ConnectionTable connTable) throws IOException {
 +    // send HANDSHAKE
 +    // send this server's port.  It's expected on the other side
 +    if (useNIO()) {
 +      handshakeNio();
 +    }
 +    else {
 +      handshakeStream();
 +    }
 +
 +    startReader(connTable); // this reader only reads the handshake and then exits
 +    waitForHandshake(); // waiting for reply
 +  }
 +
 +  /** time between connection attempts*/
 +  private static final int RECONNECT_WAIT_TIME
 +    = Integer.getInteger("gemfire.RECONNECT_WAIT_TIME", 2000).intValue();
 +
 +  /** creates a new connection to a remote server.
 +   *  We are initiating this connection; the other side must accept us
 +   *  We will almost always send messages; small acks are received.
 +   */
 +  protected static Connection createSender(final MembershipManager mgr,
 +                                           final ConnectionTable t,
 +                                           final boolean preserveOrder,
 +                                           final DistributedMember remoteAddr,
 +                                           final boolean sharedResource,
 +                                           final long startTime,
 +                                           final long ackTimeout,
 +                                           final long ackSATimeout)
 +    throws IOException, DistributedSystemDisconnectedException
 +  {
 +    boolean warningPrinted = false;
 +    boolean success = false;
 +    boolean firstTime = true;
 +    Connection conn = null;
 +    // keep trying.  Note that this may be executing during the shutdown window
 +    // where a cancel criterion has not been established, but threads are being
 +    // interrupted.  In this case we must allow the connection to succeed even
 +    // though subsequent messaging using the socket may fail
 +    boolean interrupted = Thread.interrupted();
 +    boolean severeAlertIssued = false;
 +    boolean suspected = false;
 +    long reconnectWaitTime = RECONNECT_WAIT_TIME;
 +    boolean connectionErrorLogged = false;
 +    try {
 +      while (!success) { // keep trying
 +        // Quit if DM has stopped distribution
 +        t.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +        long now = System.currentTimeMillis();
 +        if (!severeAlertIssued && ackSATimeout > 0  &&  startTime + ackTimeout < now) {
 +          if (startTime + ackTimeout + ackSATimeout < now) {
 +            if (remoteAddr != null) {
 +              logger.fatal(LocalizedMessage.create(
 +                  LocalizedStrings.Connection_UNABLE_TO_FORM_A_TCPIP_CONNECTION_TO_0_IN_OVER_1_SECONDS, new Object[] { remoteAddr,
 +                  (ackSATimeout + ackTimeout) / 1000 }));
 +            }
 +            severeAlertIssued = true;
 +          }
 +          else if (!suspected) {
 +            if (remoteAddr != null) {
 +              logger.warn(LocalizedMessage.create(
 +                  LocalizedStrings.Connection_UNABLE_TO_FORM_A_TCPIP_CONNECTION_TO_0_IN_OVER_1_SECONDS,
 +                  new Object[] { remoteAddr, (ackTimeout)/1000 }));
 +            }
 +            mgr.suspectMember(remoteAddr, LocalizedStrings.Connection_UNABLE_TO_FORM_A_TCPIP_CONNECTION_IN_A_REASONABLE_AMOUNT_OF_TIME.toLocalizedString());
 +            suspected = true;
 +          }
 +          reconnectWaitTime = Math.min(RECONNECT_WAIT_TIME,
 +              ackSATimeout - (now - startTime - ackTimeout));
 +          if (reconnectWaitTime <= 0) {
 +            reconnectWaitTime = RECONNECT_WAIT_TIME;
 +          }
 +        } else if (!suspected && (startTime > 0) && (ackTimeout > 0)
 +            && (startTime + ackTimeout < now)) {
 +          mgr.suspectMember(remoteAddr, LocalizedStrings.Connection_UNABLE_TO_FORM_A_TCPIP_CONNECTION_IN_A_REASONABLE_AMOUNT_OF_TIME.toLocalizedString());
 +          suspected = true;
 +        }
 +        if (firstTime) {
 +          firstTime = false;
 +          if (!mgr.memberExists(remoteAddr) || mgr.isShunned(remoteAddr) || mgr.shutdownInProgress()) {
 +            throw new IOException("Member " + remoteAddr + " left the system");
 +          }
 +        }
 +        else {
 +          // if we're sending an alert and can't connect, bail out.  A sick
 +          // alert listener should not prevent cache operations from continuing
 +          if (AlertAppender.isThreadAlerting()) {
 +            // do not change the text of this exception - it is looked for in exception handlers
 +            throw new IOException("Cannot form connection to alert listener " + remoteAddr);
 +          }
 +            
 +          // Wait briefly...
 +          interrupted = Thread.interrupted() || interrupted;
 +          try {
 +            Thread.sleep(reconnectWaitTime);
 +          }
 +          catch (InterruptedException ie) {
 +            interrupted = true;
 +            t.getConduit().getCancelCriterion().checkCancelInProgress(ie);
 +          }
 +          t.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +          if (giveUpOnMember(mgr, remoteAddr)) {
 +            throw new IOException(LocalizedStrings.Connection_MEMBER_LEFT_THE_GROUP.toLocalizedString(remoteAddr));
 +          }
 +          if (!warningPrinted) {
 +            warningPrinted = true;
 +            logger.warn(LocalizedMessage.create(LocalizedStrings.Connection_CONNECTION_ATTEMPTING_RECONNECT_TO_PEER__0, remoteAddr));
 +          }          
 +          t.getConduit().stats.incReconnectAttempts();
 +        }
 +        //create connection
 +        try {
 +          conn = null;
 +          conn = new Connection(mgr, t, preserveOrder, remoteAddr, sharedResource);
 +        }
 +        catch (javax.net.ssl.SSLHandshakeException se) {
 +          // no need to retry if certificates were rejected
 +          throw se;
 +        }
 +        catch (IOException ioe) {
 +          // Only give up if the member leaves the view.
 +          if (giveUpOnMember(mgr, remoteAddr)) {
 +            throw ioe;
 +          }
 +          t.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +          if ("Too many open files".equals(ioe.getMessage())) {
 +            t.fileDescriptorsExhausted();
 +          }
 +          else if (!connectionErrorLogged) {
 +            connectionErrorLogged = true; // otherwise change to use 100ms intervals causes a lot of these
 +            logger.info(LocalizedMessage.create(
 +                LocalizedStrings.Connection_CONNECTION_FAILED_TO_CONNECT_TO_PEER_0_BECAUSE_1,
 +                new Object[] {sharedResource, preserveOrder, remoteAddr, ioe}));
 +          }
 +        } // IOException
 +        finally {
 +          if (conn == null) {
 +            t.getConduit().stats.incFailedConnect();
 +          }
 +        }
 +        if (conn != null) {
 +          // handshake
 +          try {
 +            conn.attemptHandshake(t);
 +            if (conn.isSocketClosed()) {
 +              // something went wrong while reading the handshake
 +              // and the socket was closed or this guy sent us a
 +              // ShutdownMessage
 +              if (giveUpOnMember(mgr, remoteAddr)) {
 +                throw new IOException(LocalizedStrings.Connection_MEMBER_LEFT_THE_GROUP.toLocalizedString(remoteAddr));
 +              }
 +              t.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +              // no success but no need to log; just retry
 +            }
 +            else {
 +              success = true;
 +            }
 +          }
 +          catch (DistributedSystemDisconnectedException e) {
 +            throw e;
 +          }
 +          catch (ConnectionException e) {
 +            if (giveUpOnMember(mgr, remoteAddr)) {
 +              IOException ioe = new IOException(LocalizedStrings.Connection_HANDSHAKE_FAILED.toLocalizedString());
 +              ioe.initCause(e);
 +              throw ioe;
 +            }
 +            t.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +            logger.info(LocalizedMessage.create(
 +                LocalizedStrings.Connection_CONNECTION_HANDSHAKE_FAILED_TO_CONNECT_TO_PEER_0_BECAUSE_1,
 +                new Object[] {sharedResource, preserveOrder, remoteAddr ,e}));
 +          }
 +          catch (IOException e) {
 +            if (giveUpOnMember(mgr, remoteAddr)) {
 +              throw e;
 +            }
 +            t.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +            logger.info(LocalizedMessage.create(
 +                LocalizedStrings.Connection_CONNECTION_HANDSHAKE_FAILED_TO_CONNECT_TO_PEER_0_BECAUSE_1,
 +                new Object[] {sharedResource, preserveOrder, remoteAddr ,e}));
 +            if (!sharedResource && "Too many open files".equals(e.getMessage())) {
 +              t.fileDescriptorsExhausted();
 +            }
 +          }
 +          finally {
 +            if (!success) {
 +              try {
 +                conn.requestClose(LocalizedStrings.Connection_FAILED_HANDSHAKE.toLocalizedString()); 
 +              } catch (Exception ignore) {}
 +              conn = null;
 +            }
 +          }
 +        }
 +      } // while
 +      if (warningPrinted) {
 +        logger.info(LocalizedMessage.create(
 +            LocalizedStrings.Connection_0_SUCCESSFULLY_REESTABLISHED_CONNECTION_TO_PEER_1,
 +            new Object[] {mgr.getLocalMember(), remoteAddr}));
 +      }
 +    }
 +    finally {
 +      try {
 +        if (!success) {
 +          if (conn != null) {
 +            conn.requestClose(LocalizedStrings.Connection_FAILED_CONSTRUCTION.toLocalizedString());
 +            conn = null;
 +          }
 +        }
 +      }
 +      finally {
 +        if (interrupted) {
 +          Thread.currentThread().interrupt();
 +        }
 +      }
 +    }
 +    //Assert.assertTrue(conn != null);
 +    if (conn == null) {
 +      throw new ConnectionException(
 +        LocalizedStrings.Connection_CONNECTION_FAILED_CONSTRUCTION_FOR_PEER_0
 +          .toLocalizedString(remoteAddr));
 +    }
 +    if (preserveOrder && BATCH_SENDS) {
 +      conn.createBatchSendBuffer();
 +    }
 +    conn.finishedConnecting = true;
 +    return conn;
 +  }
 +  
 +  private static boolean giveUpOnMember(MembershipManager mgr, DistributedMember remoteAddr) {
 +    return !mgr.memberExists(remoteAddr) || mgr.isShunned(remoteAddr) || mgr.shutdownInProgress();
 +  }
 +
 +  private void setRemoteAddr(DistributedMember m) {
 +    this.remoteAddr = this.owner.getDM().getCanonicalId(m);
 +    MembershipManager mgr = this.owner.owner.getMembershipManager();
 +    mgr.addSurpriseMember(m);
 +  }
 +  
 +  /** creates a new connection to a remote server.
 +   *  We are initiating this connection; the other side must accept us
 +   *  We will almost always send messages; small acks are received.
 +   */
 +  private Connection(MembershipManager mgr,
 +                     ConnectionTable t,
 +                     boolean preserveOrder,
 +                     DistributedMember remoteID,
 +                     boolean sharedResource)
 +    throws IOException, DistributedSystemDisconnectedException
 +  {    
 +    InternalDistributedMember remoteAddr = (InternalDistributedMember)remoteID;
 +    if (t == null) {
 +      throw new IllegalArgumentException(LocalizedStrings.Connection_CONNECTIONTABLE_IS_NULL.toLocalizedString());
 +    }
 +    this.isReceiver = false;
 +    this.owner = t;
 +    this.sharedResource = sharedResource;
 +    this.preserveOrder = preserveOrder;
 +    setRemoteAddr(remoteAddr);
 +    this.conduitIdStr = this.owner.getConduit().getId().toString();
 +    this.handshakeRead = false;
 +    this.handshakeCancelled = false;
 +    this.connected = true;
 +
 +    this.uniqueId = idCounter.getAndIncrement();
 +
 +    // connect to listening socket
 +
 +    InetSocketAddress addr = new InetSocketAddress(remoteAddr.getInetAddress(), remoteAddr.getDirectChannelPort());
 +    if (useNIO()) {
 +      SocketChannel channel = SocketChannel.open();
 +      this.owner.addConnectingSocket(channel.socket(), addr.getAddress());
 +      try {
 +        channel.socket().setTcpNoDelay(true);
 +
 +        channel.socket().setKeepAlive(SocketCreator.ENABLE_TCP_KEEP_ALIVE);
 +  
 +        /** If conserve-sockets is false, the socket can be used for receiving responses,
 +         * so set the receive buffer accordingly.
 +         */
 +        if(!sharedResource) {
 +          setReceiveBufferSize(channel.socket(), this.owner.getConduit().tcpBufferSize);
 +        } 
 +        else {
 +          setReceiveBufferSize(channel.socket(), SMALL_BUFFER_SIZE); // make small since only receive ack messages
 +        }
 +        setSendBufferSize(channel.socket());
 +        channel.configureBlocking(true);
 +
 +        int connectTime = getP2PConnectTimeout();; 
 +
 +        try {
 +          SocketUtils.connect(channel.socket(), addr, connectTime);
 +        } catch (NullPointerException e) {
 +          // bug #45044 - jdk 1.7 sometimes throws an NPE here
 +          ConnectException c = new ConnectException("Encountered bug #45044 - retrying");
 +          c.initCause(e);
 +          // prevent a hot loop by sleeping a little bit
 +          try {
 +            Thread.sleep(1000);
 +          } catch (InterruptedException ie) {
 +            Thread.currentThread().interrupt();
 +          }
 +          throw c;
 +        } catch (CancelledKeyException e) {
 +          // bug #44469: for some reason NIO throws this runtime exception
 +          //             instead of an IOException on timeouts
 +          ConnectException c = new ConnectException(LocalizedStrings.Connection_ATTEMPT_TO_CONNECT_TIMED_OUT_AFTER_0_MILLISECONDS
 +              .toLocalizedString(new Object[]{connectTime}));
 +          c.initCause(e);
 +          throw c;
 +        } catch (ClosedSelectorException e) {
 +          // bug #44808: for some reason JRockit NIO thorws this runtime exception
 +          //             instead of an IOException on timeouts
 +          ConnectException c = new ConnectException(LocalizedStrings.Connection_ATTEMPT_TO_CONNECT_TIMED_OUT_AFTER_0_MILLISECONDS
 +              .toLocalizedString(new Object[]{connectTime}));
 +          c.initCause(e);
 +          throw c;
 +        }
 +      }
 +      finally {
 +        this.owner.removeConnectingSocket(channel.socket());
 +      }
 +      this.socket = channel.socket();
 +    }
 +    else {
 +      if (TCPConduit.useSSL) {
 +        // socket = javax.net.ssl.SSLSocketFactory.getDefault()
 +        //  .createSocket(remoteAddr.getInetAddress(), remoteAddr.getPort());
 +        int socketBufferSize = sharedResource ? SMALL_BUFFER_SIZE : this.owner.getConduit().tcpBufferSize;
 +        this.socket = SocketCreator.getDefaultInstance().connectForServer( remoteAddr.getInetAddress(), remoteAddr.getDirectChannelPort(), socketBufferSize );
 +        // Set the receive buffer size local fields. It has already been set in the socket.
 +        setSocketBufferSize(this.socket, false, socketBufferSize, true);
 +        setSendBufferSize(this.socket);
 +      }
 +      else {
 +        //socket = new Socket(remoteAddr.getInetAddress(), remoteAddr.getPort());
 +        Socket s = new Socket();
 +        this.socket = s;
 +        s.setTcpNoDelay(true);
 +        s.setKeepAlive(SocketCreator.ENABLE_TCP_KEEP_ALIVE);
 +        setReceiveBufferSize(s, SMALL_BUFFER_SIZE);
 +        setSendBufferSize(s);
 +        SocketUtils.connect(s, addr, 0);
 +      }
 +    }
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Connection: connected to {} with stub {}", remoteAddr, addr);
 +    }
 +    try { getSocket().setTcpNoDelay(true); } catch (SocketException e) {  }
 +  }
 +
 +  /**
 +   * Batch sends currently should not be turned on because:
 +   *  1. They will be used for all sends (instead of just no-ack)
 +   *     and thus will break messages that wait for a response (or kill perf).
 +   *  2. The buffer is not properly flushed and closed on shutdown.
 +   *     The code attempts to do this but must not be doing it  correctly.
 +   */
 +  private static final boolean BATCH_SENDS = Boolean.getBoolean("p2p.batchSends");
 +  protected static final int BATCH_BUFFER_SIZE = Integer.getInteger("p2p.batchBufferSize", 1024*1024).intValue();
 +  protected static final int BATCH_FLUSH_MS = Integer.getInteger("p2p.batchFlushTime", 50).intValue();
 +  protected Object batchLock;
 +  protected ByteBuffer fillBatchBuffer;
 +  protected ByteBuffer sendBatchBuffer;
 +  private BatchBufferFlusher batchFlusher;
 +
 +  private void createBatchSendBuffer() {
 +    // batch send buffer isn't needed if old-io is being used
 +    if (!this.useNIO) {
 +      return;
 +    }
 +    this.batchLock = new Object();
 +    if (TCPConduit.useDirectBuffers) {
 +      this.fillBatchBuffer = ByteBuffer.allocateDirect(BATCH_BUFFER_SIZE);
 +      this.sendBatchBuffer = ByteBuffer.allocateDirect(BATCH_BUFFER_SIZE);
 +    } else {
 +      this.fillBatchBuffer = ByteBuffer.allocate(BATCH_BUFFER_SIZE);
 +      this.sendBatchBuffer = ByteBuffer.allocate(BATCH_BUFFER_SIZE);
 +    }
 +    this.batchFlusher = new BatchBufferFlusher();
 +    this.batchFlusher.start();
 +  }
 +
 +  private class BatchBufferFlusher extends Thread  {
 +    private volatile boolean flushNeeded = false;
 +    private volatile boolean timeToStop = false;
 +    private DMStats stats;
 +
 +
 +    public BatchBufferFlusher() {
 +      setDaemon(true);
 +      this.stats = owner.getConduit().stats;
 +    }
 +    /**
 +     * Called when a message writer needs the current fillBatchBuffer flushed
 +     */
 +    public void flushBuffer(ByteBuffer bb) {
 +      final long start = DistributionStats.getStatTime();
 +      try {
 +        synchronized (this) {
 +          synchronized (batchLock) {
 +            if (bb != fillBatchBuffer) {
 +              // it must have already been flushed. So just return
 +              // and use the new fillBatchBuffer
 +              return;
 +            }
 +          }
 +          this.flushNeeded = true;
 +          this.notify();
 +        }
 +        synchronized (batchLock) {
 +          // Wait for the flusher thread
 +          while (bb == fillBatchBuffer) {
 +            Connection.this.owner.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +            boolean interrupted = Thread.interrupted();
 +            try {
 +              batchLock.wait();  // spurious wakeup ok
 +            } 
 +            catch (InterruptedException ex) {
 +              interrupted = true;
 +            }
 +            finally {
 +              if (interrupted) {
 +                Thread.currentThread().interrupt();
 +              }
 +            }
 +          } // while
 +        }
 +      } finally {
 +        owner.getConduit().stats.incBatchWaitTime(start);
 +      }
 +    }
 +
 +    public void close() {
 +      synchronized (this) {
 +        this.timeToStop = true;
 +        this.flushNeeded = true;
 +        this.notify();
 +      }
 +    }
 +
 +    @Override
 +    public void run() {
 +      try {
 +        synchronized (this) {
 +          while (!timeToStop) {
 +            if (!this.flushNeeded && fillBatchBuffer.position() <= (BATCH_BUFFER_SIZE/2)) {
 +              wait(BATCH_FLUSH_MS); // spurious wakeup ok
 +            }
 +            if (this.flushNeeded || fillBatchBuffer.position() > (BATCH_BUFFER_SIZE/2)) {
 +              final long start = DistributionStats.getStatTime();
 +              synchronized (batchLock) {
 +                // This is the only block of code that will swap
 +                // the buffer references
 +                this.flushNeeded = false;
 +                ByteBuffer tmp = fillBatchBuffer;
 +                fillBatchBuffer = sendBatchBuffer;
 +                sendBatchBuffer = tmp;
 +                batchLock.notifyAll();
 +              }
 +              // We now own the sendBatchBuffer
 +              if (sendBatchBuffer.position() > 0) {
 +                final boolean origSocketInUse = socketInUse;
 +                socketInUse = true;
 +                try {
 +                  sendBatchBuffer.flip();
 +                  SocketChannel channel = getSocket().getChannel();
 +                  nioWriteFully(channel, sendBatchBuffer, false, null);
 +                  sendBatchBuffer.clear();
 +                } catch (IOException ex) {
 +                  logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_EXCEPTION_FLUSHING_BATCH_SEND_BUFFER_0,ex));
 +                  readerShuttingDown = true;
 +                  requestClose(LocalizedStrings.Connection_EXCEPTION_FLUSHING_BATCH_SEND_BUFFER_0.toLocalizedString(ex));
 +                } catch (ConnectionException ex) {
 +                  logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_EXCEPTION_FLUSHING_BATCH_SEND_BUFFER_0,ex));
 +                  readerShuttingDown = true;
 +                  requestClose(LocalizedStrings.Connection_EXCEPTION_FLUSHING_BATCH_SEND_BUFFER_0.toLocalizedString(ex));
 +                } finally {
 +                  accessed();
 +                  socketInUse = origSocketInUse;
 +                }
 +              }
 +              this.stats.incBatchFlushTime(start);
 +            }
 +          }
 +        }
 +      } catch (InterruptedException ex) {
 +        // time for this thread to shutdown
 +//        Thread.currentThread().interrupt();
 +      }
 +    }
 +  }
 +
 +  private void closeBatchBuffer() {
 +    if (this.batchFlusher != null) {
 +      this.batchFlusher.close();
 +    }
 +  }
 +
 +  /** use to test message prep overhead (no socket write).
 +   * WARNING: turning this on completely disables distribution of batched sends
 +   */
 +  private static final boolean SOCKET_WRITE_DISABLED = Boolean.getBoolean("p2p.disableSocketWrite");
 +
 +  private void batchSend(ByteBuffer src) throws IOException {
 +    if (SOCKET_WRITE_DISABLED) {
 +      return;
 +    }
 +    final long start = DistributionStats.getStatTime();
 +    try {
 +      ByteBuffer dst = null;
 +      Assert.assertTrue(src.remaining() <= BATCH_BUFFER_SIZE , "Message size(" + src.remaining() + ") exceeded BATCH_BUFFER_SIZE(" + BATCH_BUFFER_SIZE + ")");
 +      do {
 +        synchronized (this.batchLock) {
 +          dst = this.fillBatchBuffer;
 +          if (src.remaining() <= dst.remaining()) {
 +            final long copyStart = DistributionStats.getStatTime();
 +            dst.put(src);
 +            this.owner.getConduit().stats.incBatchCopyTime(copyStart);
 +            return;
 +          }
 +        }
 +        // If we got this far then we do not have room in the current
 +        // buffer and need the flusher thread to flush before we can fill it
 +        this.batchFlusher.flushBuffer(dst);
 +      } while (true);
 +    } finally {
 +      this.owner.getConduit().stats.incBatchSendTime(start);
 +    }
 +  }
 +
 +  /**
 +   * Request that the manager close this connection, or close it
 +   * forcibly if there is no manager.  Invoking this method ensures
 +   * that the proper synchronization is done.
 +   */
 +  void requestClose(String reason) {
 +    close(reason, true, true, false, false);
 +  }
 +
 +  boolean isClosing() {
 +    return this.closing.get();
 +  }
 +
 +  /**
 +   * Used to close a connection that has not yet been registered
 +   * with the distribution manager.
 +   */
 +  void closePartialConnect(String reason) {
 +    close(reason, false, false, false, false);
 +  }
 +  
 +  void closePartialConnect(String reason, boolean beingSick) {
 +    close(reason, false, false, beingSick, false);
 +  }
 +
 +  void closeForReconnect(String reason) {
 +    close(reason, true, false, false, false);
 +  }
 +
 +  void closeOldConnection(String reason) {
 +    close(reason, true, true, false, true);
 +  }
 +
 +  /**
 +   * Closes the connection.
 +   *
 +   * @see #requestClose
 +   */
 +  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="TLW_TWO_LOCK_WAIT")
 +  private void close(String reason, boolean cleanupEndpoint, 
 +      boolean p_removeEndpoint, boolean beingSick, boolean forceRemoval) {
 +    boolean removeEndpoint = p_removeEndpoint;
 +    // use getAndSet outside sync on this to fix 42330
 +    boolean onlyCleanup = this.closing.getAndSet(true);
 +    if (onlyCleanup && !forceRemoval) {
 +      return;
 +    }
 +    if (!onlyCleanup) {
 +    synchronized (this) {
 +      this.stopped = true;
 +      if (this.connected) {
 +        if (this.asyncQueuingInProgress
 +            && this.pusherThread != Thread.currentThread()) {
 +          // We don't need to do this if we are the pusher thread
 +          // and we have determined that we need to close the connection.
 +          // See bug 37601.
 +          synchronized (this.outgoingQueue) {
 +            // wait for the flusher to complete (it may timeout)
 +            while (this.asyncQueuingInProgress) {
 +              // Don't do this: causes closes to not get done in the event
 +              // of an orderly shutdown:
 +  //            this.owner.getConduit().getCancelCriterion().checkCancelInProgress(null);
 +              boolean interrupted = Thread.interrupted();
 +              try {
 +                this.outgoingQueue.wait(); // spurious wakeup ok
 +              } catch (InterruptedException ie) {
 +                interrupted = true;
 +  //                this.owner.getConduit().getCancelCriterion().checkCancelInProgress(ie);
 +              }
 +              finally {
 +                if (interrupted) Thread.currentThread().interrupt();
 +              }
 +            } // while
 +          } // synchronized
 +        }
 +        this.connected = false;
 +        closeSenderSem();
 +        {
 +          final DMStats stats = this.owner.getConduit().stats;
 +          if (this.finishedConnecting) {
 +            if (this.isReceiver) {
 +              stats.decReceivers();
 +            } else {
 +              stats.decSenders(this.sharedResource, this.preserveOrder);
 +            }
 +          }
 +        }
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Closing socket for {}", this);
 +        }
 +      }
 +        else if (!forceRemoval) {
 +        removeEndpoint = false;
 +      }
 +      // make sure our socket is closed
 +      asyncClose(false);
 +      nioLengthSet = false;
 +    } // synchronized
 +    
 +      // moved the call to notifyHandshakeWaiter out of the above
 +      // synchronized block to fix bug #42159
 +      // Make sure anyone waiting for a handshake stops waiting
 +      notifyHandshakeWaiter(false);
 +    // wait a bit for the our reader thread to exit
 +    // don't wait if we are the reader thread
 +    boolean isIBM = false;
 +    // if network partition detection is enabled or this is an admin vm
 +    // we can't wait for the reader thread when running in an IBM JRE.  See
 +    // bug 41889
 +    if (this.owner.owner.config.getEnableNetworkPartitionDetection() ||
 +        this.owner.owner.getLocalAddr().getVmKind() == DistributionManager.ADMIN_ONLY_DM_TYPE ||
 +        this.owner.owner.getLocalAddr().getVmKind() == DistributionManager.LOCATOR_DM_TYPE) {
 +      isIBM = "IBM Corporation".equals(System.getProperty("java.vm.vendor"));
 +    }
 +    {
 +      // Now that readerThread is returned to a pool after we close
 +      // we need to be more careful not to join on a thread that belongs
 +      // to someone else.
 +      Thread readerThreadSnapshot = this.readerThread;
 +      if (!beingSick && readerThreadSnapshot != null && !isIBM
 +          && this.isRunning && !this.readerShuttingDown
 +          && readerThreadSnapshot != Thread.currentThread()) {
 +        try {
 +          readerThreadSnapshot.join(500);
 +          readerThreadSnapshot = this.readerThread;
 +          if (this.isRunning && !this.readerShuttingDown
 +              && readerThreadSnapshot != null
 +              && owner.getDM().getRootCause() == null) { // don't wait twice if there's a system failure
 +            readerThreadSnapshot.join(1500);
 +            if (this.isRunning) {
 +              logger.info(LocalizedMessage.create(LocalizedStrings.Connection_TIMED_OUT_WAITING_FOR_READERTHREAD_ON_0_TO_FINISH, this));
 +            }
 +          }
 +        }
 +        catch (IllegalThreadStateException ignore) {
 +          // ignored - thread already stopped
 +        }
 +        catch (InterruptedException ignore) {
 +          Thread.currentThread().interrupt();
 +          // but keep going, we're trying to close.
 +        }
 +      }
 +    }
 +
 +    closeBatchBuffer();
 +    closeAllMsgDestreamers();
 +    }
 +    if (cleanupEndpoint) {
 +      if (this.isReceiver) {
 +        this.owner.removeReceiver(this);
 +      }
 +      if (removeEndpoint) {
 +        if (this.sharedResource) {
 +          if (!this.preserveOrder) {
 +            // only remove endpoint when shared unordered connection
 +            // is closed. This is part of the fix for bug 32980.
 +            if (!this.isReceiver) {
 +              // Only remove endpoint if sender.
 +              if (this.finishedConnecting) {
 +                // only remove endpoint if our constructor finished
 +                this.owner.removeEndpoint(this.remoteAddr, reason);
 +              }
 +            }
 +          }
 +          else {
 +            this.owner.removeSharedConnection(reason, this.remoteAddr, this.preserveOrder, this);
 +          }
 +        }
 +        else if (!this.isReceiver) {
 +          this.owner.removeThreadConnection(this.remoteAddr, this);
 +        }
 +      }
 +      else {
 +        // This code is ok to do even if the ConnectionTable
 +        // has never added this Connection to its maps since
 +        // the calls in this block use our identity to do the removes.
 +        if (this.sharedResource) {
 +          this.owner.removeSharedConnection(reason, this.remoteAddr, this.preserveOrder, this);
 +        }
 +        else if (!this.isReceiver) {
 +          this.owner.removeThreadConnection(this.remoteAddr, this);
 +        }
 +      }
 +    }
 +    
 +    //This cancels the idle timer task, but it also removes the tasks
 +    //reference to this connection, freeing up the connection (and it's buffers
 +    //for GC sooner.
 +    if(idleTask != null) {
 +      idleTask.cancel();
 +    }
 +    
 +    if(ackTimeoutTask!=null){
 +        ackTimeoutTask.cancel();
 +    }
 +
 +  }
 +
 +  /** starts a reader thread */
 +  private void startReader(ConnectionTable connTable) { 
 +    Assert.assertTrue(!this.isRunning); 
 +    stopped = false; 
 +    this.isRunning = true; 
 +    connTable.executeCommand(this);  
 +  } 
 +
 +
 +  /** in order to read non-NIO socket-based messages we need to have a thread
 +      actively trying to grab bytes out of the sockets input queue.
 +      This is that thread. */
 +  public void run() {
 +    this.readerThread = Thread.currentThread();
 +    this.readerThread.setName(p2pReaderName());
 +    ConnectionTable.threadWantsSharedResources();
 +    makeReaderThread(this.isReceiver);
 +    try {
 +      if (useNIO()) {
 +        runNioReader();
 +      } else {
 +        runOioReader();
 +      }
 +    } finally {
 +      // bug36060: do the socket close within a finally block
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Stopping {} for {}", p2pReaderName(), remoteAddr);
 +      }
 +      initiateSuspicionIfSharedUnordered();
 +      if (this.isReceiver) {
 +        if (!this.sharedResource) {
 +          this.owner.owner.stats.incThreadOwnedReceivers(-1L, dominoCount.get());
 +        }
 +        asyncClose(false);
 +        this.owner.removeAndCloseThreadOwnedSockets();
 +      }
 +      ByteBuffer tmp = this.nioInputBuffer;
 +      if(tmp != null) {
 +        this.nioInputBuffer = null;
 +        final DMStats stats = this.owner.getConduit().stats;
 +        Buffers.releaseReceiveBuffer(tmp, stats);
 +      }
 +      // make sure that if the reader thread exits we notify a thread waiting
 +      // for the handshake.
 +      // see bug 37524 for an example of listeners hung in waitForHandshake
 +      notifyHandshakeWaiter(false);
 +      this.readerThread.setName("unused p2p reader");
 +      synchronized (this.stateLock) {
 +        this.isRunning = false;
 +        this.readerThread = null;
 +      }
 +    } // finally
 +  }
 +
 +  private String p2pReaderName() {
 +    StringBuffer sb = new StringBuffer(64);
 +    if (this.isReceiver) {
 +      sb.append("P2P message reader@");
 +    } else {
 +      sb.append("P2P handshake reader@");
 +    }
 +    sb.append(Integer.toHexString(System.identityHashCode(this)));
 +    if (!this.isReceiver) {
 +      sb.append('-')
 +        .append(getUniqueId());
 +    }
 +    return sb.toString();
 +  }
 +
 +  private void runNioReader() {
 +    // take a snapshot of uniqueId to detect reconnect attempts; see bug 37592
 +    SocketChannel channel = null;
 +    try {
 +      channel = getSocket().getChannel();
 +      channel.configureBlocking(true);
 +    } catch (ClosedChannelException e) {
 +      // bug 37693: the channel was asynchronously closed.  Our work
 +      // is done.
 +      try { 
 +        requestClose(LocalizedStrings.Connection_RUNNIOREADER_CAUGHT_CLOSED_CHANNEL.toLocalizedString()); 
 +      } catch (Exception ignore) {}      
 +      return; // exit loop and thread
 +    } catch (IOException ex) {
 +      if (stopped || owner.getConduit().getCancelCriterion().cancelInProgress() != null) {
 +        try { 
 +          requestClose(LocalizedStrings.Connection_RUNNIOREADER_CAUGHT_SHUTDOWN.toLocalizedString());
 +        } catch (Exception ignore) {}
 +        return; // bug37520: exit loop (and thread)
 +      }
 +      logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_FAILED_SETTING_CHANNEL_TO_BLOCKING_MODE_0, ex));
 +      this.readerShuttingDown = true;
 +      try { requestClose(LocalizedStrings.Connection_FAILED_SETTING_CHANNEL_TO_BLOCKING_MODE_0.toLocalizedString(ex)); } catch (Exception ignore) {}
 +      return;
 +    }
 +
 +    if (!stopped) {
 +//      Assert.assertTrue(owner != null, "How did owner become null");
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Starting {}", p2pReaderName());
 +      }
 +    }
 +    // we should not change the state of the connection if we are a handshake reader thread
 +    // as there is a race between this thread and the application thread doing direct ack
 +    // fix for #40869
 +    boolean isHandShakeReader = false;
 +    try {
 +      for (;;) {
 +        if (stopped) {
 +          break;
 +        }
 +        if (SystemFailure.getFailure() != null) {
 +          // Allocate no objects here!
 +          Socket s = this.socket;
 +          if (s != null) {
 +            try {
 +              s.close();
 +            }
 +            catch (IOException e) {
 +              // don't care
 +            }
 +          }
 +          SystemFailure.checkFailure(); // throws
 +        }
 +        if (this.owner.getConduit().getCancelCriterion().cancelInProgress() != null) {
 +          break;
 +        }
 +
 +        try {
 +          ByteBuffer buff = getNIOBuffer();
 +          synchronized(stateLock) {
 +            connectionState = STATE_READING;
 +          }
 +          int amt = channel.read(buff);
 +          synchronized(stateLock) {
 +            connectionState = STATE_IDLE;
 +          }
 +          if (amt == 0) {
 +            continue;
 +          }
 +          if (amt < 0) {
 +            this.readerShuttingDown = true;
 +            try {
 +              requestClose("SocketChannel.read returned EOF");
 +              requestClose(LocalizedStrings.Connection_SOCKETCHANNEL_READ_RETURNED_EOF.toLocalizedString());
 +            } catch (Exception e) {
 +              // ignore - shutting down
 +            }
 +            return;
 +          }
 +
 +          processNIOBuffer();
 +          if (!this.isReceiver
 +              && (this.handshakeRead || this.handshakeCancelled)) {
 +            if (logger.isDebugEnabled()) {
 +              if (this.handshakeRead) {
 +                logger.debug("{} handshake has been read {}", p2pReaderName(), this);
 +              } else {
 +                logger.debug("{} handshake has been cancelled {}", p2pReaderName(), this);
 +              }
 +            }
 +            isHandShakeReader = true;
 +            // Once we have read the handshake the reader can go away
 +            break;
 +          }
 +        }
 +        catch (CancelException e) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("{} Terminated <{}> due to cancellation", p2pReaderName(), this, e);
 +          }
 +          this.readerShuttingDown = true;
 +          try { 
 +            requestClose(LocalizedStrings.Connection_CACHECLOSED_IN_CHANNEL_READ_0.toLocalizedString(e));
 +          } catch (Exception ex) {}
 +          return;
 +        }
 +        catch (ClosedChannelException e) {
 +          this.readerShuttingDown = true;
 +          try { 
 +            requestClose(LocalizedStrings.Connection_CLOSEDCHANNELEXCEPTION_IN_CHANNEL_READ_0.toLocalizedString(e));
 +          } catch (Exception ex) {}
 +          return;
 +        }
 +        catch (IOException e) {
 +          if (! isSocketClosed()
 +                && !"Socket closed".equalsIgnoreCase(e.getMessage()) // needed for Solaris jdk 1.4.2_08
 +                ) {
 +            if (logger.isDebugEnabled() && !isIgnorableIOException(e)) {
 +              logger.debug("{} io exception for {}", p2pReaderName(), this, e);
 +            }
 +            if(e.getMessage().contains("interrupted by a call to WSACancelBlockingCall")) {
 +              if (logger.isDebugEnabled()) {
 +                logger.debug("{} received unexpected WSACancelBlockingCall exception, which may result in a hang", p2pReaderName()); 
 +              }
 +            }
 +          }
 +          this.readerShuttingDown = true;
 +          try { 
 +            requestClose(LocalizedStrings.Connection_IOEXCEPTION_IN_CHANNEL_READ_0.toLocalizedString(e));
 +          } catch (Exception ex) {}
 +          return;
 +
 +        } catch (Exception e) {
 +          this.owner.getConduit().getCancelCriterion().checkCancelInProgress(null); // bug 37101
 +          if (!stopped && ! isSocketClosed() ) {
 +            logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_0_EXCEPTION_IN_CHANNEL_READ, p2pReaderName()), e);
 +          }
 +          this.readerShuttingDown = true;
 +          try { 
 +            requestClose(LocalizedStrings.Connection_0_EXCEPTION_IN_CHANNEL_READ.toLocalizedString(e)); 
 +          } catch (Exception ex) {}
 +          return;
 +        }
 +      } // for
 +    }
 +    finally {
 +      if (!isHandShakeReader) {
 +        synchronized(stateLock) {
 +          connectionState = STATE_IDLE;
 +        }
 +      }
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{} runNioReader terminated id={} from {}", p2pReaderName(), conduitIdStr, remoteAddr);
 +      }
 +    }
 +  }
 +
 +  /** initiate suspect processing if a shared/ordered connection is lost and we're not shutting down */
 +  private void initiateSuspicionIfSharedUnordered() {
 +    if (this.isReceiver && this.handshakeRead && !this.preserveOrder && this.sharedResource) {
 +      if (this.owner.getConduit().getCancelCriterion().cancelInProgress() == null) {
 +        this.owner.getDM().getMembershipManager().suspectMember(this.getRemoteAddress(),
 +            INITIATING_SUSPECT_PROCESSING);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * checks to see if an exception should not be logged: i.e., "forcibly closed",
 +   * "reset by peer", or "connection reset"
 +   * */
 +  public static final boolean isIgnorableIOException(Exception e) {
 +    if (e instanceof ClosedChannelException) {
 +      return true;
 +    }
 +
 +    String msg = e.getMessage();
 +    if (msg == null) {
 +      msg = e.toString();
 +    }
 +
 +    msg = msg.toLowerCase();
 +    return (msg.indexOf("forcibly closed") >= 0)
 +      ||   (msg.indexOf("reset by peer")   >= 0)
 +      ||   (msg.indexOf("connection reset")   >= 0);
 +  }
 +
 +  private static boolean validMsgType(int msgType) {
 +    return msgType == NORMAL_MSG_TYPE
 +      || msgType == CHUNKED_MSG_TYPE
 +      || msgType == END_CHUNKED_MSG_TYPE;
 +  }
 +
 +  private void closeAllMsgDestreamers() {
 +    synchronized (this.destreamerLock) {
 +      if (this.idleMsgDestreamer != null) {
 +        this.idleMsgDestreamer.close();
 +        this.idleMsgDestreamer = null;
 +      }
 +      if (this.destreamerMap != null) {
 +        Iterator it = this.destreamerMap.values().iterator();
 +        while (it.hasNext()) {
 +          MsgDestreamer md = (MsgDestreamer)it.next();
 +          md.close();
 +        }
 +        this.destreamerMap = null;
 +      }
 +    }
 +  }
 +
 +  MsgDestreamer obtainMsgDestreamer(short msgId, final Version v) {
 +    synchronized (this.destreamerLock) {
 +      if (this.destreamerMap == null) {
 +        this.destreamerMap = new HashMap();
 +      }
 +      Short key = new Short(msgId);
 +      MsgDestreamer result = (MsgDestreamer)this.destreamerMap.get(key);
 +      if (result == null) {
 +        result = this.idleMsgDestreamer;
 +        if (result != null) {
 +          this.idleMsgDestreamer = null;
 +        } else {
 +          result = new MsgDestreamer(this.owner.getConduit().stats, 
 +              this.owner.owner.getCancelCriterion(), v);
 +        }
 +        result.setName(p2pReaderName() + " msgId=" + msgId);
 +        this.destreamerMap.put(key, result);
 +      }
 +      return result;
 +    }
 +  }
 +  void releaseMsgDestreamer(short msgId, MsgDestreamer md) {
 +    Short key = new Short(msgId);
 +    synchronized (this.destreamerLock) {
 +      this.destreamerMap.remove(key);
 +      if (this.idleMsgDestreamer == null) {
 +        md.reset();
 +        this.idleMsgDestreamer = md;
 +      } else {
 +        md.close();
 +      }
 +    }
 +  }
 +
 +  private void sendFailureReply(int rpId, String exMsg, Throwable ex, boolean directAck) {
 +    ReplySender dm = null;
 +    if(directAck) {
 +      dm = new DirectReplySender(this);
 +    } else if(rpId != 0) {
 +      dm = this.owner.getDM();
 +    }
 +    if (dm != null) {
 +      ReplyMessage.send(getRemoteAddress(), rpId, new ReplyException(exMsg, ex), dm);
 +    }
 +  }
 +  private void runOioReader() {
 +    InputStream input = null;
 +    try {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Socket is of type: {}", getSocket().getClass() );
 +      }
 +      input = new BufferedInputStream(getSocket().getInputStream(), INITIAL_CAPACITY);
 +    }
 +    catch (IOException io) {
 +      if (stopped || owner.getConduit().getCancelCriterion().cancelInProgress() != null) {
 +        return; // bug 37520: exit run loop (and thread)
 +      }
 +      logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_UNABLE_TO_GET_INPUT_STREAM), io);
 +      stopped = true;
 +    }
 +
 +    if (!stopped) {
 +      Assert.assertTrue(owner != null, LocalizedStrings.Connection_OWNER_SHOULD_NOT_BE_NULL.toLocalizedString());
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Starting {}", p2pReaderName());
 +      }
 +    }
 +
 +    byte[] lenbytes = new byte[MSG_HEADER_BYTES];
 +
 +    final ByteArrayDataInput dis = new ByteArrayDataInput();
 +    while (!stopped) {
 +      try {
 +        if (SystemFailure.getFailure() != null) {
 +          // Allocate no objects here!
 +          Socket s = this.socket;
 +          if (s != null) {
 +            try {
 +              s.close();
 +            }
 +            catch (IOException e) {
 +              // don't care
 +            }
 +          }
 +          SystemFailure.checkFailure(); // throws
 +        }
 +        if (this.owner.getConduit().getCancelCriterion().cancelInProgress() != null) {
 +          break;
 +        }
 +        int len = 0;
 +        if (readFully(input, lenbytes, lenbytes.length) < 0) {
 +          stopped = true;
 +          continue;
 +        }
 +//        long recvNanos = DistributionStats.getStatTime();
 +        len = ((lenbytes[MSG_HEADER_SIZE_OFFSET]&0xff) * 0x1000000) +
 +          ((lenbytes[MSG_HEADER_SIZE_OFFSET+1]&0xff) * 0x10000) +
 +          ((lenbytes[MSG_HEADER_SIZE_OFFSET+2]&0xff) * 0x100) +
 +          (lenbytes[MSG_HEADER_SIZE_OFFSET+3]&0xff);
 +        /*byte msgHdrVersion =*/ calcHdrVersion(len);
 +        len = calcMsgByteSize(len);
 +        int msgType = lenbytes[MSG_HEADER_TYPE_OFFSET];
 +        short msgId = (short)((lenbytes[MSG_HEADER_ID_OFFSET]&0xff * 0x100)
 +                              + (lenbytes[MSG_HEADER_ID_OFFSET+1]&0xff));
 +        boolean myDirectAck = (msgType & DIRECT_ACK_BIT) != 0;
 +        if (myDirectAck) {
 +          msgType &= ~DIRECT_ACK_BIT; // clear the bit
 +        }
 +        // Following validation fixes bug 31145
 +        if (!validMsgType(msgType)) {
 +          logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_UNKNOWN_P2P_MESSAGE_TYPE_0, Integer.valueOf(msgType)));
 +          this.readerShuttingDown = true;
 +          requestClose(LocalizedStrings.Connection_UNKNOWN_P2P_MESSAGE_TYPE_0.toLocalizedString(Integer.valueOf(msgType)));
 +          break;
 +        }
 +        if (logger.isTraceEnabled())
 +          logger.trace("{} reading {} bytes", conduitIdStr, len);
 +        byte[] bytes = new byte[len];
 +        if (readFully(input, bytes, len) < 0) {
 +          stopped = true;
 +          continue;
 +        }
 +        boolean interrupted = Thread.interrupted();
 +        try {
 +          if (this.handshakeRead) {
 +            if (msgType == NORMAL_MSG_TYPE) {
 +              //DMStats stats = this.owner.getConduit().stats;
 +              //long start = DistributionStats.getStatTime();
 +              this.owner.getConduit().stats.incMessagesBeingReceived(true, len);
 +              dis.initialize(bytes, this.remoteVersion);
 +              DistributionMessage msg = null;
 +              try {
 +                ReplyProcessor21.initMessageRPId();
 +                long startSer = this.owner.getConduit().stats.startMsgDeserialization();
 +                msg = (DistributionMessage)InternalDataSerializer.readDSFID(dis);
 +                this.owner.getConduit().stats.endMsgDeserialization(startSer);
 +                if (dis.available() != 0) {
 +                  logger.warn(LocalizedMessage.create(
 +                      LocalizedStrings.Connection_MESSAGE_DESERIALIZATION_OF_0_DID_NOT_READ_1_BYTES,
 +                      new Object[] { msg, Integer.valueOf(dis.available())}));
 +                }
 +                //stats.incBatchCopyTime(start);
 +                try {
 +                  //start = DistributionStats.getStatTime();
 +                  if (!dispatchMessage(msg, len, myDirectAck)) {
 +                    continue;
 +                  }
 +                  //stats.incBatchSendTime(start);
 +                }
 +                catch (MemberShunnedException e) {
 +                  continue;
 +                }
 +                catch (Exception de) {
 +                  this.owner.getConduit().getCancelCriterion().checkCancelInProgress(de); // bug 37101
 +                  logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_ERROR_DISPATCHING_MESSAGE), de);
 +                }
 +              }
 +              catch (VirtualMachineError err) {
 +                SystemFailure.initiateFailure(err);
 +                // If this ever returns, rethrow the error.  We're poisoned
 +                // now, so don't let this thread continue.
 +                throw err;
 +              }
 +              catch (Throwable e) {
 +                // Whenever you catch Error or Throwable, you must also
 +                // catch VirtualMachineError (see above).  However, there is
 +                // _still_ a possibility that you are dealing with a cascading
 +                // error condition, so you also need to check to see if the JVM
 +                // is still usable:
 +                SystemFailure.checkFailure();
 +                // In particular I want OutOfMem to be caught here
 +                if (!myDirectAck) {
 +                  String reason = LocalizedStrings.Connection_ERROR_DESERIALIZING_MESSAGE.toLocalizedString();
 +                  sendFailureReply(ReplyProcessor21.getMessageRPId(), reason, e, myDirectAck);
 +                }
 +                if(e instanceof CancelException) {
 +                  if (!(e instanceof CacheClosedException)) {
 +                    // Just log a message if we had trouble deserializing due to CacheClosedException; see bug 43543
 +                    throw (CancelException) e;
 +                  }
 +                }
 +                logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_ERROR_DESERIALIZING_MESSAGE), e);
 +                //requestClose();
 +                //return;
 +              } finally {
 +                ReplyProcessor21.clearMessageRPId();
 +              }
 +            } else if (msgType == CHUNKED_MSG_TYPE) {
 +              MsgDestreamer md = obtainMsgDestreamer(msgId, remoteVersion);
 +              this.owner.getConduit().stats.incMessagesBeingReceived(md.size() == 0, len);
 +              try {
 +                md.addChunk(bytes);
 +              } catch (IOException ex) {
 +                logger.fatal(LocalizedMessage.create(LocalizedStrings.Connection_FAILED_HANDLING_CHUNK_MESSAGE), ex);
 +              }
 +            } else /* (msgType == END_CHUNKED_MSG_TYPE) */ {
 +              MsgDestreamer md = obtainMsgDestreamer(msgId, remoteVersion);
 +              this.owner.getConduit().stats.incMessagesBeingReceived(md.size() == 0, len);
 +              try {
 +                md.addChunk(bytes);
 +     

<TRUNCATED>


[074/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
index 0000000,8a7d351..cfc05f2
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
@@@ -1,0 -1,1022 +1,1022 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.tcp;
+ 
+ import java.io.DataInput;
+ import java.io.DataInputStream;
+ import java.io.DataOutput;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.ObjectInput;
+ import java.io.ObjectOutput;
+ import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
+ import java.nio.BufferUnderflowException;
+ import java.nio.ByteBuffer;
+ import java.nio.ByteOrder;
+ 
+ import com.gemstone.gemfire.internal.ByteBufferWriter;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ 
+ /**
+  * <p>
+  * ByteBufferInputStream is an input stream for ByteBuffer objects. It's
+  * incredible that the jdk doesn't have one of these already.
+  * </p>
+  * 
+  * The methods in this class throw BufferUnderflowException, not EOFException,
+  * if the end of the buffer is reached before we read the full amount. That
+  * breaks the contract for InputStream and DataInput, but it works for our code.
+  * 
+  * @author Dan Smith
+  * @author Bruce Schuchardt
+  * @author Darrel Schneider
+  * @since 3.0
+  */
+ 
+ public class ByteBufferInputStream extends InputStream implements DataInput, java.io.Externalizable
+ {
+   /**
+    * This interface is used to wrap either a ByteBuffer or an offheap Chunk
+    * as the source of bytes for a ByteBufferInputStream.
+    * 
+    * @author dschneider
+    *
+    */
+   public static interface ByteSource {
+     int position();
+     int limit();
+     int capacity();
+     int remaining();
+ 
+     void position(int newPosition);
+     void limit(int endOffset);
+ 
+     void get(byte[] b);
+     void get(byte[] b, int off, int len);
+     byte get();
+     byte get(int pos);
+     short getShort();
+     short getShort(int pos);
+     char getChar();
+     char getChar(int pos);
+     int getInt();
+     int getInt(int pos);
+     long getLong();
+     long getLong(int pos);
+     float getFloat();
+     float getFloat(int pos);
+     double getDouble();
+     double getDouble(int pos);
+ 
+     boolean hasArray();
+     byte[] array();
+     int arrayOffset();
+ 
+     ByteSource duplicate();
+     ByteSource slice(int length);
+     ByteSource slice(int pos, int limit);
+     
+     /**
+      * Returns the ByteBuffer that this ByteSource wraps; null if no ByteBuffer
+      */
+     ByteBuffer getBackingByteBuffer();
+ 
+     void sendTo(ByteBuffer out);
+     void sendTo(DataOutput out) throws IOException;
+   }
+   
+   public static class ByteSourceFactory {
+     public static ByteSource wrap(byte[] bytes) {
+       return new ByteBufferByteSource(ByteBuffer.wrap(bytes));
+     }
+     public static ByteSource create(ByteBuffer bb) {
+       return new ByteBufferByteSource(bb);
+     }
 -    public static ByteSource create(Chunk chunk) {
++    public static ByteSource create(ObjectChunk chunk) {
+       // Since I found a way to create a DirectByteBuffer (using reflection) from a Chunk
+       // we might not even need the ByteSource abstraction any more.
+       // But it is possible that createByteBuffer will not work on a different jdk so keep it for now.
+       ByteBuffer bb = chunk.createDirectByteBuffer();
+       if (bb != null) {
+         return create(bb);
+       } else {
+         return new OffHeapByteSource(chunk);
+       }
+     }
+   }
+   
+   public static class ByteBufferByteSource implements ByteSource {
+     private final ByteBuffer bb;
+     public ByteBufferByteSource(ByteBuffer bb) {
+       this.bb = bb;
+     }
+     /**
+      * Returns the current hash code of this byte source.
+      *
+      * <p> The hash code of a byte source depends only upon its remaining
+      * elements; that is, upon the elements from <tt>position()</tt> up to, and
+      * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+      *
+      * <p> Because byte source hash codes are content-dependent, it is inadvisable
+      * to use byte sources as keys in hash maps or similar data structures unless it
+      * is known that their contents will not change.  </p>
+      *
+      * @return  The current hash code of this byte source
+      */
+     @Override
+     public int hashCode() {
+       int h = 1;
+       int p = position();
+       for (int i = limit() - 1; i >= p; i--) {
+         h = 31 * h + (int)get(i);
+       }
+       return h;
+     }
+     @Override
+     public boolean equals(Object ob) {
+       if (this == ob) {
+         return true;
+       }
+       if (!(ob instanceof ByteSource)) {
+         return false;
+       }
+       ByteSource that = (ByteSource)ob;
+       if (this.remaining() != that.remaining()) {
+         return false;
+       }
+       int p = this.position();
+       for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
+         if (this.get(i) != that.get(j)) {
+           return false;
+         }
+       }
+       return true;
+     }
+ 
+     @Override
+     public ByteSource duplicate() {
+       return ByteSourceFactory.create(this.bb.duplicate());
+     }
+     @Override
+     public byte get() {
+       return this.bb.get();
+     }
+     @Override
+     public void get(byte[] b, int off, int len) {
+       this.bb.get(b, off, len);
+     }
+     @Override
+     public int remaining() {
+       return this.bb.remaining();
+     }
+     @Override
+     public int position() {
+       return this.bb.position();
+     }
+     @Override
+     public byte get(int pos) {
+       return this.bb.get(pos);
+     }
+     @Override
+     public char getChar() {
+       return this.bb.getChar();
+     }
+     @Override
+     public char getChar(int pos) {
+       return this.bb.getChar(pos);
+     }
+     @Override
+     public double getDouble() {
+       return this.bb.getDouble();
+     }
+     @Override
+     public double getDouble(int pos) {
+       return this.bb.getDouble(pos);
+     }
+     @Override
+     public float getFloat() {
+       return this.bb.getFloat();
+     }
+     @Override
+     public float getFloat(int pos) {
+       return this.bb.getFloat(pos);
+     }
+     @Override
+     public void get(byte[] b) {
+       this.bb.get(b);
+     }
+     @Override
+     public int getInt() {
+       return this.bb.getInt();
+     }
+     @Override
+     public int getInt(int pos) {
+       return this.bb.getInt(pos);
+     }
+     @Override
+     public long getLong() {
+       return this.bb.getLong();
+     }
+     @Override
+     public long getLong(int pos) {
+       return this.bb.getLong(pos);
+     }
+     @Override
+     public short getShort() {
+       return this.bb.getShort();
+     }
+     @Override
+     public short getShort(int pos) {
+       return this.bb.getShort(pos);
+     }
+     @Override
+     public int limit() {
+       return this.bb.limit();
+     }
+     @Override
+     public void position(int newPosition) {
+       this.bb.position(newPosition);
+     }
+     @Override
+     public boolean hasArray() {
+       return this.bb.hasArray();
+     }
+     @Override
+     public byte[] array() {
+       return this.bb.array();
+     }
+     @Override
+     public int arrayOffset() {
+       return this.bb.arrayOffset();
+     }
+     @Override
+     public void limit(int endOffset) {
+       this.bb.limit(endOffset);
+     }
+     @Override
+     public ByteSource slice(int length) {
+       if (length < 0) {
+         throw new IllegalArgumentException();
+       }
+       ByteBuffer dup = this.bb.duplicate();
+       dup.limit(dup.position() + length);
+       return ByteSourceFactory.create(dup.slice());
+     }
+     @Override
+     public ByteSource slice(int pos, int limit) {
+       ByteBuffer dup = this.bb.duplicate();
+       dup.limit(limit);
+       dup.position(pos);
+       return ByteSourceFactory.create(dup.slice());
+     }
+     @Override
+     public int capacity() {
+       return this.bb.capacity();
+     }
+     @Override
+     public void sendTo(ByteBuffer out) {
+       out.put(this.bb);
+     }
+     @Override
+     public void sendTo(DataOutput out) throws IOException {
+       int len = remaining();
+       if (len == 0) return;
+       if (out instanceof ByteBufferWriter) {
+         ((ByteBufferWriter) out).write(this.bb);
+         return;
+       }
+       if (this.bb.hasArray()) {
+         byte[] bytes = this.bb.array();
+         int offset = this.bb.arrayOffset() + this.bb.position();
+         out.write(bytes, offset, len);
+         this.bb.position(this.bb.limit());
+       } else {
+         while (len > 0) {
+           out.writeByte(get());
+           len--;
+         }
+       }
+     }
+     @Override
+     public ByteBuffer getBackingByteBuffer() {
+       return this.bb;
+     }
+   }
+   
+   public static class OffHeapByteSource implements ByteSource {
+     private int position;
+     private int limit;
 -    private final Chunk chunk;
++    private final ObjectChunk chunk;
+ 
 -    public OffHeapByteSource(Chunk c) {
++    public OffHeapByteSource(ObjectChunk c) {
+       this.chunk = c;
+       this.position = 0;
+       this.limit = capacity();
+     }
+     private OffHeapByteSource(OffHeapByteSource other) {
+       this.chunk = other.chunk;
+       this.position = other.position;
+       this.limit = other.limit;
+     }
+     
+     /**
+      * Returns the current hash code of this byte source.
+      *
+      * <p> The hash code of a byte source depends only upon its remaining
+      * elements; that is, upon the elements from <tt>position()</tt> up to, and
+      * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+      *
+      * <p> Because byte source hash codes are content-dependent, it is inadvisable
+      * to use byte sources as keys in hash maps or similar data structures unless it
+      * is known that their contents will not change.  </p>
+      *
+      * @return  The current hash code of this byte source
+      */
+     @Override
+     public int hashCode() {
+       int h = 1;
+       int p = position();
+       for (int i = limit() - 1; i >= p; i--) {
+         h = 31 * h + (int)get(i);
+       }
+       return h;
+     }
+      
+     @Override
+     public boolean equals(Object ob) {
+       if (this == ob) {
+         return true;
+       }
+       if (!(ob instanceof ByteSource)) {
+         return false;
+       }
+       ByteSource that = (ByteSource)ob;
+       if (this.remaining() != that.remaining()) {
+         return false;
+       }
+       int p = this.position();
+       for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
+         if (this.get(i) != that.get(j)) {
+           return false;
+         }
+       }
+       return true;
+     }
+     
+     @Override
+     public int remaining() {
+       return this.limit - this.position;
+     }
+ 
+     @Override
+     public int position() {
+       return this.position;
+     }
+ 
+     @Override
+     public int limit() {
+       return this.limit;
+     }
+ 
+     @Override
+     public void position(int newPosition) {
+       if ((newPosition > this.limit) || (newPosition < 0)) {
+         throw new IllegalArgumentException();
+       }
+       this.position = newPosition;
+     }
+     
+     @Override
+     public void limit(int newLimit) {
+       if ((newLimit > capacity()) || (newLimit < 0)) {
+         throw new IllegalArgumentException();
+       }
+       this.limit = newLimit;
+       if (this.position > this.limit) {
+         this.position = this.limit;
+       }
+     }
+     
+     @Override
+     public int capacity() {
+       return this.chunk.getDataSize();
+     }
+ 
+     private final int nextGetIndex() {
+       int p = this.position;
+       if (p >= this.limit) {
+         throw new BufferUnderflowException();
+       }
+       this.position += 1;
+       return p;
+     }
+ 
+     private final int nextGetIndex(int nb) {
+       int p = this.position;
+       if (this.limit - p < nb) {
+         throw new BufferUnderflowException();
+       }
+       this.position += nb;
+       return p;
+     }
+ 
+     /**
+      * Checks the given index against the limit, throwing an {@link
+      * IndexOutOfBoundsException} if it is not smaller than the limit
+      * or is smaller than zero.
+      */
+     private final void checkIndex(int i) {
+       if ((i < 0) || (i >= this.limit)) {
+         throw new IndexOutOfBoundsException();
+       }
+     }
+ 
+     private final void checkIndex(int i, int nb) {
+       if ((i < 0) || (nb > this.limit - i)) {
+         throw new IndexOutOfBoundsException();
+       }
+     }
+     private static void checkBounds(int off, int len, int size) {
+       if ((off | len | (off + len) | (size - (off + len))) < 0) {
+         throw new IndexOutOfBoundsException();
+       }
+     }
+     
+     @Override
+     public void get(byte[] b) {
+       basicGet(b, 0, b.length);
+     }
+     @Override
+     public void get(byte[] dst, int offset, int length) {
+       checkBounds(offset, length, dst.length);
+       basicGet(dst, offset, length);
+     }
+     private void basicGet(byte[] dst, int offset, int length) {
+       if (length > remaining()) {
+         throw new BufferUnderflowException();
+       }
+       int p = this.position;
+       this.position += length;
+       this.chunk.readBytes(p, dst, offset, length);
+     }
+ 
+     @Override
+     public byte get() {
+       return this.chunk.readByte(nextGetIndex());
+     }
+     @Override
+     public byte get(int pos) {
+       checkIndex(pos);
+       return this.chunk.readByte(pos);
+     }
+ 
+     /**
+      * Return true if the hardware supported unaligned reads from memory.
+      */
+     private static boolean determineUnaligned() {
+       try {
+         Class c = Class.forName("java.nio.Bits");
+         Method m = c.getDeclaredMethod("unaligned");
+         m.setAccessible(true);
+         return (boolean) m.invoke(null);
+       } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+         return false;
+         //throw new IllegalStateException("Could not invoke java.nio.Bits.unaligned()", e);
+       }
+     }
+     private static final boolean unaligned = determineUnaligned();
+     
+     @Override
+     public short getShort() {
+       return basicGetShort(this.nextGetIndex(2));
+     }
+     @Override
+     public short getShort(int pos) {
+       this.checkIndex(pos, 2);
+       return basicGetShort(pos);
+     }
+     private short basicGetShort(int pos) {
+       long addr = this.chunk.getAddressForReading(pos, 2);
+       if (unaligned) {
+         short result = UnsafeMemoryChunk.readAbsoluteShort(addr);
+         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
+           result = Short.reverseBytes(result);
+         }
+         return result;
+       } else {
+         int ch1 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         int ch2 = UnsafeMemoryChunk.readAbsoluteByte(addr);
+         return (short)((ch1 << 8) + (ch2 << 0));
+       }
+     }
+ 
+     @Override
+     public char getChar() {
+       return basicGetChar(this.nextGetIndex(2));
+     }
+     @Override
+     public char getChar(int pos) {
+       this.checkIndex(pos, 2);
+       return basicGetChar(pos);
+     }
+     private char basicGetChar(int pos) {
+       long addr = this.chunk.getAddressForReading(pos, 2);
+       if (unaligned) {
+         char result = UnsafeMemoryChunk.readAbsoluteChar(addr);
+         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
+           result = Character.reverseBytes(result);
+         }
+         return result;
+       } else {
+         int ch1 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         int ch2 = UnsafeMemoryChunk.readAbsoluteByte(addr);
+         return (char)((ch1 << 8) + (ch2 << 0));
+       }
+     }
+ 
+     @Override
+     public int getInt() {
+       return basicGetInt(this.nextGetIndex(4));
+     }
+     @Override
+     public int getInt(int pos) {
+       this.checkIndex(pos, 4);
+       return basicGetInt(pos);
+     }
+     
+     private int basicGetInt(final int pos) {
+       long addr = this.chunk.getAddressForReading(pos, 4);
+       if (unaligned) {
+         int result = UnsafeMemoryChunk.readAbsoluteInt(addr);
+         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
+           result = Integer.reverseBytes(result);
+         }
+         return result;
+       } else {
+         byte b0 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b1 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b2 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b3 = UnsafeMemoryChunk.readAbsoluteByte(addr);
+         return (b0 << 24) + ((b1 & 255) << 16) + ((b2 & 255) << 8) + ((b3 & 255) << 0);
+       }
+     }
+ 
+     @Override
+     public long getLong() {
+       return basicGetLong(this.nextGetIndex(8));
+     }
+     @Override
+     public long getLong(int pos) {
+       this.checkIndex(pos, 8);
+       return basicGetLong(pos);
+     }
+     private long basicGetLong(final int pos) {
+       long addr = this.chunk.getAddressForReading(pos, 8);
+       if (unaligned) {
+         long result = UnsafeMemoryChunk.readAbsoluteLong(addr);
+         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
+           result = Long.reverseBytes(result);
+         }
+         return result;
+       } else {
+         byte b0 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b1 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b2 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b3 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b4 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b5 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b6 = UnsafeMemoryChunk.readAbsoluteByte(addr++);
+         byte b7 = UnsafeMemoryChunk.readAbsoluteByte(addr);
+         return (((long)b0 << 56) +
+             ((long)(b1 & 255) << 48) +
+             ((long)(b2 & 255) << 40) +
+             ((long)(b3 & 255) << 32) +
+             ((long)(b4 & 255) << 24) +
+             ((b5 & 255) << 16) +
+             ((b6 & 255) <<  8) +
+             ((b7 & 255) <<  0));
+       }
+     }
+ 
+     @Override
+     public float getFloat() {
+       return basicGetFloat(this.nextGetIndex(4));
+     }
+     @Override
+     public float getFloat(int pos) {
+       this.checkIndex(pos, 4);
+       return basicGetFloat(pos);
+    }
+     private float basicGetFloat(int pos) {
+       return Float.intBitsToFloat(basicGetInt(pos));
+     }
+ 
+     @Override
+     public double getDouble() {
+       return basicGetDouble(this.nextGetIndex(8));
+     }
+     @Override
+     public double getDouble(int pos) {
+       this.checkIndex(pos, 8);
+       return basicGetDouble(pos);
+     }
+     private double basicGetDouble(int pos) {
+       return Double.longBitsToDouble(basicGetLong(pos));
+     }
+ 
+     @Override
+     public boolean hasArray() {
+       return false;
+     }
+ 
+     @Override
+     public byte[] array() {
+       throw new UnsupportedOperationException();
+     }
+ 
+     @Override
+     public int arrayOffset() {
+       throw new UnsupportedOperationException();
+     }
+ 
+     @Override
+     public ByteSource duplicate() {
+       return new OffHeapByteSource(this);
+     }
+ 
+     @Override
+     public ByteSource slice(int length) {
+       if (length < 0) {
+         throw new IllegalArgumentException();
+       }
+       return slice(this.position, this.position + length);
+     }
+ 
+     @Override
+     public ByteSource slice(int pos, int limit) {
+       if ((limit > capacity()) || (limit < 0)) {
+         throw new IllegalArgumentException();
+       }
+       if ((pos > limit) || (pos < 0)) {
+         throw new IllegalArgumentException();
+       }
+       return new OffHeapByteSource(this.chunk.slice(pos, limit));
+     }
+ 
+     @Override
+     public void sendTo(ByteBuffer out) {
+       int len = remaining();
+       while (len > 0) {
+         out.put(get());
+         len--;
+       }
+       // We will not even create an instance of this class if createByteBuffer works on this platform.
+ //      if (len > 0) {
+ //        ByteBuffer bb = this.chunk.createByteBuffer();
+ //        bb.position(position());
+ //        bb.limit(limit());
+ //        out.put(bb);
+ //        position(limit());
+ //      }
+     }
+     
+     @Override
+     public void sendTo(DataOutput out) throws IOException {
+       int len = remaining();
+       while (len > 0) {
+         out.writeByte(get());
+         len--;
+       }
+     }
+     @Override
+     public ByteBuffer getBackingByteBuffer() {
+       return null;
+     }
+   }
+   
+   private ByteSource buffer;
+ 
+   public ByteBufferInputStream(ByteBuffer buffer) {
+     setBuffer(buffer);
+   }
+   
+   public ByteBufferInputStream() {
+   }
+   
+   protected ByteBufferInputStream(ByteBufferInputStream copy) {
+     this.buffer = copy.buffer.duplicate();
+   }
+ 
 -  public ByteBufferInputStream(Chunk blob) {
++  public ByteBufferInputStream(ObjectChunk blob) {
+     this.buffer = ByteSourceFactory.create(blob);
+   }
+ 
+   public final void setBuffer(ByteSource buffer) {
+     if(buffer == null) {
+       throw new NullPointerException();
+     }
+     this.buffer = buffer;
+   }
+   
+   public final void setBuffer(ByteBuffer bb) {
+     if (bb == null) {
+       throw new NullPointerException();
+     }
+     setBuffer(ByteSourceFactory.create(bb));
+   }
+   
+   /**
+    * See the InputStream read method for javadocs.
+    * Note that if an attempt
+    * to read past the end of the wrapped ByteBuffer is done this method
+    * throws BufferUnderflowException
+    */
+   @Override
+   public final int read() {
+     return (buffer.get() & 0xff);
+   }
+   
+ 
+   /* this method is not thread safe
+    * See the InputStream read method for javadocs.
+    * Note that if an attempt
+    * to read past the end of the wrapped ByteBuffer is done this method
+    * throws BufferUnderflowException
+    */
+   @Override
+   public final int read(byte b[], int off, int len) {
+     buffer.get(b, off, len);
+     return len;
+   }
+ 
+   @Override
+   public int available() {
+     return this.buffer.remaining();
+   }
+   
+   public int position() {
+     return this.buffer.position();
+   }
+ 
+   // GemFire does not use mark or reset so I changed this class
+   // to just inherit from InputStream which does not support mark/reset.
+   // That way we do not need to add support for them to the new ByteSource class.
+   
+ //  @Override
+ //  public boolean markSupported() {
+ //    return true;
+ //  }
+ //
+ //  @Override
+ //  public void mark(int limit) {
+ //    this.buffer.mark();
+ //  }
+ //
+ //  @Override
+ //  public void reset() {
+ //    this.buffer.reset();
+ //  }
+ 
+   @Override
+   public long skip(long n) throws IOException {
+     if (n <= Integer.MAX_VALUE) {
+       return skipBytes((int) n);
+     } else {
+       return super.skip(n);
+     }
+   }
+ 
+   public boolean readBoolean() {
+     return this.buffer.get() != 0;
+   }
+   public boolean readBoolean(int pos) {
+     return this.buffer.get(pos) != 0;
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readByte()
+    */
+   public byte readByte() {
+     return this.buffer.get();
+   }
+   public byte readByte(int pos) {
+     return this.buffer.get(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readChar()
+    */
+   public char readChar() {
+     return this.buffer.getChar();
+   }
+   public char readChar(int pos) {
+     return this.buffer.getChar(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readDouble()
+    */
+   public double readDouble() {
+     return this.buffer.getDouble();
+   }
+   public double readDouble(int pos) {
+     return this.buffer.getDouble(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readFloat()
+    */
+   public float readFloat() {
+     return this.buffer.getFloat();
+   }
+   public float readFloat(int pos) {
+     return this.buffer.getFloat(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readFully(byte[])
+    */
+   public void readFully(byte[] b) {
+     this.buffer.get(b);
+     
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readFully(byte[], int, int)
+    */
+   public void readFully(byte[] b, int off, int len) {
+     this.buffer.get(b, off, len);
+     
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readInt()
+    */
+   public int readInt() {
+     return this.buffer.getInt();
+   }
+   public int readInt(int pos) {
+     return this.buffer.getInt(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readLine()
+    */
+   public String readLine() {
+     throw new UnsupportedOperationException();
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readLong()
+    */
+   public long readLong() {
+     return this.buffer.getLong();
+   }
+   public long readLong(int pos) {
+     return this.buffer.getLong(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readShort()
+    */
+   public short readShort() {
+     return this.buffer.getShort();
+   }
+   public short readShort(int pos) {
+     return this.buffer.getShort(pos);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readUTF()
+    */
+   public String readUTF() throws IOException {
+     return DataInputStream.readUTF(this);
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readUnsignedByte()
+    */
+   public int readUnsignedByte() {
+     return this.buffer.get() & 0xff;
+   }
+   public int readUnsignedByte(int pos) {
+     return this.buffer.get(pos) & 0xff;
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#readUnsignedShort()
+    */
+   public int readUnsignedShort() {
+     return this.buffer.getShort() & 0xffff;
+   }
+   public int readUnsignedShort(int pos) {
+     return this.buffer.getShort(pos) & 0xffff;
+   }
+ 
+   /* (non-Javadoc)
+    * @see java.io.DataInput#skipBytes(int)
+    */
+   public int skipBytes(int n) {
+     int newPosition = this.buffer.position() + n;
+     if(newPosition > this.buffer.limit()) {
+       newPosition = this.buffer.limit();
+       n = newPosition - this.buffer.position();
+     }
+     this.buffer.position(newPosition);
+     return n;
+   }
+ 
+   public int size() {
+     return this.buffer.limit();
+   }
+ 
+   public byte get(int idx) {
+     return this.buffer.get(idx);
+   }
+ 
+   public short getShort(int idx) {
+     return this.buffer.getShort(idx);
+   }
+ 
+   public int getInt(int idx) {
+     return this.buffer.getInt(idx);
+   }
+ 
+   public void position(int absPos) {
+ //    if (absPos < 0) {
+ //      throw new IllegalArgumentException("position was less than zero " + absPos);
+ //    } else if (absPos > this.buffer.limit()) {
+ //      throw new IllegalArgumentException( "position " + absPos + " was greater than the limit " + this.buffer.limit());
+ //    }
+     this.buffer.position(absPos);
+   }
+ 
+   public void sendTo(DataOutput out) throws IOException {
+     this.buffer.position(0);
+     this.buffer.sendTo(out);
+  }
+   
+   public void sendTo(ByteBuffer out) {
+     this.buffer.position(0);
+     this.buffer.sendTo(out);
+  }
+ 
+   public ByteSource slice(int length) {
+     return this.buffer.slice(length);
+   }
+   
+   public ByteSource slice(int startOffset, int endOffset) {
+     return this.buffer.slice(startOffset, endOffset);
+   }
+ 
+   public void writeExternal(ObjectOutput out) throws IOException {
+     out.writeBoolean(this.buffer != null);
+     if (this.buffer != null) {
+       out.writeInt(this.buffer.capacity());
+       out.writeInt(this.buffer.limit());
+       out.writeInt(this.buffer.position());
+       for (int i=0; i < this.buffer.capacity(); i++) {
+         out.write(this.buffer.get(i));
+       }
+     }
+   }
+ 
+   public void readExternal(ObjectInput in) throws IOException,
+       ClassNotFoundException {
+     boolean hasBuffer = in.readBoolean();
+     if (hasBuffer) {
+       int capacity = in.readInt();
+       int limit = in.readInt();
+       int position = in.readInt();
+       byte[] bytes = new byte[capacity];
+       int bytesRead = in.read(bytes);
+       if (bytesRead != capacity) {
+         throw new IOException("Expected to read " + capacity + " bytes but only read " + bytesRead + " bytes.");
+       }
+       setBuffer(ByteBuffer.wrap(bytes, position, limit-position));
+     } else {
+       this.buffer = null;
+     }
+   }
+ 
+   public ByteSource getBuffer() {
+     return buffer;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
index 0000000,52f332f..d632158
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
@@@ -1,0 -1,85 +1,85 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.tcp;
+ 
+ import java.nio.ByteBuffer;
+ 
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ 
+ /**
+  * You should only create an instance of this class if the bytes this buffer reads
+  * will never change. If you want a buffer than can be refilled with other bytes then
+  * create an instance of ByteBufferInputStream instead.
+  * Note that even though this class is immutable the position on its ByteBuffer can change.
+  * 
+  * @author darrel
+  * @since 6.6
+  */
+ public class ImmutableByteBufferInputStream extends ByteBufferInputStream {
+ 
+   /**
+    * Create an immutable input stream by whose contents are the first length
+    * bytes from the given input stream.
+    * @param existing the input stream whose content will go into this stream. Note that this existing stream will be read by this class (a copy is not made) so it should not be changed externally.
+    * @param length the number of bytes to put in this stream
+    */
+   public ImmutableByteBufferInputStream(ByteBufferInputStream existing,
+       int length) {
+     setBuffer(existing.slice(length));
+   }
+   /**
+    * Create an immutable input stream whose contents are the given bytes
+    * @param bytes the content of this stream. Note that this byte array will be read by this class (a copy is not made) so it should not be changed externally.
+    */
+   public ImmutableByteBufferInputStream(byte[] bytes) {
+     setBuffer(ByteBuffer.wrap(bytes));
+   }
+ 
+   /**
+    * Create an immutable input stream whose contents are the given bytes
+    * @param bb the content of this stream. Note that bb will be read by this class (a copy is not made) so it should not be changed externally.
+    */
+   public ImmutableByteBufferInputStream(ByteBuffer bb) {
+     setBuffer(bb.slice());
+   }
+   /**
+    * Create an immutable input stream by copying another. A somewhat shallow copy is made.
+    * @param copy the input stream to copy. Note that this copy stream will be read by this class (a copy is not made) so it should not be changed externally.
+    */
+   public ImmutableByteBufferInputStream(ImmutableByteBufferInputStream copy) {
+     super(copy);
+   }
+   public ImmutableByteBufferInputStream() {
+     // for serialization
+   }
+   
 -  public ImmutableByteBufferInputStream(Chunk blob) {
++  public ImmutableByteBufferInputStream(ObjectChunk blob) {
+     super(blob);
+   }
+   @Override
+   public boolean markSupported() {
+     return false;
+   }
+   @Override
+   public void mark(int limit) {
+     // unsupported but exception thrown by reset
+   }
+   @Override
+   public void reset() {
+     throw new UnsupportedOperationException();
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
index 0000000,7a4840e..40015a4
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
@@@ -1,0 -1,195 +1,195 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.util;
+ 
+ import java.io.IOException;
+ 
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.distributed.internal.DMStats;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.internal.ByteArrayDataInput;
+ import com.gemstone.gemfire.internal.DSCODE;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.pdx.internal.PdxInputStream;
+ 
+ /**
+  * A "blob" is a serialized representation of an object into a byte[].
+  * BlobHelper provides utility methods for
+  * serializing and deserializing the object.
+  * 
+  * 
+  */
+ 
+ public class BlobHelper {
+ 
+   /**
+    * A blob is a serialized Object. This method serializes the object into a
+    * blob and returns the byte array that contains the blob.
+    */
+   public static byte[] serializeToBlob(Object obj) throws IOException {
+     return serializeToBlob(obj, null);
+   }
+ 
+   /**
+    * A blob is a serialized Object.  This method serializes the
+    * object into a blob and returns the byte array that contains the blob.
+    */
+   public static byte[] serializeToBlob(Object obj, Version version)
+   throws IOException
+   {
+     final long start = startSerialization();
+     HeapDataOutputStream hdos = new HeapDataOutputStream(version);
+     DataSerializer.writeObject(obj, hdos);
+     byte[] result = hdos.toByteArray();
+     endSerialization(start, result.length);
+     return result;
+   }
+ 
+   /**
+    * A blob is a serialized Object.  This method serializes the
+    * object into the given HeapDataOutputStream.
+    */
+   public static void serializeTo(Object obj, HeapDataOutputStream hdos)
+     throws IOException
+   {
+     final int startBytes = hdos.size();
+     final long start = startSerialization();
+     DataSerializer.writeObject(obj, hdos);
+     endSerialization(start, hdos.size()-startBytes);
+   }
+                                                                         
+ 
+ 
+   /**
+    * A blob is a serialized Object.  This method 
+    * returns the deserialized object.
+    */
+   public static Object deserializeBlob(byte[] blob) throws IOException,
+       ClassNotFoundException {
+     return deserializeBlob(blob, null, null);
+   }
+ 
+   /**
+    * A blob is a serialized Object.  This method 
+    * returns the deserialized object.
+    */
+   public static Object deserializeBlob(byte[] blob, Version version,
+       ByteArrayDataInput in) throws IOException, ClassNotFoundException {
+     Object result;
+     final long start = startDeserialization();
+     /*
+     final StaticSystemCallbacks sysCb;
+     if (version != null && (sysCb = GemFireCacheImpl.FactoryStatics
+         .systemCallbacks) != null) {
+       // may need to change serialized shape for SQLFire
+       result = sysCb.fromVersion(blob, true, version, in);
+     }
+     else*/ if (blob.length > 0 && blob[0] == DSCODE.PDX) {
+       // If the first byte of blob indicates a pdx then wrap
+       // blob in a PdxInputStream instead.
+       // This will prevent us from making a copy of the byte[]
+       // every time we deserialize a PdxInstance.
+       PdxInputStream is = new PdxInputStream(blob);
+       result = DataSerializer.readObject(is);
+     } else {
+       // if we have a nested pdx then we want to make a copy
+       // when a PdxInstance is created so that the byte[] will
+       // just have the pdx bytes and not the outer objects bytes.
+       if (in == null) {
+         in = new ByteArrayDataInput();
+       }
+       in.initialize(blob, version);
+       result = DataSerializer.readObject(in);
+     }
+     endDeserialization(start, blob.length);
+     // this causes a small performance drop in d-no-ack performance tests
+ //    if (dis.available() != 0) {
+ //      LogWriterI18n lw = InternalDistributedSystem.getLoggerI18n();
+ //      if (lw != null && lw.warningEnabled()) {
+ //        lw.warning(
+ //            LocalizedStrings.BlobHelper_DESERIALIZATION_OF_A_0_DID_NOT_READ_1_BYTES_THIS_INDICATES_A_LOGIC_ERROR_IN_THE_SERIALIZATION_CODE_FOR_THIS_CLASS,
+ //            new Object[] {((result!=null) ? result.getClass().getName() : "NULL"), Integer.valueOf(dis.available())});   
+ //            
+ //      }
+ //    }
+     return result;
+   }
+ 
+   /**
+    * A blob is a serialized Object.  This method 
+    * returns the deserialized object.
+    * If a PdxInstance is returned then it will refer to Chunk's off-heap memory
+    * with an unretained reference.
+    */
 -  public static @Unretained Object deserializeOffHeapBlob(Chunk blob) throws IOException, ClassNotFoundException {
++  public static @Unretained Object deserializeOffHeapBlob(ObjectChunk blob) throws IOException, ClassNotFoundException {
+     Object result;
+     final long start = startDeserialization();
+     // For both top level and nested pdxs we just want a reference to this off-heap blob.
+     // No copies.
+     // For non-pdx we want a stream that will read directly from the chunk.
+     PdxInputStream is = new PdxInputStream(blob);
+     result = DataSerializer.readObject(is);
+     endDeserialization(start, blob.getDataSize());
+     return result;
+   }
+ 
+   public static Object deserializeBuffer(ByteArrayDataInput in, int numBytes)
+       throws IOException, ClassNotFoundException {
+     final long start = startDeserialization();
+     Object result = DataSerializer.readObject(in);
+     endDeserialization(start, numBytes);
+     return result;
+   }
+ 
+   private static long startSerialization() {
+     long result = 0;
+     DMStats stats = InternalDistributedSystem.getDMStats();
+     if (stats != null) {
+       result = stats.startSerialization();
+     }
+     return result;
+   }
+   
+   private static void endSerialization(long start, int bytes) {
+     DMStats stats = InternalDistributedSystem.getDMStats();
+     if (stats != null) {
+       stats.endSerialization(start, bytes);
+     }
+   }
+ 
+   private static long startDeserialization() {
+     long result = 0;
+     DMStats stats = InternalDistributedSystem.getDMStats();
+     if (stats != null) {
+       result = stats.startDeserialization();
+     }
+     return result;
+   }
+   
+   private static void endDeserialization(long start, int bytes) {
+     DMStats stats = InternalDistributedSystem.getDMStats();
+     if (stats != null) {
+       stats.endDeserialization(start, bytes);
+     }
+   }
+   
+ }



[066/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
index 0000000,6e24398..ad9b3e1
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
@@@ -1,0 -1,1875 +1,1875 @@@
+ package com.gemstone.gemfire.security;
+ 
+ /*
+  * 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.
+  */
+ 
+ 
+ import java.io.File;
+ import java.io.FileOutputStream;
+ import java.io.IOException;
+ import java.io.PrintStream;
+ import java.lang.reflect.Field;
+ import java.lang.reflect.Modifier;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Properties;
+ import java.util.Set;
+ 
+ import javax.net.ServerSocketFactory;
+ import javax.net.SocketFactory;
+ import javax.net.ssl.KeyManager;
+ import javax.net.ssl.SSLContext;
+ import javax.net.ssl.SSLContextSpi;
+ import javax.net.ssl.SSLServerSocketFactory;
+ import javax.net.ssl.SSLSocketFactory;
+ import javax.net.ssl.TrustManager;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.cache.AttributesFactory;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.DataPolicy;
+ import com.gemstone.gemfire.cache.DynamicRegionFactory;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionAttributes;
+ import com.gemstone.gemfire.cache.Scope;
+ import com.gemstone.gemfire.cache.client.NoAvailableServersException;
+ import com.gemstone.gemfire.cache.client.Pool;
+ import com.gemstone.gemfire.cache.client.PoolFactory;
+ import com.gemstone.gemfire.cache.client.PoolManager;
+ import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+ import com.gemstone.gemfire.cache.client.ServerOperationException;
+ import com.gemstone.gemfire.cache.client.ServerRefusedConnectionException;
+ import com.gemstone.gemfire.cache.client.internal.PoolImpl;
+ import com.gemstone.gemfire.cache.client.internal.ProxyCache;
+ import com.gemstone.gemfire.cache.execute.Execution;
+ import com.gemstone.gemfire.cache.execute.Function;
+ import com.gemstone.gemfire.cache.execute.FunctionException;
+ import com.gemstone.gemfire.cache.execute.FunctionService;
+ import com.gemstone.gemfire.cache.query.Query;
+ import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.server.CacheServer;
+ import com.gemstone.gemfire.cache30.ClientServerTestCase;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.Locator;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.internal.AvailablePort;
+ import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+ import com.gemstone.gemfire.internal.logging.PureLogWriter;
+ import com.gemstone.gemfire.internal.util.Callable;
+ import com.gemstone.gemfire.test.dunit.Assert;
+ import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+ import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
+ import com.gemstone.gemfire.test.dunit.NetworkUtils;
+ import com.gemstone.gemfire.test.dunit.Wait;
+ import com.gemstone.gemfire.test.dunit.WaitCriterion;
+ 
+ /**
+  * Contains utility methods for setting up servers/clients for authentication
+  * and authorization tests.
+  * 
+  * @author sumedh
+  * @since 5.5
+  */
+ public class SecurityTestUtil extends DistributedTestCase {
+ 
+   public SecurityTestUtil(String name) {
+     super(name);
+   }
+ 
+   private static Locator locator = null;
+ 
+   private static Cache cache = null;
+ 
+   private static Properties currentJavaProps = null;
+ 
+   private static String locatorString = null;
+ 
+   private static Integer mcastPort = null;
+ 
+   public static final int NO_EXCEPTION = 0;
+ 
+   public static final int AUTHREQ_EXCEPTION = 1;
+ 
+   public static final int AUTHFAIL_EXCEPTION = 2;
+ 
+   public static final int CONNREFUSED_EXCEPTION = 3;
+ 
+   public static final int NOTAUTHZ_EXCEPTION = 4;
+ 
+   public static final int OTHER_EXCEPTION = 5;
+   
+   public static final int NO_AVAILABLE_SERVERS = 6;
+ 
+   // Indicates that AuthReqException may not necessarily be thrown
+   public static final int NOFORCE_AUTHREQ_EXCEPTION = 16;
+ 
+   protected static final String regionName = "AuthRegion";
+ 
+   protected static final String[] keys = { "key1", "key2", "key3", "key4",
+       "key5", "key6", "key7", "key8" };
+ 
+   protected static final String[] values = { "value1", "value2", "value3",
+       "value4", "value5", "value6", "value7", "value8" };
+ 
+   protected static final String[] nvalues = { "nvalue1", "nvalue2", "nvalue3",
+       "nvalue4", "nvalue5", "nvalue6", "nvalue7", "nvalue8" };
+ 
+   static String[] expectedExceptions = null;
+ 
+   private static Pool pool = null;
+ 
+   private static boolean multiUserAuthMode = false;
+ 
+   private static final int numberOfUsers = 1;
+ 
+   static ProxyCache[] proxyCaches = new ProxyCache[numberOfUsers];
+ 
+   private static Region regionRef = null;
+ 
+   public static void addExpectedExceptions(String[] expectedExceptions,
+       LogWriter logger) {
+     if (expectedExceptions != null) {
+       for (int index = 0; index < expectedExceptions.length; index++) {
+         logger.info("<ExpectedException action=add>"
+             + expectedExceptions[index] + "</ExpectedException>");
+       }
+     }
+   }
+ 
+   public static void removeExpectedExceptions(String[] expectedExceptions,
+       LogWriter logger) {
+     if (expectedExceptions != null) {
+       for (int index = 0; index < expectedExceptions.length; index++) {
+         logger.info("<ExpectedException action=remove>"
+             + expectedExceptions[index] + "</ExpectedException>");
+       }
+     }
+   }
+ 
+   public static void setJavaProps(Properties javaProps) {
+ 
+     removeJavaProperties(currentJavaProps);
+     addJavaProperties(javaProps);
+     currentJavaProps = javaProps;
+   }
+ 
+   public DistributedSystem createSystem(Properties sysProps, Properties javaProps) {
+ 
+     closeCache();
+     clearStaticSSLContext();
+     setJavaProps(javaProps);
+ 
+     DistributedSystem dsys = getSystem(sysProps);
+     assertNotNull(dsys);
+     addExpectedExceptions(SecurityTestUtil.expectedExceptions, system
+         .getLogWriter());
+     return dsys;
+   }
+ 
+   void openCache() {
+ 
+     assertNotNull(system);
+     assertTrue(system.isConnected());
+     cache = CacheFactory.create(system);
+     assertNotNull(cache);
+   }
+ 
+   private static void initClientDynamicRegionFactory(String poolName) {
+ 
+     DynamicRegionFactory.get().open(
+         new DynamicRegionFactory.Config(null, poolName, false,true));
+   }
+ 
+   public static void initDynamicRegionFactory() {
+ 
+     DynamicRegionFactory.get().open(
+         new DynamicRegionFactory.Config(null, null, false, true));
+   }
+ 
+   public static Integer getLocatorPort() {
+ 
+     Integer locatorPort = new Integer(AvailablePort
+         .getRandomAvailablePort(AvailablePort.SOCKET));
+     String addr = NetworkUtils.getIPLiteral();
+     if (locatorString == null) {
+       locatorString = addr + "[" + locatorPort + ']';
+     }
+     else {
+       locatorString += "," + addr + "[" + locatorPort + ']';
+     }
+     return locatorPort;
+   }
+ 
+   /**
+    * Note that this clears the string after returning for convenience in reusing
+    * for other tests. Hence it should normally be invoked only once for a test.
+    */
+   public static String getLocatorString() {
+ 
+     String locString = locatorString;
+     locatorString = null;
+     return locString;
+   }
+ 
+   public static Properties concatProperties(Properties[] propsList) {
+ 
+     Properties props = new Properties();
+     for (int index = 0; index < propsList.length; ++index) {
+       if (propsList[index] != null) {
+         props.putAll(propsList[index]);
+       }
+     }
+     return props;
+   }
+ 
+   public static void registerExpectedExceptions(String[] expectedExceptions) {
+     SecurityTestUtil.expectedExceptions = expectedExceptions;
+   }
+ 
+   private static void addJavaProperties(Properties javaProps) {
+ 
+     if (javaProps != null) {
+       Iterator iter = javaProps.entrySet().iterator();
+       while (iter.hasNext()) {
+         Map.Entry entry = (Map.Entry)iter.next();
+         System.setProperty((String)entry.getKey(), (String)entry.getValue());
+       }
+     }
+   }
+ 
+   private static void removeJavaProperties(Properties javaProps) {
+ 
+     if (javaProps != null) {
+       Properties props = System.getProperties();
+       Iterator iter = javaProps.keySet().iterator();
+       while (iter.hasNext()) {
+         props.remove(iter.next());
+       }
+       System.setProperties(props);
+     }
+   }
+ 
+   public static Integer createCacheServer(Properties authProps,
+       Object javaProps, Integer dsPort, String locatorString,
+       Integer serverPort, Integer expectedResult) {
+ 
+     return createCacheServer(authProps, javaProps, dsPort, locatorString,
+         serverPort, Boolean.FALSE, expectedResult);
+   }
+ 
+   public static Integer createCacheServer(Properties authProps,
+       Object javaProps, Integer locatorPort, String locatorString,
+       Integer serverPort, Boolean setupDynamicRegionFactory,
+       Integer expectedResult) {
+ 
+     if (authProps == null) {
+       authProps = new Properties();
+     }
+     authProps.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+     if (locatorString != null && locatorString.length() > 0) {
+       authProps.setProperty(DistributionConfig.LOCATORS_NAME, locatorString);
+       if (locatorPort != null) {
+         authProps.setProperty(DistributionConfig.START_LOCATOR_NAME,
+             NetworkUtils.getIPLiteral() + "[" + locatorPort.toString() + ']');
+       }
+     } else {
+       authProps.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
+     }
+     authProps.setProperty(DistributionConfig.SECURITY_LOG_LEVEL_NAME, "finest");
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Set the server properties to: " + authProps);
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Set the java properties to: " + javaProps);
+ 
+     SecurityTestUtil tmpInstance = new SecurityTestUtil("temp");
+     try {
+       tmpInstance.createSystem(authProps, (Properties)javaProps);
+       if (expectedResult.intValue() != NO_EXCEPTION) {
+         fail("Expected a security exception when starting peer");
+       }
+     }
+     catch (AuthenticationRequiredException ex) {
+       if (expectedResult.intValue() == AUTHREQ_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when starting peer: " + ex);
+         return new Integer(0);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting peer", ex);
+       }
+     }
+     catch (AuthenticationFailedException ex) {
+       if (expectedResult.intValue() == AUTHFAIL_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when starting peer: " + ex);
+         return new Integer(0);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting peer", ex);
+       }
+     }
+     catch (Exception ex) {
+       Assert.fail("Got unexpected exception when starting peer", ex);
+     }
+ 
+     if (setupDynamicRegionFactory.booleanValue()) {
+       initDynamicRegionFactory();
+     }
+     tmpInstance.openCache();
+     AttributesFactory factory = new AttributesFactory();
+     factory.setScope(Scope.DISTRIBUTED_ACK);
+     factory.setDataPolicy(DataPolicy.REPLICATE);
+     RegionAttributes attrs = factory.create();
+     cache.createRegion(regionName, attrs);
+     int port;
+     if (serverPort == null || serverPort.intValue() <= 0) {
 -      port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
++      port = 0;
+     }
+     else {
+       port = serverPort.intValue();
+     }
+     CacheServer server1 = cache.addCacheServer();
+     server1.setPort(port);
+     server1.setNotifyBySubscription(true);
+     try {
+       server1.start();
+     }
+     catch (Exception ex) {
+       Assert.fail("Got unexpected exception when starting CacheServer", ex);
+     }
+     return new Integer(server1.getPort());
+   }
+ 
+   public static void createCacheClient(String authInitModule,
+       Properties authProps, Properties javaProps, Integer[] ports,
+       Object numConnections, Integer expectedResult) {
+     createCacheClient(authInitModule, authProps, javaProps, ports,
+         numConnections, "false", expectedResult);
+   }
+ 
+   public static void createCacheClient(String authInitModule,
+       Properties authProps, Properties javaProps, Integer[] ports,
+       Object numConnections, String multiUserMode, Integer expectedResult) {
+     createCacheClient(authInitModule, authProps, javaProps, ports,
+         (Integer)numConnections, Boolean.FALSE, multiUserMode, expectedResult);
+   }
+ 
+   public static void createCacheClient(String authInitModule,
+       Properties authProps, Properties javaProps, Integer[] ports,
+       Integer numConnections, Boolean setupDynamicRegionFactory,
+       Integer expectedResult) {
+     createCacheClient(authInitModule, authProps, javaProps, ports,
+         numConnections, setupDynamicRegionFactory, "false", expectedResult);
+   }
+ 
+   public static void createCacheClient(String authInitModule,
+       Properties authProps, Properties javaProps, Integer[] ports,
+       Integer numConnections, Boolean setupDynamicRegionFactory,
+       String multiUserMode, Integer expectedResult) {
+     createCacheClient(authInitModule, authProps, javaProps, ports,
+         numConnections, setupDynamicRegionFactory, multiUserMode, Boolean.TRUE,
+         expectedResult);
+   }
+ 
+   public static void createCacheClient(String authInitModule,
+       Properties authProps, Properties javaProps, Integer[] ports,
+       Integer numConnections, Boolean setupDynamicRegionFactory,
+       String multiUserMode, Boolean subscriptionEnabled,
+       Integer expectedResult) {
+ 
+     multiUserAuthMode = Boolean.valueOf(multiUserMode);
+     if (authProps == null) {
+       authProps = new Properties();
+     }
+     authProps.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+     authProps.setProperty(DistributionConfig.LOCATORS_NAME, "");
+     authProps.setProperty(DistributionConfig.SECURITY_LOG_LEVEL_NAME, "finest");
+     // TODO (ashetkar) Add " && (!multiUserAuthMode)" below.
+     if (authInitModule != null) {
+       authProps.setProperty(DistributionConfig.SECURITY_CLIENT_AUTH_INIT_NAME,
+           authInitModule);
+     }
+ 
+     SecurityTestUtil tmpInstance = new SecurityTestUtil("temp");
+     tmpInstance.createSystem(authProps, javaProps);
+     AttributesFactory factory = new AttributesFactory();
+     int[] portsI = new int[ports.length];
+     for(int z=0;z<ports.length;z++) {
+       portsI[z] = ports[z].intValue();
+     }
+    
+     try {
+       PoolFactory poolFactory = PoolManager.createFactory();
+       poolFactory.setRetryAttempts(200);
+       if (multiUserAuthMode) {
+         poolFactory.setMultiuserAuthentication(multiUserAuthMode);
+         // [sumedh] Why is this false here only to be overridden in
+         // ClientServerTestCase.configureConnectionPoolWithNameAndFactory below?
+         // Actually setting it to false causes MultiuserAPIDUnitTest to fail.
+         //poolFactory.setSubscriptionEnabled(false);
+       }
+       pool = ClientServerTestCase.configureConnectionPoolWithNameAndFactory(factory,
+           NetworkUtils.getIPLiteral(), portsI, subscriptionEnabled, 0,
+           numConnections == null ? -1 : numConnections.intValue(), null, null,
+           poolFactory);
+ 
+       if (setupDynamicRegionFactory.booleanValue()) {
+         initClientDynamicRegionFactory(pool.getName());
+       }
+       tmpInstance.openCache();
+       try {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("multi-user mode " + multiUserAuthMode);
+         proxyCaches[0] = (ProxyCache)((PoolImpl) pool).createAuthenticatedCacheView(authProps);
+         if (!multiUserAuthMode) {
+           fail("Expected a UnsupportedOperationException but got none in single-user mode");
+         }
+       } catch (UnsupportedOperationException uoe) {
+         if (!multiUserAuthMode) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected UnsupportedOperationException in single-user mode");
+         }
+         else {
+           Assert.fail("Got unexpected exception in multi-user mode ", uoe);
+         }
+       }
+ 
+       factory.setScope(Scope.LOCAL);
+       if (multiUserAuthMode) {
+         factory.setDataPolicy(DataPolicy.EMPTY);
+       }
+       RegionAttributes attrs = factory.create();
+       cache.createRegion(regionName, attrs);
+ 
+       if (expectedResult.intValue() != NO_EXCEPTION
+           && expectedResult.intValue() != NOFORCE_AUTHREQ_EXCEPTION) {
+         if (!multiUserAuthMode) {
+           fail("Expected an exception when starting client");
+         }
+       }
+     }
+     catch (AuthenticationRequiredException ex) {
+       if (expectedResult.intValue() == AUTHREQ_EXCEPTION
+           || expectedResult.intValue() == NOFORCE_AUTHREQ_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when starting client: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting client", ex);
+       }
+     }
+     catch (AuthenticationFailedException ex) {
+       if (expectedResult.intValue() == AUTHFAIL_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when starting client: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting client", ex);
+       }
+     }
+     catch (ServerRefusedConnectionException ex) {
+       if (expectedResult.intValue() == CONNREFUSED_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when starting client: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting client", ex);
+       }
+     }
+     catch (Exception ex) {
+       Assert.fail("Got unexpected exception when starting client", ex);
+     }
+   }
+ 
+   public static void createCacheClientForMultiUserMode(Integer numOfUsers,
+       String authInitModule, Properties[] authProps, Properties javaProps,
+       Integer[] ports, Integer numConnections,
+       Boolean setupDynamicRegionFactory, Integer expectedResult) {
+     createCacheClientForMultiUserMode(numOfUsers, authInitModule, authProps,
+         javaProps, ports, numConnections, setupDynamicRegionFactory, null,
+         expectedResult);
+   }
+ 
+   public static void createCacheClientForMultiUserMode(Integer numOfUsers,
+       String authInitModule, Properties[] authProps, Properties javaProps,
+       Integer[] ports, Integer numConnections,
+       Boolean setupDynamicRegionFactory, String durableClientId,
+       Integer expectedResult) {
+ 
+     if (numOfUsers == null || numOfUsers < 1) {
+       fail("Number of users cannot be less than one");
+     }
+     multiUserAuthMode = true;
+     // Assert that number of users == length of arrays of the provided params
+ //    if (numOfUsers != authInitModules.length) {
+ //      fail("Number of authInitModules provided does not match with numOfUsers specified, "
+ //          + authInitModules.length);
+ //    }
+     if (numOfUsers != authProps.length) {
+       fail("Number of authProps provided does not match with numOfUsers specified, "
+           + authProps.length);
+     }
+ //    if (numOfUsers != javaProps.length) {
+ //      fail("Number of javaProps provided does not match with numOfUsers specified, "
+ //          + javaProps.length);
+ //    }
+ //    if (numOfUsers != expectedResult.length) {
+ //      fail("Number of expectedResult provided does not match with numOfUsers specified, "
+ //          + expectedResult.length);
+ //    }
+     if (authProps[0] == null) {
+       authProps[0] = new Properties();
+     }
+     authProps[0].setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+     authProps[0].setProperty(DistributionConfig.LOCATORS_NAME, "");
+     authProps[0].setProperty(DistributionConfig.SECURITY_LOG_LEVEL_NAME,
+         "finest");
+     Properties props = new Properties();
+     if (authInitModule != null) {
+       authProps[0].setProperty(
+           DistributionConfig.SECURITY_CLIENT_AUTH_INIT_NAME, authInitModule);
+       props.setProperty(DistributionConfig.SECURITY_CLIENT_AUTH_INIT_NAME,
+           authInitModule);
+     }
+     if (durableClientId != null) {
+       props.setProperty(DistributionConfig.DURABLE_CLIENT_ID_NAME,
+           durableClientId);
+       props.setProperty(DistributionConfig.DURABLE_CLIENT_TIMEOUT_NAME, String
+           .valueOf(DistributionConfig.DEFAULT_DURABLE_CLIENT_TIMEOUT));
+     }
+ 
+     SecurityTestUtil tmpInstance = new SecurityTestUtil("temp");
+     tmpInstance.createSystem(props, javaProps);
+     AttributesFactory factory = new AttributesFactory();
+     int[] portsI = new int[ports.length];
+     for(int z=0;z<ports.length;z++) {
+       portsI[z] = ports[z].intValue();
+     }
+    
+     try {
+       tmpInstance.openCache();
+       PoolFactory poolFactory = PoolManager.createFactory();
+       poolFactory.setRetryAttempts(200);
+       poolFactory.setMultiuserAuthentication(multiUserAuthMode);
+       poolFactory.setSubscriptionEnabled(true);
+       pool = ClientServerTestCase.configureConnectionPoolWithNameAndFactory(factory,
+           NetworkUtils.getIPLiteral(), portsI, true, 1,
+           numConnections == null ? -1 : numConnections.intValue(), null, null,
+           poolFactory);
+ 
+       if (setupDynamicRegionFactory.booleanValue()) {
+         initClientDynamicRegionFactory(pool.getName());
+       }
+       proxyCaches = new ProxyCache[numOfUsers];
+       for (int i=0; i<numOfUsers; i++) {
+         proxyCaches[i] = (ProxyCache)((PoolImpl) pool).createAuthenticatedCacheView(authProps[i]);
+       }
+ 
+       factory.setScope(Scope.LOCAL);
+       factory.setDataPolicy(DataPolicy.EMPTY);
+       RegionAttributes attrs = factory.create();
+       cache.createRegion(regionName, attrs);
+ 
+       if (expectedResult.intValue() != NO_EXCEPTION
+           && expectedResult.intValue() != NOFORCE_AUTHREQ_EXCEPTION) {
+         if (!multiUserAuthMode) {
+           fail("Expected an exception when starting client");
+         }
+       }
+     }
+     catch (AuthenticationRequiredException ex) {
+       if (expectedResult.intValue() == AUTHREQ_EXCEPTION
+           || expectedResult.intValue() == NOFORCE_AUTHREQ_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when starting client: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting client", ex);
+       }
+     }
+     catch (AuthenticationFailedException ex) {
+       if (expectedResult.intValue() == AUTHFAIL_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when starting client: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting client", ex);
+       }
+     }
+     catch (ServerRefusedConnectionException ex) {
+       if (expectedResult.intValue() == CONNREFUSED_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when starting client: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when starting client", ex);
+       }
+     }
+     catch (Exception ex) {
+       Assert.fail("Got unexpected exception when starting client", ex);
+     }
+   }
+ 
+   public static void createProxyCache(Integer[] userIndices, Properties[] props) {
+     int j = 0;
+     for (int i : userIndices) {
+       SecurityTestUtil.proxyCaches[i] = (ProxyCache)((PoolImpl) SecurityTestUtil.pool)
+           .createAuthenticatedCacheView(props[j]);
+       j++;
+     }
+   }
+ 
+   public static void stopCacheServers() {
+     Iterator iter = getCache().getCacheServers().iterator();
+     if (iter.hasNext()) {
+       CacheServer server = (CacheServer)iter.next();
+       server.stop();
+       assertFalse(server.isRunning());
+     }
+   }
+ 
+   public static void restartCacheServers() {
+     Iterator iter = getCache().getCacheServers().iterator();
+     if (iter.hasNext()) {
+       CacheServer server = (CacheServer)iter.next();
+       try {
+         server.start();
+       }
+       catch (Exception ex) {
+         Assert.fail("Unexpected exception when restarting cache servers", ex);
+       }
+       assertTrue(server.isRunning());
+     }
+   }
+ 
+   public static void startLocator(String name, Integer port, Object extraProps,
+       Object javaProps, String[] expectedExceptions) {
+ 
+     File logFile = new File(name + "-locator" + port.intValue() + ".log");
+     try {
+       Properties authProps = new Properties();
+       if (extraProps != null) {
+         authProps.putAll((Properties)extraProps);
+       }
+       authProps.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+       authProps.setProperty(DistributionConfig.LOCATORS_NAME, 
+                             NetworkUtils.getIPLiteral() + "[" + port + "]");
+       authProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+       clearStaticSSLContext();
+       setJavaProps((Properties)javaProps);
+       FileOutputStream logOut = new FileOutputStream(logFile);
+       PrintStream logStream = new PrintStream(logOut);
+       LogWriter logger = new PureLogWriter(InternalLogWriter.CONFIG_LEVEL,
+           logStream);
+       addExpectedExceptions(expectedExceptions, logger);
+       logStream.flush();
+       locator = Locator.startLocatorAndDS(port.intValue(), logFile, null,
+           authProps);
+     }
+     catch (IOException ex) {
+       Assert.fail("While starting locator on port " + port.intValue(), ex);
+     }
+   }
+ 
+   public static void stopLocator(Integer port, String[] expectedExceptions) {
+ 
+     try {
+       locator.stop();
+       removeExpectedExceptions(expectedExceptions, locator
+           .getDistributedSystem().getLogWriter());
+     }
+     catch (Exception ex) {
+       Assert.fail("While stopping locator on port " + port.intValue(), ex);
+     }
+   }
+ 
+   public static Cache getCache() {
+     return cache;
+   }
+ 
+   // Some useful region methods used by security tests
+ 
+   public static void waitForCondition(Callable cond) {
+     waitForCondition(cond, 100, 120);
+   }
+ 
+   public static void waitForCondition(final Callable cond, int sleepMillis,
+       int numTries) {
+     WaitCriterion ev = new WaitCriterion() {
+       public boolean done() {
+         try {
+           return ((Boolean)cond.call()).booleanValue();
+         }
+         catch (Exception e) {
+           Assert.fail("Unexpected exception", e);
+         }
+         return false; // NOTREACHED
+       }
+       public String description() {
+         return null;
+       }
+     };
+     Wait.waitForCriterion(ev, sleepMillis * numTries, 200, true);
+   }
+ 
+   public static Object getLocalValue(Region region, Object key) {
+ 
+     Region.Entry entry = region.getEntry(key);
+     return (entry != null ? entry.getValue() : null);
+   }
+ 
+   public static void doProxyCacheClose() {
+     for (int i=0; i<proxyCaches.length; i++) {
+       proxyCaches[i].close();
+     }
+   }
+ 
+   private static void doPutsP(Integer num, Integer expectedResult,
+       boolean newVals) {
+     doPutsP(num, Integer.valueOf(0), expectedResult, newVals);
+   }
+ 
+   private static void doPutsP(Integer num, Integer multiUserIndex,
+       Integer expectedResult, boolean newVals) {
+ 
+     assertTrue(num.intValue() <= keys.length);
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+         regionRef = region;
+       }
+       else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     }
+     catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing puts: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when doing puts", ex);
+       }
+     }
+     for (int index = 0; index < num.intValue(); ++index) {
+       try {
+         if (newVals) {
+           region.put(keys[index], nvalues[index]);
+         }
+         else {
+           region.put(keys[index], values[index]);
+         }
+         if (expectedResult.intValue() != NO_EXCEPTION) {
+           fail("Expected a NotAuthorizedException while doing puts");
+         }
+       }
+       catch(NoAvailableServersException ex) {
+         if(expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NoAvailableServers when doing puts: "
+               + ex.getCause());
+           continue;
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing puts", ex);
+         }
+       }
+       catch (ServerConnectivityException ex) {
+         if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+             && (ex.getCause() instanceof NotAuthorizedException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NotAuthorizedException when doing puts: "
+                   + ex.getCause());
+           continue;
+         }
+         if ((expectedResult.intValue() == AUTHREQ_EXCEPTION)
+             && (ex.getCause() instanceof AuthenticationRequiredException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected AuthenticationRequiredException when doing puts: "
+                   + ex.getCause());
+           continue;
+         }
+         if ((expectedResult.intValue() == AUTHFAIL_EXCEPTION)
+             && (ex.getCause() instanceof AuthenticationFailedException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected AuthenticationFailedException when doing puts: "
+                   + ex.getCause());
+           continue;
+         }
+         else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing puts: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing puts", ex);
+         }
+       }
+       catch (Exception ex) {
+         if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing puts: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing puts", ex);
+         }
+       }
+     }
+   }
+ 
+   private static void doGetAllP(Integer multiUserIndex,
+       Integer expectedResult, boolean useTX) {
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       }
+       else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     }
+     catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing getAll: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when doing getAll", ex);
+       }
+     }
+     try {
+       List keys = new ArrayList();
+       keys.add("key1");
+       keys.add("key2");
+       if (useTX) {
+         getCache().getCacheTransactionManager().begin();
+       }
+       Map entries = region.getAll(keys);
+       // Also check getEntry()
+       region.getEntry("key1");
+       if (useTX) {
+         getCache().getCacheTransactionManager().commit();
+       }
+       assertNotNull(entries);
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)) {
+         assertEquals(0, entries.size());
+       } else if ((expectedResult.intValue() == NO_EXCEPTION)) {
+         assertEquals(2, entries.size());
+         assertEquals("value1", entries.get("key1"));
+         assertEquals("value2", entries.get("key2"));
+       }
+     } catch (NoAvailableServersException ex) {
+       if (expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NoAvailableServers when doing getAll: "
+                 + ex.getCause());
+       } else {
+         Assert.fail("Got unexpected exception when doing getAll", ex);
+       }
+     } catch (ServerConnectivityException ex) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && (ex.getCause() instanceof NotAuthorizedException)) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when doing getAll: "
+                 + ex.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing getAll: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing getAll", ex);
+       }
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing getAll: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing getAll", ex);
+       }
+     }
+   }
+ 
+   private static void doGetsP(Integer num, Integer expectedResult,
+       boolean newVals) {
+     doGetsP(num, Integer.valueOf(0), expectedResult, newVals);
+   }
+ 
+   private static void doGetsP(Integer num, Integer multiUserIndex,
+       Integer expectedResult, boolean newVals) {
+ 
+     assertTrue(num.intValue() <= keys.length);
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       }
+       else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     }
+     catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing gets: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when doing gets", ex);
+       }
+     }
+     for (int index = 0; index < num.intValue(); ++index) {
+       Object value = null;
+       try {
+         try {
+           region.localInvalidate(keys[index]);
+         }
+         catch (Exception ex) {
+         }
+         value = region.get(keys[index]);
+         if (expectedResult.intValue() != NO_EXCEPTION) {
+           fail("Expected a NotAuthorizedException while doing gets");
+         }
+       }
+       catch(NoAvailableServersException ex) {
+         if(expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NoAvailableServers when doing gets: "
+               + ex.getCause());
+           continue;
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing gets", ex);
+         }
+       }
+       catch (ServerConnectivityException ex) {
+         if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+             && (ex.getCause() instanceof NotAuthorizedException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NotAuthorizedException when doing gets: "
+                   + ex.getCause());
+           continue;
+         }
+         else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing gets: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing gets", ex);
+         }
+       }
+       catch (Exception ex) {
+         if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing gets: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing gets", ex);
+         }
+       }
+       assertNotNull(value);
+       if (newVals) {
+         assertEquals(nvalues[index], value);
+       }
+       else {
+         assertEquals(values[index], value);
+       }
+     }
+   }
+ 
+   private static void doLocalGetsP(int num, boolean checkNVals) {
+ 
+     assertTrue(num <= keys.length);
+     String[] vals = values;
+     if (checkNVals) {
+       vals = nvalues;
+     }
+     final Region region = getCache().getRegion(regionName);
+     assertNotNull(region);
+     for (int index = 0; index < num; ++index) {
+       final String key = keys[index];
+       final String expectedVal = vals[index];
+       waitForCondition(new Callable() {
+         public Object call() throws Exception {
+           Object value = getLocalValue(region, key);
+           return Boolean.valueOf(expectedVal.equals(value));
+         }
+       }, 1000, 30 / num);
+     }
+     for (int index = 0; index < num; ++index) {
+       Region.Entry entry = region.getEntry(keys[index]);
+       assertNotNull(entry);
+       assertEquals(vals[index], entry.getValue());
+     }
+   }
+ 
+   private static void doRegionDestroysP(Integer multiuserIndex,
+       Integer expectedResult) {
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiuserIndex].getRegion(regionName);
+       } else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when doing region destroy: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing region destroy", ex);
+       }
+     }
+ 
+     try {
+       region.destroyRegion();
+       if (expectedResult.intValue() != NO_EXCEPTION) {
+         fail("Expected a NotAuthorizedException while doing region destroy");
+       }
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiuserIndex].getRegion(regionName);
+       } else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNull(region);
+     } catch (NoAvailableServersException ex) {
+       if (expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NoAvailableServers when doing region destroy: "
+                 + ex.getCause());
+       } else {
+         Assert.fail("Got unexpected exception when doing region destroy", ex);
+       }
+     } catch (ServerConnectivityException ex) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && (ex.getCause() instanceof NotAuthorizedException)) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when doing region destroy: "
+                 + ex.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when doing region destroy: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing region destroy", ex);
+       }
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when doing region destroy: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing region destroy", ex);
+       }
+     }
+   }
+   
+   private static void doDestroysP(Integer num, Integer multiUserIndex,
+       Integer expectedResult, boolean newVals) {
+ 
+     assertTrue(num.intValue() <= keys.length);
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       }
+       else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     }
+     catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing destroys: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when doing destroys", ex);
+       }
+     }
+     for (int index = 0; index < num.intValue(); ++index) {
+       try {
+         region.destroy(keys[index]);
+         if (expectedResult.intValue() != NO_EXCEPTION) {
+           fail("Expected a NotAuthorizedException while doing destroys");
+         }
+       }
+       catch(NoAvailableServersException ex) {
+         if(expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NoAvailableServers when doing destroys: "
+               + ex.getCause());
+           continue;
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing destroys", ex);
+         }
+       }
+       catch (ServerConnectivityException ex) {
+         if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+             && (ex.getCause() instanceof NotAuthorizedException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NotAuthorizedException when doing destroys: "
+                   + ex.getCause());
+           continue;
+         }
+         else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing destroys: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing destroys", ex);
+         }
+       }
+       catch (Exception ex) {
+         if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing destroys: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing destroys", ex);
+         }
+       }
+     }
+   }
+ 
+   private static void doInvalidatesP(Integer num, Integer multiUserIndex,
+       Integer expectedResult, boolean newVals) {
+ 
+     assertTrue(num.intValue() <= keys.length);
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       }
+       else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     }
+     catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing invalidates: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when doing invalidates", ex);
+       }
+     }
+     for (int index = 0; index < num.intValue(); ++index) {
+       try {
+         region.invalidate(keys[index]);
+         if (expectedResult.intValue() != NO_EXCEPTION) {
+           fail("Expected a NotAuthorizedException while doing invalidates");
+         }
+       }
+       catch(NoAvailableServersException ex) {
+         if(expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NoAvailableServers when doing invalidates: "
+               + ex.getCause());
+           continue;
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing invalidates", ex);
+         }
+       }
+       catch (ServerConnectivityException ex) {
+         if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+             && (ex.getCause() instanceof NotAuthorizedException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NotAuthorizedException when doing invalidates: "
+                   + ex.getCause());
+           continue;
+         }
+         else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing invalidates: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing invalidates", ex);
+         }
+       }
+       catch (Exception ex) {
+         if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing invalidates: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing invalidates", ex);
+         }
+       }
+     }
+   }
+ 
+   private static void doContainsKeysP(Integer num, Integer multiUserIndex,
+       Integer expectedResult, boolean newVals, boolean expectedValue) {
+ 
+     assertTrue(num.intValue() <= keys.length);
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       }
+       else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     }
+     catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing containsKey: " + ex);
+       }
+       else {
+         Assert.fail("Got unexpected exception when doing containsKey", ex);
+       }
+     }
+     for (int index = 0; index < num.intValue(); ++index) {
+       boolean result = false;
+       try {
+         result = region.containsKeyOnServer(keys[index]);
+         if (expectedResult.intValue() != NO_EXCEPTION) {
+           fail("Expected a NotAuthorizedException while doing containsKey");
+         }
+       }
+       catch(NoAvailableServersException ex) {
+         if(expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NoAvailableServers when doing containsKey: "
+               + ex.getCause());
+           continue;
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing containsKey", ex);
+         }
+       }
+       catch (ServerConnectivityException ex) {
+         if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+             && (ex.getCause() instanceof NotAuthorizedException)) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+               "Got expected NotAuthorizedException when doing containsKey: "
+                   + ex.getCause());
+           continue;
+         }
+         else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing containsKey: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing containsKey", ex);
+         }
+       }
+       catch (Exception ex) {
+         if (expectedResult.intValue() == OTHER_EXCEPTION) {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing containsKey: " + ex);
+         }
+         else {
+           Assert.fail("Got unexpected exception when doing containsKey", ex);
+         }
+       }
+       assertEquals(expectedValue, result);
+     }
+   }
+ 
+   private static void doQueriesP(Integer multiUserIndex,
+       Integer expectedResult, Integer expectedValue) {
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       } else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing queries: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing queries", ex);
+       }
+     }
+     String queryStr = "SELECT DISTINCT * FROM " + region.getFullPath();
+     try {
+       SelectResults queryResults = region.query(queryStr);
+       Set resultSet = queryResults.asSet();
+       assertEquals(expectedValue.intValue(), resultSet.size());
+       if (expectedResult.intValue() != NO_EXCEPTION) {
+         fail("Expected a NotAuthorizedException while doing queries");
+       }
+     } catch (NoAvailableServersException ex) {
+       if (expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NoAvailableServers when doing queries: "
+                 + ex.getCause());
+       } else {
+         Assert.fail("Got unexpected exception when doing queries", ex);
+       }
+     } catch (ServerConnectivityException ex) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && (ex.getCause() instanceof NotAuthorizedException)) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when doing queries: "
+                 + ex.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing queries: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing queries", ex);
+       }
+     } catch (QueryInvocationTargetException qite) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && (qite.getCause() instanceof NotAuthorizedException)) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when doing queries: "
+                 + qite.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing queries: " + qite);
+       } else {
+         Assert.fail("Got unexpected exception when doing queries", qite);
+       }
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Got expected exception when doing queries: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when doing queries", ex);
+       }
+     }
+   }
+ 
+   private static void doFunctionExecuteP(Integer multiUserIndex,
+       Function function, Integer expectedResult, Object expectedValue,
+       String method) {
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       } else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing function: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing function", ex);
+       }
+     }
+     try {
+       FunctionService.registerFunction(function);
+       Execution execution = null;
+       if ("region".equals(method)) {
+         execution = FunctionService.onRegion(region);
+       } else if ("server".equals(method)) {
+         if (multiUserAuthMode) {
+           execution = FunctionService.onServer(proxyCaches[multiUserIndex]);
+         } else {
+           execution = FunctionService.onServer(pool);
+         }
+       } else { // if ("servers".equals(method)) {
+         if (multiUserAuthMode) {
+           execution = FunctionService.onServers(proxyCaches[multiUserIndex]);
+         } else {
+           execution = FunctionService.onServers(pool);
+         }
+       }
+       execution.execute(function.getId());
+       if (expectedResult.intValue() != NO_EXCEPTION) {
+         fail("Expected a NotAuthorizedException while executing function");
+       }
+     } catch (NoAvailableServersException ex) {
+       if (expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NoAvailableServers when executing function: "
+                 + ex.getCause());
+       } else {
+         Assert.fail("Got unexpected exception when executing function", ex);
+       }
+     } catch (ServerConnectivityException ex) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && (ex.getCause() instanceof NotAuthorizedException)) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when executing function: "
+                 + ex.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing function: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing function", ex);
+       }
+     } catch (FunctionException ex) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && ((ex.getCause() instanceof NotAuthorizedException) || ((ex
+               .getCause() instanceof ServerOperationException) && (((ServerOperationException)ex
+               .getCause()).getCause() instanceof NotAuthorizedException)))) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when executing function: "
+                 + ex.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing function: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing function", ex);
+       }
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing function: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing function", ex);
+       }
+     }
+   }
+ 
+   private static void doQueryExecuteP(Integer multiUserIndex,
+       Integer expectedResult, Integer expectedValue) {
+     Region region = null;
+     try {
+       if (multiUserAuthMode) {
+         region = proxyCaches[multiUserIndex].getRegion(regionName);
+       } else {
+         region = getCache().getRegion(regionName);
+       }
+       assertNotNull(region);
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing query: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing query", ex);
+       }
+     }
+     try {
+       String queryString = "SELECT DISTINCT * FROM " + region.getFullPath();
+       Query query = null;
+       if (multiUserAuthMode) {
+         query = proxyCaches[multiUserIndex].getQueryService().newQuery(queryString);
+       }
+       else {
+         region.getCache().getQueryService().newQuery(queryString);
+       }
+       SelectResults result = (SelectResults)query.execute();
+       if (expectedResult.intValue() != NO_EXCEPTION) {
+         fail("Expected a NotAuthorizedException while executing function");
+       }
+       assertEquals(expectedValue.intValue(), result.asList().size());
+     } catch (NoAvailableServersException ex) {
+       if (expectedResult.intValue() == SecurityTestUtil.NO_AVAILABLE_SERVERS) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NoAvailableServers when executing query: "
+                 + ex.getCause());
+       } else {
+         Assert.fail("Got unexpected exception when executing query", ex);
+       }
+     } catch (ServerConnectivityException ex) {
+       if ((expectedResult.intValue() == NOTAUTHZ_EXCEPTION)
+           && (ex.getCause() instanceof NotAuthorizedException)) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected NotAuthorizedException when executing query: "
+                 + ex.getCause());
+       } else if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing query: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing query", ex);
+       }
+     } catch (Exception ex) {
+       if (expectedResult.intValue() == OTHER_EXCEPTION) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+             "Got expected exception when executing query: " + ex);
+       } else {
+         Assert.fail("Got unexpected exception when executing query", ex);
+       }
+     }
+   }
+ 
+   public static void doPuts(Integer num) {
+ 
+     doPutsP(num, new Integer(NO_EXCEPTION), false);
+   }
+ 
+   public static void doPuts(Integer num, Integer expectedResult) {
+ 
+     doPutsP(num, expectedResult, false);
+   }
+ 
+   public static void doMultiUserPuts(Integer num, Integer numOfUsers,
+       Integer[] expectedResults) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserPuts(): numOfUsers = " + numOfUsers
+           + ", but expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("PUT: MultiUser# " + i);
+       doPutsP(num, Integer.valueOf(i), expectedResults[i], false);
+     }
+   }
+ 
+   public static void doGets(Integer num) {
+ 
+     doGetsP(num, new Integer(NO_EXCEPTION), false);
+   }
+ 
+   public static void doGets(Integer num, Integer expectedResult) {
+ 
+     doGetsP(num, expectedResult, false);
+   }
+ 
+   public static void doMultiUserGetAll(Integer numOfUsers, Integer[] expectedResults) {
+     doMultiUserGetAll(numOfUsers, expectedResults, false);
+   }
+ 
+   public static void doMultiUserGetAll(Integer numOfUsers,
+       Integer[] expectedResults, boolean useTX) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserGetAll(): numOfUsers = " + numOfUsers
+           + ", but expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info(
+           "GET_ALL" + (useTX ? " in TX" : "") + ": MultiUser# " + i);
+       doGetAllP(Integer.valueOf(i), expectedResults[i], useTX);
+     }
+   }
+   
+   public static void doMultiUserGets(Integer num, Integer numOfUsers,
+       Integer[] expectedResults) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserGets(): numOfUsers = " + numOfUsers
+           + ", but expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("GET: MultiUser# " + i);
+       doGetsP(num, Integer.valueOf(i), expectedResults[i], false);
+     }
+   }
+ 
+   public static void doMultiUserRegionDestroys(Integer numOfUsers,
+       Integer[] expectedResults) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserRegionDestroys(): numOfUsers = " + numOfUsers
+           + ", but expected results " + expectedResults.length);
+     }
+     for (int i = numOfUsers-1; i >= 0; i--) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("DESTROY: MultiUser# " + i);
+       doRegionDestroysP(Integer.valueOf(i), expectedResults[i]);
+     }
+   }
+ 
+   public static void doMultiUserDestroys(Integer num, Integer numOfUsers,
+       Integer[] expectedResults) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserDestroys(): numOfUsers = " + numOfUsers
+           + ", but expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("DESTROY: MultiUser# " + i);
+       doDestroysP(num, Integer.valueOf(i), expectedResults[i], false);
+     }
+   }
+ 
+   public static void doMultiUserInvalidates(Integer num, Integer numOfUsers,
+       Integer[] expectedResults) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserInvalidates(): numOfUsers = " + numOfUsers
+           + ", but expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("INVALIDATE: MultiUser# " + i);
+       doInvalidatesP(num, Integer.valueOf(i), expectedResults[i], false);
+     }
+   }
+ 
+   public static void doMultiUserContainsKeys(Integer num, Integer numOfUsers,
+       Integer[] expectedResults, Boolean[] results) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserContainsKeys(): numOfUsers = " + numOfUsers
+           + ", but #expected results " + expectedResults.length);
+     }
+     if (numOfUsers != results.length) {
+       fail("SecurityTestUtil.doMultiUserContainsKeys(): numOfUsers = " + numOfUsers
+           + ", but #expected output " + results.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("CONTAINS_KEY: MultiUser# " + i);
+       doContainsKeysP(num, Integer.valueOf(i), expectedResults[i], false, results[i]);
+     }
+   }
+ 
+   public static void doMultiUserQueries(Integer numOfUsers,
+       Integer[] expectedResults, Integer valueSize) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserQueries(): numOfUsers = " + numOfUsers
+           + ", but #expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("QUERY: MultiUser# " + i);
+       doQueriesP(Integer.valueOf(i), expectedResults[i], valueSize);
+     }
+   }
+ 
+   public static void doMultiUserFE(Integer numOfUsers, Function function,
+       Integer[] expectedResults, Object[] results, Boolean isFailoverCase) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserFE(): numOfUsers = " + numOfUsers
+           + ", but #expected results " + expectedResults.length);
+     }
+     if (numOfUsers != results.length) {
+       fail("SecurityTestUtil.doMultiUserFE(): numOfUsers = " + numOfUsers
+           + ", but #expected output " + results.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("FunctionExecute:onRegion MultiUser# " + i);
+       doFunctionExecuteP(Integer.valueOf(i), function, expectedResults[i], results[i], "region");
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("FunctionExecute:onServer MultiUser# " + i);
+       doFunctionExecuteP(Integer.valueOf(i), function, expectedResults[i], results[i], "server");
+     }
+     if (!isFailoverCase) {
+       for (int i = 0; i < numOfUsers; i++) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("FunctionExecute:onServers MultiUser# " + i);
+         doFunctionExecuteP(Integer.valueOf(i), function, expectedResults[i],
+             results[i], "servers");
+       }
+     }
+   }
+ 
+   public static void doMultiUserQueryExecute(Integer numOfUsers,
+       Integer[] expectedResults, Integer result) {
+     if (numOfUsers != expectedResults.length) {
+       fail("SecurityTestUtil.doMultiUserFE(): numOfUsers = " + numOfUsers
+           + ", but #expected results " + expectedResults.length);
+     }
+     for (int i = 0; i < numOfUsers; i++) {
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("QueryExecute: MultiUser# " + i);
+       doQueryExecuteP(Integer.valueOf(i), expectedResults[i], result);
+     }
+   }
+ 
+   public static void doLocalGets(Integer num) {
+ 
+     doLocalGetsP(num.intValue(), false);
+   }
+ 
+   public static void doNPuts(Integer num) {
+ 
+     doPutsP(num, new Integer(NO_EXCEPTION), true);
+   }
+ 
+   public static void doNPuts(Integer num, Integer expectedResult) {
+ 
+     doPutsP(num, expectedResult, true);
+   }
+ 
+   public static void doNGets(Integer num) {
+ 
+     doGetsP(num, new Integer(NO_EXCEPTION), true);
+   }
+ 
+   public static void doNGets(Integer num, Integer expectedResult) {
+ 
+     doGetsP(num, expectedResult, true);
+   }
+ 
+   public static void doNLocalGets(Integer num) {
+ 
+     doLocalGetsP(num.intValue(), true);
+   }
+ 
+   public static void doSimpleGet(String expectedResult) {
+     if (regionRef != null) {
+       try {
+         regionRef.get("KEY");
+         if (expectedResult != null && expectedResult.endsWith("Exception")) {
+           fail("Expected " + expectedResult + " but found none in doSimpleGet()");
+         }
+       } catch (Exception e) {
+         if (!e.getClass().getSimpleName().endsWith(expectedResult)) {
+           fail("Expected " + expectedResult + " but found "
+               + e.getClass().getSimpleName() + " in doSimpleGet()");
+         } else {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().fine(
+               "Got expected " + e.getClass().getSimpleName()
+                   + " in doSimpleGet()");
+         }
+       }
+     }
+   }
+ 
+   public static void doSimplePut(String expectedResult) {
+     if (regionRef != null) {
+       try {
+         regionRef.put("KEY", "VALUE");
+         if (expectedResult != null && expectedResult.endsWith("Exception")) {
+           fail("Expected " + expectedResult + " but found none in doSimplePut()");
+         }
+       } catch (Exception e) {
+         if (!e.getClass().getSimpleName().endsWith(expectedResult)) {
+           Assert.fail("Expected " + expectedResult + " but found "
+               + e.getClass().getSimpleName() + " in doSimplePut()", e);
+         } else {
+           com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().fine(
+               "Got expected " + e.getClass().getSimpleName()
+                   + " in doSimplePut()");
+         }
+       }
+     }
+   }
+   // Deal with javax SSL properties
+ 
+   private static void makeNullStaticField(Class cls) {
+ 
+     Field[] fields = cls.getDeclaredFields();
+     for (int index = 0; index < fields.length; ++index) {
+       Field field = fields[index];
+       try {
+         if (Modifier.isStatic(field.getModifiers())) {
+           field.setAccessible(true);
+           if (field.getClass().equals(boolean.class)) {
+             field.setBoolean(null, false);
+             assertFalse(field.getBoolean(null));
+           }
+           else if (cls.isInstance(field.get(null))) {
+             field.set(null, null);
+             assertNull(field.get(null));
+           }
+         }
+       }
+       catch (IllegalAccessException ex) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter()
+             .warning("Exception while clearing static SSL field.", ex);
+       }
+       catch (ClassCastException ex) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter()
+             .warning("Exception while clearing static SSL field.", ex);
+       }
+     }
+   }
+ 
+   private static void makeNullSSLFields(Object obj, Map fieldMap) {
+ 
+     Iterator fieldIter = fieldMap.entrySet().iterator();
+     while (fieldIter.hasNext()) {
+       Map.Entry entry = (Map.Entry)fieldIter.next();
+       Field field = (Field)entry.getKey();
+       Object fieldObj = entry.getValue();
+       try {
+         field.setAccessible(true);
+         makeNullStaticField(fieldObj.getClass());
+         field.set(obj, null);
+         assertNull(field.get(obj));
+       }
+       catch (IllegalAccessException ex) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().warning("Exception while clearing SSL fields.", ex);
+       }
+     }
+   }
+ 
+   private static HashMap getSSLFields(Object obj, Class[] classes) {
+ 
+     HashMap resultFields = new HashMap();
+     Field[] fields = obj.getClass().getDeclaredFields();
+     for (int index = 0; index < fields.length; ++index) {
+       Field field = fields[index];
+       try {
+         field.setAccessible(true);
+         Object fieldObj = field.get(obj);
+         boolean isInstance = false;
+         for (int classIndex = 0; classIndex < classes.length; ++classIndex) {
+           if ((isInstance = classes[classIndex].isInstance(fieldObj)) == true) {
+             break;
+           }
+         }
+         if (isInstance) {
+           resultFields.put(field, fieldObj);
+         }
+       }
+       catch (IllegalAccessException ex) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().warning("Exception while getting SSL fields.", ex);
+       }
+     }
+     return resultFields;
+   }
+ 
+   // This is a hack using reflection to clear the static objects in JSSE since
+   // otherwise changing the javax.* store related properties has no effect
+   // during the course of running dunit suite unless the VMs are restarted.
+   public static void clearStaticSSLContext() {
+ 
+     ServerSocketFactory defaultServerFact = SSLServerSocketFactory.getDefault();
+     // Get the class of this and use reflection to blank out any static
+     // SSLContext objects inside
+     Map contextMap = getSSLFields(defaultServerFact, new Class[] {
+         SSLContext.class, SSLContextSpi.class });
+     makeNullSSLFields(defaultServerFact, contextMap);
+     Iterator contextObjsIter = contextMap.values().iterator();
+     while (contextObjsIter.hasNext()) {
+       Object contextObj = contextObjsIter.next();
+       Map contextObjsMap = getSSLFields(contextObj, new Class[] {
+           TrustManager.class, KeyManager.class, TrustManager[].class,
+           KeyManager[].class });
+       makeNullSSLFields(contextObj, contextObjsMap);
+     }
+     makeNullStaticField(SSLServerSocketFactory.class);
+ 
+     // Do the same for normal SSL socket factory
+     SocketFactory defaultFact = SSLSocketFactory.getDefault();
+     contextMap = getSSLFields(defaultFact, new Class[] { SSLContext.class,
+         SSLContextSpi.class });
+     makeNullSSLFields(defaultFact, contextMap);
+     contextObjsIter = contextMap.values().iterator();
+     while (contextObjsIter.hasNext()) {
+       Object contextObj = contextObjsIter.next();
+       Map contextObjsMap = getSSLFields(contextObj, new Class[] {
+           TrustManager.class, KeyManager.class, TrustManager[].class,
+           KeyManager[].class });
+       makeNullSSLFields(contextObj, contextObjsMap);
+     }
+     makeNullStaticField(SSLSocketFactory.class);
+     makeNullStaticField(SSLContext.class);
+   }
+ 
+   private static LogWriter getLogger() {
+ 
+     LogWriter logger = null;
+     DistributedSystem dsys = system;
+     if (dsys == null || !dsys.isConnected()) {
+       while ((dsys = InternalDistributedSystem.getAnyInstance()) != null
+           && !dsys.isConnected()) {
+       }
+     }
+     if (dsys != null && dsys.isConnected()) {
+       logger = dsys.getLogWriter();
+     }
+     return logger;
+   }
+ 
+   public static void closeCache() {
+ 
+     LogWriter logger = getLogger();
+     if (logger != null) {
+       removeExpectedExceptions(SecurityTestUtil.expectedExceptions, logger);
+     }
+     if (cache != null && !cache.isClosed()) {
+       DistributedSystem sys = cache.getDistributedSystem();
+       cache.close();
+       sys.disconnect();
+       cache = null;
+     }
+     disconnectFromDS();
+   }
+ 
+   public static void closeCache(Boolean keepAlive) {
+     LogWriter logger = getLogger();
+     if (logger != null) {
+       removeExpectedExceptions(SecurityTestUtil.expectedExceptions, logger);
+     }
+     if (cache != null && !cache.isClosed()) {
+       DistributedSystem sys = cache.getDistributedSystem();
+       cache.close(keepAlive);
+       sys.disconnect();
+       cache = null;
+     }
+     disconnectFromDS();
+   }
+ 
+ }


[075/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java
index 0000000,0000000..5020c7a
new file mode 100644
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapForm.java
@@@ -1,0 -1,0 +1,40 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.offheap;
++
++/**
++ * Used to keep the heapForm around while an operation is still in progress.
++ * This allows the operation to access the serialized heap form instead of copying
++ * it from offheap. See bug 48135.
++ */
++public class ObjectChunkWithHeapForm extends ObjectChunk {
++  private final byte[] heapForm;
++  
++  public ObjectChunkWithHeapForm(ObjectChunk chunk, byte[] heapForm) {
++    super(chunk);
++    this.heapForm = heapForm;
++  }
++
++  @Override
++  protected byte[] getRawBytes() {
++    return this.heapForm;
++  }
++  
++  public ObjectChunk getChunkWithoutHeapForm() {
++    return new ObjectChunk(this);
++  }
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
index 0000000,1ec722d..bd380e2
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
@@@ -1,0 -1,142 +1,142 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.internal.DSCODE;
+ import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
+ import com.gemstone.gemfire.internal.cache.EntryBits;
+ import com.gemstone.gemfire.internal.cache.RegionEntry;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ /**
+  * This abstract class is intended to be used by {@link MemoryChunk} implementations that also want
+  * to be a CachedDeserializable.
+  * 
+  * @author darrel
+  * @since 9.0
+  */
+ public abstract class OffHeapCachedDeserializable extends AbstractStoredObject implements MemoryChunkWithRefCount {
+   public abstract void setSerializedValue(byte[] value);
+   @Override
+   public abstract byte[] getSerializedValue();
+   @Override
+   public abstract int getSizeInBytes();
+   @Override
+   public abstract int getValueSizeInBytes();
+   @Override
+   public abstract Object getDeserializedValue(Region r, RegionEntry re);
+ 
+   @Override
+   public void fillSerializedValue(BytesAndBitsForCompactor wrapper, byte userBits) {
+     if (isSerialized()) {
+       userBits = EntryBits.setSerialized(userBits, true);
+     }
 -    wrapper.setChunkData((Chunk) this, userBits);
++    wrapper.setChunkData((ObjectChunk) this, userBits);
+   }
+   
+   String getShortClassName() {
+     String cname = getClass().getName();
+     return cname.substring(getClass().getPackage().getName().length()+1);
+   }
+ 
+   @Override
+   public String toString() {
+     return getShortClassName()+"@"+this.hashCode();
+   }
+   public boolean checkDataEquals(@Unretained OffHeapCachedDeserializable other) {
+     if (this == other) {
+       return true;
+     }
+     if (isSerialized() != other.isSerialized()) {
+       return false;
+     }
+     int mySize = getValueSizeInBytes();
+     if (mySize != other.getValueSizeInBytes()) {
+       return false;
+     }
+     // We want to be able to do this operation without copying any of the data into the heap.
+     // Hopefully the jvm is smart enough to use our stack for this short lived array.
+     final byte[] dataCache1 = new byte[1024];
+     final byte[] dataCache2 = new byte[dataCache1.length];
+     // TODO OFFHEAP: no need to copy to heap. Just get the address of each and compare each byte.
+     int i;
+     // inc it twice since we are reading two different off-heap objects
+     SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+     SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+     for (i=0; i < mySize-(dataCache1.length-1); i+=dataCache1.length) {
+       this.readBytes(i, dataCache1);
+       other.readBytes(i, dataCache2);
+       for (int j=0; j < dataCache1.length; j++) {
+         if (dataCache1[j] != dataCache2[j]) {
+           return false;
+         }
+       }
+     }
+     int bytesToRead = mySize-i;
+     if (bytesToRead > 0) {
+       // need to do one more read which will be less than dataCache.length
+       this.readBytes(i, dataCache1, 0, bytesToRead);
+       other.readBytes(i, dataCache2, 0, bytesToRead);
+       for (int j=0; j < bytesToRead; j++) {
+         if (dataCache1[j] != dataCache2[j]) {
+           return false;
+         }
+       }
+     }
+     return true;
+   }
+   
+   public boolean isSerializedPdxInstance() {
+     byte dsCode = this.readByte(0);
+     return dsCode == DSCODE.PDX || dsCode == DSCODE.PDX_ENUM || dsCode == DSCODE.PDX_INLINE_ENUM;
+   }
+   
+   public boolean checkDataEquals(byte[] serializedObj) {
+     // caller was responsible for checking isSerialized
+     int mySize = getValueSizeInBytes();
+     if (mySize != serializedObj.length) {
+       return false;
+     }
+     // We want to be able to do this operation without copying any of the data into the heap.
+     // Hopefully the jvm is smart enough to use our stack for this short lived array.
+     // TODO OFFHEAP: compare as ByteBuffers?
+     final byte[] dataCache = new byte[1024];
+     int idx=0;
+     int i;
+     SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+     for (i=0; i < mySize-(dataCache.length-1); i+=dataCache.length) {
+       this.readBytes(i, dataCache);
+       for (int j=0; j < dataCache.length; j++) {
+         if (dataCache[j] != serializedObj[idx++]) {
+           return false;
+         }
+       }
+     }
+     int bytesToRead = mySize-i;
+     if (bytesToRead > 0) {
+       // need to do one more read which will be less than dataCache.length
+       this.readBytes(i, dataCache, 0, bytesToRead);
+       for (int j=0; j < bytesToRead; j++) {
+         if (dataCache[j] != serializedObj[idx++]) {
+           return false;
+         }
+       }
+     }
+     return true;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
index 0000000,84e4218..b62d97a
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
@@@ -1,0 -1,418 +1,406 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import com.gemstone.gemfire.internal.DSCODE;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializableFactory;
+ import com.gemstone.gemfire.internal.cache.DiskEntry;
+ import com.gemstone.gemfire.internal.cache.DiskId;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.cache.OffHeapRegionEntry;
+ import com.gemstone.gemfire.internal.cache.RegionEntryContext;
+ import com.gemstone.gemfire.internal.cache.Token;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ /**
+  * The class just has static methods
+  * that operate on instances of {@link OffHeapRegionEntry}.
+  * It allows common code to be shared for all the
+  * classes we have that implement {@link OffHeapRegionEntry}.
+  * 
+  * @author darrel
+  * @since 9.0
+  */
+ public class OffHeapRegionEntryHelper {
+ 
+   protected static final long NULL_ADDRESS = 0L<<1;
+   protected static final long INVALID_ADDRESS = 1L<<1;
+   protected static final long LOCAL_INVALID_ADDRESS = 2L<<1;
+   protected static final long DESTROYED_ADDRESS = 3L<<1;
+   protected static final long REMOVED_PHASE1_ADDRESS = 4L<<1;
+   protected static final long REMOVED_PHASE2_ADDRESS = 5L<<1;
+   protected static final long END_OF_STREAM_ADDRESS = 6L<<1;
+   protected static final long NOT_AVAILABLE_ADDRESS = 7L<<1;
+   protected static final long TOMBSTONE_ADDRESS = 8L<<1;
+   public static final int MAX_LENGTH_FOR_DATA_AS_ADDRESS = 8;
 - /* private static final ChunkFactory chunkFactory ;
 -  static {
 -    ChunkFactory factory;
 -    try {
 -       factory= SimpleMemoryAllocatorImpl.getAllocator().getChunkFactory();
 -         
 -    }catch(CacheClosedException ce) {
 -      factory = null;
 -    }
 -    chunkFactory = factory;
 -  }*/
+   
+   private static final Token[] addrToObj = new Token[]{
+     null,
+     Token.INVALID,
+     Token.LOCAL_INVALID,
+     Token.DESTROYED,
+     Token.REMOVED_PHASE1,
+     Token.REMOVED_PHASE2,
+     Token.END_OF_STREAM,
+     Token.NOT_AVAILABLE,
+     Token.TOMBSTONE,
+   };
+   
+   private static long objectToAddress(@Unretained Object v) {
 -    if (v instanceof Chunk) return ((Chunk) v).getMemoryAddress();
++    if (v instanceof ObjectChunk) return ((ObjectChunk) v).getMemoryAddress();
+     if (v instanceof DataAsAddress) return ((DataAsAddress) v).getEncodedAddress();
+     if (v == null) return NULL_ADDRESS;
+     if (v == Token.TOMBSTONE) return TOMBSTONE_ADDRESS;
+     if (v == Token.INVALID) return INVALID_ADDRESS;
+     if (v == Token.LOCAL_INVALID) return LOCAL_INVALID_ADDRESS;
+     if (v == Token.DESTROYED) return DESTROYED_ADDRESS;
+     if (v == Token.REMOVED_PHASE1) return REMOVED_PHASE1_ADDRESS;
+     if (v == Token.REMOVED_PHASE2) return REMOVED_PHASE2_ADDRESS;
+     if (v == Token.END_OF_STREAM) return END_OF_STREAM_ADDRESS;
+     if (v == Token.NOT_AVAILABLE) return NOT_AVAILABLE_ADDRESS;
+     throw new IllegalStateException("Can not convert " + v + " to an off heap address.");
+   }
+   
+   /**
+    * This method may release the object stored at ohAddress if the result
+    * needs to be decompressed and the decompress parameter is true.
+    * This decompressed result will be on the heap.
+    * 
+    * @param ohAddress OFF_HEAP_ADDRESS
+    * @param decompress true if off-heap value should be decompressed before returning
+    * @param context used for decompression
+    * @return OFF_HEAP_OBJECT (sometimes)
+    */
+   @Unretained @Retained
+   public static Object addressToObject(@Released @Retained long ohAddress, boolean decompress, RegionEntryContext context) {
+     if (isOffHeap(ohAddress)) {
 -      //Chunk chunk = chunkFactory.newChunk(ohAddress);
 -      @Unretained Chunk chunk =  SimpleMemoryAllocatorImpl.getAllocator().getChunkFactory().newChunk(ohAddress);
++      @Unretained ObjectChunk chunk =  new ObjectChunk(ohAddress);
+       @Unretained Object result = chunk;
+       if (decompress && chunk.isCompressed()) {
+         try {
+           // to fix bug 47982 need to:
+           byte[] decompressedBytes = chunk.getDecompressedBytes(context);
+           if (chunk.isSerialized()) {
+             // return a VMCachedDeserializable with the decompressed serialized bytes since chunk is serialized
+             result = CachedDeserializableFactory.create(decompressedBytes);
+           } else {
+             // return a byte[] since chunk is not serialized
+             result = decompressedBytes;
+           }
+         } finally {
+           // decompress is only true when this method is called by _getValueRetain.
+           // In that case the caller has already retained ohAddress because it thought
+           // we would return it. But we have unwrapped it and are returning the decompressed results.
+           // So we need to release the chunk here.
+             chunk.release();
+         }
+       }
+       return result;
+     } else if ((ohAddress & ENCODED_BIT) != 0) {
+       DataAsAddress daa = new DataAsAddress(ohAddress);
+       Object result = daa;
+       if (decompress && daa.isCompressed()) {
+         byte[] decompressedBytes = daa.getDecompressedBytes(context);
+         if (daa.isSerialized()) {
+           // return a VMCachedDeserializable with the decompressed serialized bytes since daa is serialized
+           result = CachedDeserializableFactory.create(decompressedBytes);
+         } else {
+           // return a byte[] since daa is not serialized
+           result = decompressedBytes;
+         }
+       }
+       return result;
+     } else {
+       return addrToObj[(int) ohAddress>>1];
+     }
+   }
+   
+   public static int getSerializedLengthFromDataAsAddress(DataAsAddress dataAsAddress) {
+     final long ohAddress = dataAsAddress.getEncodedAddress();
+     
+      if ((ohAddress & ENCODED_BIT) != 0) {     
+       boolean isLong = (ohAddress & LONG_BIT) != 0;     
+       if (isLong) {
+        return 9;
+       } else {
+         return (int) ((ohAddress & SIZE_MASK) >> SIZE_SHIFT);        
+       }     
+     } else {
+       return 0;
+     }
+   }
+   
+  /*
+   * This method is optimized for cases where if the caller wants to convert address to a Token
+   * compared to addressToObject which would deserialize the value.
+   */
+   private static Token addressToToken(long ohAddress) {
+     if (isOffHeap(ohAddress) || (ohAddress & ENCODED_BIT) != 0) {
+       return Token.NOT_A_TOKEN;
+     } else {
+       return addrToObj[(int) ohAddress>>1];
+     }
+   }
+ 
+   private static void releaseAddress(@Released long ohAddress) {
+     if (isOffHeap(ohAddress)) {
 -      Chunk.release(ohAddress, true);
++      ObjectChunk.release(ohAddress);
+     }
+   }
+   
+   /**
+    * The address in 're' will be @Released.
+    */
+   public static void releaseEntry(@Released OffHeapRegionEntry re) {
+     if (re instanceof DiskEntry) {
+       DiskId did = ((DiskEntry) re).getDiskId();
+       if (did != null && did.isPendingAsync()) {
+         synchronized (did) {
+           // This may not be needed so remove this call if it causes problems.
+           // We no longer need this entry to be written to disk so unschedule it
+           // before we change its value to REMOVED_PHASE2.
+           did.setPendingAsync(false);
+           setValue(re, Token.REMOVED_PHASE2);
+           return;
+         }
+       }
+     }
+     setValue(re, Token.REMOVED_PHASE2);
+   }
+ 
+   public static void releaseEntry(@Unretained OffHeapRegionEntry re, @Released MemoryChunkWithRefCount expectedValue) {
+     long oldAddress = objectToAddress(expectedValue);
+     final long newAddress = objectToAddress(Token.REMOVED_PHASE2);
+     if (re.setAddress(oldAddress, newAddress) || re.getAddress() != newAddress) {
+       releaseAddress(oldAddress);
+     } /*else {
+       if (!calledSetValue || re.getAddress() != newAddress) {
+         expectedValue.release();
+       }
+     }*/
+   }
+   
+   /**
+    * This bit is set to indicate that this address has data encoded in it.
+    */
+   private static long ENCODED_BIT = 1L;
+   /**
+    * This bit is set to indicate that the encoded data is serialized.
+    */
+   static long SERIALIZED_BIT = 2L;
+   /**
+    * This bit is set to indicate that the encoded data is compressed.
+    */
+   static long COMPRESSED_BIT = 4L;
+   /**
+    * This bit is set to indicate that the encoded data is a long whose value fits in 7 bytes.
+    */
+   private static long LONG_BIT = 8L;
+   /**
+    * size is in the range 0..7 so we only need 3 bits.
+    */
+   private static long SIZE_MASK = 0x70L;
+   /**
+    * number of bits to shift the size by.
+    */
+   private static int SIZE_SHIFT = 4;
+   // the msb of this byte is currently unused
+   
+   /**
+    * Returns 0 if the data could not be encoded as an address.
+    */
+   public static long encodeDataAsAddress(byte[] v, boolean isSerialized, boolean isCompressed) {
+     if (v.length < MAX_LENGTH_FOR_DATA_AS_ADDRESS) {
+       long result = 0L;
+       for (int i=0; i < v.length; i++) {
+         result |= v[i] & 0x00ff;
+         result <<= 8;
+       }
+       result |= (v.length << SIZE_SHIFT) | ENCODED_BIT;
+       if (isSerialized) {
+         result |= SERIALIZED_BIT;
+       }
+       if (isCompressed) {
+         result |= COMPRESSED_BIT;
+       }
+       return result;
+     } else if (isSerialized && !isCompressed) {
+       // Check for some special types that take more than 7 bytes to serialize
+       // but that might be able to be inlined with less than 8 bytes.
+       if (v[0] == DSCODE.LONG) {
+         // A long is currently always serialized as 8 bytes (9 if you include the dscode).
+         // But many long values will actually be small enough for is to encode in 7 bytes.
+         if ((v[1] == 0 && (v[2] & 0x80) == 0) || (v[1] == -1 && (v[2] & 0x80) != 0)) {
+           // The long can be encoded as 7 bytes since the most signification byte
+           // is simply an extension of the sign byte on the second most signification byte.
+           long result = 0L;
+           for (int i=2; i < v.length; i++) {
+             result |= v[i] & 0x00ff;
+             result <<= 8;
+           }
+           result |= (7 << SIZE_SHIFT) | LONG_BIT | SERIALIZED_BIT | ENCODED_BIT;
+           return result;
+         }
+       }
+     }
+     return 0L;
+   }
+ 
+   static Object decodeAddressToObject(long ohAddress) {
+       byte[] bytes = decodeAddressToBytes(ohAddress, true, false);
+ 
+       boolean isSerialized = (ohAddress & SERIALIZED_BIT) != 0;
+       if (isSerialized) {
+          return EntryEventImpl.deserialize(bytes);
+       } else {
+           return bytes;
+       }
+   }
+ 
+   static byte[] decodeAddressToBytes(long addr, boolean decompress, boolean compressedOk) {
+     assert (addr & ENCODED_BIT) != 0;
+     boolean isCompressed = (addr & COMPRESSED_BIT) != 0;
+     int size = (int) ((addr & SIZE_MASK) >> SIZE_SHIFT);
+     boolean isLong = (addr & LONG_BIT) != 0;
+     byte[] bytes;
+     if (isLong) {
+       bytes = new byte[9];
+       bytes[0] = DSCODE.LONG;
+       for (int i=8; i >=2; i--) {
+         addr >>= 8;
+         bytes[i] = (byte) (addr & 0x00ff);
+       }
+       if ((bytes[2] & 0x80) != 0) {
+         bytes[1] = -1;
+       } else {
+         bytes[1] = 0;
+       }
+     } else {
+       bytes = new byte[size];
+       for (int i=size-1; i >=0; i--) {
+         addr >>= 8;
+         bytes[i] = (byte) (addr & 0x00ff);
+       }
+     }
+     if (decompress && isCompressed) {
+       if (!compressedOk) {
+         throw new UnsupportedOperationException("Did not expect DataAsAddress to be compressed");
+       }
+     }
+     return bytes;
+   }
+ 
+   /**
+    * The previous value at the address in 're' will be @Released and then the
+    * address in 're' will be set to the @Unretained address of 'v'.
+    */
+   public static void setValue(@Released OffHeapRegionEntry re, @Unretained Object v) {
+     // setValue is called when synced so I don't need to worry
+     // about oldAddress being released by someone else.
+     final long newAddress = objectToAddress(v);
+     long oldAddress;
+     do {
+       oldAddress = re.getAddress();
+     } while (!re.setAddress(oldAddress, newAddress));
+     ReferenceCountHelper.setReferenceCountOwner(re);
+     releaseAddress(oldAddress);
+     ReferenceCountHelper.setReferenceCountOwner(null);
+   }
+  
+   public static Token getValueAsToken(@Unretained OffHeapRegionEntry re) {
+     return addressToToken(re.getAddress());
+   }
+ 
+   @Unretained
+   public static Object _getValue(@Unretained OffHeapRegionEntry re) {
+     return addressToObject(re.getAddress(), false, null); // no context needed so decompress is false
+   }
+   
+   public static boolean isOffHeap(long addr) {
+     if ((addr & ENCODED_BIT) != 0) return false;
+     if (addr < 0) return true;
+     addr >>= 1; // shift right 1 to convert to array index;
+     return addr >= addrToObj.length;
+   }
+ 
+   /**
+    * If the value stored at the location held in 're' is returned, then it will
+    * be Retained.  If the value returned is 're' decompressed into another
+    * off-heap location, then 're' will be Unretained but the new,
+    * decompressed value will be Retained.  Therefore, whichever is returned
+    * (the value at the address in 're' or the decompressed value) it will have
+    * been Retained.
+    * 
+    * @return possible OFF_HEAP_OBJECT (caller must release)
+    */
+   @Retained
+   public static Object _getValueRetain(@Retained @Unretained OffHeapRegionEntry re, boolean decompress, RegionEntryContext context) {
+     int retryCount = 0;
+     @Retained long addr = re.getAddress();
+     while (isOffHeap(addr)) {
 -      if (Chunk.retain(addr)) {
++      if (ObjectChunk.retain(addr)) {
+         @Unretained long addr2 = re.getAddress();
+         if (addr != addr2) {
+           retryCount = 0;
 -          Chunk.release(addr, true);
++          ObjectChunk.release(addr);
+           // spin around and try again.
+           addr = addr2;
+         } else {
+           return addressToObject(addr, decompress, context);
+         }
+       } else {
+         // spin around and try again
+         long addr2 = re.getAddress();
+         retryCount++;
+         if (retryCount > 100) {
+           throw new IllegalStateException("retain failed addr=" + addr + " addr2=" + addr + " 100 times" + " history=" + ReferenceCountHelper.getFreeRefCountInfo(addr));
+         }
+         addr = addr2;
+         // Since retain returned false our region entry should have a different
+         // value in it. However the actual address could be the exact same one
+         // because addr was released, then reallocated from the free list and set
+         // back into this region entry. See bug 47782
+       }
+     }
+     return addressToObject(addr, decompress, context);
+   }
+   
+  
+ 
+   public static boolean isSerialized(long address) {
+     return (address & SERIALIZED_BIT) != 0;
+   }
+ 
+   public static boolean isCompressed(long address) {
+     return (address & COMPRESSED_BIT) != 0;
+   }
+   
+   private static final ThreadLocal<Object> clearNeedsToCheckForOffHeap = new ThreadLocal<Object>();
+   public static boolean doesClearNeedToCheckForOffHeap() {
+     return clearNeedsToCheckForOffHeap.get() != null;
+   }
+   public static void doWithOffHeapClear(Runnable r) {
+     clearNeedsToCheckForOffHeap.set(Boolean.TRUE);
+     try {
+       r.run();
+     } finally {
+       clearNeedsToCheckForOffHeap.remove();
+     }
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
index 0000000,12d297b..14bde59
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
@@@ -1,0 -1,625 +1,511 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Set;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionService;
+ import com.gemstone.gemfire.internal.cache.BucketRegion;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+ import com.gemstone.gemfire.internal.cache.PartitionedRegionDataStore;
+ import com.gemstone.gemfire.internal.cache.RegionEntry;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ /**
+  * This allocator is somewhat like an Arena allocator.
+  * We start out with an array of multiple large chunks of memory.
+  * We also keep lists of any chunk that have been allocated and freed.
+  * An allocation will always try to find a chunk in a free list that is a close fit to the requested size.
+  * If no close fits exist then it allocates the next slice from the front of one the original large chunks.
+  * If we can not find enough free memory then all the existing free memory is compacted.
+  * If we still do not have enough to make the allocation an exception is thrown.
+  * 
+  * @author darrel
+  * @author Kirk Lund
+  * @since 9.0
+  */
 -public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
++public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
+ 
+   static final Logger logger = LogService.getLogger();
+   
+   public static final String FREE_OFF_HEAP_MEMORY_PROPERTY = "gemfire.free-off-heap-memory";
+   
 -  /**
 -   * How many extra allocations to do for each actual slab allocation.
 -   * Is this really a good idea?
 -   */
 -  public static final int BATCH_SIZE = Integer.getInteger("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE", 1);
 -  /**
 -   * Every allocated chunk smaller than TINY_MULTIPLE*TINY_FREE_LIST_COUNT will allocate a chunk of memory that is a multiple of this value.
 -   * Sizes are always rounded up to the next multiple of this constant
 -   * so internal fragmentation will be limited to TINY_MULTIPLE-1 bytes per allocation
 -   * and on average will be TINY_MULTIPLE/2 given a random distribution of size requests.
 -   * This does not account for the additional internal fragmentation caused by the off-heap header
 -   * which currently is always 8 bytes.
 -   */
 -  public final static int TINY_MULTIPLE = Integer.getInteger("gemfire.OFF_HEAP_ALIGNMENT", 8);
 -  /**
 -   * Number of free lists to keep for tiny allocations.
 -   */
 -  public final static int TINY_FREE_LIST_COUNT = Integer.getInteger("gemfire.OFF_HEAP_FREE_LIST_COUNT", 16384);
 -  public final static int MAX_TINY = TINY_MULTIPLE*TINY_FREE_LIST_COUNT;
 -  /**
 -   * How many unused bytes are allowed in a huge memory allocation.
 -   */
 -  public final static int HUGE_MULTIPLE = 256;
 -  
 -  volatile OffHeapMemoryStats stats;
++  private volatile OffHeapMemoryStats stats;
+   
 -  volatile OutOfOffHeapMemoryListener ooohml;
 -  
 -  /** The MemoryChunks that this allocator is managing by allocating smaller chunks of them.
 -   * The contents of this array never change.
 -   */
 -  private final UnsafeMemoryChunk[] slabs;
 -  private final long totalSlabSize;
 -  private final int largestSlab;
++  private volatile OutOfOffHeapMemoryListener ooohml;
+   
++  OutOfOffHeapMemoryListener getOutOfOffHeapMemoryListener() {
++    return this.ooohml;
++  }
++
+   public final FreeListManager freeList;
+ 
+   private MemoryInspector memoryInspector;
+ 
+   private volatile MemoryUsageListener[] memoryUsageListeners = new MemoryUsageListener[0];
+   
+   private static SimpleMemoryAllocatorImpl singleton = null;
 -  final ChunkFactory chunkFactory;
+   
+   public static SimpleMemoryAllocatorImpl getAllocator() {
+     SimpleMemoryAllocatorImpl result = singleton;
+     if (result == null) {
+       throw new CacheClosedException("Off Heap memory allocator does not exist.");
+     }
+     return result;
+   }
+ 
+   private static final boolean DO_EXPENSIVE_VALIDATION = Boolean.getBoolean("gemfire.OFF_HEAP_DO_EXPENSIVE_VALIDATION");
+   
+   public static MemoryAllocator create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
+       int slabCount, long offHeapMemorySize, long maxSlabSize) {
+     return create(ooohml, stats, lw, slabCount, offHeapMemorySize, maxSlabSize,
 -        null, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE, 
 -        new UnsafeMemoryChunk.Factory() {
++        null, new AddressableMemoryChunkFactory() {
+       @Override
 -      public UnsafeMemoryChunk create(int size) {
++      public AddressableMemoryChunk create(int size) {
+         return new UnsafeMemoryChunk(size);
+       }
+     });
+   }
+ 
+   private static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
+       int slabCount, long offHeapMemorySize, long maxSlabSize, 
 -      UnsafeMemoryChunk[] slabs, int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple,
 -      UnsafeMemoryChunk.Factory memChunkFactory) {
++      AddressableMemoryChunk[] slabs, AddressableMemoryChunkFactory memChunkFactory) {
+     SimpleMemoryAllocatorImpl result = singleton;
+     boolean created = false;
+     try {
+     if (result != null) {
+       result.reuse(ooohml, lw, stats, offHeapMemorySize, slabs);
+       if (lw != null) {
 -        lw.config("Reusing " + result.getTotalMemory() + " bytes of off-heap memory. The maximum size of a single off-heap object is " + result.largestSlab + " bytes.");
++        lw.config("Reusing " + result.getTotalMemory() + " bytes of off-heap memory. The maximum size of a single off-heap object is " + result.freeList.getLargestSlabSize() + " bytes.");
+       }
+       created = true;
+       LifecycleListener.invokeAfterReuse(result);
+     } else {
+       if (slabs == null) {
+         // allocate memory chunks
+         //SimpleMemoryAllocatorImpl.cleanupPreviousAllocator();
+         if (lw != null) {
+           lw.config("Allocating " + offHeapMemorySize + " bytes of off-heap memory. The maximum size of a single off-heap object is " + maxSlabSize + " bytes.");
+         }
+         slabs = new UnsafeMemoryChunk[slabCount];
+         long uncreatedMemory = offHeapMemorySize;
+         for (int i=0; i < slabCount; i++) {
+           try {
+             if (uncreatedMemory >= maxSlabSize) {
+               slabs[i] = memChunkFactory.create((int) maxSlabSize);
+               uncreatedMemory -= maxSlabSize;
+             } else {
+               // the last slab can be smaller then maxSlabSize
+               slabs[i] = memChunkFactory.create((int) uncreatedMemory);
+             }
+           } catch (OutOfMemoryError err) {
+             if (i > 0) {
+               if (lw != null) {
+                 lw.severe("Off-heap memory creation failed after successfully allocating " + (i*maxSlabSize) + " bytes of off-heap memory.");
+               }
+             }
+             for (int j=0; j < i; j++) {
+               if (slabs[j] != null) {
+                 slabs[j].release();
+               }
+             }
+             throw err;
+           }
+         }
+       }
+ 
 -      result = new SimpleMemoryAllocatorImpl(ooohml, stats, slabs, tinyMultiple, batchSize, tinyFreeListCount, hugeMultiple);
++      result = new SimpleMemoryAllocatorImpl(ooohml, stats, slabs);
+       singleton = result;
+       LifecycleListener.invokeAfterCreate(result);
+       created = true;
+     }
+     } finally {
+       if (!created) {
+         if (stats != null) {
+           stats.close();
+         }
+         if (ooohml != null) {
+           ooohml.close();
+         }
+       }
+     }
+     return result;
+   }
 -  // for unit tests
 -  static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
 -      int slabCount, long offHeapMemorySize, long maxSlabSize, UnsafeMemoryChunk.Factory memChunkFactory) {
++  static SimpleMemoryAllocatorImpl createForUnitTest(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
++      int slabCount, long offHeapMemorySize, long maxSlabSize, AddressableMemoryChunkFactory memChunkFactory) {
+     return create(ooohml, stats, lw, slabCount, offHeapMemorySize, maxSlabSize, 
 -        null, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE, memChunkFactory);
 -  }
 -  // for unit tests
 -  public static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, UnsafeMemoryChunk[] slabs) {
 -    return create(oooml, stats, slabs, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE);
++        null, memChunkFactory);
+   }
 -  // for unit tests
 -  static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, UnsafeMemoryChunk[] slabs,
 -      int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple) {
++  public static SimpleMemoryAllocatorImpl createForUnitTest(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, AddressableMemoryChunk[] slabs) {
+     int slabCount = 0;
+     long offHeapMemorySize = 0;
+     long maxSlabSize = 0;
+     if (slabs != null) {
+       slabCount = slabs.length;
+       for (int i=0; i < slabCount; i++) {
+         int slabSize = slabs[i].getSize();
+         offHeapMemorySize += slabSize;
+         if (slabSize > maxSlabSize) {
+           maxSlabSize = slabSize;
+         }
+       }
+     }
 -    return create(oooml, stats, null, slabCount, offHeapMemorySize, maxSlabSize, slabs, tinyMultiple, batchSize, tinyFreeListCount, hugeMultiple, null);
++    return create(oooml, stats, null, slabCount, offHeapMemorySize, maxSlabSize, slabs, null);
+   }
+   
+   
 -  private void reuse(OutOfOffHeapMemoryListener oooml, LogWriter lw, OffHeapMemoryStats newStats, long offHeapMemorySize, UnsafeMemoryChunk[] slabs) {
++  private void reuse(OutOfOffHeapMemoryListener oooml, LogWriter lw, OffHeapMemoryStats newStats, long offHeapMemorySize, AddressableMemoryChunk[] slabs) {
+     if (isClosed()) {
+       throw new IllegalStateException("Can not reuse a closed off-heap memory manager.");
+     }
+     if (oooml == null) {
+       throw new IllegalArgumentException("OutOfOffHeapMemoryListener is null");
+     }
+     if (getTotalMemory() != offHeapMemorySize) {
+       if (lw != null) {
+         lw.warning("Using " + getTotalMemory() + " bytes of existing off-heap memory instead of the requested " + offHeapMemorySize);
+       }
+     }
 -    if (slabs != null) {
 -      // this will only happen in unit tests
 -      if (slabs != this.slabs) {
 -        // If the unit test gave us a different array
 -        // of slabs then something is wrong because we
 -        // are trying to reuse the old already allocated
 -        // array which means that the new one will never
 -        // be used. Note that this code does not bother
 -        // comparing the contents of the arrays.
 -        throw new IllegalStateException("attempted to reuse existing off-heap memory even though new off-heap memory was allocated");
 -      }
++    if (!this.freeList.okToReuse(slabs)) {
++      throw new IllegalStateException("attempted to reuse existing off-heap memory even though new off-heap memory was allocated");
+     }
+     this.ooohml = oooml;
+     newStats.initialize(this.stats);
+     this.stats = newStats;
+   }
+ 
 -  private SimpleMemoryAllocatorImpl(final OutOfOffHeapMemoryListener oooml, final OffHeapMemoryStats stats, final UnsafeMemoryChunk[] slabs,
 -      int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple) {
++  private SimpleMemoryAllocatorImpl(final OutOfOffHeapMemoryListener oooml, final OffHeapMemoryStats stats, final AddressableMemoryChunk[] slabs) {
+     if (oooml == null) {
+       throw new IllegalArgumentException("OutOfOffHeapMemoryListener is null");
+     }
 -    if (tinyMultiple <= 0 || (tinyMultiple & 3) != 0) {
 -      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8.");
 -    }
 -    if (tinyMultiple > 256) {
 -      // this restriction exists because of the dataSize field in the object header.
 -      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be <= 256 and a multiple of 8.");
 -    }
 -    if (batchSize <= 0) {
 -      throw new IllegalStateException("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE must be >= 1.");
 -    }
 -    if (tinyFreeListCount <= 0) {
 -      throw new IllegalStateException("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
 -    }
 -    if (hugeMultiple > 256 || hugeMultiple < 0) {
 -      // this restriction exists because of the dataSize field in the object header.
 -      throw new IllegalStateException("HUGE_MULTIPLE must be >= 0 and <= 256 but it was " + hugeMultiple);
 -    }
+     
+     this.ooohml = oooml;
+     this.stats = stats;
 -    this.slabs = slabs;
 -    this.chunkFactory = new GemFireChunkFactory();
 -    
++
+     //OSProcess.printStacks(0, InternalDistributedSystem.getAnyInstance().getLogWriter(), false);
+     this.stats.setFragments(slabs.length);
 -    largestSlab = slabs[0].getSize();
 -    this.stats.setLargestFragment(largestSlab);
 -    long total = 0;
 -    for (int i=0; i < slabs.length; i++) {
 -      //debugLog("slab"+i + " @" + Long.toHexString(slabs[i].getMemoryAddress()), false);
 -      //UnsafeMemoryChunk.clearAbsolute(slabs[i].getMemoryAddress(), slabs[i].getSize()); // HACK to see what this does to bug 47883
 -      total += slabs[i].getSize();
 -    }
 -    totalSlabSize = total;
 -    this.stats.incMaxMemory(this.totalSlabSize);
 -    this.stats.incFreeMemory(this.totalSlabSize);
++    this.stats.setLargestFragment(slabs[0].getSize());
+     
 -    this.freeList = new FreeListManager(this);
++    this.freeList = new FreeListManager(this, slabs);
+     this.memoryInspector = new MemoryInspectorImpl(this.freeList);
++
++    this.stats.incMaxMemory(this.freeList.getTotalMemory());
++    this.stats.incFreeMemory(this.freeList.getTotalMemory());
+   }
+   
 -  public List<Chunk> getLostChunks() {
 -    List<Chunk> liveChunks = this.freeList.getLiveChunks();
 -    List<Chunk> regionChunks = getRegionLiveChunks();
 -    Set<Chunk> liveChunksSet = new HashSet<>(liveChunks);
 -    Set<Chunk> regionChunksSet = new HashSet<>(regionChunks);
++  public List<ObjectChunk> getLostChunks() {
++    List<ObjectChunk> liveChunks = this.freeList.getLiveChunks();
++    List<ObjectChunk> regionChunks = getRegionLiveChunks();
++    Set<ObjectChunk> liveChunksSet = new HashSet<>(liveChunks);
++    Set<ObjectChunk> regionChunksSet = new HashSet<>(regionChunks);
+     liveChunksSet.removeAll(regionChunksSet);
 -    return new ArrayList<Chunk>(liveChunksSet);
++    return new ArrayList<ObjectChunk>(liveChunksSet);
+   }
+   
+   /**
+    * Returns a possibly empty list that contains all the Chunks used by regions.
+    */
 -  private List<Chunk> getRegionLiveChunks() {
 -    ArrayList<Chunk> result = new ArrayList<Chunk>();
++  private List<ObjectChunk> getRegionLiveChunks() {
++    ArrayList<ObjectChunk> result = new ArrayList<ObjectChunk>();
+     RegionService gfc = GemFireCacheImpl.getInstance();
+     if (gfc != null) {
+       Iterator<Region<?,?>> rootIt = gfc.rootRegions().iterator();
+       while (rootIt.hasNext()) {
+         Region<?,?> rr = rootIt.next();
+         getRegionLiveChunks(rr, result);
+         Iterator<Region<?,?>> srIt = rr.subregions(true).iterator();
+         while (srIt.hasNext()) {
+           getRegionLiveChunks(srIt.next(), result);
+         }
+       }
+     }
+     return result;
+   }
+ 
 -  private void getRegionLiveChunks(Region<?,?> r, List<Chunk> result) {
++  private void getRegionLiveChunks(Region<?,?> r, List<ObjectChunk> result) {
+     if (r.getAttributes().getOffHeap()) {
+ 
+       if (r instanceof PartitionedRegion) {
+         PartitionedRegionDataStore prs = ((PartitionedRegion) r).getDataStore();
+         if (prs != null) {
+           Set<BucketRegion> brs = prs.getAllLocalBucketRegions();
+           if (brs != null) {
+             for (BucketRegion br : brs) {
+               if (br != null && !br.isDestroyed()) {
+                 this.basicGetRegionLiveChunks(br, result);
+               }
+ 
+             }
+           }
+         }
+       } else {
+         this.basicGetRegionLiveChunks((LocalRegion) r, result);
+       }
+ 
+     }
+ 
+   }
+   
 -  private void basicGetRegionLiveChunks(LocalRegion r, List<Chunk> result) {
++  private void basicGetRegionLiveChunks(LocalRegion r, List<ObjectChunk> result) {
+     for (Object key : r.keySet()) {
+       RegionEntry re = ((LocalRegion) r).getRegionEntry(key);
+       if (re != null) {
+         /**
+          * value could be GATEWAY_SENDER_EVENT_IMPL_VALUE or region entry value.
+          */
+         @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
+         Object value = re._getValue();
 -        if (value instanceof Chunk) {
 -          result.add((Chunk) value);
++        if (value instanceof ObjectChunk) {
++          result.add((ObjectChunk) value);
+         }
+       }
+     }
+   }
+ 
 -  @Override
 -  public MemoryChunk allocate(int size, ChunkType chunkType) {
 -    //System.out.println("allocating " + size);
 -    Chunk result = this.freeList.allocate(size, chunkType);
 -    //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
++  private ObjectChunk allocateChunk(int size) {
++    ObjectChunk result = this.freeList.allocate(size);
++    int resultSize = result.getSize();
++    stats.incObjects(1);
++    stats.incUsedMemory(resultSize);
++    stats.incFreeMemory(-resultSize);
++    notifyListeners();
+     if (ReferenceCountHelper.trackReferenceCounts()) {
+       ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
+     }
+     return result;
+   }
+   
++  @Override
++  public MemoryChunk allocate(int size) {
++    //System.out.println("allocating " + size);
++    ObjectChunk result = allocateChunk(size);
++    //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
++    return result;
++  }
++  
+   public static void debugLog(String msg, boolean logStack) {
+     if (logStack) {
+       logger.info(msg, new RuntimeException(msg));
+     } else {
+       logger.info(msg);
+     }
+   }
+   
+   @Override
 -  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed, ChunkType chunkType) {
++  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed) {
+     long addr = OffHeapRegionEntryHelper.encodeDataAsAddress(v, isSerialized, isCompressed);
+     if (addr != 0L) {
+       return new DataAsAddress(addr);
+     }
 -    if (chunkType == null) {
 -      chunkType = GemFireChunk.TYPE;
 -    }
 -
 -    Chunk result = this.freeList.allocate(v.length, chunkType);
++    ObjectChunk result = allocateChunk(v.length);
+     //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()), true);
+     //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()) +  "chunkSize=" + result.getSize() + " isSerialized=" + isSerialized + " v=" + Arrays.toString(v), true);
 -    if (ReferenceCountHelper.trackReferenceCounts()) {
 -      ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
 -    }
 -    assert result.getChunkType() == chunkType: "chunkType=" + chunkType + " getChunkType()=" + result.getChunkType();
+     result.setSerializedValue(v);
+     result.setSerialized(isSerialized);
+     result.setCompressed(isCompressed);
+     return result;
+   }
+   
+   @Override
+   public long getFreeMemory() {
+     return this.freeList.getFreeMemory();
+   }
+ 
+   @Override
+   public long getUsedMemory() {
+     return this.freeList.getUsedMemory();
+   }
+ 
+   @Override
+   public long getTotalMemory() {
 -    return totalSlabSize;
++    return this.freeList.getTotalMemory();
+   }
+   
+   @Override
+   public void close() {
+     try {
+       LifecycleListener.invokeBeforeClose(this);
+     } finally {
+       this.ooohml.close();
+       if (Boolean.getBoolean(FREE_OFF_HEAP_MEMORY_PROPERTY)) {
+         realClose();
+       }
+     }
+   }
+   
+   public static void freeOffHeapMemory() {
+     SimpleMemoryAllocatorImpl ma = singleton;
+     if (ma != null) {
+       ma.realClose();
+     }
+   }
+   
+   private void realClose() {
+     // Removing this memory immediately can lead to a SEGV. See 47885.
+     if (setClosed()) {
 -      freeSlabs(this.slabs);
++      this.freeList.freeSlabs();
+       this.stats.close();
+       singleton = null;
+     }
+   }
+   
+   private final AtomicBoolean closed = new AtomicBoolean();
+   private boolean isClosed() {
+     return this.closed.get();
+   }
+   /**
+    * Returns true if caller is the one who should close; false if some other thread
+    * is already closing.
+    */
+   private boolean setClosed() {
+     return this.closed.compareAndSet(false, true);
+   }
+   
+ 
 -  private static void freeSlabs(final UnsafeMemoryChunk[] slabs) {
 -    //debugLog("called freeSlabs", false);
 -    for (int i=0; i < slabs.length; i++) {
 -      slabs[i].release();
 -    }
 -  }
 -  
 -  void freeChunk(long addr) {
 -    this.freeList.free(addr);
 -  }
 -  
 -  protected UnsafeMemoryChunk[] getSlabs() {
 -    return this.slabs;
++  FreeListManager getFreeListManager() {
++    return this.freeList;
+   }
+   
+   /**
+    * Return the slabId of the slab that contains the given addr.
+    */
+   int findSlab(long addr) {
 -    for (int i=0; i < this.slabs.length; i++) {
 -      UnsafeMemoryChunk slab = this.slabs[i];
 -      long slabAddr = slab.getMemoryAddress();
 -      if (addr >= slabAddr) {
 -        if (addr < slabAddr + slab.getSize()) {
 -          return i;
 -        }
 -      }
 -    }
 -    throw new IllegalStateException("could not find a slab for addr " + addr);
++    return this.freeList.findSlab(addr);
+   }
+   
+   public OffHeapMemoryStats getStats() {
+     return this.stats;
+   }
+   
 -  public ChunkFactory getChunkFactory() {
 -    return this.chunkFactory;
 -  }
 -
+   @Override
+   public void addMemoryUsageListener(final MemoryUsageListener listener) {
+     synchronized (this.memoryUsageListeners) {
+       final MemoryUsageListener[] newMemoryUsageListeners = Arrays.copyOf(this.memoryUsageListeners, this.memoryUsageListeners.length + 1);
+       newMemoryUsageListeners[this.memoryUsageListeners.length] = listener;
+       this.memoryUsageListeners = newMemoryUsageListeners;
+     }
+   }
+   
+   @Override
+   public void removeMemoryUsageListener(final MemoryUsageListener listener) {
+     synchronized (this.memoryUsageListeners) {
+       int listenerIndex = -1;
+       for (int i = 0; i < this.memoryUsageListeners.length; i++) {
+         if (this.memoryUsageListeners[i] == listener) {
+           listenerIndex = i;
+           break;
+         }
+       }
+ 
+       if (listenerIndex != -1) {
+         final MemoryUsageListener[] newMemoryUsageListeners = new MemoryUsageListener[this.memoryUsageListeners.length - 1];
+         System.arraycopy(this.memoryUsageListeners, 0, newMemoryUsageListeners, 0, listenerIndex);
+         System.arraycopy(this.memoryUsageListeners, listenerIndex + 1, newMemoryUsageListeners, listenerIndex,
+             this.memoryUsageListeners.length - listenerIndex - 1);
+         this.memoryUsageListeners = newMemoryUsageListeners;
+       }
+     }
+   }
+   
+   void notifyListeners() {
+     final MemoryUsageListener[] savedListeners = this.memoryUsageListeners;
+     
+     if (savedListeners.length == 0) {
+       return;
+     }
+ 
+     final long bytesUsed = getUsedMemory();
+     for (int i = 0; i < savedListeners.length; i++) {
+       savedListeners[i].updateMemoryUsed(bytesUsed);
+     }
+   }
+   
+   static void validateAddress(long addr) {
+     validateAddressAndSize(addr, -1);
+   }
+   
+   static void validateAddressAndSize(long addr, int size) {
+     // if the caller does not have a "size" to provide then use -1
+     if ((addr & 7) != 0) {
+       StringBuilder sb = new StringBuilder();
+       sb.append("address was not 8 byte aligned: 0x").append(Long.toString(addr, 16));
+       SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.singleton;
+       if (ma != null) {
+         sb.append(". Valid addresses must be in one of the following ranges: ");
 -        for (int i=0; i < ma.slabs.length; i++) {
 -          long startAddr = ma.slabs[i].getMemoryAddress();
 -          long endAddr = startAddr + ma.slabs[i].getSize();
 -          sb.append("[").append(Long.toString(startAddr, 16)).append("..").append(Long.toString(endAddr, 16)).append("] ");
 -        }
 -      }
++        ma.freeList.getSlabDescriptions(sb);
++     }
+       throw new IllegalStateException(sb.toString());
+     }
+     if (addr >= 0 && addr < 1024) {
+       throw new IllegalStateException("addr was smaller than expected 0x" + addr);
+     }
+     validateAddressAndSizeWithinSlab(addr, size, DO_EXPENSIVE_VALIDATION);
+   }
+ 
+   static void validateAddressAndSizeWithinSlab(long addr, int size, boolean doExpensiveValidation) {
+     if (doExpensiveValidation) {
+       SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.singleton;
+       if (ma != null) {
 -        for (int i=0; i < ma.slabs.length; i++) {
 -          if (ma.slabs[i].getMemoryAddress() <= addr && addr < (ma.slabs[i].getMemoryAddress() + ma.slabs[i].getSize())) {
 -            // validate addr + size is within the same slab
 -            if (size != -1) { // skip this check if size is -1
 -              if (!(ma.slabs[i].getMemoryAddress() <= (addr+size-1) && (addr+size-1) < (ma.slabs[i].getMemoryAddress() + ma.slabs[i].getSize()))) {
 -                throw new IllegalStateException(" address 0x" + Long.toString(addr+size-1, 16) + " does not address the original slab memory");
 -              }
 -            }
 -            return;
 -          }
++        if (!ma.freeList.validateAddressAndSizeWithinSlab(addr, size)) {
++          throw new IllegalStateException(" address 0x" + Long.toString(addr, 16) + " does not address the original slab memory");
+         }
 -        throw new IllegalStateException(" address 0x" + Long.toString(addr, 16) + " does not address the original slab memory");
+       }
+     }
+   }
+ 
+   public synchronized List<MemoryBlock> getOrphans() {
 -    List<Chunk> liveChunks = this.freeList.getLiveChunks();
 -    List<Chunk> regionChunks = getRegionLiveChunks();
++    List<ObjectChunk> liveChunks = this.freeList.getLiveChunks();
++    List<ObjectChunk> regionChunks = getRegionLiveChunks();
+     liveChunks.removeAll(regionChunks);
+     List<MemoryBlock> orphans = new ArrayList<MemoryBlock>();
 -    for (Chunk chunk: liveChunks) {
++    for (ObjectChunk chunk: liveChunks) {
+       orphans.add(new MemoryBlockNode(this, chunk));
+     }
+     Collections.sort(orphans,
+         new Comparator<MemoryBlock>() {
+           @Override
+           public int compare(MemoryBlock o1, MemoryBlock o2) {
+             return Long.valueOf(o1.getMemoryAddress()).compareTo(o2.getMemoryAddress());
+           }
+         });
+     //this.memoryBlocks = new WeakReference<List<MemoryBlock>>(orphans);
+     return orphans;
+   }
+ 
+   @Override
+   public MemoryInspector getMemoryInspector() {
+     return this.memoryInspector;
+   }
 -
 -  /*
 -   * Set this to "true" to perform data integrity checks on allocated and reused Chunks.  This may clobber 
 -   * performance so turn on only when necessary.
 -   */
 -  final boolean validateMemoryWithFill = Boolean.getBoolean("gemfire.validateOffHeapWithFill");
+   
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
index 0000000,7ba28a2..99fd96f
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
@@@ -1,0 -1,141 +1,141 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import com.gemstone.gemfire.LogWriter;
+ 
+ /**
+  * A "stack" of "chunk" instances. The chunks are not kept
+  * in java object form but instead each "chunk" is just an
+  * off-heap address.
+  * This class is used for each "tiny" free-list of the off-heap memory allocator.
+  */
+ public class SyncChunkStack {
+   // Ok to read without sync but must be synced on write
+   private volatile long topAddr;
+   
+   public SyncChunkStack(long addr) {
+     if (addr != 0L) SimpleMemoryAllocatorImpl.validateAddress(addr);
+     this.topAddr = addr;
+   }
+   public SyncChunkStack() {
+     this.topAddr = 0L;
+   }
+   public boolean isEmpty() {
+     return this.topAddr == 0L;
+   }
+   public void offer(long e) {
+     assert e != 0;
+     SimpleMemoryAllocatorImpl.validateAddress(e);
+     synchronized (this) {
 -      Chunk.setNext(e, this.topAddr);
++      ObjectChunk.setNext(e, this.topAddr);
+       this.topAddr = e;
+     }
+   }
+   public long poll() {
+     long result;
+     synchronized (this) {
+       result = this.topAddr;
+       if (result != 0L) {
 -        this.topAddr = Chunk.getNext(result);
++        this.topAddr = ObjectChunk.getNext(result);
+       }
+     }
+     return result;
+   }
+   /**
+    * Returns the address of the "top" item in this stack.
+    */
+   public long getTopAddress() {
+     return this.topAddr;
+   }
+   /**
+    * Removes all the Chunks from this stack
+    * and returns the address of the first chunk.
+    * The caller owns all the Chunks after this call.
+    */
+   public long clear() {
+     long result;
+     synchronized (this) {
+       result = this.topAddr;
+       if (result != 0L) {
+         this.topAddr = 0L;
+       }
+     }
+     return result;
+   }
+   public void logSizes(LogWriter lw, String msg) {
+     long headAddr = this.topAddr;
+     long addr;
+     boolean concurrentModDetected;
+     do {
+       concurrentModDetected = false;
+       addr = headAddr;
+       while (addr != 0L) {
 -        int curSize = Chunk.getSize(addr);
 -        addr = Chunk.getNext(addr);
++        int curSize = ObjectChunk.getSize(addr);
++        addr = ObjectChunk.getNext(addr);
+         testHookDoConcurrentModification();
+         long curHead = this.topAddr;
+         if (curHead != headAddr) {
+           headAddr = curHead;
+           concurrentModDetected = true;
+           // Someone added or removed from the stack.
+           // So we break out of the inner loop and start
+           // again at the new head.
+           break;
+         }
+         // TODO construct a single log msg
+         // that gets reset when concurrentModDetected.
+         lw.info(msg + curSize);
+       }
+     } while (concurrentModDetected);
+   }
+   public long computeTotalSize() {
+     long result;
+     long headAddr = this.topAddr;
+     long addr;
+     boolean concurrentModDetected;
+     do {
+       concurrentModDetected = false;
+       result = 0;
+       addr = headAddr;
+       while (addr != 0L) {
 -        result += Chunk.getSize(addr);
 -        addr = Chunk.getNext(addr);
++        result += ObjectChunk.getSize(addr);
++        addr = ObjectChunk.getNext(addr);
+         testHookDoConcurrentModification();
+         long curHead = this.topAddr;
+         if (curHead != headAddr) {
+           headAddr = curHead;
+           concurrentModDetected = true;
+           // Someone added or removed from the stack.
+           // So we break out of the inner loop and start
+           // again at the new head.
+           break;
+         }
+       }
+     } while (concurrentModDetected);
+     return result;
+   }
+   
+   /**
+    * This method allows tests to override it
+    * and do a concurrent modification to the stack.
+    * For production code it will be a noop.
+    */
+   protected void testHookDoConcurrentModification() {
+     // nothing needed in production code
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
index 0000000,ed1c843..aebc459
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
@@@ -1,0 -1,223 +1,217 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import com.gemstone.gemfire.internal.SharedLibrary;
+ import com.gemstone.gemfire.pdx.internal.unsafe.UnsafeWrapper;
+ 
+ /**
+  * Represents a single addressable chunk of off-heap memory. The size specifies
+  * the number of bytes stored at the address.
+  * 
+  * @since 9.0
+  */
 -public class UnsafeMemoryChunk implements MemoryChunk {
++public class UnsafeMemoryChunk implements AddressableMemoryChunk {
+   private static final UnsafeWrapper unsafe;
+   private static final int ARRAY_BYTE_BASE_OFFSET;
+   private static String reason;
+   static {
+ 	UnsafeWrapper tmp = null;
+ 	try {
+ 	  tmp = new UnsafeWrapper();
+ 	  reason = null;
+ 	} catch (RuntimeException ignore) {
+       reason = ignore.toString();
+ 	} catch (Error ignore) {
+       reason = ignore.toString();
+ 	}
+ 	unsafe = tmp;
+     ARRAY_BYTE_BASE_OFFSET = unsafe != null ? unsafe.arrayBaseOffset(byte[].class) : 0;
+   }
+   
+   private final long data;
+   private final int size;
+   
+   public UnsafeMemoryChunk(int size) {
+ 	if (unsafe == null) {
+       throw new OutOfMemoryError("Off-heap memory is not available because: " + reason);
+ 	}
+     try {
+     this.data = unsafe.allocateMemory(size);
+     this.size = size;
+     } catch (OutOfMemoryError err) {
+       String msg = "Failed creating " + size + " bytes of off-heap memory during cache creation.";
+       if (err.getMessage() != null && !err.getMessage().isEmpty()) {
+         msg += " Cause: " + err.getMessage();
+       }
+       if (!SharedLibrary.is64Bit() && size >= (1024*1024*1024)) {
+         msg += " The JVM looks like a 32-bit one. For large amounts of off-heap memory a 64-bit JVM is needed.";
+       }
+       throw new OutOfMemoryError(msg);
+     }
+   }
+ 
+   @Override
+   public int getSize() {
+     return (int)this.size;
+   }
+   
++  /* (non-Javadoc)
++   * @see com.gemstone.gemfire.internal.offheap.AddressableMemoryChunk#getMemoryAddress()
++   */
++  @Override
+   public long getMemoryAddress() {
+     return this.data;
+   }
+   
+   public static byte readAbsoluteByte(long addr) {
+     return unsafe.getByte(addr);
+   }
+   public static char readAbsoluteChar(long addr) {
+     return unsafe.getChar(null, addr);
+   }
+   public static short readAbsoluteShort(long addr) {
+     return unsafe.getShort(null, addr);
+   }
+   public static int readAbsoluteInt(long addr) {
+     return unsafe.getInt(null, addr);
+   }
+   public static int readAbsoluteIntVolatile(long addr) {
+     return unsafe.getIntVolatile(null, addr);
+   }
+   public static long readAbsoluteLong(long addr) {
+     return unsafe.getLong(null, addr);
+   }
+   public static long readAbsoluteLongVolatile(long addr) {
+     return unsafe.getLongVolatile(null, addr);
+   }
+ 
+   @Override
+   public byte readByte(int offset) {
+     return readAbsoluteByte(this.data+offset);
+   }
+ 
+   public static void writeAbsoluteByte(long addr, byte value) {
+     unsafe.putByte(addr, value);
+   }
+        
+   public static void writeAbsoluteInt(long addr, int value) {
+     unsafe.putInt(null, addr, value);
+   }
+   public static void writeAbsoluteIntVolatile(long addr, int value) {
+     unsafe.putIntVolatile(null, addr, value);
+   }
+   public static boolean writeAbsoluteIntVolatile(long addr, int expected, int value) {
+     return unsafe.compareAndSwapInt(null, addr, expected, value);
+   }
+   public static void writeAbsoluteLong(long addr, long value) {
+     unsafe.putLong(null, addr, value);
+   }
+   public static void writeAbsoluteLongVolatile(long addr, long value) {
+     unsafe.putLongVolatile(null, addr, value);
+   }
+   public static boolean writeAbsoluteLongVolatile(long addr, long expected, long value) {
+     return unsafe.compareAndSwapLong(null, addr, expected, value);
+   }
+ 
+   @Override
+   public void writeByte(int offset, byte value) {
+     writeAbsoluteByte(this.data+offset, value);
+   }
+ 
+   @Override
+   public void readBytes(int offset, byte[] bytes) {
+     readBytes(offset, bytes, 0, bytes.length);
+   }
+ 
+   @Override
+   public void writeBytes(int offset, byte[] bytes) {
+     writeBytes(offset, bytes, 0, bytes.length);
+   }
+ 
+   public static void readAbsoluteBytes(long addr, byte[] bytes, int bytesOffset, int size) {
+     // Throwing an Error instead of using the "assert" keyword because passing < 0 to
+     // copyMemory(...) can lead to a core dump with some JVMs and we don't want to
+     // require the -ea JVM flag.
+     if (size < 0) {
+       throw new AssertionError("Size=" + size + ", but size must be >= 0");
+     }
+     
+     assert bytesOffset >= 0 : "byteOffset=" + bytesOffset;
+     assert bytesOffset + size <= bytes.length : "byteOffset=" + bytesOffset + ",size=" + size + ",bytes.length=" + bytes.length;
+     
+     if (size == 0) {
+       return; // No point in wasting time copying 0 bytes
+     }
+     unsafe.copyMemory(null, addr, bytes, ARRAY_BYTE_BASE_OFFSET+bytesOffset, size);
+   }
+ 
+   @Override
+   public void readBytes(int offset, byte[] bytes, int bytesOffset, int size) {
+     readAbsoluteBytes(this.data+offset, bytes, bytesOffset, size);
+   }
+ 
+   public static void copyMemory(long srcAddr, long dstAddr, long size) {
+     unsafe.copyMemory(srcAddr, dstAddr, size);
+   }
+   
+   public static void writeAbsoluteBytes(long addr, byte[] bytes, int bytesOffset, int size) {
+     // Throwing an Error instead of using the "assert" keyword because passing < 0 to
+     // copyMemory(...) can lead to a core dump with some JVMs and we don't want to
+     // require the -ea JVM flag.
+     if (size < 0) {
+       throw new AssertionError("Size=" + size + ", but size must be >= 0");
+     }
+ 
+     assert bytesOffset >= 0 : "byteOffset=" + bytesOffset;
+     assert bytesOffset + size <= bytes.length : "byteOffset=" + bytesOffset + ",size=" + size + ",bytes.length=" + bytes.length;
+     
+     if (size == 0) {
+       return; // No point in wasting time copying 0 bytes
+     }
+     unsafe.copyMemory(bytes, ARRAY_BYTE_BASE_OFFSET+bytesOffset, null, addr, size);
+   }
+ 
+   public static void fill(long addr, int size, byte fill) {
+     unsafe.setMemory(addr, size, fill);
+   }
+   
+   @Override
+   public void writeBytes(int offset, byte[] bytes, int bytesOffset, int size) {
+     writeAbsoluteBytes(this.data+offset, bytes, bytesOffset, size);
+   }
+ 
+   @Override
+   public void release() {
+     unsafe.freeMemory(this.data);
+   }
+ 
+   @Override
+   public void copyBytes(int src, int dst, int size) {
+     unsafe.copyMemory(this.data+src, this.data+dst, size);
+   }
+   
+   @Override
+   public String toString() {
+     final StringBuilder sb = new StringBuilder(getClass().getSimpleName());
+     sb.append("{");
+     sb.append("MemoryAddress=").append(getMemoryAddress());
+     sb.append(", Size=").append(getSize());
+     sb.append("}");
+     return sb.toString();
+   }
 -  
 -  /**
 -   * Used to create UnsafeMemoryChunk instances.
 -   */
 -  public interface Factory {
 -    /** Create and return an UnsafeMemoryChunk.
 -     * @throws OutOfMemoryError if the create fails
 -     */
 -    public UnsafeMemoryChunk create(int size);
 -  }
+ }


[050/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
index 0ae0437,0000000..28c1e0f
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
@@@ -1,436 -1,0 +1,436 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.DataInputStream;
 +import java.net.SocketTimeoutException;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerConnectivityException;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.distributed.internal.DistributionManager;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 +import com.gemstone.gemfire.internal.cache.PutAllPartialResultException;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ChunkedMessage;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 +
 +/**
 + * Represents an operation that can be performed in a client by sending
 + * a message to a server.
 + * @since 5.7
 + */
 +public abstract class AbstractOp implements Op {
 +  
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  private final Message msg;
 +
 +  protected AbstractOp(int msgType, int msgParts) {
 +    this.msg = new Message(msgParts, Version.CURRENT);
 +    getMessage().setMessageType(msgType);
 +  }
 +
 +  /**
 +   * Returns the message that this op will send to the server
 +   */
 +  protected Message getMessage() {
 +    return this.msg;
 +  }
 +  protected void initMessagePart() {
 +    
 +  }
 +  /**
 +   * Sets the transaction id on the message
 +   */
 +  private void setMsgTransactionId() {
 +    if (participateInTransaction()
 +        && getMessage().getTransactionId() == TXManagerImpl.NOTX) {
 +      getMessage().setTransactionId(TXManagerImpl.getCurrentTXUniqueId());
 +    }
 +  }
 +
 +  /**
 +   * Attempts to send this operation's message out on the
 +   * given connection
 +   * @param cnx the connection to use when sending
 +   * @throws Exception if the send fails
 +   */
 +  protected void attemptSend(Connection cnx) throws Exception {
 +    setMsgTransactionId();
 +    if (logger.isTraceEnabled(LogMarker.DISTRIBUTION_BRIDGE_SERVER)) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Sending op={} using {}", getShortClassName(), cnx);
 +      }
 +    }
 +    getMessage().setComms(cnx.getSocket(), cnx.getInputStream(),
 +        cnx.getOutputStream(), cnx.getCommBuffer(), cnx.getStats());
 +    try {
 +      sendMessage(cnx);
 +    } finally {
 +      getMessage().unsetComms();
 +    }
 +  }
 +
 +  /** returns the class name w/o package information.  useful in logging */
 +  public String getShortClassName() {
 +    String cname = getClass().getName();
 +    return cname.substring(getClass().getPackage().getName().length()+1);
 +  }
 +
 +  /**
 +   * New implementations of AbstractOp should override this method if the
 +   * implementation should be excluded from client authentication. e.g.
 +   * PingOp#sendMessage(Connection cnx)
 +   * 
 +   * @see AbstractOp#needsUserId()
 +   * @see AbstractOp#processSecureBytes(Connection, Message)
 +   * @see ServerConnection#updateAndGetSecurityPart()
 +   */
 +  protected void sendMessage(Connection cnx) throws Exception {
 +    if (cnx.getServer().getRequiresCredentials()) {
 +      // Security is enabled on client as well as on server
-       getMessage().setEarlyAck(Message.MESSAGE_HAS_SECURE_PART);
++      getMessage().setMessageHasSecurePartFlag();
 +      HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
 +      long userId = -1;
 +
 +      if (UserAttributes.userAttributes.get() == null) { // single user mode
 +        userId = cnx.getServer().getUserId();
 +      } else { // multi user mode
 +        Object id = UserAttributes.userAttributes.get().getServerToId().get(
 +            cnx.getServer());
 +        if (id == null) {
 +          // This will ensure that this op is retried on another server, unless
 +          // the retryCount is exhausted. Fix for Bug 41501
 +          throw new ServerConnectivityException(
 +              "Connection error while authenticating user"); // TODO:LOG hdos is not closed??
 +        }
 +        userId = (Long)id;
 +      }
 +      try {
 +        hdos.writeLong(cnx.getConnectionID());
 +        hdos.writeLong(userId);
 +        getMessage().setSecurePart(
 +            ((ConnectionImpl)cnx).getHandShake().encryptBytes(
 +                hdos.toByteArray()));
 +      } finally {
 +        hdos.close();
 +      }
 +    }
 +    getMessage().send(false);
 +  }
 +
 +  /**
 +   * Attempts to read a response to this operation by reading it from the
 +   * given connection, and returning it.
 +   * @param cnx the connection to read the response from
 +   * @return the result of the operation
 +   *         or <code>null</code> if the operation has no result.
 +   * @throws Exception if the execute failed
 +   */
 +  protected Object attemptReadResponse(Connection cnx) throws Exception {
 +    Message msg = createResponseMessage();
 +    if (msg != null) {
 +      msg.setComms(cnx.getSocket(), cnx.getInputStream(),
 +          cnx.getOutputStream(), cnx.getCommBuffer(), cnx.getStats());
 +      if (msg instanceof ChunkedMessage) {
 +        try {
 +          return processResponse(msg, cnx);
 +        } finally {
 +          msg.unsetComms();
 +          // TODO (ashetkar) Handle the case when we fail to read the connection id.
 +          processSecureBytes(cnx, msg);
 +        }
 +      } else {
 +        try {
 +          msg.recv();
 +        } finally {
 +          msg.unsetComms();
 +          processSecureBytes(cnx, msg);
 +        }
 +        return processResponse(msg, cnx);
 +      }
 +    } else {
 +      return null;
 +    }
 +  }
 +
 +  /**
 +   * New implementations of AbstractOp should override this method if the
 +   * implementation should be excluded from client authentication. e.g.
 +   * PingOp#processSecureBytes(Connection cnx, Message message)
 +   * 
 +   * @see AbstractOp#sendMessage(Connection)
 +   * @see AbstractOp#needsUserId()
 +   * @see ServerConnection#updateAndGetSecurityPart()
 +   */
 +  protected void processSecureBytes(Connection cnx, Message message)
 +      throws Exception {
 +    if (cnx.getServer().getRequiresCredentials()) {
 +      if (!message.isSecureMode()) {
 +        // This can be seen during shutdown
 +        if (logger.isDebugEnabled()) {
 +          logger.trace(LogMarker.BRIDGE_SERVER, "Response message from {} for {} has no secure part.", cnx, this);
 +        }
 +        return;
 +      }
 +      byte[] partBytes = message.getSecureBytes();
 +      if (partBytes == null) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("Response message for {} has no bytes in secure part.", this);
 +        }
 +        return;
 +      }
 +      byte[] bytes = ((ConnectionImpl)cnx).getHandShake().decryptBytes(
 +          partBytes);
 +      DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
 +      cnx.setConnectionID(dis.readLong());
 +    }
 +  }
 +
 +  /**
 +   * By default just create a normal one part msg.
 +   * Subclasses can override this.
 +   */
 +  protected Message createResponseMessage() {
 +    return new Message(1, Version.CURRENT);
 +  }
 +  
 +  protected Object processResponse(Message m, Connection con) throws Exception {
 +    return processResponse(m);
 +  }
 +  
 +  /**
 +   * Processes the given response message returning the result, if any,
 +   * of the processing.
 +   * @return the result of processing the response; null if no result
 +   * @throws Exception if response could not be processed or
 +   * we received a response with a server exception.
 +   */
 +  protected abstract Object processResponse(Message msg) throws Exception;
 +
 +  /**
 +   * Return true of <code>msgType</code> indicates the operation
 +   * had an error on the server.
 +   */
 +  protected abstract boolean isErrorResponse(int msgType);
 +  /**
 +   * Process a response that contains an ack.
 +   * @param msg the message containing the response
 +   * @param opName text describing this op
 +   * @throws Exception if response could not be processed or
 +   * we received a response with a server exception.
 +   */
 +  protected void processAck(Message msg, String opName)
 +    throws Exception
 +  {
 +    final int msgType = msg.getMessageType();
 +    if (msgType == MessageType.REPLY) {
 +      return;
 +    } else {
 +      Part part = msg.getPart(0);
 +      if (msgType == MessageType.EXCEPTION) {
 +        String s = ": While performing a remote " + opName;
 +        Throwable t = (Throwable) part.getObject();
 +        if (t instanceof PutAllPartialResultException) {
 +          throw (PutAllPartialResultException)t;
 +        } else {
 +          throw new ServerOperationException(s, t);
 +        }
 +        // Get the exception toString part.
 +        // This was added for c++ thin client and not used in java
 +        // Part exceptionToStringPart = msg.getPart(1);
 +      } else if (isErrorResponse(msgType)) {
 +        throw new ServerOperationException(part.getString());
 +      } else {
 +        throw new InternalGemFireError("Unexpected message type "
 +                                       + MessageType.getString(msgType));
 +      }
 +    }
 +  }
 +  /**
 +   * Process a response that contains a single Object result.
 +   * @param msg the message containing the response
 +   * @param opName text describing this op
 +   * @return the result of the response
 +   * @throws Exception if response could not be processed or
 +   * we received a response with a server exception.
 +   */
 +  protected final Object processObjResponse(Message msg, String opName)
 +    throws Exception
 +  {
 +    Part part = msg.getPart(0);
 +    final int msgType = msg.getMessageType();
 +    if (msgType == MessageType.RESPONSE) {
 +      return part.getObject();
 +    } else {
 +      if (msgType == MessageType.EXCEPTION) {
 +        String s = "While performing a remote " + opName;
 +        throw new ServerOperationException(s, (Throwable) part.getObject());
 +        // Get the exception toString part.
 +        // This was added for c++ thin client and not used in java
 +        // Part exceptionToStringPart = msg.getPart(1);
 +      } else if (isErrorResponse(msgType)) {
 +        throw new ServerOperationException(part.getString());
 +      } else {
 +        throw new InternalGemFireError("Unexpected message type "
 +                                       + MessageType.getString(msgType));
 +      }
 +    }
 +  }
 +  /**
 +   * Used by subclasses who get chunked responses.
 +   */
 +  public interface ChunkHandler {
 +    /**
 +     * This method will be called once for every incoming chunk
 +     * @param msg the current chunk to handle
 +     */
 +    public void handle(ChunkedMessage msg) throws Exception;
 +  }
 +  /**
 +   * Process a chunked response that contains a single Object result.
 +   * @param msg the message containing the response
 +   * @param opName text describing this op
 +   * @param callback used to handle each chunks data
 +   * @throws Exception if response could not be processed or
 +   * we received a response with a server exception.
 +   */
 +  protected final void processChunkedResponse(ChunkedMessage msg, String opName, ChunkHandler callback)
 +    throws Exception
 +  {
 +    msg.readHeader();
 +    final int msgType = msg.getMessageType();
 +    if (msgType == MessageType.RESPONSE) {
 +      do {
 +        msg.receiveChunk();
 +        callback.handle(msg);
 +      } while (!msg.isLastChunk());
 +    } else {
 +      if (msgType == MessageType.EXCEPTION) {
 +        msg.receiveChunk();
 +        Part part = msg.getPart(0);
 +        String s = "While performing a remote " + opName;
 +        throw new ServerOperationException(s, (Throwable) part.getObject());
 +        // Get the exception toString part.
 +        // This was added for c++ thin client and not used in java
 +        // Part exceptionToStringPart = msg.getPart(1);
 +      } else if (isErrorResponse(msgType)) {
 +        msg.receiveChunk();
 +        Part part = msg.getPart(0);
 +        throw new ServerOperationException(part.getString());
 +      } else {
 +        throw new InternalGemFireError("Unexpected message type "
 +                                       + MessageType.getString(msgType));
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Set to true if this attempt failed
 +   */
 +  protected boolean failed;
 +  /**
 +   * Set to true if this attempt timed out
 +   */
 +  protected boolean timedOut;
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache.client.internal.Op#attempt(com.gemstone.gemfire.cache.client.internal.Connection)
 +   */
 +  public Object attempt(Connection cnx) throws Exception {
 +    this.failed = true;
 +    this.timedOut = false;
 +    long start = startAttempt(cnx.getStats());
 +    try {
 +      try {
 +        attemptSend(cnx);
 +        this.failed = false;
 +      } finally {
 +        endSendAttempt(cnx.getStats(), start);
 +      }
 +      this.failed = true;
 +      try {
 +        Object result = attemptReadResponse(cnx);
 +        this.failed = false;
 +        return result;
 +      } catch (SocketTimeoutException ste) {
 +        this.failed = false;
 +        this.timedOut = true;
 +        throw ste;
 +      } catch(Exception e) {
 +        throw e;
 +      }
 +    } finally {
 +      endAttempt(cnx.getStats(), start);
 +    }
 +  }
 +  protected final boolean hasFailed() {
 +    return this.failed;
 +  }
 +  protected final boolean hasTimedOut() {
 +    return this.timedOut;
 +  }
 +  protected abstract long startAttempt(ConnectionStats stats);
 +  protected abstract void endSendAttempt(ConnectionStats stats, long start);
 +  protected abstract void endAttempt(ConnectionStats stats, long start);
 +
 +  /**
 +   * New implementations of AbstractOp should override this method to return
 +   * false if the implementation should be excluded from client authentication.
 +   * e.g. PingOp#needsUserId()
 +   * <P/>
 +   * Also, such an operation's <code>MessageType</code> must be added in the
 +   * 'if' condition in {@link ServerConnection#updateAndGetSecurityPart()}
 +   * 
 +   * @return boolean
 +   * @see AbstractOp#sendMessage(Connection)
 +   * @see AbstractOp#processSecureBytes(Connection, Message)
 +   * @see ServerConnection#updateAndGetSecurityPart()
 +   */
 +  protected boolean needsUserId() {
 +    return true;
 +  }
 +  
 +  /**
 +   * Subclasses for AbstractOp should override this method to return
 +   * false in this message should not participate in any existing transaction
 +   * @return true if the message should participate in transaction
 +   */
 +  protected boolean participateInTransaction() {
 +    return true;
 +  }
 +
 +  @Override
 +  public boolean useThreadLocalConnection() {
 +    return true;
 +  }
 +  
 +  public boolean isGatewaySenderOp() {
 +    return false;
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
index b88948d,0000000..ff2bf1c
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
@@@ -1,98 -1,0 +1,98 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.pdx.internal.EnumInfo;
 +
 +/**
 + * Push a PDX Enum id to other servers.
 + * @author darrel
 + * @since 6.6.2
 + */
 +public class AddPDXEnumOp {
 +  /**
 +   * Register a bunch of instantiators on a server
 +   * using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static void execute(ExecutablePool pool, int id,
 +                             EnumInfo ei)
 +  {
 +    AbstractOp op = new AddPdxEnumOpImpl(id, ei);
 +    pool.execute(op);;
 +  }
 +                                                               
 +  private AddPDXEnumOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class AddPdxEnumOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public AddPdxEnumOpImpl(int id, EnumInfo ei) {
 +      super(MessageType.ADD_PDX_ENUM, 2);
 +      getMessage().addObjPart(ei);
 +      getMessage().addIntPart(id);
 +    }
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "addPDXEnum");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startAddPdxType(); /* use the addPdxType stats instead of adding more stats */
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endAddPdxTypeSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endAddPdxType(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    //Don't send the transaction id for this message type.
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
 +    
 +    //TODO - no idea what this mumbo jumbo means, but it's on
 +    //most of the other messages like this.
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
index 92dd246,0000000..9fbc674
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
@@@ -1,98 -1,0 +1,96 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.pdx.internal.PdxType;
 +
 +/**
 + * Add a PdxType to a server.
 + * @author dsmith
 + * @since 6.6
 + */
 +public class AddPDXTypeOp {
 +  /**
 +   * Register a bunch of instantiators on a server
 +   * using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static void execute(ExecutablePool pool, int id,
 +                             PdxType type)
 +  {
 +    AbstractOp op = new AddPDXTypeOpImpl(id, type);
 +    pool.execute(op);
 +  }
 +                                                               
 +  private AddPDXTypeOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class AddPDXTypeOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public AddPDXTypeOpImpl(int id, PdxType type) {
 +      super(MessageType.ADD_PDX_TYPE, 2);
 +      getMessage().addObjPart(type);
 +      getMessage().addIntPart(id);
 +    }
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "addPDXType");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startAddPdxType();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endAddPdxTypeSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endAddPdxType(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    //Don't send the transaction id for this message type.
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
 +    
-     //TODO - no idea what this mumbo jumbo means, but it's on
-     //most of the other messages like this.
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
index b0f0cec,0000000..b03c7b9
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
@@@ -1,312 -1,0 +1,312 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.DataInputStream;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.ServerLocation;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ChunkedMessage;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.command.PutUserCredentials;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.security.AuthenticationFailedException;
 +import com.gemstone.gemfire.security.AuthenticationRequiredException;
 +import com.gemstone.gemfire.security.NotAuthorizedException;
 +
 +/**
 + * Authenticates this client (or a user) on a server. This op ideally should get
 + * executed once-per-server.
 + * 
 + * When multiuser-authentication is set to false, this op gets executed
 + * immedialtely after a client-to-server connection is established.
 + * 
 + * When multiuser-authentication is set to true, this op gets executed
 + * before the user attempts to perform an op whose
 + * {@link AbstractOp#needsUserId()} returns true.
 + * 
 + * @author ashetkar
 + * @see PutUserCredentials
 + * @see ProxyCache
 + * @since 6.5
 + */
 +public class AuthenticateUserOp {
 +
 +  /**
 +   * Sends the auth credentials to the server. Used in single user mode of
 +   * authentication.
 +   * 
 +   * @param con
 +   *          The connection to use for this operation.
 +   * @param pool
 +   *          The connection pool to use for this operation.
 +   * @return Object unique user-id.
 +   */
 +  public static Object executeOn(Connection con, ExecutablePool pool) {
 +    AbstractOp op = new AuthenticateUserOpImpl(con, pool);
 +    return pool.executeOn(con, op);
 +  }
 +
 +  /**
 +   * Sends the auth credentials to the server for a particular user. Used in
 +   * multiple user mode of authentication.
 +   * 
 +   * @param location
 +   *          The ServerLocation instance whose connection instance will be used
 +   *          to perform the operation.
 +   * @param pool
 +   *          The connection pool to use for this operation.
 +   * @param securityProps
 +   * @return Object unique user-id.
 +   */
 +  public static Object executeOn(ServerLocation location, ExecutablePool pool,
 +      Properties securityProps) {
 +    AbstractOp op = new AuthenticateUserOpImpl(pool, securityProps);
 +    return pool.executeOn(location, op);
 +  }
 +
 +  private AuthenticateUserOp() {
 +    // no instances allowed
 +  }
 +
 +  static class AuthenticateUserOpImpl extends AbstractOp {
 +
 +    private Properties securityProperties = null;
 +    private boolean needsServerLocation = false;
 +
 +    public AuthenticateUserOpImpl(Connection con, ExecutablePool pool) {
 +      super(MessageType.USER_CREDENTIAL_MESSAGE, 1);
 +      byte[] credentialBytes = null;
 +      // TODO this is not a valid way to create a member ID
 +      DistributedMember server = new InternalDistributedMember(con.getSocket()
 +          .getInetAddress(), con.getSocket().getPort(), false);
 +      DistributedSystem sys = InternalDistributedSystem.getConnectedInstance();
 +      String authInitMethod = sys.getProperties().getProperty(
 +          DistributionConfig.SECURITY_CLIENT_AUTH_INIT_NAME);
 +      Properties tmpSecurityProperties = sys.getSecurityProperties();
 +
 +      // LOG: following passes the DS API LogWriters into the security API
 +      Properties credentials = HandShake.getCredentials(authInitMethod,
 +          tmpSecurityProperties, server, false, (InternalLogWriter)sys.getLogWriter(), (InternalLogWriter)sys
 +              .getSecurityLogWriter());
 +      
-       getMessage().setEarlyAck(Message.MESSAGE_HAS_SECURE_PART);
++      getMessage().setMessageHasSecurePartFlag();
 +      HeapDataOutputStream heapdos = new HeapDataOutputStream(Version.CURRENT);
 +      try {
 +        DataSerializer.writeProperties(credentials, heapdos);
 +        credentialBytes = ((ConnectionImpl)con).getHandShake()
 +            .encryptBytes(heapdos.toByteArray());
 +      } catch (Exception e) {
 +        throw new ServerOperationException(e);
 +      } finally {
 +        heapdos.close();
 +      }
 +      getMessage().addBytesPart(credentialBytes);
 +    }
 +
 +    public AuthenticateUserOpImpl(ExecutablePool pool, Properties securityProps) {
 +      this(pool, securityProps, false);
 +    }
 +
 +    public AuthenticateUserOpImpl(ExecutablePool pool, Properties securityProps, boolean needsServer) {
 +      super(MessageType.USER_CREDENTIAL_MESSAGE, 1);
 +      this.securityProperties = securityProps;
 +      this.needsServerLocation = needsServer;
 +
-       getMessage().setEarlyAck(Message.MESSAGE_HAS_SECURE_PART);
++      getMessage().setMessageHasSecurePartFlag();
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
 +      HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
 +      byte[] secureBytes = null;
 +      hdos.writeLong(cnx.getConnectionID());
 +      if (this.securityProperties != null) {
 +        byte[] credentialBytes = null;
 +        // TODO this is not a valid way to create a member ID
 +        DistributedMember server = new InternalDistributedMember(cnx
 +            .getSocket().getInetAddress(), cnx.getSocket().getPort(), false);
 +        DistributedSystem sys = InternalDistributedSystem
 +            .getConnectedInstance();
 +        String authInitMethod = sys.getProperties().getProperty(
 +            DistributionConfig.SECURITY_CLIENT_AUTH_INIT_NAME);
 +
 +        Properties credentials = HandShake.getCredentials(authInitMethod,
 +            this.securityProperties, server, false, (InternalLogWriter)sys.getLogWriter(), (InternalLogWriter)sys
 +                .getSecurityLogWriter());
 +        HeapDataOutputStream heapdos = new HeapDataOutputStream(Version.CURRENT);
 +        try {
 +          DataSerializer.writeProperties(credentials, heapdos);
 +          credentialBytes = ((ConnectionImpl)cnx).getHandShake().encryptBytes(
 +              heapdos.toByteArray());
 +        } finally {
 +          heapdos.close();
 +        }
 +        getMessage().addBytesPart(credentialBytes);
 +      }
 +      try {
 +        secureBytes = ((ConnectionImpl)cnx).getHandShake().encryptBytes(
 +            hdos.toByteArray());
 +      } finally {
 +        hdos.close();
 +      }
 +      getMessage().setSecurePart(secureBytes);
 +      getMessage().send(false);
 +    }
 +
 +    @Override
 +    public Object attempt(Connection cnx) throws Exception {
 +      if (cnx.getServer().getRequiresCredentials()) {
 +        return super.attempt(cnx);
 +      } else {
 +        return null;
 +      }
 +    }
 +
 +    @Override
 +    protected Object attemptReadResponse(Connection cnx) throws Exception {
 +      Message msg = createResponseMessage();
 +      if (msg != null) {
 +        msg.setComms(cnx.getSocket(), cnx.getInputStream(),
 +            cnx.getOutputStream(), cnx.getCommBuffer(), cnx.getStats());
 +        if (msg instanceof ChunkedMessage) {
 +          try {
 +            return processResponse(cnx, msg);
 +          } finally {
 +            msg.unsetComms();
 +            processSecureBytes(cnx, msg);
 +          }
 +        } else {
 +          try {
 +            msg.recv();
 +          } finally {
 +            msg.unsetComms();
 +            processSecureBytes(cnx, msg);
 +          }
 +          return processResponse(cnx, msg);
 +        }
 +      } else {
 +        return null;
 +      }
 +    }
 +
 +    protected Object processResponse(Connection cnx, Message msg) throws Exception {
 +      byte[] bytes = null;
 +      Part part = msg.getPart(0);
 +      final int msgType = msg.getMessageType();
 +      long userId = -1;
 +      if (msgType == MessageType.RESPONSE) {
 +        bytes = (byte[])part.getObject();
 +        if (bytes.length == 0) {
 +          cnx.getServer().setRequiresCredentials(false);
 +        } else {
 +          cnx.getServer().setRequiresCredentials(true);
 +          byte[] decrypted = ((ConnectionImpl)cnx).getHandShake().decryptBytes(bytes);
 +          DataInputStream dis = new DataInputStream(new ByteArrayInputStream(decrypted));
 +          userId = dis.readLong();
 +        }
 +        if (this.needsServerLocation) {
 +          return new Object[] {cnx.getServer(), userId};
 +       } else {
 +         return userId;
 +       }
 +      }
 +      else if (msgType == MessageType.EXCEPTION) {
 +        Object result = part.getObject();
 +        String s = "While performing a remote authenticate";
 +        if (result instanceof AuthenticationFailedException) {
 +          final AuthenticationFailedException afe =
 +            (AuthenticationFailedException)result;
 +          if ("REPLY_REFUSED".equals(afe.getMessage())) {
 +            throw new AuthenticationFailedException(s, afe.getCause());
 +          }
 +          else {
 +            throw new AuthenticationFailedException(s, afe);
 +          }
 +        }
 +        else if (result instanceof AuthenticationRequiredException) {
 +          throw new AuthenticationRequiredException(s,
 +              (AuthenticationRequiredException)result);
 +        }
 +        else if (result instanceof NotAuthorizedException) {
 +          throw new NotAuthorizedException(s, (NotAuthorizedException)result);
 +        }
 +        else {
 +          throw new ServerOperationException(s, (Throwable)result);
 +        }
 +        // Get the exception toString part.
 +        // This was added for c++ thin client and not used in java
 +        // Part exceptionToStringPart = msg.getPart(1);
 +      }
 +      else if (isErrorResponse(msgType)) {
 +        throw new ServerOperationException(part.getString());
 +      }
 +      else {
 +        throw new InternalGemFireError("Unexpected message type "
 +            + MessageType.getString(msgType));
 +      }
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.REQUESTDATAERROR;
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGet();
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetSend(start, hasFailed());
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGet(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      return null;
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
index 943f0a3,0000000..7de38fe
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
@@@ -1,95 -1,0 +1,95 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Tell a server that a connection is being closed
 + * @author darrel
 + * @since 5.7
 + */
 +public class CloseConnectionOp {
 +  /**
 +   * Tell a server that a connection is being closed
 +   * @param con the connection that is being closed
 +   * @param keepAlive whether to keep the proxy alive on the server
 +   */
 +  public static void execute(Connection con, boolean keepAlive)
 +    throws Exception
 +  {
 +    AbstractOp op = new CloseConnectionOpImpl(keepAlive);
 +    con.execute(op);
 +  }
 +                                                               
 +  private CloseConnectionOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class CloseConnectionOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public CloseConnectionOpImpl(boolean keepAlive)  {
 +      super(MessageType.CLOSE_CONNECTION, 1);
 +      getMessage().addRawPart(new byte[]{(byte)(keepAlive?1:0)}, false);
 +    }
 +    @Override  
 +    protected Message createResponseMessage() {
 +      // no response is sent
 +      return null;
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @Override  
 +    protected Object processResponse(Message msg) throws Exception {
 +      throw new IllegalStateException("should never be called");
 +    }
 +    @Override  
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override  
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startCloseCon();
 +    }
 +    @Override  
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endCloseConSend(start, hasFailed());
 +    }
 +    @Override  
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endCloseCon(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
index e04a466,0000000..c9c6dd7
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
@@@ -1,109 -1,0 +1,109 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.TXCommitMessage;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Does a commit on a server
 + * @author gregp
 + * @since 6.6
 + */
 +public class CommitOp {
 +  /**
 +   * Does a commit on a server using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static TXCommitMessage execute(ExecutablePool pool,int txId)
 +  {
 +    CommitOpImpl op = new CommitOpImpl(txId);
 +    pool.execute(op);
 +    return op.getTXCommitMessageResponse();
 +  }
 +                                                               
 +  private CommitOp() {
 +    // no instances allowed
 +  }
 +  
 +    
 +  private static class CommitOpImpl extends AbstractOp {
 +    private int txId;
 +    
 +    private TXCommitMessage tXCommitMessageResponse = null;
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public CommitOpImpl(int txId) {
 +      super(MessageType.COMMIT, 1);
 +      getMessage().setTransactionId(txId);
 +      this.txId = txId;
 +    }
 +
 +    public TXCommitMessage getTXCommitMessageResponse() {
 +      return tXCommitMessageResponse;
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      return "TXCommit(txId="+this.txId+")";
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      TXCommitMessage rcs = (TXCommitMessage)processObjResponse(msg, "commit");
 +      assert rcs != null : "TxCommit response was null";
 +      this.tXCommitMessageResponse = rcs;
 +      return rcs;
 +    }
 +     
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }    
 +    
 +    @Override  
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.EXCEPTION;
 +    }
 +    @Override  
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startCommit();
 +    }
 +    @Override  
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endCommitSend(start, hasFailed());
 +    }
 +    @Override  
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endCommit(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
index f88d1e9,0000000..8bae6ff
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
@@@ -1,171 -1,0 +1,171 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.util.List;
 +import java.util.Set;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.BucketServerLocation66;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +
 +/**
 + * Retrieves {@link ClientPartitionAdvisor} for the specified PartitionedRegion from
 + * one of the servers
 + * 
 + * @author Suranjan Kumar
 + * @author Yogesh Mahajan
 + * 
 + * @since 6.5
 + */
 +public class GetClientPRMetaDataOp {
 +
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  private GetClientPRMetaDataOp() {
 +    // no instances allowed
 +  }
 +
 +  public static void execute(ExecutablePool pool, String regionFullPath,
 +      ClientMetadataService cms) {
 +    AbstractOp op = new GetClientPRMetaDataOpImpl(regionFullPath, cms);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("GetClientPRMetaDataOp#execute : Sending GetClientPRMetaDataOp Message: {} to server using pool: {}", op.getMessage(), pool);
 +    }
 +    pool.execute(op);
 +  }
 +
 +  static class GetClientPRMetaDataOpImpl extends AbstractOp {
 +
 +    String regionFullPath = null;
 +
 +    ClientMetadataService cms = null;
 +
 +    public GetClientPRMetaDataOpImpl(String regionFullPath, ClientMetadataService cms) {
 +      super(MessageType.GET_CLIENT_PR_METADATA, 1);
 +      this.regionFullPath = regionFullPath;
 +      this.cms = cms;
 +      getMessage().addStringPart(regionFullPath);
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @SuppressWarnings("unchecked")
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      switch (msg.getMessageType()) {
 +        case MessageType.GET_CLIENT_PR_METADATA_ERROR:
 +          String errorMsg = msg.getPart(0).getString();
 +          if (logger.isDebugEnabled()) {
 +            logger.debug(errorMsg);
 +          }
 +          throw new ServerOperationException(errorMsg);
 +        case MessageType.RESPONSE_CLIENT_PR_METADATA:
 +          final boolean isDebugEnabled = logger.isDebugEnabled();
 +          if (isDebugEnabled) {
 +            logger.debug("GetClientPRMetaDataOpImpl#processResponse: received message of type : {}" + MessageType.getString(msg.getMessageType()));
 +          }
 +          int numParts = msg.getNumberOfParts();
 +          ClientPartitionAdvisor advisor = cms
 +              .getClientPartitionAdvisor(regionFullPath);
 +          for (int i = 0; i < numParts; i++) {
 +            Object result = msg.getPart(i).getObject();
 +            List<BucketServerLocation66> locations = (List<BucketServerLocation66>)result;
 +          if (!locations.isEmpty()) {
 +            int bucketId = locations.get(0).getBucketId();
 +            if (isDebugEnabled) {
 +              logger.debug("GetClientPRMetaDataOpImpl#processResponse: for bucketId : {} locations are {}", bucketId, locations);
 +            }
 +            advisor.updateBucketServerLocations(bucketId, locations, cms);
 +            
 +            Set<ClientPartitionAdvisor> cpas = cms
 +                .getColocatedClientPartitionAdvisor(regionFullPath);
 +            if (cpas != null && !cpas.isEmpty()) {
 +              for (ClientPartitionAdvisor colCPA : cpas) {
 +                colCPA.updateBucketServerLocations(bucketId, locations, cms);
 +              }
 +            }
 +          }
 +          }
 +          if (isDebugEnabled) {
 +            logger.debug("GetClientPRMetaDataOpImpl#processResponse: received ClientPRMetadata from server successfully.");
 +          }
 +          cms.setMetadataStable(true);
 +          return null;
 +        case MessageType.EXCEPTION:
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("GetClientPRMetaDataOpImpl#processResponse: received message of type EXCEPTION");
 +          }
 +          Part part = msg.getPart(0);
 +          Object obj = part.getObject();
 +          String s = "While performing  GetClientPRMetaDataOp "
 +              + ((Throwable)obj).getMessage();
 +          throw new ServerOperationException(s, (Throwable)obj);
 +        default:
 +          throw new InternalGemFireError(
 +              LocalizedStrings.Op_UNKNOWN_MESSAGE_TYPE_0
 +                  .toLocalizedString(Integer.valueOf(msg.getMessageType())));
 +      }
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGetClientPRMetadata();
 +    }
 +
 +    protected String getOpName() {
 +      return "GetClientPRMetaDataOp";
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetClientPRMetadataSend(start, hasFailed());
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGetClientPRMetadata(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
index 004872c,0000000..e1a8870
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
@@@ -1,177 -1,0 +1,177 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.util.Set;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.FixedPartitionAttributes;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +
 +/**
 + * 
 + * Retrieves {@link ClientPartitionAdvisor} related information for the
 + * specified PartitionedRegion from one of the servers
 + * 
 + * @author Suranjan Kumar
 + * @author Yogesh Mahajan
 + * 
 + * @since 6.5
 + * 
 + */
 +public class GetClientPartitionAttributesOp {
 +
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  private GetClientPartitionAttributesOp() {
 +    // no instances allowed
 +  }
 +
 +  @SuppressWarnings("unchecked")
 +  public static ClientPartitionAdvisor execute(ExecutablePool pool, String regionFullPath) {
 +    AbstractOp op = new GetClientPartitionAttributesOpImpl(regionFullPath);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("GetClientPartitionAttributesOp#execute : Sending GetClientPartitionAttributesOp Message: {} for region: {} to server using pool: {}", op.getMessage(), regionFullPath, pool);
 +    }
 +    
 +    ClientPartitionAdvisor advisor = (ClientPartitionAdvisor)pool.execute(op);
 +
 +    if (advisor != null) {
 +      advisor.setServerGroup(((PoolImpl)pool).getServerGroup());
 +    }
 +    
 +    return advisor;
 +  }
 +
 +  static class GetClientPartitionAttributesOpImpl extends AbstractOp {
 +
 +    String regionFullPath = null;
 +
 +    public GetClientPartitionAttributesOpImpl(String regionFullPath) {
 +      super(MessageType.GET_CLIENT_PARTITION_ATTRIBUTES, 1);
 +      this.regionFullPath = regionFullPath;
 +      getMessage().addStringPart(regionFullPath);
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @SuppressWarnings("unchecked")
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      switch (msg.getMessageType()) {
 +        case MessageType.GET_CLIENT_PARTITION_ATTRIBUTES_ERROR:
 +          String errorMsg = msg.getPart(0).getString();
 +          if (logger.isDebugEnabled()) {
 +            logger.debug(errorMsg);
 +          }
 +          throw new ServerOperationException(errorMsg);
 +        case MessageType.RESPONSE_CLIENT_PARTITION_ATTRIBUTES:
 +          final boolean isDebugEnabled = logger.isDebugEnabled();
 +          if (isDebugEnabled) {
 +            logger.debug("GetClientPartitionAttributesOpImpl#processResponse: received message of type : {}", MessageType.getString(msg.getMessageType()));
 +          }
 +          int bucketCount;
 +          String colocatedWith;
 +          String partitionResolverName = null;
 +          Set<FixedPartitionAttributes> fpaSet = null; 
 +          bucketCount = (Integer)msg.getPart(0).getObject();
 +          colocatedWith = (String)msg.getPart(1).getObject();
 +          if (msg.getNumberOfParts() == 4) {
 +            partitionResolverName = (String)msg.getPart(2).getObject();
 +            fpaSet = (Set<FixedPartitionAttributes>)msg.getPart(3).getObject();
 +          }
 +          else if (msg.getNumberOfParts() == 3) {
 +            Object obj = msg.getPart(2).getObject();
 +            if(obj instanceof String){
 +              partitionResolverName = (String)obj;
 +            }else{
 +              fpaSet = (Set<FixedPartitionAttributes>)obj;
 +            }
 +          }
 +          else if(bucketCount==-1){              
 +              return null;
 +          }
 +          if (isDebugEnabled) {
 +            logger.debug("GetClientPartitionAttributesOpImpl#processResponse: received all the results from server successfully.");
 +          }
 +          ClientPartitionAdvisor advisor = new ClientPartitionAdvisor(bucketCount, colocatedWith,
 +                partitionResolverName, fpaSet);
 +          return advisor;
 +
 +        case MessageType.EXCEPTION:
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("GetClientPartitionAttributesOpImpl#processResponse: received message of type EXCEPTION");
 +          }
 +          Part part = msg.getPart(0);
 +          Object obj = part.getObject();
 +          String s = "While performing  GetClientPartitionAttributesOp "+  ((Throwable)obj).getMessage();
 +          throw new ServerOperationException(s, (Throwable) obj);
 +        default:
 +          throw new InternalGemFireError(
 +              LocalizedStrings.Op_UNKNOWN_MESSAGE_TYPE_0
 +                  .toLocalizedString(Integer.valueOf(msg.getMessageType())));
 +      }
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGetClientPartitionAttributes();
 +    }
 +
 +    protected String getOpName() {
 +      return "GetClientPartitionAttributesOp";
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetClientPartitionAttributesSend(start, hasFailed());
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGetClientPartitionAttributes(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
index 7dfe9af,0000000..1038ede
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
@@@ -1,121 -1,0 +1,121 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.EventID;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +
 +/**
 + * Gets (full) value (unlike GetOp, which may get either a full value or a delta
 + * depending upon delta flag) of a given event from the ha container on server.
 + * 
 + * @since 6.1
 + */
 +public class GetEventValueOp {
 +  /**
 +   * Does a get on the primary server using connections from the given pool
 +   * @param pool the pool to use to communicate with the server.
 +   * @param event the eventid to do the get on
 +   * @param callbackArg an optional callback arg to pass to any cache callbacks
 +   * @return the entry value found by the get if any
 +   */
 +  public static Object executeOnPrimary(ExecutablePool pool, EventID event,
 +      Object callbackArg) {
 +    AbstractOp op = new GetEventValueOpImpl(event, callbackArg);
 +    return pool.executeOnPrimary(op);
 +  }
 +
 +
 +  private GetEventValueOp() {
 +    // no instances allowed
 +  }
 +
 +  static class GetEventValueOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public GetEventValueOpImpl(EventID event, Object callbackArg) {
 +      super(MessageType.REQUEST_EVENT_VALUE, callbackArg != null ? 2 : 1);
 +      getMessage().addObjPart(event);
 +      if (callbackArg != null) {
 +        getMessage().addObjPart(callbackArg);
 +      }
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      Part part = msg.getPart(0);
 +      final int msgType = msg.getMessageType();
 +      if (msgType == MessageType.RESPONSE) {
 +        return part;
 +      } else {
 +        if (msgType == MessageType.REQUEST_EVENT_VALUE_ERROR) {
 +          // Value not found in haContainer.
 +          return null;
 +        }
 +        else if (msgType == MessageType.EXCEPTION) {
 +          String s = "While performing a remote " + "getFullValue";
 +          throw new ServerOperationException(s, (Throwable) part.getObject());
 +          // Get the exception toString part.
 +          // This was added for c++ thin client and not used in java
 +          // Part exceptionToStringPart = msg.getPart(1);
 +        } else if (isErrorResponse(msgType)) {
 +          throw new ServerOperationException(part.getString());
 +        } else {
 +          throw new InternalGemFireError("Unexpected message type "
 +                                         + MessageType.getString(msgType));
 +        }
 +      }
 +    }
 +
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.REQUESTDATAERROR;
 +    }
 +
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGet();
 +    }
 +
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetSend(start, hasFailed());
 +    }
 +
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGet(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
index 9e63fba,0000000..177ea26
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
@@@ -1,84 -1,0 +1,84 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +public class GetFunctionAttributeOp {
 +
 +  public static Object execute(ExecutablePool pool, String functionId) {
 +    AbstractOp op = new GetFunctionAttributeOpImpl(functionId);
 +    return pool.execute(op);
 +  }
 +
 +  private GetFunctionAttributeOp() {
 +    // no instances allowed
 +  }
 +
 +  static class GetFunctionAttributeOpImpl extends AbstractOp {
 +
 +    private String functionId = null;
 +
 +    public GetFunctionAttributeOpImpl(String functionId) {
 +      super(MessageType.GET_FUNCTION_ATTRIBUTES, 1);
 +      this.functionId = functionId;
 +      getMessage().addStringPart(this.functionId);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      return processObjResponse(msg, "getFunctionAttribute");
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.REQUESTDATAERROR;
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGet();
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetSend(start, hasFailed());
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGet(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
index d3e9efb,0000000..1e22d81
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
@@@ -1,94 -1,0 +1,92 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.pdx.internal.EnumInfo;
 +
 +/**
 + * Retrieve the PDXType, given an integer PDX id, from a server.
 + * @author darrel
 + * @since 6.6.2
 + */
 +public class GetPDXEnumByIdOp {
 +  /**
 +   * Get a enum from the given pool.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static EnumInfo execute(ExecutablePool pool,
 +                             int enumId)
 +  {
 +    AbstractOp op = new GetPDXEnumByIdOpImpl(enumId);
 +    return (EnumInfo) pool.execute(op);
 +  }
 +                                                               
 +  private GetPDXEnumByIdOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class GetPDXEnumByIdOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public GetPDXEnumByIdOpImpl(int enumId) {
 +      super(MessageType.GET_PDX_ENUM_BY_ID, 1);
 +      getMessage().addIntPart(enumId);
 +    }
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      return processObjResponse(msg, "getPDXEnumById");
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGetPDXTypeById(); // reuse PDXType stats instead of adding new enum ones
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeByIdSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeById(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    //Don't send the transaction id for this message type.
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
 +    
-     //TODO - no idea what this mumbo jumbo means, but it's on
-     //most of the other messages like this.
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
index 0cb5d33,0000000..0590caf
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
@@@ -1,112 -1,0 +1,112 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.util.Map;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.pdx.internal.EnumInfo;
 +
 +/**
 + * Retrieve all known PDX types.
 + * 
 + * @author bakera
 + * @since 7.0
 + */
 +public class GetPDXEnumsOp {
 +
 +  public static Map<Integer, EnumInfo> execute(ExecutablePool pool) {
 +    AbstractOp op = new GetPDXEnumsOpImpl();
 +    return (Map<Integer, EnumInfo>) pool.execute(op);
 +  }
 +                                                               
 +  private GetPDXEnumsOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class GetPDXEnumsOpImpl extends AbstractOp {
 +    public GetPDXEnumsOpImpl() {
 +      super(MessageType.GET_PDX_ENUMS, 1);
 +      getMessage().addIntPart(0); // must have at least one part
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      Part part = msg.getPart(0);
 +      int msgType = msg.getMessageType();
 +      if (msgType == MessageType.RESPONSE) {
 +        return (Map<Integer, EnumInfo>) part.getObject();
 +
 +      } else {
 +        if (msgType == MessageType.EXCEPTION) {
 +          String s = "While performing a remote " + "getPdxEnums";
 +          throw new ServerOperationException(s, (Throwable) part.getObject());
 +
 +        } else if (isErrorResponse(msgType)) {
 +          throw new ServerOperationException(part.getString());
 +
 +        } else {
 +          throw new InternalGemFireError("Unexpected message type "
 +              + MessageType.getString(msgType));
 +        }
 +      }
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return 0;
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +    }
 +    
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
index 81a2b1b,0000000..bac2e80
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
@@@ -1,115 -1,0 +1,113 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.pdx.internal.EnumInfo;
 +
 +/**
 + * Retrieve the PDXType, given an integer PDX id, from a server.
 + * @author darrel
 + * @since 6.6.2
 + */
 +public class GetPDXIdForEnumOp {
 +  /**
 +   * Register a bunch of instantiators on a server
 +   * using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static int execute(ExecutablePool pool,
 +                             EnumInfo ei)
 +  {
 +    AbstractOp op = new GetPDXIdForEnumOpImpl(ei);
 +    return ((Integer) pool.execute(op)).intValue();
 +  }
 +                                                               
 +  private GetPDXIdForEnumOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class GetPDXIdForEnumOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public GetPDXIdForEnumOpImpl(EnumInfo ei) {
 +      super(MessageType.GET_PDX_ID_FOR_ENUM, 1);
 +      getMessage().addObjPart(ei);
 +    }
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      Part part = msg.getPart(0);
 +      final int msgType = msg.getMessageType();
 +      if (msgType == MessageType.RESPONSE) {
 +        return Integer.valueOf(part.getInt());
 +      } else {
 +        if (msgType == MessageType.EXCEPTION) {
 +          String s = "While performing a remote " + "getPdxIdForEnum";
 +          throw new ServerOperationException(s, (Throwable) part.getObject());
 +          // Get the exception toString part.
 +          // This was added for c++ thin client and not used in java
 +          // Part exceptionToStringPart = msg.getPart(1);
 +        } else if (isErrorResponse(msgType)) {
 +          throw new ServerOperationException(part.getString());
 +        } else {
 +          throw new InternalGemFireError("Unexpected message type "
 +                                         + MessageType.getString(msgType));
 +        }
 +      }
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGetPDXTypeById();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeByIdSend(start, hasFailed()); /* reusing type stats instead of adding enum ones */
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeById(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    //Don't send the transaction id for this message type.
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
-     //TODO - no idea what this mumbo jumbo means, but it's on
-     //most of the other messages like this.
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
index d771cb6,0000000..1b71f71
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
@@@ -1,115 -1,0 +1,113 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.pdx.internal.PdxType;
 +
 +/**
 + * Retrieve the PDXType, given an integer PDX id, from a server.
 + * @author dsmith
 + * @since 6.6
 + */
 +public class GetPDXIdForTypeOp {
 +  /**
 +   * Register a bunch of instantiators on a server
 +   * using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static int execute(ExecutablePool pool,
 +                             PdxType type)
 +  {
 +    AbstractOp op = new GetPDXIdForTypeOpImpl(type);
 +    return ((Integer) pool.execute(op)).intValue();
 +  }
 +                                                               
 +  private GetPDXIdForTypeOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class GetPDXIdForTypeOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public GetPDXIdForTypeOpImpl(PdxType type) {
 +      super(MessageType.GET_PDX_ID_FOR_TYPE, 1);
 +      getMessage().addObjPart(type);
 +    }
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      Part part = msg.getPart(0);
 +      final int msgType = msg.getMessageType();
 +      if (msgType == MessageType.RESPONSE) {
 +        return Integer.valueOf(part.getInt());
 +      } else {
 +        if (msgType == MessageType.EXCEPTION) {
 +          String s = "While performing a remote " + "getPdxIdForType";
 +          throw new ServerOperationException(s, (Throwable) part.getObject());
 +          // Get the exception toString part.
 +          // This was added for c++ thin client and not used in java
 +          // Part exceptionToStringPart = msg.getPart(1);
 +        } else if (isErrorResponse(msgType)) {
 +          throw new ServerOperationException(part.getString());
 +        } else {
 +          throw new InternalGemFireError("Unexpected message type "
 +                                         + MessageType.getString(msgType));
 +        }
 +      }
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGetPDXTypeById();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeByIdSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeById(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    //Don't send the transaction id for this message type.
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
-     //TODO - no idea what this mumbo jumbo means, but it's on
-     //most of the other messages like this.
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}



[014/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingPoolDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingPoolDUnitTest.java
index d1e42d3,0000000..4df1f81
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingPoolDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/QueryUsingPoolDUnitTest.java
@@@ -1,2588 -1,0 +1,2588 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.dunit;
 +
 +import java.io.DataInput;
 +import java.io.DataOutput;
 +import java.io.IOException;
 +import java.util.Comparator;
 +import java.util.Iterator;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import cacheRunner.Portfolio;
 +import cacheRunner.Position;
 +
 +import com.gemstone.gemfire.DataSerializable;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.query.*;
 +import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverAdapter;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
 +import com.gemstone.gemfire.cache.query.types.ObjectType;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.ClientServerTestCase;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientNotifier;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +
 +/**
 + * Tests remote (client/server) query execution.
 + *
 + * @author Barry Oglesby
 + * @author Asif
 + * @since 5.0.1
 + */
 +public class QueryUsingPoolDUnitTest extends CacheTestCase {
 +
 +  /** The port on which the bridge server was started in this VM */
 +  private static int bridgeServerPort;
 +  
 +  final String rootRegionName = "root";
 +  
 +  private final String regionName = this.getName();
 +  
 +  private final String regName = "/" + rootRegionName + "/" + regionName;
 +  
 +  // Used with compiled queries.
 +  private final String[] queryString = new String[] {
 +      "SELECT itr.value FROM " + regName + ".entries itr where itr.key = $1", // 0
 +      "SELECT DISTINCT * FROM " + regName + " WHERE id < $1 ORDER BY   id", // 1
 +      "SELECT DISTINCT * FROM " + regName + " WHERE id < $1 ORDER BY id", // 2
 +      "(SELECT DISTINCT * FROM " + regName + " WHERE id < $1).size", // 3
 +      "SELECT * FROM " + regName + " WHERE id = $1 and Ticker = $2", // 4
 +      "SELECT * FROM " + regName + " WHERE id < $1 and Ticker = $2", // 5
 +  };
 +
 +  /**
 +   * Creates a new <code>GemFireMemberStatusDUnitTest</code>
 +   */
 +  public QueryUsingPoolDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  ////////  Test Methods
 +
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    disconnectAllFromDS();
 +    IgnoredException.addIgnoredException("Connection reset");
 +    IgnoredException.addIgnoredException("Socket input is shutdown");
 +  }
 +
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    disconnectAllFromDS();
 +  }
 +
 +  public void createPool(VM vm, String poolName, String server, int port, boolean subscriptionEnabled) {
 +    createPool(vm, poolName, new String[]{server}, new int[]{port}, subscriptionEnabled);  
 +  }
 +
 +  public void createPool(VM vm, String poolName, String server, int port) {
 +    createPool(vm, poolName, new String[]{server}, new int[]{port}, false);  
 +  }
 +
 +  public void createPool(VM vm, final String poolName, final String[] servers, final int[] ports,
 +      final boolean subscriptionEnabled) {
 +    vm.invoke(new CacheSerializableRunnable("createPool :" + poolName) {
 +      public void run2() throws CacheException {
 +        // Create Cache.
 +        getCache();
 +
 +        PoolFactory cpf = PoolManager.createFactory();
 +        cpf.setSubscriptionEnabled(subscriptionEnabled);
 +        for (int i=0; i < servers.length; i++){
 +          LogWriterUtils.getLogWriter().info("### Adding to Pool. ### Server : " + servers[i] + " Port : " + ports[i]);
 +          cpf.addServer(servers[i], ports[i]);
 +        }
 +
 +        cpf.create(poolName);
 +      }
 +    });   
 +  }
 +
 +  public void validateCompiledQuery(VM vm, final long compiledQueryCount) {
 +  vm.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +    public void run2() throws CacheException {
 +      long count = 0;
 +      for (int i=0; i < 100; i++) {
 +        count = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        if (count == compiledQueryCount){
 +          break;
 +        } else {
 +          Wait.pause(1 * 100);
 +        }
 +      }
 +      assertEquals(compiledQueryCount, count);
 +    }
 +  });
 + }
 +  
 +  /**
 +   * Tests remote import query execution.
 +   */
 +  public void testRemoteImportQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name, rootRegionName, factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    final String regionName = "/" + rootRegionName + "/" + name;
 +
 +    // Create client pool.
 +    final String poolName = "testRemoteImportQueries"; 
 +    createPool(vm1, poolName, host0, port);
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct * from " + regionName;
 +
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }          
 +
 +        assertEquals(numberOfEntries, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct * from " + regionName + " where ticker = 'ibm'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct * from " + regionName + " where ticker = 'IBM'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(0, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct * from " + regionName + " where price > 49";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries/2, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct * from " + regionName + " where price = 50";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct * from " + regionName + " where ticker = 'ibm' and price = 50";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +      }
 +    });
 +
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote struct query execution.
 +   */
 +  public void testRemoteStructQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name, factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + rootRegionName + "/" + name;
 +
 +    // Create client pool.
 +    final String poolName = "testRemoteStructQueries"; 
 +    createPool(vm1, poolName, host0, port);
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct ticker, price from " + regionName;
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct ticker, price from " + regionName + " where ticker = 'ibm'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct ticker, price from " + regionName + " where ticker = 'IBM'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(0, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct ticker, price from " + regionName + " where price > 49";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries/2, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct ticker, price from " + regionName + " where price = 50";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +        queryString = "import com.gemstone.gemfire.admin.QueryUsingPoolDUnitTest.TestObject; select distinct ticker, price from " + regionName + " where ticker = 'ibm' and price = 50";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote complex query execution.
 +   */
 +  public void __testRemoteComplexQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +//    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name, factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        Portfolio portfolio = null;
 +        Position position1 = null;
 +        Position position2 = null;
 +        Properties portfolioProperties= null;
 +        Properties position1Properties = null;
 +        Properties position2Properties = null;
 +
 +        // Create portfolio 1
 +        portfolio = new Portfolio();
 +        portfolioProperties = new Properties();
 +        portfolioProperties.put("id", new Integer(1));
 +        portfolioProperties.put("type", "type1");
 +        portfolioProperties.put("status", "active");
 +
 +        position1 = new Position();
 +        position1Properties = new Properties();
 +        position1Properties.put("secId", "SUN");
 +        position1Properties.put("qty", new Double(34000.0));
 +        position1Properties.put("mktValue", new Double(24.42));
 +        position1.init(position1Properties);
 +        portfolioProperties.put("position1", position1);
 +
 +        position2 = new Position();
 +        position2Properties = new Properties();
 +        position2Properties.put("secId", "IBM");
 +        position2Properties.put("qty", new Double(8765.0));
 +        position2Properties.put("mktValue", new Double(34.29));
 +        position2.init(position2Properties);
 +        portfolioProperties.put("position2", position2);
 +
 +        portfolio.init(portfolioProperties);
 +        region.put(new Integer(1), portfolio);
 +
 +        // Create portfolio 2
 +        portfolio = new Portfolio();
 +        portfolioProperties = new Properties();
 +        portfolioProperties.put("id", new Integer(2));
 +        portfolioProperties.put("type", "type2");
 +        portfolioProperties.put("status", "inactive");
 +
 +        position1 = new Position();
 +        position1Properties = new Properties();
 +        position1Properties.put("secId", "YHOO");
 +        position1Properties.put("qty", new Double(9834.0));
 +        position1Properties.put("mktValue", new Double(12.925));
 +        position1.init(position1Properties);
 +        portfolioProperties.put("position1", position1);
 +
 +        position2 = new Position();
 +        position2Properties = new Properties();
 +        position2Properties.put("secId", "GOOG");
 +        position2Properties.put("qty", new Double(12176.0));
 +        position2Properties.put("mktValue", new Double(21.972));
 +        position2.init(position2Properties);
 +        portfolioProperties.put("position2", position2);
 +
 +        portfolio.init(portfolioProperties);
 +        region.put(new Integer(2), portfolio);
 +
 +        // Create portfolio 3
 +        portfolio = new Portfolio();
 +        portfolioProperties = new Properties();
 +        portfolioProperties.put("id", new Integer(3));
 +        portfolioProperties.put("type", "type3");
 +        portfolioProperties.put("status", "active");
 +
 +        position1 = new Position();
 +        position1Properties = new Properties();
 +        position1Properties.put("secId", "MSFT");
 +        position1Properties.put("qty", new Double(98327.0));
 +        position1Properties.put("mktValue", new Double(23.32));
 +        position1.init(position1Properties);
 +        portfolioProperties.put("position1", position1);
 +
 +        position2 = new Position();
 +        position2Properties = new Properties();
 +        position2Properties.put("secId", "AOL");
 +        position2Properties.put("qty", new Double(978.0));
 +        position2Properties.put("mktValue", new Double(40.373));
 +        position2.init(position2Properties);
 +        portfolioProperties.put("position2", position2);
 +
 +        portfolio.init(portfolioProperties);
 +        region.put(new Integer(3), portfolio);
 +
 +        // Create portfolio 4
 +        portfolio = new Portfolio();
 +        portfolioProperties = new Properties();
 +        portfolioProperties.put("id", new Integer(4));
 +        portfolioProperties.put("type", "type1");
 +        portfolioProperties.put("status", "inactive");
 +
 +        position1 = new Position();
 +        position1Properties = new Properties();
 +        position1Properties.put("secId", "APPL");
 +        position1Properties.put("qty", new Double(90.0));
 +        position1Properties.put("mktValue", new Double(67.356572));
 +        position1.init(position1Properties);
 +        portfolioProperties.put("position1", position1);
 +
 +        position2 = new Position();
 +        position2Properties = new Properties();
 +        position2Properties.put("secId", "ORCL");
 +        position2Properties.put("qty", new Double(376.0));
 +        position2Properties.put("mktValue", new Double(101.34));
 +        position2.init(position2Properties);
 +        portfolioProperties.put("position2", position2);
 +
 +        portfolio.init(portfolioProperties);
 +        region.put(new Integer(4), portfolio);
 +      }
 +    });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("mcast-port", "0");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        getCache();
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +        createRegion(name, factory.create());
 +      }
 +    });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        String queryString = null;
 +        SelectResults results = null;
 +
 +        queryString =
 +          "IMPORT cacheRunner.Position; " +
 +          "SELECT DISTINCT id, status FROM " + region.getFullPath() +
 +          "WHERE NOT (SELECT DISTINCT * FROM positions.values posnVal TYPE Position " +
 +          "WHERE posnVal.secId='AOL' OR posnVal.secId='SAP').isEmpty";
 +        try {
 +          results = region.query(queryString);
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        LogWriterUtils.getLogWriter().fine("size: " + results.size());
 +        //assertEquals(numberOfEntries, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +      }
 +    });
 +
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote full region query execution.
 +   */
 +  public void testRemoteFullRegionQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name, factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + rootRegionName + "/" + name;
 +
 +    // Create client pool.
 +    final String poolName = "testRemoteFullRegionQueries"; 
 +    createPool(vm1, poolName, host0, port);
 +
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +        Comparator comparator = null;
 +        Object[] resultsArray = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        // value query
 +        queryString = "SELECT DISTINCT itr.value FROM " + regionName + ".entries itr where itr.key = 'key-1'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +        assertTrue(results.asList().get(0) instanceof TestObject);
 +
 +        // key query
 +        queryString = "SELECT DISTINCT itr.key FROM " + regionName + ".entries itr where itr.key = 'key-1'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates());
 +        assertEquals("key-1", results.asList().get(0));
 +
 +        // order by value query
 +        queryString = "SELECT DISTINCT * FROM " + regionName + " WHERE id < 101 ORDER BY id";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries, results.size());
 +        // All order-by query results are stored in a ResultsCollectionWrapper
 +        // wrapping a list, so the assertion below is not correct even though
 +        // it should be.
 +        //assertTrue(!results.getCollectionType().allowsDuplicates());
 +        assertTrue(results.getCollectionType().isOrdered());
 +        comparator = new IdComparator();
 +        resultsArray = results.toArray();
 +        for (int i=0; i<resultsArray.length; i++) {
 +          if (i+1 != resultsArray.length) {
 +            // The id of the current element in the result set must be less
 +            // than the id of the next one to pass.
 +            assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], comparator.compare(resultsArray[i], resultsArray[i+1]) == -1);
 +          }
 +        }
 +
 +        // order by struct query
 +        queryString = "SELECT DISTINCT id, ticker, price FROM " + regionName + " WHERE id < 101 ORDER BY id";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries, results.size());
 +        // All order-by query results are stored in a ResultsCollectionWrapper
 +        // wrapping a list, so the assertion below is not correct even though
 +        // it should be.
 +        //assertTrue(!results.getCollectionType().allowsDuplicates());
 +        assertTrue(results.getCollectionType().isOrdered());
 +        comparator = new StructIdComparator();
 +        resultsArray = results.toArray();
 +        for (int i=0; i<resultsArray.length; i++) {
 +          if (i+1 != resultsArray.length) {
 +            // The id of the current element in the result set must be less
 +            // than the id of the next one to pass.
 +            assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], comparator.compare(resultsArray[i], resultsArray[i+1]) == -1);
 +          }
 +        }
 +
 +        // size query
 +        queryString = "(SELECT DISTINCT * FROM " + regionName + " WHERE id < 101).size";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        Object result = results.iterator().next();
 +        assertTrue(result instanceof Integer);
 +        int resultInt = ((Integer) result).intValue();
 +        assertEquals(resultInt, 100);
 +
 +        // query with leading/trailing spaces
 +        queryString = " SELECT DISTINCT itr.key FROM " + regionName + ".entries itr where itr.key = 'key-1' ";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertEquals("key-1", results.asList().get(0));
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests client-server query using parameters (compiled queries).
 +   */
 +  public void testClientServerQueriesWithParams() throws CacheException {
 +
 +    final String name = this.getName();
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    final Object[][] params = new Object[][] {
 +        {"key-1"}, // 0
 +        {101}, // 1
 +        {101}, // 2
 +        {101}, // 3
 +        {50, "ibm"}, // 4
 +        {50, "ibm"}, // 5
 +    };
 +
 +    final int[] expectedResults = new int[] {
 +        1, // 0
 +        100, // 1
 +        100, // 2
 +        1, // 3
 +        1, // 4
 +        50, // 5
 +    };
 +
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create and populate region") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + this.rootRegionName + "/" + this.regionName;
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueriesWithParams"; 
 +    createPool(vm1, poolName, host0, port);
 +
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        SelectResults results = null;
 +        Comparator comparator = null;
 +        Object[] resultsArray = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query :" + queryString[i]);
 +            Query query = qService.newQuery(queryString[i]);
 +            results = (SelectResults)query.execute(params[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +          try {
 +            assertEquals(expectedResults[i], results.size());
 +          }catch(Throwable th) {
 +            fail("Result mismatch for query= " + queryString[i] + " expected = "+expectedResults[i] + " actual="+results.size());
 +          }
 +        }        
 +      }
 +    });
 +
 +    final int useMaintainedCompiledQueries = queryString.length;
 +
 +    // Execute the same compiled queries multiple time
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        SelectResults results = null;
 +        Comparator comparator = null;
 +        Object[] resultsArray = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +        for (int x=0; x < useMaintainedCompiledQueries; x++){
 +          for (int i=0; i < queryString.length; i++){
 +            try {
 +              LogWriterUtils.getLogWriter().info("### Executing Query :" + queryString[i]);
 +              Query query = qService.newQuery(queryString[i]);
 +              results = (SelectResults)query.execute(params[i]);
 +            } catch (Exception e) {
 +              Assert.fail("Failed executing " + queryString[i], e);
 +            }
 +            try {
 +              assertEquals(expectedResults[i], results.size());
 +            }catch(Throwable th) {
 +              fail("Result mismatch for query= " + queryString[i] + " expected = "+expectedResults[i] + " actual="+results.size());
 +            }
 +          }        
 +        }
 +      }
 +    });
 +
 +    // Validate maintained compiled queries.
 +    // There should be only queryString.length compiled queries registered.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +
 +    // Check to see if maintained compiled queries are used.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryUsedCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryUsedCount();
 +        int numTimesUsed = (useMaintainedCompiledQueries + 1) * queryString.length;
 +        assertEquals(numTimesUsed, compiledQueryUsedCount);
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests client-server query using parameters (compiled queries).
 +   */
 +  public void testMulitipleClientServerQueriesWithParams() throws CacheException {
 +    final String name = this.getName();
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    final int numberOfEntries = 100;
 +
 +    final Object[][] params = new Object[][] {
 +        {"key-1"}, // 0
 +        {101}, // 1
 +        {101}, // 2
 +        {101}, // 3
 +        {50, "ibm"}, // 4
 +        {50, "ibm"}, // 5
 +    };
 +
 +    final int[] expectedResults = new int[] {
 +        1, // 0
 +        100, // 1
 +        100, // 2
 +        1, // 3
 +        1, // 4
 +        50, // 5
 +    };
 +
 +
 +    // Start server1
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +        Region region = getRootRegion().getSubregion(regionName);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +
 +    // Start server2
 +    vm1.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +        Region region = getRootRegion().getSubregion(regionName);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +    // Create client region
-     final int port0 = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
-     final int port1 = vm1.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port0 = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
++    final int port1 = vm1.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + this.rootRegionName + "/" + this.regionName;
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueriesWithParams"; 
 +    createPool(vm2, poolName, new String[]{host0}, new int[]{port0}, true);
 +    createPool(vm3, poolName, new String[]{host0}, new int[]{port1}, true);
 +
 +    // Execute client queries
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        SelectResults results = null;
 +        Comparator comparator = null;
 +        Object[] resultsArray = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +        for (int j=0; j < queryString.length; j++){
 +          for (int i=0; i < queryString.length; i++){
 +            try {
 +              LogWriterUtils.getLogWriter().info("### Executing Query :" + queryString[i]);
 +              Query query = qService.newQuery(queryString[i]);
 +              results = (SelectResults)query.execute(params[i]);
 +            } catch (Exception e) {
 +              Assert.fail("Failed executing " + queryString[i], e);
 +            }
 +            try {
 +              assertEquals(expectedResults[i], results.size());
 +            }catch(Throwable th) {
 +              fail("Result mismatch for query= " + queryString[i] + " expected = "+expectedResults[i] + " actual="+results.size());
 +            }
 +          }
 +        }
 +      }
 +    };
 +
 +    vm2.invoke(executeQueries);
 +    vm3.invoke(executeQueries);
 +
 +    // Validate maintained compiled queries.
 +    // There should be only queryString.length compiled queries registered.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +    
 +    this.closeClient(vm2);
 +    this.closeClient(vm3);
 +    
 +    // Validate maintained compiled queries.
 +    // All the queries will be still present in the server.
 +    // They will be cleaned up periodically.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +    
 +    vm1.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 + 
 +    // recreate clients and execute queries.
 +    createPool(vm2, poolName, new String[]{host0, host0}, new int[]{port1, port0}, true);
 +    createPool(vm3, poolName, new String[]{host0, host0}, new int[]{port0, port1}, true);
 +
 +    vm2.invoke(executeQueries);
 +    vm3.invoke(executeQueries);
 +    
 +    // Validate maintained compiled queries.
 +    // All the queries will be still present in the server.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +    
 +    vm1.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +    
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +    vm1.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +
 +  }
 +
 +  /**
 +   * Tests client-server compiled query register and cleanup.
 +   */
 +  public void testClientServerCompiledQueryRegisterAndCleanup() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final int numberOfEntries = 100;
 +
 +    final Object[][] params = new Object[][] {
 +        {"key-1"}, // 0
 +        {101}, // 1
 +        {101}, // 2
 +        {101}, // 3
 +        {50, "ibm"}, // 4
 +        {50, "ibm"}, // 5
 +    };
 +    
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create and populate region.") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + this.rootRegionName + "/" + this.regionName;
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueriesWithParams"; 
 +    createPool(vm1, poolName, host0, port);
 +    createPool(vm2, poolName, host0, port);
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);      }
 +    });
 +
 +    // Execute client queries
 +    vm2.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);      }
 +    });
 +    
 +    // Validate maintained compiled queries.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +
 +    closeClient(vm1);
 +
 +    // Validate maintained compiled queries.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });    
 +  }
 +
 +  /**
 +   * Tests client-server compiled query register and cleanup.
 +   */
 +  public void testClientServerCompiledQueryTimeBasedCleanup() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final int numberOfEntries = 100;
 +
 +    final Object[][] params = new Object[][] {
 +        {"key-1"}, // 0
 +        {101}, // 1
 +        {101}, // 2
 +        {101}, // 3
 +        {50, "ibm"}, // 4
 +        {50, "ibm"}, // 5
 +    };
 +    
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create and populate region.") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +        QueryService qs = getCache().getQueryService();
 +        DefaultQuery query = (DefaultQuery)qs.newQuery("Select * from " + regName);
 +        query.setTestCompiledQueryClearTime(2 * 1000); 
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + this.rootRegionName + "/" + this.regionName;
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueriesWithParams"; 
 +    createPool(vm1, poolName, host0, port);
 +    createPool(vm2, poolName, host0, port);
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +
 +    // Execute client queries
 +    vm2.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +        
 +    // Validate maintained compiled queries.
 +    this.validateCompiledQuery(vm0, 0);
 +        
 +    // Recreate compiled queries.
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +
 +    // Execute client queries
 +    // The client2 will be using the queries.
 +    vm2.invokeAsync(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        for (int i=0; i < 10; i++) {
 +          Wait.pause(200);
 +          executeCompiledQueries(poolName, params);
 +        }
 +      }
 +    });
 +       
 +    // Validate maintained compiled queries.
 +    validateCompiledQuery(vm0, queryString.length);
 +
 +    // Let the compiled queries to be idle (not used).
 +    Wait.pause(2 * 1000);    
 +    
 +    // Validate maintained compiled queries.
 +    this.validateCompiledQuery(vm0, 0);
 +
 +    // Close clients
 +    closeClient(vm2);
 +    closeClient(vm1);
 +    
 +    // Validate maintained compiled queries.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(0, compiledQueryCount);
 +      }
 +    });
 +    
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });    
 +  }
 +
 +  /**
 +   * Tests client-server compiled query register and cleanup.
 +   * It creates the client connections without the subscription 
 +   * enabled. This doesn't create any client proxy on the server.
 +   */
 +  public void testClientServerCompiledQueryCleanup() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final int numberOfEntries = 100;
 +
 +    final Object[][] params = new Object[][] {
 +        {"key-1"}, // 0
 +        {101}, // 1
 +        {101}, // 2
 +        {101}, // 3
 +        {50, "ibm"}, // 4
 +        {50, "ibm"}, // 5
 +    };
 +    
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create and populate region.") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +        QueryService qs = getCache().getQueryService();
 +        DefaultQuery query = (DefaultQuery)qs.newQuery("Select * from " + regName);
 +        query.setTestCompiledQueryClearTime(2 * 1000); 
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + this.rootRegionName + "/" + this.regionName;
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueriesWithParams"; 
 +    final boolean subscriptiuonEnabled = false;
 +    createPool(vm1, poolName, host0, port, subscriptiuonEnabled);
 +    createPool(vm2, poolName, host0, port, subscriptiuonEnabled);
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +
 +    // Execute client queries
 +    vm2.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +    
 +    // Validate maintained compiled queries.
 +    this.validateCompiledQuery(vm0, 0);
 +    
 +    
 +    // Recreate compiled queries.
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +
 +    // Execute client queries
 +    // The client2 will be using the queries.
 +    vm2.invokeAsync(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        for (int i=0; i < 10; i++) {
 +          Wait.pause(10);
 +          executeCompiledQueries(poolName, params);
 +        }
 +      }
 +    });
 +       
 +    // Validate maintained compiled queries.
 +    this.validateCompiledQuery(vm0, queryString.length);
 +
 +    // Close clients
 +    // Let the compiled queries to be idle (not used).
 +    //pause(2 * 1000);    
 +    
 +    // Validate maintained compiled queries.
 +    this.validateCompiledQuery(vm0, 0);
 +    
 +    // Recreate compiled queries.
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        executeCompiledQueries(poolName, params);
 +      }
 +    });
 +    
 +    
 +    // Validate maintained compiled queries.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryCount();
 +        assertEquals(queryString.length, compiledQueryCount);
 +      }
 +    });
 +
 +    // Close clients
 +    closeClient(vm2);
 +    closeClient(vm1);
 +
 +    // Validate maintained compiled queries.
 +    // since not used it should get cleaned up after sometime.
 +    this.validateCompiledQuery(vm0, 0);
 +    
 +    
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });    
 +  }
 +
 +  /**
 +   * Tests client-server query using parameters (compiled queries).
 +   */
 +  public void testBindParamsWithMulitipleClients() throws CacheException {
 +
 +    final String name = this.getName();
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    final int numberOfEntries = 100;
 +
 +    final Object[][] params = new Object[][] {
 +        {"key-1"}, // 0
 +        {101}, // 1
 +        {101}, // 2
 +        {101}, // 3
 +        {50, "ibm"}, // 4
 +        {50, "ibm"}, // 5
 +    };
 +
 +    final String[] querys = new String[] {
 +        "SELECT itr.value FROM " + regName + ".entries itr where itr.key = 'key-1'", // 0
 +        "SELECT DISTINCT * FROM " + regName + " WHERE id < 101 ORDER BY id", // 1
 +        "SELECT DISTINCT * FROM " + regName + " WHERE id < 101 ORDER BY id", // 2
 +        "(SELECT DISTINCT * FROM " + regName + " WHERE id < 101).size", // 3
 +        "SELECT * FROM " + regName + " WHERE id = 50 and Ticker = 'ibm'", // 4
 +        "SELECT * FROM " + regName + " WHERE id < 50 and Ticker = 'ibm'", // 5
 +    };
 +
 +    final int[] expectedResults = new int[] {
 +        1, // 0
 +        100, // 1
 +        100, // 2
 +        1, // 3
 +        1, // 4
 +        50, // 5
 +    };
 +
 +    // Start server1
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer();
 +        Region region = getRootRegion().getSubregion(regionName);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +    // Create client region
-     final int port0 = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port0 = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + this.rootRegionName + "/" + this.regionName;
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueriesWithParams"; 
 +    createPool(vm1, poolName, new String[]{host0}, new int[]{port0}, true);
 +    createPool(vm2, poolName, new String[]{host0}, new int[]{port0}, true);
 +    createPool(vm3, poolName, new String[]{host0}, new int[]{port0}, true);
 +
 +    // Execute client query multiple times and validate results.
 +    SerializableRunnable executeSameQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService qService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +        
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }      
 +        // Use minimal query, so that there will be multiple 
 +        // clients using the same compiled query at server.
 +        for (int j=0; j < 5; j++){
 +          for (int i=0; i < 2; i++){
 +            try {
 +              LogWriterUtils.getLogWriter().info("### Executing Query :" + queryString[i]);
 +              Query query = qService.newQuery(queryString[i]);
 +              rs[0][0] = (SelectResults)query.execute(params[i]);
 +              Query query2 = qService.newQuery(querys[i]);
 +              rs[0][1] = (SelectResults)query2.execute();
 +              // Compare results.
 +            } catch (Exception e) {
 +              Assert.fail("Failed executing " + queryString[i], e);
 +            }
 +            LogWriterUtils.getLogWriter().info("### Comparing results for Query :" + ((i+1) * (j+1)) + " : " + queryString[i]);
 +            compareQueryResultsWithoutAndWithIndexes(rs, 1);
 +            LogWriterUtils.getLogWriter().info("### Done Comparing results for Query :" + ((i+1) * (j+1)) + " : " + queryString[i]); 
 +          }
 +        }
 +      }
 +    };
 +
 +    vm1.invokeAsync(executeSameQueries);
 +    vm2.invokeAsync(executeSameQueries);
 +    vm3.invokeAsync(executeSameQueries);
 +    
 +    // Wait till the query execution completes.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryUsedCount = -1;
 +        while (true) {
 +          LogWriterUtils.getLogWriter().info("### CompiledQueryUsedCount :" + compiledQueryUsedCount);
 +          if (compiledQueryUsedCount == CacheClientNotifier.getInstance().getStats().getCompiledQueryUsedCount()) {
 +            LogWriterUtils.getLogWriter().info("### previous and current CompiledQueryUsedCounts are same :" + compiledQueryUsedCount);
 +            break;
 +          } else {
 +            compiledQueryUsedCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryUsedCount();
 +            try {
 +              Thread.currentThread().sleep(3 * 1000);
 +            } catch (Exception ex) {
 +              break;
 +            }
 +          }
 +        }
 +      }
 +    });
 +    
 +    // Execute client queries and validate results.
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        SelectResults results = null;
 +        SelectResults results2 = null;
 +        Comparator comparator = null;
 +        Object[] resultsArray = null;
 +        QueryService qService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +        
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +        for (int j=0; j < queryString.length; j++){
 +          for (int i=0; i < queryString.length; i++){
 +            try {
 +              LogWriterUtils.getLogWriter().info("### Executing Query :" + queryString[i]);
 +              Query query = qService.newQuery(queryString[i]);
 +              rs[0][0] = (SelectResults)query.execute(params[i]);
 +              Query query2 = qService.newQuery(querys[i]);
 +              rs[0][1] = (SelectResults)query2.execute();
 +              // Compare results.
 +              compareQueryResultsWithoutAndWithIndexes(rs, 1);
 +            } catch (Exception e) {
 +              Assert.fail("Failed executing " + queryString[i], e);
 +            }
 +          }
 +        }
 +      }
 +    };
 +
 +    vm1.invokeAsync(executeQueries);
 +    vm2.invokeAsync(executeQueries);
 +    vm3.invokeAsync(executeQueries);
 +    
 +    // Wait till the query execution completes.
 +    vm0.invoke(new CacheSerializableRunnable("validate compiled query.") {
 +      public void run2() throws CacheException {
 +        long compiledQueryUsedCount = -1;
 +        while (true) {
 +          LogWriterUtils.getLogWriter().info("### previous CompiledQueryUsedCount :" + compiledQueryUsedCount);
 +          if (compiledQueryUsedCount == CacheClientNotifier.getInstance().getStats().getCompiledQueryUsedCount()) {
 +            LogWriterUtils.getLogWriter().info("### previous and current CompiledQueryUsedCounts are same :" + compiledQueryUsedCount);
 +            break;
 +          } else {
 +            compiledQueryUsedCount = CacheClientNotifier.getInstance().getStats().getCompiledQueryUsedCount();
 +            try {
 +              Thread.currentThread().sleep(3 * 1000);
 +            } catch (Exception ex) {
 +              break;
 +            }
 +          }
 +        }
 +      }
 +    });
 +      
 +    this.closeClient(vm1);
 +    this.closeClient(vm2);
 +    this.closeClient(vm3);
 +    
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +    
 +  }
 +
 +  /**
 +   * Tests remote join query execution.
 +   */
 +  public void testRemoteJoinRegionQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name+"1", factory.create());
 +        createRegion(name+"2", factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region1 = getRootRegion().getSubregion(name+"1");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region1.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +        Region region2 = getRootRegion().getSubregion(name+"2");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region2.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    final String regionName1 = "/" + rootRegionName + "/" + name+"1";
 +    final String regionName2 = "/" + rootRegionName + "/" + name+"2";
 +
 +    // Create client pool.
 +    final String poolName = "testRemoteJoinRegionQueries"; 
 +    createPool(vm1, poolName, host0, port);
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        queryString =
 +          "select distinct a, b.price from " + regionName1 + " a, " + regionName2 + " b where a.price = b.price";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(numberOfEntries, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +        queryString =
 +          "select distinct a, b.price from " + regionName1 + " a, " + regionName2 + " b where a.price = b.price and a.price = 50";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote query execution using a BridgeClient as the CacheWriter
 +   * and CacheLoader.
 +   */
 +  public void testRemoteBridgeClientQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name, factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + rootRegionName + "/" + name;
 +
 +    // Create client pool.
 +    final String poolName1 = "testRemoteBridgeClientQueries1"; 
 +    final String poolName2 = "testRemoteBridgeClientQueries2"; 
 +
 +    createPool(vm1, poolName1, host0, port);
 +    createPool(vm2, poolName2, host0, port);
 +
 +    // Execute client queries in VM1
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName1)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        queryString = "SELECT DISTINCT itr.value FROM " + regionName + ".entries itr where itr.key = 'key-1'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +        assertTrue(results.asList().get(0) instanceof TestObject);
 +
 +        queryString = "SELECT DISTINCT itr.key FROM " + regionName + ".entries itr where itr.key = 'key-1'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +        assertEquals("key-1", results.asList().get(0));
 +      }
 +    });
 +
 +    // Execute client queries in VM2
 +    vm2.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName2)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        queryString = "SELECT DISTINCT itr.value FROM " + regionName + ".entries itr where itr.key = 'key-1'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +        assertTrue(results.asList().get(0) instanceof TestObject);
 +
 +        queryString = "SELECT DISTINCT itr.key FROM " + regionName + ".entries itr where itr.key = 'key-1'";
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          results = (SelectResults)query.execute();
 +        } catch (Exception e) {
 +          Assert.fail("Failed executing " + queryString, e);
 +        }
 +        assertEquals(1, results.size());
 +        assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +        assertEquals("key-1", results.asList().get(0));
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * This the dunit test for the bug no : 36969
 +   * @throws Exception
 +   */
 +
 +  public void testBug36969() throws Exception
 +  {
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create two regions") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        final Region region1 = createRegion(name, factory.createRegionAttributes());
 +        final Region region2 = createRegion(name+"_2", factory.createRegionAttributes());
 +        QueryObserverHolder.setInstance(new QueryObserverAdapter() {
 +          public void afterQueryEvaluation(Object result) {
 +            //Destroy the region in the test
 +            region1.close();
 +          }
 +
 +        });
 +        Wait.pause(1000);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region1.put("key-"+i, new TestObject(i, "ibm"));
 +          region2.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName1 = "/" + rootRegionName + "/" + name;
 +    final String regionName2 = "/" + rootRegionName + "/" + name + "_2";
 +
 +    // Create client pool.
 +    final String poolName = "testBug36969";
 +    createPool(vm1, poolName, host0, port);
 +
 +    // Execute client queries in VM1      
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = "select distinct * from " + regionName1 + ", "+regionName2;
 +//        SelectResults results = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +
 +        try {
 +          Query query = qService.newQuery(queryString);
 +          query.execute();
 +          fail("The query should have experienced RegionDestroyedException");
 +        } catch(Exception e) {
 +          // OK
 +        }
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        QueryObserverHolder.setInstance(new QueryObserverAdapter());
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +
 +
 +
 +  }
 +
 +  /**
 +   * Tests remote full region query execution.
 +   */
 +  public void testRemoteSortQueriesUsingIndex() throws CacheException {
 +
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        createRegion(name, factory.create());
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(name);
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +        // Create index
 +        try {
 +          QueryService qService = region.getCache().getQueryService();
 +          qService.createIndex("idIndex",IndexType.FUNCTIONAL, "id", region.getFullPath());
 +        } catch (Exception e) {
 +          Assert.fail("Failed to create index.", e);
 +        }          
 +
 +      }
 +    });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName = "/" + rootRegionName + "/" + name;
 +
 +    // Create client pool.
 +    final String poolName = "testRemoteFullRegionQueries"; 
 +    createPool(vm1, poolName, host0, port);
 +
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        String queryString = null;
 +        SelectResults results = null;
 +        Comparator comparator = null;
 +        Object[] resultsArray = null;
 +        QueryService qService = null;
 +        Integer v1 = 0;
 +        Integer v2 = 0;
 +        
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }          
 +
 +        // order by value query
 +        String[] qString = {
 +            "SELECT DISTINCT * FROM " + regionName + " WHERE id < 101 ORDER BY id",
 +            "SELECT DISTINCT id FROM " + regionName + " WHERE id < 101 ORDER BY id",
 +        };
 +        
 +        for (int cnt=0; cnt < qString.length; cnt++) {
 +          queryString = qString[cnt];
 +          try {
 +            Query query = qService.newQuery(queryString);
 +            results = (SelectResults)query.execute();
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          // All order-by query results are stored in a ResultsCollectionWrapper
 +          // wrapping a list, so the assertion below is not correct even though
 +          // it should be.
 +          //assertTrue(!results.getCollectionType().allowsDuplicates());
 +          assertTrue(results.getCollectionType().isOrdered());
 +          comparator = new IdValueComparator();
 +
 +          resultsArray = results.toArray();
 +          for (int i=0; i<resultsArray.length; i++) {
 +            if (i+1 != resultsArray.length) {
 +              // The id of the current element in the result set must be less
 +              // than the id of the next one to pass.
 +              if (resultsArray[i] instanceof TestObject) {
 +                v1 = ((TestObject)resultsArray[i]).getId();
 +                v2 = ((TestObject)resultsArray[i+1]).getId();
 +              } else {
 +                v1 = (Integer)resultsArray[i];
 +                v2 = (Integer)resultsArray[i + 1];
 +              }
 +              assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], 
 +                  comparator.compare(v1, v2) == -1);
 +            }
 +          }
 +        }
 +      
 +        // order by struct query
 +        String[] qString2 = {
 +            "SELECT DISTINCT id, ticker, price FROM " + regionName + " WHERE id < 101 ORDER BY id",
 +            "SELECT DISTINCT ticker, id FROM " + regionName + " WHERE id < 101  ORDER BY id",
 +            "SELECT DISTINCT id, ticker FROM " + regionName + " WHERE id < 101  ORDER BY id asc",
 +        };
 +
 +        for (int cnt=0; cnt < qString2.length; cnt++) {
 +          queryString = qString2[cnt];
 +          try {
 +            Query query = qService.newQuery(queryString);
 +            results = (SelectResults)query.execute();
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          // All order-by query results are stored in a ResultsCollectionWrapper
 +          // wrapping a list, so the assertion below is not correct even though
 +          // it should be.
 +          //assertTrue(!results.getCollectionType().allowsDuplicates());
 +          assertTrue(results.getCollectionType().isOrdered());
 +          comparator = new StructIdComparator();
 +          resultsArray = results.toArray();
 +          for (int i=0; i<resultsArray.length; i++) {
 +            if (i+1 != resultsArray.length) {
 +              // The id of the current element in the result set must be less
 +              // than the id of the next one to pass.
 +              assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], comparator.compare(resultsArray[i], resultsArray[i+1]) == -1);
 +            }
 +          }
 +        }
 +      }
 +    });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +
 +  public void testUnSupportedOps() throws Exception
 +  {
 +    final String name = this.getName();
 +    final String rootRegionName = "root";
 +
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Properties config = new Properties();
 +        config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +        system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +
 +        Wait.pause(1000);
 +        try {
 +          startBridgeServer(0, false);
 +        } catch (Exception ex) {
 +          Assert.fail("While starting CacheServer", ex);
 +        }
 +      }
 +    });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create two regions") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        final Region region1 = createRegion(name, factory.createRegionAttributes());
 +        final Region region2 = createRegion(name+"_2", factory.createRegionAttributes());
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region1.put("key-"+i, new TestObject(i, "ibm"));
 +          region2.put("key-"+i, new TestObject(i, "ibm"));
 +        }
 +
 +      }
 +    });
 +
-     final int port = vm0.invokeInt(QueryUsingPoolDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> QueryUsingPoolDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    final String regionName1 = "/" + rootRegionName + "/" + name;
 +//    final String regionName2 = "/" + rootRegionName + "/" + name + "_2";
 +
 +    // Create client pool.
 +    final String poolName = "testUnSupportedOps";
 +    createPool(vm1, poolName, host0, port);
 +
 +    // Execute client queries in VM1      
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        final Region region1 = createRegion(name, factory.createRegionAttributes());
 +
 +        String queryString = "select distinct * from " + regionName1 + " where ticker = $1";
 +        Object[] params = new Object[] { new String("ibm")};
 +//        SelectResults results = null;
 +        QueryService qService = null;
 +
 +        try {
 +          qService = (PoolManager.find(poolName)).getQueryService();
 +        } catch (Exception e) {
 +          Asse

<TRUNCATED>


[048/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HFileSortedOplog.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HFileSortedOplog.java
index 8fc9c8e,0000000..5ba20d2
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HFileSortedOplog.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HFileSortedOplog.java
@@@ -1,853 -1,0 +1,853 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.hdfs.internal.hoplog;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.Closeable;
 +import java.io.DataInput;
 +import java.io.DataInputStream;
 +import java.io.IOException;
 +import java.nio.ByteBuffer;
 +import java.util.Arrays;
 +import java.util.EnumMap;
 +import java.util.Map;
 +import java.util.Map.Entry;
 +import java.util.NoSuchElementException;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +
++import com.gemstone.gemfire.internal.hll.HyperLogLog;
++import com.gemstone.gemfire.internal.hll.ICardinality;
 +import org.apache.hadoop.fs.FileSystem;
 +import org.apache.hadoop.fs.Path;
 +import org.apache.hadoop.ipc.RemoteException;
 +import org.apache.hadoop.util.ShutdownHookManager;
 +
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.hdfs.HDFSIOException;
 +import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreImpl;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.HyperLogLog;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.ICardinality;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.DelegatingSerializedComparator;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.HFileStoreStatistics;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.SortedOplogStatistics;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.SortedOplogStatistics.ScanOperation;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.SortedReader.SerializedComparator;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.util.Hex;
 +import com.gemstone.gemfire.internal.util.SingletonValue;
 +import com.gemstone.gemfire.internal.util.SingletonValue.SingletonBuilder;
 +
 +import org.apache.hadoop.hbase.io.hfile.BlockCache;
 +import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory;
 +import org.apache.hadoop.hbase.io.hfile.CacheConfig;
 +import org.apache.hadoop.hbase.io.hfile.Compression.Algorithm;
 +import org.apache.hadoop.hbase.io.hfile.HFile;
 +import org.apache.hadoop.hbase.io.hfile.HFile.Reader;
 +import org.apache.hadoop.hbase.io.hfile.HFile.Writer;
 +import org.apache.hadoop.hbase.io.hfile.HFileBlockIndex.BlockIndexReader;
 +import org.apache.hadoop.hbase.io.hfile.HFileScanner;
 +import org.apache.hadoop.hbase.regionserver.StoreFile.BloomType;
 +import org.apache.hadoop.hbase.util.BloomFilterFactory;
 +import org.apache.hadoop.hbase.util.BloomFilterWriter;
 +
 +/**
 + * Implements hfile based {@link Hoplog}
 + */
 +public final class HFileSortedOplog extends AbstractHoplog {
 +
 +//  private static final boolean CACHE_DATA_BLOCKS_ON_READ = !Boolean.getBoolean("gemfire.HFileSortedOplog.DISABLE_CACHE_ON_READ");
 +  private final CacheConfig cacheConf;
 +  private ICardinality entryCountEstimate;
 +  
 +  // a cached reader for the file
 +  private final SingletonValue<HFileReader> reader;
 +
 +  public HFileSortedOplog(HDFSStoreImpl store, Path hfilePath,
 +      BlockCache blockCache, SortedOplogStatistics stats,
 +      HFileStoreStatistics storeStats) throws IOException {
 +    super(store, hfilePath, stats);
 +    cacheConf = getCacheConfInstance(blockCache, stats, storeStats);
 +    reader = getReaderContainer();
 +  }
 +
 +  /**
 +   * THIS METHOD SHOULD BE USED FOR LONER ONLY
 +   */
 +  public static HFileSortedOplog getHoplogForLoner(FileSystem inputFS,
 +      Path hfilePath) throws IOException {
 +    return new HFileSortedOplog(inputFS, hfilePath, null, null, null);
 +  }
 +
 +  private HFileSortedOplog(FileSystem inputFS, Path hfilePath,
 +      BlockCache blockCache, SortedOplogStatistics stats,
 +      HFileStoreStatistics storeStats) throws IOException {
 +    super(inputFS, hfilePath, stats);
 +    cacheConf = getCacheConfInstance(blockCache, stats, storeStats);
 +    reader = getReaderContainer();
 +  }
 +
 +  protected CacheConfig getCacheConfInstance(BlockCache blockCache,
 +      SortedOplogStatistics stats, HFileStoreStatistics storeStats) {
 +    CacheConfig tmpConfig = null;
 +//    if (stats == null) {
 +      tmpConfig = new CacheConfig(conf);
 +//    } else {
 +//      tmpConfig = new CacheConfig(conf, CACHE_DATA_BLOCKS_ON_READ, blockCache,
 +//          HFileSortedOplogFactory.convertStatistics(stats, storeStats));
 +//    }
 +    tmpConfig.shouldCacheBlockOnRead(BlockCategory.ALL_CATEGORIES);
 +    return tmpConfig;
 +  }  
 +
 +  private SingletonValue<HFileReader> getReaderContainer() {
 +    return new SingletonValue<HFileReader>(new SingletonBuilder<HFileReader>() {
 +      @Override
 +      public HFileReader create() throws IOException {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}Creating hoplog reader", logPrefix);
 +        return new HFileReader();
 +      }
 +
 +      @Override
 +      public void postCreate() {
 +        if (readerListener != null) {
 +          readerListener.readerCreated();
 +        }
 +      }
 +      
 +      @Override
 +      public void createInProgress() {
 +      }
 +    });
 +  }
 +  
 +  @Override
 +  public HoplogReader getReader() throws IOException {
 +    return reader.get();
 +  }
 +  
 +  @Override
 +  public ICardinality getEntryCountEstimate() throws IOException {
 +    ICardinality result = entryCountEstimate;
 +    if (result == null) {
 +      HoplogReader rdr = getReader(); // keep this out of the critical section
 +      synchronized(this) {
 +        result = entryCountEstimate;
 +          if (result == null) {
 +            entryCountEstimate = result = rdr.getCardinalityEstimator();
 +          }
 +        }
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public HoplogWriter createWriter(int keys) throws IOException {
 +    return new HFileSortedOplogWriter(keys);
 +  }
 +
 +  @Override
 +  public boolean isClosed() {
 +    HFileReader rdr = reader.getCachedValue();
 +    return rdr == null || rdr.isClosed();
 +  }
 +  
 +  @Override
 +  public void close() throws IOException {
 +    close(true);
 +  }
 +
 +  @Override
 +  public void close(boolean clearCache) throws IOException {
 +    compareAndClose(null, clearCache);
 +  }
 +  
 +  private void compareAndClose(HFileReader hfileReader, boolean clearCache) throws IOException {
 +    HFileReader rdr ;
 +    if (hfileReader == null) {
 +      rdr = reader.clear(true);
 +    } else {
 +      boolean result = reader.clear(hfileReader, true);
 +      if (! result) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}skipping close, provided hfileReader mismatched", logPrefix);
 +        return;
 +      } 
 +      rdr = hfileReader;
 +    }
 +    
 +    if (rdr != null) {
 +      try {
 +        rdr.close(clearCache);
 +      } finally {
 +        if (readerListener != null) {
 +          readerListener.readerClosed();
 +        }
 +      }
 +    }
 +  }
 +  
 +  @Override
 +  public String toString() {
 +    return "HFileSortedOplog[" + getFileName() + "]";
 +  }
 +
 +  private class HFileSortedOplogWriter implements HoplogWriter {
 +    private final Writer writer;
 +    private final BloomFilterWriter bfw;
 +    private final AtomicBoolean closed = new AtomicBoolean(false);
 +
 +    public HFileSortedOplogWriter(int keys) throws IOException {
 +      try {
 +        int hfileBlockSize = Integer.getInteger(
 +            HoplogConfig.HFILE_BLOCK_SIZE_CONF, (1 << 16));
 +
 +        Algorithm compress = Algorithm.valueOf(System.getProperty(HoplogConfig.COMPRESSION,
 +            HoplogConfig.COMPRESSION_DEFAULT));
 +
 +//        ByteComparator bc = new ByteComparator();
 +        writer = HFile.getWriterFactory(conf, cacheConf)
 +            .withPath(fsProvider.getFS(), path)
 +            .withBlockSize(hfileBlockSize)
 +//            .withComparator(bc)
 +            .withCompression(compress)
 +            .create();
 +//        bfw = BloomFilterFactory.createGeneralBloomAtWrite(conf, cacheConf, BloomType.ROW, keys,
 +//            writer, bc);
 +        bfw = BloomFilterFactory.createGeneralBloomAtWrite(conf, cacheConf, BloomType.ROW, keys,
 +            writer);
 +
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}Created hoplog writer with compression " + compress, logPrefix);
 +      } catch (IOException e) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}IO Error while creating writer", logPrefix);
 +        throw e;
 +      }
 +    }
 +
 +    @Override
 +    public void append(byte[] key, byte[] value) throws IOException {
 +      writer.append(key, value);
 +      bfw.add(key, 0, key.length);
 +    }
 +
 +    @Override
 +    public void append(ByteBuffer key, ByteBuffer value) throws IOException {
 +      byte[] keyBytes = byteBufferToArray(key);
 +      byte[] valueBytes = byteBufferToArray(value);
 +      writer.append(keyBytes, valueBytes);
 +      bfw.add(keyBytes, 0, keyBytes.length);
 +    }
 +
 +    @Override
 +    public void close() throws IOException {
 +      close(null);
 +    }
 +
 +    @Override
 +    public void close(EnumMap<Meta, byte[]> metadata) throws IOException {
 +      if (closed.get()) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}Writer already closed", logPrefix);
 +        return;
 +      }
 +      
 +      bfw.compactBloom();
 +      writer.addGeneralBloomFilter(bfw);
 +
 +      // append system metadata
 +      writer.appendFileInfo(Meta.GEMFIRE_MAGIC.toBytes(), Hoplog.MAGIC);
 +      writer.appendFileInfo(Meta.SORTED_OPLOG_VERSION.toBytes(), HoplogVersion.V1.toBytes());
 +      writer.appendFileInfo(Meta.GEMFIRE_VERSION.toBytes(), Version.CURRENT.toBytes());
 +      
 +      // append comparator info
 +//      if (writer.getComparator() instanceof DelegatingSerializedComparator) {
 +//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
 +//        DataOutput out = new DataOutputStream(bos);
 +//        
 +//        writeComparatorInfo(out, ((DelegatingSerializedComparator) writer.getComparator()).getComparators());
 +//        writer.appendFileInfo(Meta.COMPARATORS.toBytes(), bos.toByteArray());
 +//      }
 +      
 +      // append user metadata
 +      HyperLogLog cachedEntryCountEstimate = null;
 +      if (metadata != null) {
 +        for (Entry<Meta, byte[]> entry : metadata.entrySet()) {
 +          writer.appendFileInfo(entry.getKey().toBytes(), entry.getValue());
 +          if (Meta.LOCAL_CARDINALITY_ESTIMATE_V2.equals(entry.getKey())) {
 +             cachedEntryCountEstimate = HyperLogLog.Builder.build(entry.getValue()); 
 +          }
 +        }
 +      }
 +      
 +      writer.close();
 +      if (logger.isDebugEnabled())
 +        logger.debug("{}Completed closing writer", logPrefix);
 +      closed.set(true);
 +      // cache estimate value to avoid reads later
 +      entryCountEstimate = cachedEntryCountEstimate;
 +    }
 +
 +    @Override
 +    public void hsync() throws IOException {
 +      throw new UnsupportedOperationException("hsync is not supported for HFiles"); 
 +    }
 +
 +    @Override
 +    public long getCurrentSize() throws IOException {
 +      throw new UnsupportedOperationException("getCurrentSize is not supported for HFiles"); 
 +    }
 +    
 +//    private void writeComparatorInfo(DataOutput out, SerializedComparator[] comparators) throws IOException {
 +//      out.writeInt(comparators.length);
 +//      for (SerializedComparator sc : comparators) {
 +//        out.writeUTF(sc.getClass().getName());
 +//        if (sc instanceof DelegatingSerializedComparator) {
 +//          writeComparatorInfo(out, ((DelegatingSerializedComparator) sc).getComparators());
 +//        }
 +//      }
 +//    }
 +  }
 +  
 +  private void handleReadIOError(HFileReader hfileReader, IOException e, boolean skipFailIfSafe) {
 +    if (logger.isDebugEnabled())
 +      logger.debug("Read IO error", e);
 +    boolean safeError = ShutdownHookManager.get().isShutdownInProgress();
 +    if (safeError) {
 +      // IOException because of closed file system. This happens when member is
 +      // shutting down
 +      if (logger.isDebugEnabled())
 +        logger.debug("IO error caused by filesystem shutdown", e);
 +      throw new CacheClosedException("IO error caused by filesystem shutdown", e);
 +    } 
 +    
 +    // expose the error wrapped inside remote exception. Remote exceptions are
 +    // handled by file system client. So let the caller handle this error
 +    if (e instanceof RemoteException) {
 +      e = ((RemoteException) e).unwrapRemoteException();
 +      throw new HDFSIOException(LocalizedStrings.HOPLOG_FAILED_TO_READ_HDFS_FILE.toLocalizedString(path), e);
 +    } 
 +    
 +    FileSystem currentFs = fsProvider.checkFileSystem();
 +    if (hfileReader != null && hfileReader.previousFS != currentFs) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Detected new FS client, closing old reader", logPrefix);
 +        if (currentFs != null) {
 +          if (logger.isDebugEnabled())
 +            logger.debug("CurrentFs:" + currentFs.getUri() + "-"
 +                + currentFs.hashCode(), logPrefix);
 +        }
 +        if (hfileReader.previousFS != null) {
 +          if (logger.isDebugEnabled())
 +            logger.debug("OldFs:" + hfileReader.previousFS.getUri() + "-"
 +                + hfileReader.previousFS.hashCode() + ", closing old reader", logPrefix);
 +        }
 +      }
 +      try {
 +        HFileSortedOplog.this.compareAndClose(hfileReader, false);
 +      } catch (Exception ex) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("Failed to close reader", ex);
 +      }
 +      if (skipFailIfSafe) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("Not faling after io error since FS client changed");
 +        return;
 +      }
 +    }
 +
 +    // it is not a safe error. let the caller handle it
 +    throw new HDFSIOException(LocalizedStrings.HOPLOG_FAILED_TO_READ_HDFS_FILE.toLocalizedString(path), e);
 +  }
 +
 +  class HFileReader implements HoplogReader, Closeable {
 +    private final Reader reader;
 +    private volatile BloomFilter hoplogBloom;
 +    private final AtomicBoolean closed;
 +    private final Map<byte[], byte[]> fileInfo;
 +    private final HyperLogLog estimator;
 +    private final FileSystem previousFS;
 +    
 +    public HFileReader() throws IOException {
 +      try {
 +        FileSystem fs = fsProvider.getFS();
 +        reader = HFile.createReader(fs, path, cacheConf);
 +        fileInfo = reader.loadFileInfo();
 +        closed = new AtomicBoolean(false);
 +
 +        validate();
 +        if (reader.getComparator() instanceof DelegatingSerializedComparator) {
 +          loadComparators((DelegatingSerializedComparator) reader.getComparator());
 +        }
 +
 +        // read the old HLL if it exists so that a CardinalityMergeException will trigger a Major Compaction
 +        byte[] hll = fileInfo.get(Meta.LOCAL_CARDINALITY_ESTIMATE.toBytes());
 +        if (hll != null) {
 +          entryCountEstimate = estimator = HyperLogLog.Builder.build(hll);
 +        } else if ((hll = fileInfo.get(Meta.LOCAL_CARDINALITY_ESTIMATE_V2.toBytes())) != null) {
 +          entryCountEstimate = estimator = HyperLogLog.Builder.build(hll);
 +        } else {
 +          estimator = new HyperLogLog(HdfsSortedOplogOrganizer.HLL_CONSTANT);
 +        }
 +        
 +        previousFS = fs;
 +      } catch (IOException e) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("IO Error while creating reader", e);
 +        throw e;
 +      }
 +    }
 +
 +    @Override
 +    public byte[] read(byte[] key) throws IOException {
 +      IOException err = null;
 +      HFileReader delegateReader = this;
 +      for (int retry = 1; retry >= 0; retry --) {
 +        try {
 +          return delegateReader.readDelegate(key);
 +        } catch (IOException e) {
 +          err = e;
 +          handleReadIOError(delegateReader, e, retry > 0);
 +          // Current reader may have got closed in error handling. Get the new
 +          // one for retry attempt
 +          try {
 +            delegateReader = (HFileReader) HFileSortedOplog.this.getReader(); 
 +          } catch (IOException ex) {
 +            handleReadIOError(null, e, false);
 +          }
 +        }
 +      }
 +
 +      if (logger.isDebugEnabled())
 +        logger.debug("Throwing err from read delegate ", err);
 +      throw err;
 +    }
 +
 +    private byte[] readDelegate(byte[] key) throws IOException {
 +      try {
 +        if (!getBloomFilter().mightContain(key)) {
 +          // bloom filter check failed, the key is not present in this hoplog
 +          return null;
 +        }
 +      } catch (IllegalArgumentException e) {
 +        if (IOException.class.isAssignableFrom(e.getCause().getClass())) {
 +          throw (IOException) e.getCause();
 +        } else {
 +          throw e;
 +        }
 +      }
 +      
 +      byte[] valueBytes = null;
 +      ByteBuffer bb = get(key);
 +      if (bb != null) {
 +        valueBytes = new byte[bb.remaining()];
 +        bb.get(valueBytes);
 +      } else {
 +        stats.getBloom().falsePositive();
 +      }
 +      return valueBytes;
 +    }
 +
 +    @Override
 +    public ByteBuffer get(byte[] key) throws IOException {
 +      assert key != null;
 +      HFileScanner seek = reader.getScanner(false, true);
 +      if (seek.seekTo(key) == 0) {
 +        return seek.getValue();
 +      }
 +      return null;
 +    }
 +
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan(byte[] from, boolean fromInclusive, byte[] to,
 +        boolean toInclusive) throws IOException {
 +      IOException err = null;
 +      HFileReader delegateReader = this;
 +      for (int retry = 1; retry >= 0; retry --) {
 +        try {
 +          return delegateReader.scanDelegate(from, fromInclusive, to, toInclusive);
 +        } catch (IOException e) {
 +          err = e;
 +          handleReadIOError(delegateReader, e, retry > 0);
 +          // Current reader may have got closed in error handling. Get the new
 +          // one for retry attempt
 +          try {
 +            delegateReader = (HFileReader) HFileSortedOplog.this.getReader(); 
 +          } catch (IOException ex) {
 +            handleReadIOError(null, e, false);
 +          }
 +        }
 +      }
 +      if (logger.isDebugEnabled())
 +        logger.debug("Throwing err from scan delegate ", err);
 +      throw err;
 +    }
 +
 +    private HoplogIterator<byte[], byte[]> scanDelegate(byte[] from, boolean fromInclusive, byte[] to,
 +        boolean toInclusive) throws IOException {
 +      return new HFileSortedIterator(reader.getScanner(true, false), from,
 +          fromInclusive, to, toInclusive);
 +    }
 +    
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan(long offset, long length)
 +        throws IOException {
 +      /**
 +       * Identifies the first and last key to be scanned based on offset and
 +       * length. It loads hfile block index and identifies the first hfile block
 +       * starting after offset. The key of that block is from key for scanner.
 +       * Similarly it locates first block starting beyond offset + length range.
 +       * It uses key of that block as the to key for scanner
 +       */
 +
 +      // load block indexes in memory
 +      BlockIndexReader bir = reader.getDataBlockIndexReader();
 +      int blockCount = bir.getRootBlockCount();
 +      
 +      byte[] fromKey = null, toKey = null;
 +
 +      // find from key
 +      int i = 0;
 +      for (; i < blockCount; i++) {
 +        if (bir.getRootBlockOffset(i) < offset) {
 +          // hfile block has offset less than this reader's split offset. check
 +          // the next block
 +          continue;
 +        }
 +
 +        // found the first hfile block starting after offset
 +        fromKey = bir.getRootBlockKey(i);
 +        break;
 +      }
 +
 +      if (fromKey == null) {
 +        // seems no block starts after the offset. return no-op scanner
 +        return new HFileSortedIterator(null, null, false, null, false);
 +      }
 +      
 +      // find to key
 +      for (; i < blockCount; i++) {
 +        if (bir.getRootBlockOffset(i) < (offset + length)) {
 +          // this hfile block lies within the offset+lenght range. check the
 +          // next block for a higher offset
 +          continue;
 +        }
 +
 +        // found the first block starting beyong offset+length range.
 +        toKey = bir.getRootBlockKey(i);
 +        break;
 +      }
 +
 +      // from key is included in scan and to key is excluded
 +      HFileScanner scanner = reader.getScanner(true, false);
 +      return new HFileSortedIterator(scanner, fromKey, true, toKey, false);
 +    }
 +    
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan() throws IOException {
 +      return scan(null, null);
 +    }
 +
 +    public HoplogIterator<byte[], byte[]> scan(byte[] from, byte[] to)
 +        throws IOException {
 +      return scan(from, true, to, false);
 +    }
 +
 +    @Override
 +    public BloomFilter getBloomFilter() throws IOException {
 +      BloomFilter result = hoplogBloom;
 +      if (result == null) {
 +        synchronized (this) {
 +          result = hoplogBloom;
 +          if (result == null) {
 +            hoplogBloom = result = new BloomFilterImpl();
 +          }
 +        }
 +      }
 +      return result;
 +    }
 +
 +    @Override
 +    public boolean isClosed() {
 +      return closed.get();
 +    }
 +    
 +    @Override
 +    public void close() throws IOException {
 +      close(true);
 +    }
 +    
 +    public void close(boolean clearCache) throws IOException {
 +      if (closed.compareAndSet(false, true)) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}Closing reader", logPrefix);
 +        reader.close(clearCache);
 +      }
 +    }
 +
 +    @Override
 +    public long getEntryCount() {
 +      return reader.getEntries();
 +    }
 +
 +    public ICardinality getCardinalityEstimator() {
 +      return estimator;
 +    }
 +
 +    @Override
 +    public long sizeEstimate() {
 +      return getCardinalityEstimator().cardinality();
 +    }
 +
 +    private void validate() throws IOException {
 +      // check magic
 +      byte[] magic = fileInfo.get(Meta.GEMFIRE_MAGIC.toBytes());
 +      if (!Arrays.equals(magic, MAGIC)) {
 +        throw new IOException(LocalizedStrings.Soplog_INVALID_MAGIC.toLocalizedString(Hex.toHex(magic)));
 +      }
 +      
 +      // check version compatibility
 +      byte[] ver = fileInfo.get(Meta.SORTED_OPLOG_VERSION.toBytes());
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Hoplog version is " + Hex.toHex(ver), logPrefix);
 +      }
 +      
 +      if (!Arrays.equals(ver, HoplogVersion.V1.toBytes())) {
 +        throw new IOException(LocalizedStrings.Soplog_UNRECOGNIZED_VERSION.toLocalizedString(Hex.toHex(ver)));
 +      }
 +    }
 +    
 +    private void loadComparators(DelegatingSerializedComparator comparator) throws IOException {
 +      byte[] raw = fileInfo.get(Meta.COMPARATORS.toBytes());
 +      assert raw != null;
 +
 +      DataInput in = new DataInputStream(new ByteArrayInputStream(raw));
 +      comparator.setComparators(readComparators(in));
 +    }
 +    
 +    private SerializedComparator[] readComparators(DataInput in) throws IOException {
 +      try {
 +        SerializedComparator[] comps = new SerializedComparator[in.readInt()];
 +        assert comps.length > 0;
 +        
 +        for (int i = 0; i < comps.length; i++) {
 +          comps[i] = (SerializedComparator) Class.forName(in.readUTF()).newInstance();
 +          if (comps[i] instanceof DelegatingSerializedComparator) {
 +            ((DelegatingSerializedComparator) comps[i]).setComparators(readComparators(in));
 +          }
 +        }
 +        return comps;
 +        
 +      } catch (Exception e) {
 +        throw new IOException(e);
 +      }
 +    }
 +    
 +    class BloomFilterImpl implements BloomFilter {
 +      private final org.apache.hadoop.hbase.util.BloomFilter hfileBloom;
 +
 +      public BloomFilterImpl() throws IOException {
 +        DataInput bin = reader.getGeneralBloomFilterMetadata();
 +        // instantiate bloom filter if meta present in hfile
 +        if (bin != null) {
 +          hfileBloom = BloomFilterFactory.createFromMeta(bin, reader);
 +          if (reader.getComparator() instanceof DelegatingSerializedComparator) {
 +            loadComparators((DelegatingSerializedComparator) hfileBloom.getComparator());
 +          }
 +        } else {
 +          hfileBloom = null;
 +        }
 +      }
 +
 +      @Override
 +      public boolean mightContain(byte[] key) {
 +        assert key != null;
 +        return mightContain(key, 0, key.length);
 +      }
 +
 +      @Override
 +      public boolean mightContain(byte[] key, int keyOffset, int keyLength) {
 +        assert key != null;
 +        long start = stats.getBloom().begin();
 +        boolean found = hfileBloom == null ? true : hfileBloom.contains(key, keyOffset, keyLength, null);
 +        stats.getBloom().end(start);
 +        return found;
 +      }
 +
 +      @Override
 +      public long getBloomSize() {
 +        return hfileBloom == null ? 0 : hfileBloom.getByteSize();
 +      }
 +    }
 +
 +    // TODO change the KV types to ByteBuffer instead of byte[]
 +    public final class HFileSortedIterator implements HoplogIterator<byte[], byte[]> {
 +      private final HFileScanner scan;
 +      
 +      private final byte[] from;
 +      private final boolean fromInclusive;
 +      
 +      private final byte[] to;
 +      private final boolean toInclusive;
 +      
 +      private ByteBuffer prefetchedKey;
 +      private ByteBuffer prefetchedValue;
 +      private ByteBuffer currentKey;
 +      private ByteBuffer currentValue;
 +      
 +      // variable linked to scan stats
 +      ScanOperation scanStat;
 +      private long scanStart;
 +      
 +      public HFileSortedIterator(HFileScanner scan, byte[] from, boolean fromInclusive, byte[] to, 
 +          boolean toInclusive) throws IOException {
 +        this.scan = scan;
 +        this.from = from;
 +        this.fromInclusive = fromInclusive;
 +        this.to = to;
 +        this.toInclusive = toInclusive;
 +
 +        scanStat = (stats == null) ? new SortedOplogStatistics("", "").new ScanOperation(
 +            0, 0, 0, 0, 0, 0, 0) : stats.getScan();
 +        scanStart = scanStat.begin();
 +
 +        if (scan == null) {
 +          return;
 +        }
 +
 +        assert from == null || to == null
 +            || scan.getReader().getComparator().compare(from, to) <= 0;
 +
 +        initIterator();
 +      }
 +      
 +      /*
 +       * prefetches first key and value from the file for hasnext to work
 +       */
 +      private void initIterator() throws IOException {
 +        long startNext = scanStat.beginIteration();
 +        boolean scanSuccessful = true;
 +        if (from == null) {
 +          scanSuccessful = scan.seekTo();
 +        } else {
 +          int compare = scan.seekTo(from);
 +          if (compare == 0 && !fromInclusive || compare > 0) {
 +            // as from in exclusive and first key is same as from, skip the first key
 +            scanSuccessful = scan.next();
 +          }
 +        }
 +        
 +        populateKV(startNext, scanSuccessful);
 +      }
 +      
 +      @Override
 +      public boolean hasNext() {
 +        return prefetchedKey != null;
 +      }
 +
 +      @Override
 +      public byte[] next() throws IOException {
 +        return byteBufferToArray(nextBB());
 +      }
 +
 +      public ByteBuffer nextBB() throws IOException {
 +        long startNext = scanStat.beginIteration();
 +        if (prefetchedKey == null) {
 +          throw new NoSuchElementException();
 +        }
 +
 +        currentKey = prefetchedKey;
 +        currentValue = prefetchedValue;
 +
 +        prefetchedKey = null;
 +        prefetchedValue = null;
 +
 +        if (scan.next()) {
 +          populateKV(startNext, true);
 +        }
 +        
 +        return currentKey;
 +      }
 +
 +      
 +      private void populateKV(long nextStartTime, boolean scanSuccessful) {
 +        if (!scanSuccessful) {
 +          //end of file reached. collect stats and return
 +          scanStat.endIteration(0, nextStartTime);
 +          return;
 +        }
 +        
 +        prefetchedKey = scan.getKey();
 +        prefetchedValue = scan.getValue();
 +        
 +        if (to != null) {
 +          // TODO Optimization? Perform int comparison instead of byte[]. Identify
 +          // offset of key greater than two.
 +          int compare = -1;
 +          compare = scan.getReader().getComparator().compare
 +              (prefetchedKey.array(), prefetchedKey.arrayOffset(), prefetchedKey.remaining(), to, 0, to.length);
 +          if (compare > 0 || (compare == 0 && !toInclusive)) {
 +            prefetchedKey = null;
 +            prefetchedValue = null;
 +            return;
 +          }
 +        }
 +        
 +        // account for bytes read and time spent
 +        int byteCount = prefetchedKey.remaining() + prefetchedValue.remaining();
 +        scanStat.endIteration(byteCount, nextStartTime);
 +      }
 +      
 +
 +      @Override
 +      public byte[] getKey() {
 +        return byteBufferToArray(getKeyBB());
 +      }
 +      public ByteBuffer getKeyBB() {
 +        return currentKey;
 +      }
 +
 +      @Override
 +      public byte[] getValue() {
 +        return byteBufferToArray(getValueBB());
 +      }
 +      public ByteBuffer getValueBB() {
 +        return currentValue;
 +      }
 +
 +      @Override
 +      public void remove() {
 +        throw new UnsupportedOperationException("Cannot delete a key-value from a hfile sorted oplog");
 +      }
 +      
 +      @Override
 +      public void close() {
 +        scanStat.end(scanStart);
 +      }
 +    }
 +  }
 +  
 +  public static byte[] byteBufferToArray(ByteBuffer bb) {
 +    if (bb == null) {
 +      return null;
 +    }
 +    
 +    byte[] tmp = new byte[bb.remaining()];
 +    bb.duplicate().get(tmp);
 +    return tmp;
 +  }
 +}


[044/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/LocatorLauncher.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/LocatorLauncher.java
index d13dae5,0000000..b0be89f
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/LocatorLauncher.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/LocatorLauncher.java
@@@ -1,2046 -1,0 +1,2051 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed;
 +
 +import java.io.File;
 +import java.io.FileNotFoundException;
 +import java.io.IOException;
 +import java.lang.management.ManagementFactory;
 +import java.net.ConnectException;
 +import java.net.InetAddress;
 +import java.net.UnknownHostException;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.TreeMap;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.TimeoutException;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +import java.util.concurrent.atomic.AtomicReference;
 +import java.util.logging.Level;
 +
 +import javax.management.MalformedObjectNameException;
 +import javax.management.ObjectName;
 +
 +import com.gemstone.gemfire.cache.client.internal.locator.LocatorStatusResponse;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalLocator;
 +import com.gemstone.gemfire.internal.DistributionLocator;
 +import com.gemstone.gemfire.internal.GemFireVersion;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.lang.ObjectUtils;
 +import com.gemstone.gemfire.internal.lang.StringUtils;
 +import com.gemstone.gemfire.internal.lang.SystemUtils;
 +import com.gemstone.gemfire.internal.process.ConnectionFailedException;
 +import com.gemstone.gemfire.internal.process.ControlNotificationHandler;
 +import com.gemstone.gemfire.internal.process.ControllableProcess;
 +import com.gemstone.gemfire.internal.process.FileAlreadyExistsException;
 +import com.gemstone.gemfire.internal.process.MBeanInvocationFailedException;
 +import com.gemstone.gemfire.internal.process.PidUnavailableException;
 +import com.gemstone.gemfire.internal.process.ProcessController;
 +import com.gemstone.gemfire.internal.process.ProcessControllerFactory;
 +import com.gemstone.gemfire.internal.process.ProcessControllerParameters;
 +import com.gemstone.gemfire.internal.process.ProcessLauncherContext;
 +import com.gemstone.gemfire.internal.process.ProcessType;
 +import com.gemstone.gemfire.internal.process.ProcessUtils;
 +import com.gemstone.gemfire.internal.process.StartupStatusListener;
 +import com.gemstone.gemfire.internal.process.UnableToControlProcessException;
 +import com.gemstone.gemfire.internal.util.IOUtils;
 +import com.gemstone.gemfire.lang.AttachAPINotFoundException;
 +import com.gemstone.gemfire.management.internal.cli.json.GfJsonArray;
 +import com.gemstone.gemfire.management.internal.cli.json.GfJsonException;
 +import com.gemstone.gemfire.management.internal.cli.json.GfJsonObject;
 +import joptsimple.OptionException;
 +import joptsimple.OptionParser;
 +import joptsimple.OptionSet;
 +
 +/**
 + * The LocatorLauncher class is a launcher for a GemFire Locator.
 + * 
 + * @author John Blum
 + * @author Kirk Lund
 + * @see com.gemstone.gemfire.distributed.AbstractLauncher
 + * @see com.gemstone.gemfire.distributed.ServerLauncher
 + * @since 7.0
 + */
 +@SuppressWarnings({ "unused" })
 +public final class LocatorLauncher extends AbstractLauncher<String> {
 +
 +  /**
 +   * @deprecated This is specific to the internal implementation and may go away in a future release.
 +   */
 +  public static final Integer DEFAULT_LOCATOR_PORT = getDefaultLocatorPort();
 +
 +  private static final Boolean DEFAULT_LOAD_SHARED_CONFIG_FROM_DIR = Boolean.FALSE;
 +
 +  private static final Map<String, String> helpMap = new HashMap<>();
 +
 +  static {
 +    helpMap.put("launcher", LocalizedStrings.LocatorLauncher_LOCATOR_LAUNCHER_HELP.toLocalizedString());
 +    helpMap.put(Command.START.getName(), LocalizedStrings.LocatorLauncher_START_LOCATOR_HELP.toLocalizedString(String.valueOf(
 +      getDefaultLocatorPort())));
 +    helpMap.put(Command.STATUS.getName(), LocalizedStrings.LocatorLauncher_STATUS_LOCATOR_HELP.toLocalizedString());
 +    helpMap.put(Command.STOP.getName(),LocalizedStrings.LocatorLauncher_STOP_LOCATOR_HELP.toLocalizedString());
 +    helpMap.put(Command.VERSION.getName(), LocalizedStrings.LocatorLauncher_VERSION_LOCATOR_HELP.toLocalizedString());
 +    helpMap.put("bind-address", LocalizedStrings.LocatorLauncher_LOCATOR_BIND_ADDRESS_HELP.toLocalizedString());
 +    helpMap.put("debug",LocalizedStrings.LocatorLauncher_LOCATOR_DEBUG_HELP.toLocalizedString());
 +    helpMap.put("dir",LocalizedStrings.LocatorLauncher_LOCATOR_DIR_HELP.toLocalizedString());
 +    helpMap.put("force", LocalizedStrings.LocatorLauncher_LOCATOR_FORCE_HELP.toLocalizedString());
 +    helpMap.put("help", LocalizedStrings.SystemAdmin_CAUSES_GEMFIRE_TO_PRINT_OUT_INFORMATION_INSTEAD_OF_PERFORMING_THE_COMMAND_THIS_OPTION_IS_SUPPORTED_BY_ALL_COMMANDS.toLocalizedString());
 +    helpMap.put("hostname-for-clients", LocalizedStrings.LocatorLauncher_LOCATOR_HOSTNAME_FOR_CLIENTS_HELP.toLocalizedString());
 +    helpMap.put("member", LocalizedStrings.LocatorLauncher_LOCATOR_MEMBER_HELP.toLocalizedString());
 +    helpMap.put("pid", LocalizedStrings.LocatorLauncher_LOCATOR_PID_HELP.toLocalizedString());
 +    helpMap.put("port", LocalizedStrings.LocatorLauncher_LOCATOR_PORT_HELP.toLocalizedString(String.valueOf(
 +      getDefaultLocatorPort())));
 +    helpMap.put("redirect-output", LocalizedStrings.LocatorLauncher_LOCATOR_REDIRECT_OUTPUT_HELP.toLocalizedString());
 +  }
 +
 +  private static final Map<Command, String> usageMap = new TreeMap<>();
 +
 +  static {
 +    usageMap.put(Command.START, "start <member-name> [--bind-address=<IP-address>] [--hostname-for-clients=<IP-address>] [--port=<port>] [--dir=<Locator-working-directory>] [--force] [--debug] [--help]");
 +    usageMap.put(Command.STATUS, "status [--bind-address=<IP-address>] [--port=<port>] [--member=<member-ID/Name>] [--pid=<process-ID>] [--dir=<Locator-working-directory>] [--debug] [--help]");
 +    usageMap.put(Command.STOP, "stop [--member=<member-ID/Name>] [--pid=<process-ID>] [--dir=<Locator-working-directory>] [--debug] [--help]");
 +    usageMap.put(Command.VERSION, "version");
 +  }
 +
 +  /**
 +   * @deprecated This is specific to the internal implementation and may go away in a future release.
 +   */
 +  public static final boolean DEFAULT_ENABLE_PEER_LOCATION = true;
 +  
 +  /**
 +   * @deprecated This is specific to the internal implementation and may go away in a future release.
 +   */
 +  public static final boolean DEFAULT_ENABLE_SERVER_LOCATION = true;
 +  
 +  /**
 +   * @deprecated This is specific to the internal implementation and may go away in a future release.
 +   */
 +  public static final String DEFAULT_LOCATOR_PID_FILE = "vf.gf.locator.pid";
 +
 +  private static final String DEFAULT_LOCATOR_LOG_EXT = ".log";
 +  private static final String DEFAULT_LOCATOR_LOG_NAME = "locator";
 +  private static final String LOCATOR_SERVICE_NAME = "Locator";
 +
 +  private static final AtomicReference<LocatorLauncher> INSTANCE = new AtomicReference<>();
 +
 +  //private volatile transient boolean debug;
 +
 +  private final transient ControlNotificationHandler controlHandler;
 +  
 +  private final AtomicBoolean starting = new AtomicBoolean(false);
 +
 +  private final boolean force;
 +  private final boolean help;
 +  private final boolean redirectOutput;
 +  
 +  private final Command command;
 +
 +  private final boolean bindAddressSpecified;
 +  private final boolean portSpecified;
 +  private final boolean workingDirectorySpecified;
 +
 +  private final InetAddress bindAddress;
 +
 +  private final Integer pid;
 +  private final Integer port;
 +
 +  private volatile transient InternalLocator locator;
 +
 +  private final Properties distributedSystemProperties;
 +
 +  private final String hostnameForClients;
 +  private final String memberName;
 +  private final String workingDirectory;
 +
 +  // NOTE in addition to debug and locator, the other shared, mutable state
 +  private volatile transient String statusMessage;
 +  
 +  private volatile transient ControllableProcess process;
 +
 +  private final transient LocatorControllerParameters controllerParameters;
 +  
 +  /**
 +   * Launches a GemFire Locator from the command-line configured with the given arguments.
 +   * 
 +   * @param args the command-line arguments used to configure the GemFire Locator at runtime.
 +   */
 +  public static void main(final String... args) {
 +    try {
 +      new Builder(args).build().run();
 +    }
 +    catch (AttachAPINotFoundException e) {
 +      System.err.println(e.getMessage());
 +    }
 +  }
 +
 +  private static Integer getDefaultLocatorPort() {
 +    return Integer.getInteger(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY,
 +      DistributionLocator.DEFAULT_LOCATOR_PORT);
 +  }
 +
 +  /**
 +   * Gets the instance of the LocatorLauncher used to launch the GemFire Locator, or null if this VM does not
 +   * have an instance of LocatorLauncher indicating no GemFire Locator is running.
 +   * 
 +   * @return the instance of LocatorLauncher used to launcher a GemFire Locator in this VM.
 +   */
 +  public static LocatorLauncher getInstance() {
 +    return INSTANCE.get();
 +  }
 +
 +  /**
 +   * Gets the LocatorState for this process or null if this process was not launched using this VM's
 +   * LocatorLauncher reference.
 +   * 
 +   * @return the LocatorState for this process or null.
 +   */
 +  public static LocatorState getLocatorState() {
 +    return (getInstance() != null ? getInstance().status() : null);
 +  }
 +
 +  /**
 +   * Private constructor used to properly construct an immutable instance of the LocatorLauncher using a Builder.
 +   * The Builder is used to configure a LocatorLauncher instance.  The Builder can process user input from the
 +   * command-line or be used to properly construct an instance of the LocatorLauncher programmatically using the API.
 +   * 
 +   * @param builder an instance of LocatorLauncher.Builder for configuring and constructing an instance of the
 +   * LocatorLauncher.
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.Builder
 +   */
 +  private LocatorLauncher(final Builder builder) {
 +    this.command = builder.getCommand();
 +    setDebug(Boolean.TRUE.equals(builder.getDebug()));
 +    this.force = Boolean.TRUE.equals(builder.getForce());
 +    this.help = Boolean.TRUE.equals(builder.getHelp());
 +    this.bindAddressSpecified = builder.isBindAddressSpecified();
 +    this.bindAddress = builder.getBindAddress();
 +    this.distributedSystemProperties = builder.getDistributedSystemProperties();
 +    this.hostnameForClients = builder.getHostnameForClients();
 +    this.memberName = builder.getMemberName();
 +    // TODO:KIRK: set ThreadLocal for LogService with getLogFile or getLogFileName
 +    this.pid = builder.getPid();
 +    this.portSpecified = builder.isPortSpecified();
 +    this.port = builder.getPort();
 +    this.redirectOutput = Boolean.TRUE.equals(builder.getRedirectOutput());
 +    this.workingDirectorySpecified = builder.isWorkingDirectorySpecified();
 +    this.workingDirectory = builder.getWorkingDirectory();
 +    this.controllerParameters = new LocatorControllerParameters();
 +    this.controlHandler = new ControlNotificationHandler() {
 +      @Override
 +      public void handleStop() {
 +        if (isStoppable()) {
 +          stopInProcess();
 +        }
 +      }
 +      @Override
 +      public ServiceState<?> handleStatus() {
 +        return statusInProcess();
 +      }
 +    };
 +  }
 +
 +  /**
 +   * Gets the reference to the Locator object representing the running GemFire Locator.
 +   * 
 +   * @return a reference to the Locator.
 +   */
 +  final InternalLocator getLocator() {
 +    return this.locator;
 +  }
 +
 +  /**
 +   * Gets an identifier that uniquely identifies and represents the Locator associated with this launcher.
 +   * 
 +   * @return a String value identifier to uniquely identify the Locator and it's launcher.
 +   * @see #getBindAddressAsString()
 +   * @see #getPortAsString()
 +   */
 +  public final String getId() {
 +    return LocatorState.getBindAddressAsString(this).concat("[").concat(LocatorState.getPortAsString(this)).concat("]");
 +  }
 +
 +  /**
 +   * Get the Locator launcher command used to invoke the Locator.
 +   * 
 +   * @return the Locator launcher command used to invoke the Locator.
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command
 +   */
 +  public Command getCommand() {
 +    return this.command;
 +  }
 +
 +  /**
 +   * Determines whether the PID file is allowed to be overwritten when the Locator is started and a PID file
 +   * already exists in the Locator's specified working directory.
 +   * 
 +   * @return boolean indicating if force has been enabled.
 +   */
 +  public boolean isForcing() {
 +    return this.force;
 +  }
 +
 +  /**
 +   * Determines whether this launcher will be used to display help information.  If so, then none of the standard
 +   * Locator launcher commands will be used to affect the state of the Locator.  A launcher is said to be 'helping'
 +   * if the user entered the "--help" option (switch) on the command-line.
 +   * 
 +   * @return a boolean value indicating if this launcher is used for displaying help information.
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command
 +   */
 +  public boolean isHelping() {
 +    return this.help;
 +  }
 +  
 +  /**
 +   * Determines whether this launcher will redirect output to system logs when
 +   * starting a new Locator process.
 +   * 
 +   * @return a boolean value indicating if this launcher will redirect output 
 +   * to system logs when starting a new Locator process
 +   */
 +  public boolean isRedirectingOutput() {
 +    return this.redirectOutput;
 +  }
 +
 +  /**
 +   * Gets the IP address of the NIC to which the Locator has bound itself listening for client requests.
 +   * 
 +   * @return an InetAddress object representing the configured bind address for the Locator.
 +   * @see java.net.InetAddress
 +   */
 +  public InetAddress getBindAddress() {
 +    return this.bindAddress;
 +  }
 +
 +  /**
 +   * Gets the host, as either hostname or IP address, on which the Locator was bound and running.  An attempt is made
 +   * to get the canonical hostname for IP address to which the Locator was bound for accepting client requests.  If
 +   * the bind address is null or localhost is unknown, then a default String value of "localhost/127.0.0.1" is returned.
 +   * 
 +   * Note, this information is purely information and should not be used to re-construct state or for
 +   * other purposes.
 +   * 
 +   * @return the hostname or IP address of the host running the Locator, based on the bind-address, or
 +   * 'localhost/127.0.0.1' if the bind address is null and localhost is unknown.
 +   * @see java.net.InetAddress
 +   * @see #getBindAddress()
 +   */
 +  protected String getBindAddressAsString() {
 +    try {
 +      if (getBindAddress() != null) {
 +        return getBindAddress().getCanonicalHostName();
 +      }
 +
 +      InetAddress localhost = SocketCreator.getLocalHost();
 +
 +      return localhost.getCanonicalHostName();
 +    }
 +    catch (UnknownHostException ignore) {
 +      // TODO determine a better value for the host on which the Locator is running to return here...
 +      // NOTE returning localhost/127.0.0.1 implies the bindAddress was null and no IP address for localhost
 +      // could be found
 +      return "localhost/127.0.0.1";
 +    }
 +  }
 +
 +  /**
 +   * Gets the hostname that clients will use to lookup the running Locator.
 +   * 
 +   * @return a String indicating the hostname used by clients to lookup the Locator.
 +   */
 +  public String getHostnameForClients() {
 +    return this.hostnameForClients;
 +  }
 +
 +  /**
 +   * Gets the name of the log file used to log information about this Locator.
 +   * 
 +   * @return a String value indicating the name of this Locator's log file.
 +   */
 +  public String getLogFileName() {
 +    return StringUtils.defaultIfBlank(getMemberName(), DEFAULT_LOCATOR_LOG_NAME).concat(DEFAULT_LOCATOR_LOG_EXT);
 +  }
 +
 +  /**
 +   * Gets the name of this member (this Locator) in the GemFire distributed system and determined by the 'name' GemFire
 +   * property.
 +   * 
 +   * @return a String indicating the name of the member (this Locator) in the GemFire distributed system.
 +   * @see AbstractLauncher#getMemberName()
 +   */
 +  public String getMemberName() {
 +    return StringUtils.defaultIfBlank(this.memberName, super.getMemberName());
 +  }
 +
 +  /**
 +   * Gets the user-specified process ID (PID) of the running Locator that LocatorLauncher uses to issue status and
 +   * stop commands to the Locator.
 +   * 
 +   * @return an Integer value indicating the process ID (PID) of the running Locator.
 +   */
 +  @Override
 +  public Integer getPid() {
 +    return this.pid;
 +  }
 +
 +  /**
 +   * Gets the port number on which the Locator listens for client requests.
 +   * 
 +   * @return an Integer value indicating the port number on which the Locator is listening for client requests.
 +   */
 +  public Integer getPort() {
 +    return this.port;
 +  }
 +
 +  /**
 +   * Gets the port number represented as a String value.  If the port number is null, the the default Locator port
 +   * (10334) is returned;
 +   * 
 +   * @return the port number as a String value.
 +   * @see #getPort()
 +   */
 +  public String getPortAsString() {
 +    return ObjectUtils.defaultIfNull(getPort(), getDefaultLocatorPort()).toString();
 +  }
 +
 +  /**
 +   * Gets the GemFire Distributed System (cluster) Properties.
 +   *
 +   * @return a Properties object containing the configuration settings for the GemFire Distributed System (cluster).
 +   * @see java.util.Properties
 +   */
 +  public Properties getProperties() {
 +    return (Properties) this.distributedSystemProperties.clone();
 +  }
 +
 +  /**
 +   * Gets the name for a GemFire Locator.
 +   * 
 +   * @return a String indicating the name for a GemFire Locator.
 +   */
 +  public String getServiceName() {
 +    return LOCATOR_SERVICE_NAME;
 +  }
 +
 +  /**
 +   * Gets the working directory pathname in which the Locator will be run.
 +   * 
 +   * @return a String value indicating the pathname of the Locator's working directory.
 +   */
 +  @Override
 +  public String getWorkingDirectory() {
 +    return this.workingDirectory;
 +  }
 +
 +  /**
 +   * Displays help for the specified Locator launcher command to standard err.  If the Locator launcher command
 +   * is unspecified, then usage information is displayed instead.
 +   * 
 +   * @param command the Locator launcher command in which to display help information.
 +   * @see #usage()
 +   */
 +  public void help(final Command command) {
 +    if (Command.isUnspecified(command)) {
 +      usage();
 +    }
 +    else {
 +      info(StringUtils.wrap(helpMap.get(command.getName()), 80, ""));
 +      info("\n\nusage: \n\n");
 +      info(StringUtils.wrap("> java ... " + getClass().getName() + " " + usageMap.get(command), 80, "\t\t"));
 +      info("\n\noptions: \n\n");
 +
 +      for (String option : command.getOptions()) {
 +        info(StringUtils.wrap("--" + option + ": " + helpMap.get(option) + "\n", 80, "\t"));
 +      }
 +
 +      info("\n\n");
 +    }
 +  }
 +
 +  /**
 +   * Displays usage information on the proper invocation of the LocatorLauncher from the command-line to standard err.
 +   * 
 +   * @see #help(com.gemstone.gemfire.distributed.LocatorLauncher.Command)
 +   */
 +  public void usage() {
 +    info(StringUtils.wrap(helpMap.get("launcher"), 80, "\t"));
 +    info("\n\nSTART\n\n");
 +    help(Command.START);
 +    info("STATUS\n\n");
 +    help(Command.STATUS);
 +    info("STOP\n\n");
 +    help(Command.STOP);
 +  }
 +
 +  /**
 +   * The Runnable method used to launch the Locator with the specified command.  If 'start' has been issued, then run
 +   * will block as expected for the Locator to stop.  The 'start' command is implemented with a call to start()
 +   * followed by a call to waitOnLocator().
 +   * 
 +   * @see java.lang.Runnable
 +   * @see LocatorLauncher.Command
 +   * @see LocatorLauncher#start()
 +   * @see LocatorLauncher#waitOnLocator()
 +   * @see LocatorLauncher#status()
 +   * @see LocatorLauncher#stop()
 +   * @see LocatorLauncher#version()
 +   * @see LocatorLauncher#help(com.gemstone.gemfire.distributed.LocatorLauncher.Command)
 +   * @see LocatorLauncher#usage()
 +   */
 +  public void run() {
 +    if (!isHelping()) {
 +      switch (getCommand()) {
 +        case START:
 +          info(start());
 +          waitOnLocator();
 +          break;
 +        case STATUS:
 +          info(status());
 +          break;
 +        case STOP:
 +          info(stop());
 +          break;
 +        case VERSION:
 +          info(version());
 +          break;
 +        default:
 +          usage();
 +      }
 +    }
 +    else {
 +      help(getCommand());
 +    }
 +  }
 +
 +  /**
 +   * Gets a File reference with the path to the PID file for the Locator.
 +   * 
 +   * @return a File reference to the path of the Locator's PID file.
 +   */
 +  protected File getLocatorPidFile() {
 +    return new File(getWorkingDirectory(), ProcessType.LOCATOR.getPidFileName());
 +  }
 +  
 +  /**
 +   * Determines whether a GemFire Locator can be started with this instance of LocatorLauncher.
 +   * 
 +   * @return a boolean indicating whether a GemFire Locator can be started with this instance of LocatorLauncher,
 +   * which is true if the LocatorLauncher has not already started a Locator or a Locator is not already running.
 +   * @see #start()
 +   */
 +  private boolean isStartable() {
 +    return (!isRunning() && this.starting.compareAndSet(false, true));
 +  }
 +
 +  /**
 +   * Starts a Locator running on the specified port and bind address, as determined by getPort and getBindAddress
 +   * respectively, defaulting to 10334 and 'localhost' if not specified, with both peer and server location enabled.
 +   * 
 +   * 'start' is an asynchronous invocation of the Locator.  As such, this method makes no guarantees whether the
 +   * Locator's location services (peer and server) are actually running before it returns.  The Locator's
 +   * location-based services are initiated in separate, daemon Threads and depends on the relative timing
 +   * and scheduling of those Threads by the JVM.  If the application using this API wishes for the Locator to continue
 +   * running after normal application processing completes, then one must call <code>waitOnLocator</code>.
 +   * 
 +   * Given the nature of start, the Locator's status will be in either 1 of 2 possible states.  If the 'request' to
 +   * start the Locator proceeds without exception, the status will be 'STARTED'.  However, if any exception is
 +   * encountered during the normal startup sequence, then a RuntimeException is thrown and the status is set to
 +   * 'STOPPED'.
 +   * 
 +   * @return a LocatorState to reflect the state of the Locator after start.
 +   * @throws RuntimeException if the Locator failed to start for any reason.
 +   * @throws IllegalStateException if the Locator is already running.
 +   * @see #failOnStart(Throwable)
 +   * @see #getBindAddress()
 +   * @see #getDistributedSystemProperties()
 +   * @see #isForcing()
 +   * @see #getLogFile()
 +   * @see #getLocatorPidFile
 +   * @see #getPort()
 +   * @see #status()
 +   * @see #stop()
 +   * @see #waitOnLocator()
 +   * @see #waitOnStatusResponse(long, long, java.util.concurrent.TimeUnit)
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status#NOT_RESPONDING
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status#ONLINE
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status#STARTING
 +   */
 +  @SuppressWarnings("deprecation")
 +  public LocatorState start() {
 +    if (isStartable()) {
 +      INSTANCE.compareAndSet(null, this);
 +
 +      try {
 +        this.process = new ControllableProcess(this.controlHandler, new File(getWorkingDirectory()), ProcessType.LOCATOR, isForcing());
 +        
 +        assertPortAvailable(getBindAddress(), getPort());
 +
 +        ProcessLauncherContext.set(isRedirectingOutput(), getOverriddenDefaults(), new StartupStatusListener() {
 +          @Override
 +          public void setStatus(final String statusMessage) {
 +            LocatorLauncher.this.statusMessage = statusMessage;
 +          }
 +        });
 +        
 +        //TODO : remove the extra param for loadFromSharedConfigDir
 +        try {
 +          this.locator = InternalLocator.startLocator(getPort(), getLogFile(), null, null, null, getBindAddress(),
 +            getDistributedSystemProperties(), DEFAULT_ENABLE_PEER_LOCATION, DEFAULT_ENABLE_SERVER_LOCATION,
 +              getHostnameForClients(), false);
 +        }
 +        finally {
 +          ProcessLauncherContext.remove();
 +        }
 +
 +        debug("Running Locator on (%1$s) in (%2$s) as (%2$s)...", getId(), getWorkingDirectory(), getMember());
 +        running.set(true);
 +
 +        return new LocatorState(this, Status.ONLINE);
 +      }
 +      catch (IOException e) {
 +        failOnStart(e);
 +        throw new RuntimeException(LocalizedStrings.Launcher_Command_START_IO_ERROR_MESSAGE.toLocalizedString(
 +          getServiceName(), getWorkingDirectory(), getId(), e.getMessage()), e);
 +      }
 +      catch (FileAlreadyExistsException e) {
 +        failOnStart(e);
 +        throw new RuntimeException(LocalizedStrings.Launcher_Command_START_PID_FILE_ALREADY_EXISTS_ERROR_MESSAGE
 +          .toLocalizedString(getServiceName(), getWorkingDirectory(), getId()), e);
 +      }
 +      catch (PidUnavailableException e) {
 +        failOnStart(e);
 +        throw new RuntimeException(LocalizedStrings.Launcher_Command_START_PID_UNAVAILABLE_ERROR_MESSAGE
 +          .toLocalizedString(getServiceName(), getId(), getWorkingDirectory(), e.getMessage()), e);
 +      }
 +      catch (Error e) {
 +        failOnStart(e);
 +        throw e;
 +      }
 +      catch (RuntimeException e) {
 +        failOnStart(e);
 +        throw e;
 +      }
 +      catch (Exception e) {
 +        failOnStart(e);
 +        throw new RuntimeException(e);
 +      }
 +      finally {
 +        this.starting.set(false);
 +      }
 +    }
 +    else {
 +      throw new IllegalStateException(LocalizedStrings.Launcher_Command_START_SERVICE_ALREADY_RUNNING_ERROR_MESSAGE
 +        .toLocalizedString(getServiceName(), getWorkingDirectory(), getId()));
 +    }
 +  }
 +
 +  @Override
 +  protected Properties getDistributedSystemProperties() {
 +     Properties properties = super.getDistributedSystemProperties(getProperties());
 +     return properties;
 +  }
 +
 +  /**
 +   * A helper method to ensure the same sequence of actions are taken when the Locator fails to start
 +   * caused by some exception.
 +   * 
 +   * @param cause the Throwable thrown during the startup or wait operation on the Locator.
 +   */
 +  private void failOnStart(final Throwable cause) {
 +
 +    if (cause != null) {
 +      logger.log(Level.INFO, "locator is exiting due to an exception", cause);
 +    } else {
 +      logger.log(Level.INFO, "locator is exiting normally");
 +    }
 +    
 +    if (this.locator != null) {
 +      this.locator.stop();
 +      this.locator = null;
 +    }
 +    if (this.process != null) {
 +      this.process.stop();
 +      this.process = null;
 +    }
 +
 +    INSTANCE.compareAndSet(this, null);
 +
 +    this.running.set(false);
 +  }
 +
 +  /**
 +   * Waits on the Locator to stop causing the calling Thread to join with the Locator's location-based services Thread.
 +   * 
 +   * @return the Locator's status once it stops.
 +   * @throws AssertionError if the Locator has not been started and the reference is null (assertions must be enabled
 +   * for the error to be thrown).
 +   * @see #failOnStart(Throwable)
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState
 +   */
 +  public LocatorState waitOnLocator() {
 +    Throwable t = null;
 +
 +    try {
 +      // make sure the Locator was started and the reference was set
 +      assert getLocator() != null : "The Locator must first be started with a call to start!";
 +
 +      debug("Waiting on Locator (%1$s) to stop...", getId());
 +
 +      // prevent the JVM from exiting by joining the Locator Thread
 +      getLocator().waitToStop();
 +    }
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      t = e;
 +      debug(e);
 +    }
 +    catch (RuntimeException e) {
 +      t = e;
 +      throw e;
 +    }
 +    catch (Throwable e) {
 +      t = e;
 +      throw e;
 +    }
 +    finally {
 +      failOnStart(t);
 +    }
 +
 +    return new LocatorState(this, Status.STOPPED);
 +  }
 +
 +  /**
 +   * Waits for a Locator status request response to be returned up to the specified timeout in the given unit of time.
 +   * This call will send status requests at fixed intervals in the given unit of time until the timeout expires.  If
 +   * the request to determine the Locator's status is successful, then the Locator is considered to be 'ONLINE'.
 +   * Otherwise, the Locator is considered to be unresponsive to the status request.
 +   * 
 +   * However, this does not necessarily imply the Locator start was unsuccessful, only that a response was not received
 +   * in the given time period.
 +   * 
 +   * Note, this method does not block or cause the Locator's location-based services (daemon Threads) to continue
 +   * running in anyway if the main application Thread terminates when running the Locator in-process.  If the caller
 +   * wishes to start a Locator in an asynchronous manner within the application process, then a call should be made to
 +   * <code>waitOnLocator</code>.
 +   * 
 +   * @param timeout a long value in time unit indicating when the period of time should expire in attempting
 +   * to determine the Locator's status.
 +   * @param interval a long value in time unit for how frequent the requests should be sent to the Locator.
 +   * @param timeUnit the unit of time in which the timeout and interval are measured.
 +   * @return the state of the Locator, which will either be 'ONLINE' or "NOT RESPONDING'.  If the status returned is
 +   * 'NOT RESPONDING', it just means the Locator did not respond to the status request within the given time period.
 +   * It should not be taken as the Locator failed to start.
 +   * @see #waitOnLocator()
 +   */
 +  public LocatorState waitOnStatusResponse(final long timeout, final long interval, final TimeUnit timeUnit) {
 +    final long endTimeInMilliseconds = (System.currentTimeMillis() + timeUnit.toMillis(timeout));
 +
 +    while (System.currentTimeMillis() < endTimeInMilliseconds) {
 +      try {
 +        LocatorStatusResponse response = InternalLocator.statusLocator(getPort(), getBindAddress());
 +        return new LocatorState(this, Status.ONLINE, response);
 +      }
 +      catch (Exception ignore) {
 +        try {
 +          synchronized (this) {
 +            timeUnit.timedWait(this, interval);
 +          }
 +        }
 +        catch (InterruptedException ignoreInterrupt) {
 +          // NOTE just go and send another status request to the Locator...
 +        }
 +      }
 +    }
 +
 +    // NOTE just because we were not able to communicate with the Locator in the given amount of time does not mean
 +    // the Locator is having problems.  The Locator could be slow in starting up and the timeout may not be
 +    // long enough.
 +    return new LocatorState(this, Status.NOT_RESPONDING);
 +  }
 +
 +  /**
 +   * Attempts to determine the state of the Locator.  The Locator's status will be in only 1 of 2 possible states,
 +   * either ONLINE or OFFLINE.  This method behaves differently depending on which parameters were specified when
 +   * the LocatorLauncher was constructed with an instance of Builder.  If either the 'dir' or the 'pid' command-line
 +   * option were specified, then an attempt is made to determine the Locator's status by using the dir or pid to
 +   * correctly identify the Locator's MemberMXBean registered in the MBeanServer of the Locator's JVM, and invoking
 +   * the 'status' operation.  The same behavior occurs if the caller specified the Locator's GemFire member name or ID.
 +   * 
 +   * However, if 'dir' or 'pid' were not specified, then determining the Locator's status defaults to using the
 +   * configured bind address and port.  If the bind address or port was not specified when using the Builder to
 +   * construct a LocatorLauncher instance, then the defaults for both bind address and port are used.  In either case,
 +   * an actual TCP/IP request is made to the Locator's ServerSocket to ensure it is listening for client requests.
 +   * This is true even when the LocatorLauncher is used in-process by calling the API.
 +   * 
 +   * If the conditions above hold, then the Locator is deemed to be 'ONLINE', otherwise, the Locator is considered
 +   * 'OFFLINE'.
 +   * 
 +   * @return the Locator's state.
 +   * @see #start()
 +   * @see #stop()
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState
 +   */
 +  public LocatorState status() {
 +    final LocatorLauncher launcher = getInstance();
 +    // if this instance is starting then return local status
 +    if (this.starting.get()) {
 +      debug("Getting status from the LocatorLauncher instance that actually launched the GemFire Locator.%n");
 +      return new LocatorState(this, Status.STARTING);
 +    }
 +    // if this instance is running then return local status
 +    else if (isRunning()) {
 +      debug("Getting Locator status using host (%1$s) and port (%2$s)%n", getBindAddressAsString(), getPortAsString());
 +      return statusWithPort();
 +    }
 +    // if in-process do not use ProcessController
 +    else if (isPidInProcess() && launcher != null) {
 +      return launcher.statusInProcess();
 +    }
 +    // attempt to get status using pid if provided
 +    else if (getPid() != null) {
 +      debug("Getting Locator status using process ID (%1$s)%n", getPid());
 +      return statusWithPid();
 +    }
 +    // attempt to get status using workingDirectory unless port was specified
 +    else if (!(this.bindAddressSpecified || this.portSpecified)) {
 +      debug("Getting Locator status using working directory (%1$s)%n", getWorkingDirectory());
 +      return statusWithWorkingDirectory();
 +    }
 +    // attempt to get status using host and port (Note, bind address doubles as host when the launcher
 +    // is used to get the Locator's status).
 +    else {
 +      debug("Getting Locator status using host (%1$s) and port (%2$s)%n", getBindAddressAsString(), getPortAsString());
 +      return statusWithPort();
 +    }
 +  }
 +
 +  private LocatorState statusInProcess() {
 +    if (this.starting.get()) {
 +      debug("Getting status from the LocatorLauncher instance that actually launched the GemFire Locator.%n");
 +      return new LocatorState(this, Status.STARTING);
 +    }
 +    else {
 +      debug("Getting Locator status using host (%1$s) and port (%2$s)%n", getBindAddressAsString(), getPortAsString());
 +      return statusWithPort();
 +    }
 +
 +  }
 +
 +  private LocatorState statusWithPid() {
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, getPid());
 +      controller.checkPidSupport();
 +      final String statusJson = controller.status();
 +      return LocatorState.fromJson(statusJson);
 +    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to locator JVM
 +      return createNoResponseState(e, "Failed to connect to locator with process id " + getPid());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    } 
 +    catch (UnableToControlProcessException e) {
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    } 
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      return createNoResponseState(e, "Interrupted while trying to communicate with locator with process id " + getPid());
 +    } 
 +    catch (TimeoutException e) {
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    }
 +  }
 +
 +  private LocatorState statusWithPort() {
 +    try {
 +      LocatorStatusResponse response = InternalLocator.statusLocator(getPort(), getBindAddress());
 +      return new LocatorState(this, Status.ONLINE, response);
 +    }
 +    catch (Exception e) {
 +      return createNoResponseState(e, "Failed to connect to locator " + getId());
 +    }
 +  }
 +
 +  private LocatorState statusWithWorkingDirectory() {
 +    int parsedPid = 0;
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName(), READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
 +      parsedPid = controller.getProcessId();
 +      
 +      // note: in-process request will go infinite loop unless we do the following
 +      if (parsedPid == ProcessUtils.identifyPid()) {
 +        LocatorLauncher runningLauncher = getInstance();
 +        if (runningLauncher != null) {
 +          return runningLauncher.status();
 +        }
 +      }
 +
 +      final String statusJson = controller.status();
 +      return LocatorState.fromJson(statusJson);
 +    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to locator JVM
 +      return createNoResponseState(e, "Failed to connect to locator with process id " + parsedPid);
 +    } 
 +    catch (FileNotFoundException e) {
 +      // could not find pid file
 +      return createNoResponseState(e, "Failed to find process file " + ProcessType.LOCATOR.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (PidUnavailableException e) {
 +      // couldn't determine pid from within locator JVM
 +      return createNoResponseState(e, "Failed to find usable process id within file " + ProcessType.LOCATOR.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (UnableToControlProcessException e) {
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      return createNoResponseState(e, "Interrupted while trying to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (TimeoutException e) {
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    }
 +  }
 +
 +  /**
 +   * Determines whether the Locator can be stopped in-process, such as when a Locator is embedded in an application
 +   * and the LocatorLauncher API is being used.
 +   * 
 +   * @return a boolean indicating whether the Locator can be stopped in-process (the application's process with
 +   * an embedded Locator).
 +   */
 +  protected boolean isStoppable() {
 +    return (isRunning() && getLocator() != null);
 +  }
 +
 +  /**
 +   * Stop shuts the running Locator down.  Using the API, the Locator is requested to stop by calling the Locator
 +   * object's 'stop' method.  Internally, this method is no different than using the LocatorLauncher class from the
 +   * command-line or from within GemFire shell (Gfsh).  In every single case, stop sends a TCP/IP 'shutdown' request
 +   * on the configured address/port to which the Locator is bound and listening.
 +   * 
 +   * If the "shutdown" request is successful, then the Locator will be 'STOPPED'.  Otherwise, the Locator is considered
 +   * 'OFFLINE' since the actual state cannot be fully assessed (as in the application process in which the Locator was
 +   * hosted may still be running and the Locator object may still exist even though it is no longer responding to
 +   * location-based requests).  The later is particularly important in cases where the system resources (such as
 +   * Sockets) may not have been cleaned up yet.  Therefore, by returning a status of 'OFFLINE', the value is meant to
 +   * reflect this in-deterministic state.
 +   * 
 +   * @return a LocatorState indicating the state of the Locator after stop has been requested.
 +   * @see #start()
 +   * @see #status()
 +   * @see com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status#NOT_RESPONDING
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.Status#STOPPED
 +   */
 +  public LocatorState stop() {
 +    final LocatorLauncher launcher = getInstance();
 +    // if this instance is running then stop it
 +    if (isStoppable()) {
 +      return stopInProcess();
 +    }
 +    // if in-process but difference instance of LocatorLauncher
 +    else if (isPidInProcess() && launcher != null) {
 +      return launcher.stopInProcess();
 +    }
 +    // attempt to stop Locator using pid...
 +    else if (getPid() != null) {
 +      return stopWithPid();
 +    }
 +    // attempt to stop Locator using the working directory...
 +    //else if (this.workingDirectorySpecified) {
 +    else if (getWorkingDirectory() != null) {
 +      return stopWithWorkingDirectory();
 +    }
 +    else {
 +      return new LocatorState(this, Status.NOT_RESPONDING);
 +    }
 +  }
 +  
 +  private LocatorState stopInProcess() {
 +    if (isStoppable()) {
 +      this.locator.stop();
 +      this.locator = null;
 +      this.process.stop();
 +      this.process = null;
 +      INSTANCE.compareAndSet(this, null); // note: other thread may return Status.NOT_RESPONDING now
 +      this.running.set(false);
 +      return new LocatorState(this, Status.STOPPED);
 +    } else {
 +      return new LocatorState(this, Status.NOT_RESPONDING);
 +    }
 +  }
 +
 +  private LocatorState stopWithPid() {
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(new LocatorControllerParameters(), getPid());
 +      controller.checkPidSupport();
 +      controller.stop();
 +      return new LocatorState(this, Status.STOPPED);
 +    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to locator JVM
 +      return createNoResponseState(e, "Failed to connect to locator with process id " + getPid());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    } 
 +    catch (UnableToControlProcessException e) {
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + getPid());
 +    }
 +  }
 +
 +  @Deprecated
 +  private LocatorState stopWithPort() {
 +    try {
 +      InternalLocator.stopLocator(getPort(), getBindAddress());
 +      return new LocatorState(this, Status.STOPPED);
 +    }
 +    catch (ConnectException e) {
 +      if (getBindAddress() == null) {
 +        return createNoResponseState(e, "Failed to connect to locator on port " + getPort());
 +      } 
 +      else {
 +        return createNoResponseState(e, "Failed to connect to locator on " + getId());
 +      }
 +    }
 +  }
 +
 +  private LocatorState stopWithWorkingDirectory() {
 +    int parsedPid = 0;
 +    try {
 +      final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName(), READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
 +      parsedPid = controller.getProcessId();
 +      
 +      // NOTE in-process request will go infinite loop unless we do the following
 +      if (parsedPid == ProcessUtils.identifyPid()) {
 +        final LocatorLauncher runningLauncher = getInstance();
 +        if (runningLauncher != null) {
 +          return runningLauncher.stopInProcess();
 +        }
 +      }
 +      
 +      controller.stop();
 +      return new LocatorState(this, Status.STOPPED);
 +    }
 +    catch (ConnectionFailedException e) {
 +      // failed to attach to locator JVM
 +      return createNoResponseState(e, "Failed to connect to locator with process id " + parsedPid);
 +    } 
 +    catch (FileNotFoundException e) {
 +      // could not find pid file
 +      return createNoResponseState(e, "Failed to find process file " + ProcessType.LOCATOR.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (IOException e) {
 +      // failed to open or read file or dir
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      return createNoResponseState(e, "Interrupted while trying to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (MBeanInvocationFailedException e) {
 +      // MBean either doesn't exist or method or attribute don't exist
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    } 
 +    catch (PidUnavailableException e) {
 +      // couldn't determine pid from within locator JVM
 +      return createNoResponseState(e, "Failed to find usable process id within file " + ProcessType.LOCATOR.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (TimeoutException e) {
 +      return createNoResponseState(e, "Timed out trying to find usable process id within file " + ProcessType.LOCATOR.getPidFileName() + " in " + getWorkingDirectory());
 +    } 
 +    catch (UnableToControlProcessException e) {
 +      return createNoResponseState(e, "Failed to communicate with locator with process id " + parsedPid);
 +    }
 +  }
 +
 +  private LocatorState createNoResponseState(final Exception cause, final String errorMessage) {
 +    debug(cause);
 +    //info(errorMessage);
 +    return new LocatorState(this, Status.NOT_RESPONDING, errorMessage);
 +  }
 +  
 +  private Properties getOverriddenDefaults() {
 +    Properties overriddenDefaults = new Properties();
 +
 +    overriddenDefaults.put(ProcessLauncherContext.OVERRIDDEN_DEFAULTS_PREFIX.concat(DistributionConfig.LOG_FILE_NAME),
 +      getLogFileName());
 +
 +    for (String key : System.getProperties().stringPropertyNames()) {
 +      if (key.startsWith(ProcessLauncherContext.OVERRIDDEN_DEFAULTS_PREFIX)) {
 +        overriddenDefaults.put(key, System.getProperty(key));
 +      }
 +    }
 +    
 +    return overriddenDefaults;
 +  }
 +  
 +  private class LocatorControllerParameters implements ProcessControllerParameters {
 +    @Override
 +    public File getPidFile() {
 +      return getLocatorPidFile();
 +    }
 +
 +    @Override
 +    public File getWorkingDirectory() {
 +      return new File(LocatorLauncher.this.getWorkingDirectory());
 +    }
 +  
 +    @Override
 +    public int getProcessId() {
 +      return getPid();
 +    }
 +    
 +    @Override
 +    public ProcessType getProcessType() {
 +      return ProcessType.LOCATOR;
 +    }
 +  
 +    @Override
 +    public ObjectName getNamePattern() {
 +      try {
 +        return ObjectName.getInstance("GemFire:type=Member,*");
 +      } catch (MalformedObjectNameException e) {
 +        return null;
 +      } catch (NullPointerException e) {
 +        return null;
 +      }
 +    }
 +  
 +    @Override
 +    public String getPidAttribute() {
 +      return "ProcessId";
 +    }
 +  
 +    @Override
 +    public String getStopMethod() {
 +      return "shutDownMember";
 +    }
 +    
 +    @Override
 +    public String getStatusMethod() {
 +      return "status";
 +    }
 +  
 +    @Override
 +    public String[] getAttributes() {
 +      return new String[] {"Locator", "Server"};
 +    }
 +  
 +    @Override
 +    public Object[] getValues() {
 +      return new Object[] {Boolean.TRUE, Boolean.FALSE};
 +    }
 +  }
 +
 +  /**
 +   * Following the Builder design pattern, the LocatorLauncher Builder is used to configure and create a properly
 +   * initialized instance of the LocatorLauncher class for running the Locator and performing other Locator
 +   * operations.
 +   */
 +  public static class Builder {
 +
 +    protected static final Command DEFAULT_COMMAND = Command.UNSPECIFIED;
 +
 +    private Boolean debug;
 +    private Boolean force;
 +    private Boolean help;
 +    private Boolean redirectOutput;
 +    private Boolean loadSharedConfigFromDir;
 +    private Command command;
 +
 +    private InetAddress bindAddress;
 +
 +    private Integer pid;
 +    private Integer port;
 +
 +    private final Properties distributedSystemProperties = new Properties();
 +
 +    private String hostnameForClients;
 +    private String memberName;
 +    private String workingDirectory;
 +
 +    /**
 +     * Default constructor used to create an instance of the Builder class for programmatical access.
 +     */
 +    public Builder() {
 +    }
 +
 +    /**
 +     * Constructor used to create and configure an instance of the Builder class with the specified arguments, often
 +     * passed from the command-line when launching an instance of this class from the command-line using the Java
 +     * launcher.
 +     * 
 +     * @param args the array of arguments used to configure the Builder.
 +     */
 +    public Builder(final String... args) {
 +      parseArguments(args != null ? args : new String[0]);
 +    }
 +
 +    /**
 +     * Gets an instance of the JOpt Simple OptionParser to parse the command-line arguments.
 +     * 
 +     * @return an instance of the JOpt Simple OptionParser configured with the command-line options used by the Locator.
 +     */
 +    private OptionParser getParser() {
 +      final OptionParser parser = new OptionParser(true);
 +
 +      parser.accepts("bind-address").withRequiredArg().ofType(String.class);
 +      parser.accepts("debug");
 +      parser.accepts("dir").withRequiredArg().ofType(String.class);
 +      parser.accepts("force");
 +      parser.accepts("help");
 +      parser.accepts("hostname-for-clients").withRequiredArg().ofType(String.class);
 +      parser.accepts("pid").withRequiredArg().ofType(Integer.class);
 +      parser.accepts("port").withRequiredArg().ofType(Integer.class);
 +      parser.accepts("redirect-output");
 +      parser.accepts("version");
 +
 +      return parser;
 +    }
 +
 +    /**
 +     * Parses an array of arguments to configure this Builder with the intent of constructing a Locator launcher to
 +     * invoke a Locator.  This method is called to parse the arguments specified by the user on the command-line.
 +     * 
 +     * @param args the array of arguments used to configure this Builder and create an instance of LocatorLauncher.
 +     */
 +    protected void parseArguments(final String... args) {
 +      try {
 +        parseCommand(args);
 +        parseMemberName(args);
 +
 +        final OptionSet options = getParser().parse(args);
 +
 +        setDebug(options.has("debug"));
 +        setForce(options.has("force"));
 +        setHelp(options.has("help"));
 +        setRedirectOutput(options.has("redirect-output"));
 +
 +        if (!isHelping()) {
 +          if (options.has("bind-address")) {
 +            setBindAddress(ObjectUtils.toString(options.valueOf("bind-address")));
 +          }
 +
 +          if (options.has("dir")) {
 +            setWorkingDirectory(ObjectUtils.toString(options.valueOf("dir")));
 +          }
 +
 +          if (options.has("hostname-for-clients")) {
 +            setHostnameForClients(ObjectUtils.toString(options.valueOf("hostname-for-clients")));
 +          }
 +
 +          if (options.has("pid")) {
 +            setPid((Integer) options.valueOf("pid"));
 +          }
 +
 +          if (options.has("port")) {
 +            setPort((Integer) options.valueOf("port"));
 +          }
 +
 +          if (options.has("version")) {
 +            setCommand(Command.VERSION);
 +          }
 +        }
 +      }
 +      catch (OptionException e) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_PARSE_COMMAND_LINE_ARGUMENT_ERROR_MESSAGE
 +          .toLocalizedString("Locator", e.getMessage()), e);
 +      }
 +      catch (Exception e) {
 +        throw new RuntimeException(e.getMessage(), e);
 +      }
 +    }
 +
 +    /**
 +     * Iterates the list of arguments in search of the target Locator launcher command.
 +     * 
 +     * @param args an array of arguments from which to search for the Locator launcher command.
 +     * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command#valueOfName(String)
 +     * @see #parseArguments(String...)
 +     */
 +    protected void parseCommand(final String... args) {
 +      // search the list of arguments for the command; technically, the command should be the first argument in the
 +      // list, but does it really matter?  stop after we find one valid command.
 +      for (String arg : args) {
 +        final Command command = Command.valueOfName(arg);
 +        if (command != null) {
 +          setCommand(command);
 +          break;
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Iterates the list of arguments in search of the Locator's GemFire member name.  If the argument does not
 +     * start with '-' or is not the name of a Locator launcher command, then the value is presumed to be the member name
 +     * for the Locator in GemFire.
 +     * 
 +     * @param args the array of arguments from which to search for the Locator's member name in GemFire.
 +     * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command#isCommand(String)
 +     * @see #parseArguments(String...)
 +     */
 +    protected void parseMemberName(final String[] args) {
 +      for (String arg : args) {
 +        if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) {
 +          setMemberName(arg);
 +          break;
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Gets the Locator launcher command used during the invocation of the LocatorLauncher.
 +     * 
 +     * @return the Locator launcher command used to invoke (run) the LocatorLauncher class.
 +     * @see #setCommand(com.gemstone.gemfire.distributed.LocatorLauncher.Command)
 +     * @see LocatorLauncher.Command
 +     */
 +    public Command getCommand() {
 +      return ObjectUtils.defaultIfNull(this.command, DEFAULT_COMMAND);
 +    }
 +
 +    /**
 +     * Sets the Locator launcher command used during the invocation of the LocatorLauncher
 +     * 
 +     * @param command the targeted Locator launcher command used during the invocation (run) of LocatorLauncher.
 +     * @return this Builder instance.
 +     * @see #getCommand()
 +     * @see LocatorLauncher.Command
 +     */
 +    public Builder setCommand(final Command command) {
 +      this.command = command;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether the new instance of the LocatorLauncher will be set to debug mode.
 +     * 
 +     * @return a boolean value indicating whether debug mode is enabled or disabled.
 +     * @see #setDebug(Boolean)
 +     */
 +    public Boolean getDebug() {
 +      return this.debug;
 +    }
 +
 +    /**
 +     * Sets whether the new instance of the LocatorLauncher will be set to debug mode.
 +     * 
 +     * @param debug a boolean value indicating whether debug mode is to be enabled or disabled.
 +     * @return this Builder instance.
 +     * @see #getHelp()
 +     */
 +    public Builder setDebug(final Boolean debug) {
 +      this.debug = debug;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the GemFire Distributed System (cluster) Properties configuration.
 +     *
 +     * @return a Properties object containing configuration settings for the GemFire Distributed System (cluster).
 +     * @see java.util.Properties
 +     */
 +    public Properties getDistributedSystemProperties() {
 +      return this.distributedSystemProperties;
 +    }
 +
 +    /**
 +     * Gets the boolean value used by the Locator to determine if it should overwrite the PID file if it already exists.
 +     * 
 +     * @return the boolean value specifying whether or not to overwrite the PID file if it already exists.
 +     * @see com.gemstone.gemfire.internal.process.LocalProcessLauncher
 +     * @see #setForce(Boolean)
 +     */
 +    public Boolean getForce() {
 +      return ObjectUtils.defaultIfNull(this.force, DEFAULT_FORCE);
 +    }
 +
 +    /**
 +     * Sets the boolean value used by the Locator to determine if it should overwrite the PID file if it already exists.
 +     * 
 +     * @param force a boolean value indicating whether to overwrite the PID file when it already exists.
 +     * @return this Builder instance.
 +     * @see com.gemstone.gemfire.internal.process.LocalProcessLauncher
 +     * @see #getForce()
 +     */
 +    public Builder setForce(final Boolean force) {
 +      this.force = force;
 +      return this;
 +    }
 +
 + 
 +    /**
 +     * Determines whether the new instance of LocatorLauncher will be used to output help information for either
 +     * a specific command, or for using LocatorLauncher in general.
 +     * 
 +     * @return a boolean value indicating whether help will be output during the invocation of LocatorLauncher.
 +     * @see #setHelp(Boolean)
 +     */
 +    public Boolean getHelp() {
 +      return this.help;
 +    }
 +
 +    /**
 +     * Determines whether help has been enabled.
 +     * 
 +     * @return a boolean indicating if help was enabled.
 +     */
 +    private boolean isHelping() {
 +      return Boolean.TRUE.equals(getHelp());
 +    }
 +
 +    /**
 +     * Sets whether the new instance of LocatorLauncher will be used to output help information for either a specific
 +     * command, or for using LocatorLauncher in general.
 +     * 
 +     * @param help a boolean indicating whether help information is to be displayed during invocation of LocatorLauncher.
 +     * @return this Builder instance.
 +     * @see #getHelp()
 +     */
 +    public Builder setHelp(final Boolean help) {
 +      this.help = help;
 +      return this;
 +    }
 +
 +    final boolean isBindAddressSpecified() {
 +      return (getBindAddress() != null);
 +
 +    }
 +    /**
 +     * Gets the IP address to which the Locator has bound itself listening for client requests.
 +     * 
 +     * @return an InetAddress with the IP address or hostname on which the Locator is bound and listening.
 +     * @see #setBindAddress(String)
 +     * @see java.net.InetAddress
 +     */
 +    public InetAddress getBindAddress() {
 +      return this.bindAddress;
 +    }
 +
 +    /**
 +     * Sets the IP address as an java.net.InetAddress to which the Locator has bound itself listening for client
 +     * requests.
 +     * 
 +     * @param bindAddress the InetAddress with the IP address or hostname on which the Locator is bound and listening.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException wrapping the UnknownHostException if the IP address or hostname for the
 +     * bind address is unknown.
 +     * @see #getBindAddress()
 +     * @see java.net.InetAddress
 +     */
 +    public Builder setBindAddress(final String bindAddress) {
 +      if (StringUtils.isBlank(bindAddress)) {
 +        this.bindAddress = null;
 +        return this;
 +      }
 +      else {
 +        try {
 +          this.bindAddress = InetAddress.getByName(bindAddress);
-           return this;
++          if (SocketCreator.isLocalHost(this.bindAddress)) {
++            return this;
++          }
++          else {
++            throw new IllegalArgumentException(bindAddress + " is not an address for this machine.");
++          }
 +        }
 +        catch (UnknownHostException e) {
 +          throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE
 +            .toLocalizedString("Locator"), e);
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Gets the hostname used by clients to lookup the Locator.
 +     * 
 +     * @return a String indicating the hostname Locator binding used in client lookups.
 +     * @see #setHostnameForClients(String)
 +     */
 +    public String getHostnameForClients() {
 +      return this.hostnameForClients;
 +    }
 +
 +    /**
 +     * Sets the hostname used by clients to lookup the Locator.
 +     * 
 +     * @param hostnameForClients a String indicating the hostname Locator binding used in client lookups.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the hostname was not specified (is blank or empty), such as when the
 +     * --hostname-for-clients command-line option may have been specified without any argument.
 +     * @see #getHostnameForClients()
 +     */
 +    public Builder setHostnameForClients(final String hostnameForClients) {
 +      if (StringUtils.isEmpty(StringUtils.trim(hostnameForClients))) {
 +        throw new IllegalArgumentException(
 +          LocalizedStrings.LocatorLauncher_Builder_INVALID_HOSTNAME_FOR_CLIENTS_ERROR_MESSAGE.toLocalizedString());
 +      }
 +      this.hostnameForClients = hostnameForClients;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the member name of this Locator in GemFire.
 +     * 
 +     * @return a String indicating the member name of this Locator in GemFire.
 +     * @see #setMemberName(String)
 +     */
 +    public String getMemberName() {
 +      return this.memberName;
 +    }
 +
 +    /**
 +     * Sets the member name of the Locator in GemFire.
 +     * 
 +     * @param memberName a String indicating the member name of this Locator in GemFire.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the member name is invalid.
 +     * @see #getMemberName()
 +     */
 +    public Builder setMemberName(final String memberName) {
 +      if (StringUtils.isEmpty(StringUtils.trim(memberName))) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_MEMBER_NAME_ERROR_MESSAGE
 +          .toLocalizedString("Locator"));
 +      }
 +      this.memberName = memberName;
 +      return this;
 +    }
 +
 +    /**
 +     * Gets the process ID (PID) of the running Locator indicated by the user as an argument to the LocatorLauncher.
 +     * This PID is used by the Locator launcher to determine the Locator's status, or invoke shutdown on the Locator.
 +     * 
 +     * @return a user specified Integer value indicating the process ID of the running Locator.
 +     * @see #setPid(Integer)
 +     */
 +    public Integer getPid() {
 +      return this.pid;
 +    }
 +
 +    /**
 +     * Sets the process ID (PID) of the running Locator indicated by the user as an argument to the LocatorLauncher.
 +     * This PID will be used by the Locator launcher to determine the Locator's status, or invoke shutdown on
 +     * the Locator.
 +     * 
 +     * @param pid a user specified Integer value indicating the process ID of the running Locator.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the process ID (PID) is not valid (greater than zero if not null).
 +     * @see #getPid()
 +     */
 +    public Builder setPid(final Integer pid) {
 +      if (pid != null && pid < 0) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_PID_ERROR_MESSAGE.toLocalizedString());
 +      }
 +      this.pid = pid;
 +      return this;
 +    }
 +
 +    boolean isPortSpecified() {
 +      return (this.port != null);
 +    }
 +    
 +    /**
 +     * Gets the port number used by the Locator to listen for client requests.  If the port was not specified, then the
 +     * default Locator port (10334) is returned.
 +     * 
 +     * @return the specified Locator port or the default port if unspecified.
 +     * @see #setPort(Integer)
 +     */
 +    public Integer getPort() {
 +      return ObjectUtils.defaultIfNull(port, getDefaultLocatorPort());
 +    }
 +
 +    /**
 +     * Sets the port number used by the Locator to listen for client requests.  The port number must be between 1 and
 +     * 65535 inclusive.
 +     * 
 +     * @param port an Integer value indicating the port used by the Locator to listen for client requests.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException if the port number is not valid.
 +     * @see #getPort()
 +     */
 +    public Builder setPort(final Integer port) {
 +      // NOTE if the user were to specify a port number of 0, then java.net.ServerSocket will pick an ephemeral port
 +      // to bind the socket, which we do not want.
 +      if (port != null && (port < 0 || port > 65535)) {
 +        throw new IllegalArgumentException(LocalizedStrings.Launcher_Builder_INVALID_PORT_ERROR_MESSAGE
 +          .toLocalizedString("Locator"));
 +      }
 +      this.port = port;
 +      return this;
 +    }
 +
 +    /**
 +     * Determines whether the new instance of LocatorLauncher will redirect
 +     * output to system logs when starting a Locator.
 +     * 
 +     * @return a boolean value indicating if output will be redirected to system 
 +     * logs when starting a Locator
 +     * 
 +     * @see #setRedirectOutput(Boolean)
 +     */
 +    public Boolean getRedirectOutput() {
 +      return this.redirectOutput;
 +    }
 +
 +    /**
 +     * Determines whether redirecting of output has been enabled.
 +     * 
 +     * @return a boolean indicating if redirecting of output was enabled.
 +     */
 +    private boolean isRedirectingOutput() {
 +      return Boolean.TRUE.equals(getRedirectOutput());
 +    }
 +
 +    /**
 +     * Sets whether the new instance of LocatorLauncher will redirect output to system logs when starting a Locator.
 +     * 
 +     * @param redirectOutput a boolean value indicating if output will be redirected to system logs when starting
 +     * a Locator.
 +     * @return this Builder instance.
 +     * @see #getRedirectOutput()
 +     */
 +    public Builder setRedirectOutput(final Boolean redirectOutput) {
 +      this.redirectOutput = redirectOutput;
 +      return this;
 +    }
 +
 +    boolean isWorkingDirectorySpecified() {
 +      return !StringUtils.isBlank(this.workingDirectory);
 +    }
 +
 +    /**
 +     * Gets the working directory pathname in which the Locator will be ran.  If the directory is unspecified,
 +     * then working directory defaults to the current directory.
 +     * 
 +     * @return a String indicating the working directory pathname.
 +     * @see #setWorkingDirectory(String)
 +     */
 +    public String getWorkingDirectory() {
 +      return IOUtils.tryGetCanonicalPathElseGetAbsolutePath(
 +        new File(StringUtils.defaultIfBlank(this.workingDirectory, DEFAULT_WORKING_DIRECTORY)));
 +    }
 +
 +    /**
 +     * Sets the working directory in which the Locator will be ran.  This also the directory in which all Locator
 +     * files (such as log and license files) will be written.  If the directory is unspecified, then the working
 +     * directory defaults to the current directory.
 +     * 
 +     * @param workingDirectory a String indicating the pathname of the directory in which the Locator will be ran.
 +     * @return this Builder instance.
 +     * @throws IllegalArgumentException wrapping a FileNotFoundException if the working directory pathname cannot be
 +     * found.
 +     * @see #getWorkingDirectory()
 +     * @see java.io.FileNotFoundException
 +     */
 +    public Builder setWorkingDirectory(final String workingDirectory) {
 +      if (!new File(StringUtils.defaultIfBlank(workingDirectory, DEFAULT_WORKING_DIRECTORY)).isDirectory()) {
 +        throw new IllegalArgumentException(
 +          LocalizedStrings.Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE.toLocalizedString("Locator"),
 +            new FileNotFoundException(workingDirectory));
 +      }
 +      this.workingDirectory = workingDirectory;
 +      return this;
 +    }
 +
 +    /**
 +     * Sets a GemFire Distributed System Property.
 +     *
 +     * @param propertyName a String indicating the name of the GemFire Distributed System property.
 +     * @param propertyValue a String value for the GemFire Distributed System property.
 +     * @return this Builder instance.
 +     */
 +    public Builder set(final String propertyName, final String propertyValue) {
 +      this.distributedSystemProperties.setProperty(propertyName, propertyValue);
 +      return this;
 +    }
 +
 +    /**
 +     * Validates the configuration settings and properties of this Builder, ensuring that all invariants have been met.
 +     * Currently, the only invariant constraining the Builder is that the user must specify the member name for the
 +     * Locator in the GemFire distributed system as a command-line argument, or by setting the memberName property
 +     * programmatically using the corresponding setter method.  If the member name is not given, then the user must
 +     * have specified the pathname to the gemfire.properties file before validate is called.  It is then assumed,
 +     * but not further validated, that the user has specified the Locator's member name in the properties file.
 +     * 
 +     * @throws IllegalStateException if the Builder is not properly configured.
 +     */
 +    protected void validate() {
 +      if (!isHelping()) {
 +        validateOnStart();
 +        validateOnStatus();
 +        validateOnStop();
 +        // no validation for 'version' required
 +      }
 +    }
 +
 +    /**
 +     * Validates the arguments passed to the Builder when the 'start' command has been issued.
 +     * 
 +     * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command#START
 +     */
 +    protected void validateOnStart() {
 +      if (Command.START.equals(getCommand())) {
 +        if (StringUtils.isBlank(getMemberName())
 +          && !isSet(System.getProperties(), DistributionConfig.GEMFIRE_PREFIX + DistributionConfig.NAME_NAME)
 +          && !isSet(getDistributedSystemProperties(), DistributionConfig.NAME_NAME)
 +          && !isSet(loadGemFireProperties(DistributedSystem.getPropertyFileURL()), DistributionConfig.NAME_NAME))
 +        {
 +          throw new IllegalStateException(LocalizedStrings.Launcher_Builder_MEMBER_NAME_VALIDATION_ERROR_MESSAGE
 +            .toLocalizedString("Locator"));
 +        }
 +
 +        if (!SystemUtils.CURRENT_DIRECTORY.equals(getWorkingDirectory())) {
 +          throw new IllegalStateException(LocalizedStrings.Launcher_Builder_WORKING_DIRECTORY_OPTION_NOT_VALID_ERROR_MESSAGE
 +            .toLocalizedString("Locator"));
 +        }
 +      }
 +    }
 +
 +    /**
 +     * Validates the arguments passed to the Builder when the 'status' command has been issued.
 +     * 
 +     * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command#STATUS
 +     */
 +    protected void validateOnStatus() {
 +      if (Command.STATUS.equals(getCommand())) {
 +      }
 +    }
 +
 +    /**
 +     * Validates the arguments passed to the Builder when the 'stop' command has been issued.
 +     * 
 +     * @see com.gemstone.gemfire.distributed.LocatorLauncher.Command#STOP
 +     */
 +    protected void validateOnStop() {
 +      if (Command.STOP.equals(getCommand())) {
 +      }
 +    }
 +
 +    /**
 +     * Validates the Builder configuration settings and then constructs an instance of the LocatorLauncher class
 +     * to invoke operations on a GemFire Locator.
 +     * 
 +     * @return a newly constructed instance of LocatorLauncher configured with this Builder.
 +     * @see #validate()
 +     * @see com.gemstone.gemfire.distributed.LocatorLauncher
 +     */
 +    public LocatorLauncher build() {
 +      validate();
 +      return new LocatorLauncher(this);
 +    }
 +  }
 +
 +  /**
 +   * An enumerated type representing valid commands to the Locator launcher.
 +   */
 +  public static enum Command {
 +    START("start", "bind-address", "hostname-for-clients", "port", "force", "debug", "help"),
 +    STATUS("status", "bind-address", "port", "member", "pid", "dir", "debug", "help"),
 +    STOP("stop", "member", "pid", "dir", "debug", "help"),
 +    VERSION("version"),
 +    UNSPECIFIED("unspecified");
 +
 +    private final List<String> options;
 +
 +    private final String name;
 +
 +    Command(final String name, final String... options) {
 +      assert !StringUtils.isBlank(name) : "The name of the locator launcher command must be specified!";
 +      this.name = name;
 +      this.options = (options != null ? Collections.unmodifiableList(Arrays.asList(options))
 +        : Collections.<String>emptyList());
 +    }
 +
 +    /**
 +     * Determines whether the specified name refers to a valid Locator launcher command, as defined by this
 +     * enumerated type.
 +     * 
 +     * @param name a String value indicating the potential name of a Locator launcher command.
 +     * @return a boolean indicating whether the specified name for a Locator launcher command is valid.
 +     */
 +    public static boolean isCommand(final String name) {
 +      return (valueOfName(name) != null);
 +    }
 +
 +    /**
 +     * Determines whether the given Locator launcher command has been properly specified.  The command is deemed
 +     * unspecified if the reference is null or the Command is UNSPECIFIED.
 +     * 
 +     * @param command the Locator launcher command.
 +     * @return a boolean value indicating whether the Locator launcher command is unspecified.
 +     * @see Command#UNSPECIFIED
 +     */
 +    public static boolean isUnspecified(final Command command) {
 +      return (command == null || command.isUnspecified());
 +    }
 +
 +    /**
 +     * Looks up a Locator launcher command by name.  The equality comparison on name is case-insensitive.
 +     * 
 +     * @param name a String value indicating the name of the Locator launcher command.
 +     * @return an enumerated type representing the command name or null if the no such command with the specified name
 +     * exists.
 +     */
 +    public static Command valueOfName(final String name) {
 +      for (Command command : values()) {
 +        if (command.getName().equalsIgnoreCase(name)) {
 +          return command;
 +        }
 +      }
 +
 +      return null;
 +    }
 +
 +    /**
 +     * Gets the name of the Locator launcher command.
 +     * 
 +     * @return a String value indicating the name of the Locator launcher command.
 +     */
 +    public String getName() {
 +      return this.name;
 +    }
 +
 +    /**
 +     * Gets a set of valid options that can be used with the Locator launcher command when used from the command-line.
 +     * 
 +     * @return a Set of Strings indicating the names of the options available to the Locator launcher command.
 +     */
 +    public List<String> getOptions() {
 +      return this.options;
 +    }
 +
 +    /**
 +     * Determines whether this Locator launcher command has the specified command-line option.
 +     * 
 +     * @param option a String indicating the name of the command-line option to this command.
 +     * @return a boolean value indicating whether this command has the specified named command-line option.
 +     */
 +    public boolean hasOption(final String option) {
 +      return getOptions().contains(StringUtils.toLowerCase(option));
 +    }
 +
 +    /**
 +     * Convenience method for determining whether this is the UNSPECIFIED Locator launcher command.
 +     * 
 +     * @return a boolean indicating if this command is UNSPECIFIED.
 +     * @see #UNSPECIFIED
 +     */
 +    public boolean isUnspecified() {
 +      return UNSPECIFIED.equals(this);
 +    }
 +
 +    /**
 +     * Gets the String representation of this Locator launcher command.
 +     * 
 +     * @return a String value representing this Locator launcher command.
 +     */
 +    @Override
 +    public String toString() {
 +      return getName();
 +    }
 +  }
 +
 +  /**
 +   * The LocatorState is an immutable type representing the state of the specified Locator at any given moment in time.
 +   * The state of the Locator is assessed at the exact moment an instance of this class is constructed.
 +   * 
 +   * @see com.gemstone.gemfire.distributed.AbstractLauncher.ServiceState
 +   */
 +  public static final class LocatorState extends ServiceState<String> {
 +
 +    /**
 +     * Unmarshals a LocatorState instance from the JSON String.
 +     * 
 +     * @return a LocatorState value unmarshalled from the JSON String.
 +     */
 +    public static LocatorState fromJson(final String json) {
 +      try {
 +        final GfJsonObject gfJsonObject = new GfJsonObject(json);
 +        
 +        final Status status = Status.valueOfDescription(gfJsonObject.getString(JSON_STATUS));
 +
 +        final List<String> jvmArguments = Arrays.asList(GfJsonArray.toStringArray(
 +          gfJsonObject.getJSONArray(JSON_JVMARGUMENTS)));
 +
 +        return new LocatorState(status, 
 +            gfJsonObject.getString(JSON_STATUSMESSAGE),
 +            gfJsonObject.getLong(JSON_TIMESTAMP),
 +            gfJsonObject.getString(JSON_LOCATION),
 +            gfJsonObject.getInt(JSON_PID),
 +            gfJsonObject.getLong(JSON_UPTIME),
 +            gfJsonObject.getString(JSON_WORKINGDIRECTORY),
 +            jvmArguments,
 +            gfJsonObject.getString(JSON_CLASSPATH),
 +            gfJsonObject.getString(JSON_GEMFIREVERSION),
 +            gfJsonObject.getString(JSON_JAVAVERSION),
 +            gfJsonObject.getString(JSON_LOGFILE),
 +            gfJsonObject.getString(JSON_HOST),
 +            gfJsonObject.getString(JSON_PORT),
 +            gfJsonObject.getString(JSON_MEMBERNAME));
 +      }
 +      catch (GfJsonException e) {
 +        throw new IllegalArgumentException("Unable to create LocatorStatus from JSON: ".concat(json), e);
 +      }
 +    }
 +
 +    public LocatorState(final LocatorLauncher launcher, final Status status) {
 +      // if status is NOT_RESPONDING then this is executing inside the JVM asking for he status; pid etc will be set according to the caller's JVM instead
 +      this(status,
 +        launcher.statusMessage,
 +        System.currentTimeMillis(),
 +        launcher.getId(),
 +        identifyPid(),
 +        ManagementFactory.getRuntimeMXBean().getUptime(),
 +        launcher.getWorkingDirectory(),
 +        ManagementFactory.getRuntimeMXBean().getInputArguments(),
 +        System.getProperty("java.class.path"),
 +        GemFireVersion.getGemFireVersion(),
 +        System.getProperty("java.version"),
 +        getLogFileCanonicalPath(launcher),
 +        launcher.getBindAddressAsString(),
 +        launcher.getPortAsString(),
 +        launcher.getMemberName());
 +    }
 +    
 +    public LocatorState(final LocatorLauncher launcher, final Status status, final String errorMessage) {
 +      this(status, // status
 +          errorMessage, // statusMessage
 +          System.currentTimeMillis(), // timestamp
 +          null, // locatorLocation
 +          null, // pid
 +          0L, // uptime
 +          launcher.getWorkingDirectory(), // workingDirectory
 +          Collections.<String>emptyList(), // jvmArguments
 +          null, // classpath
 +          GemFireVersion.getGemFireVersion(), // gemfireVersion
 +          null, // javaVersion
 +          null, // logFile
 +          null, // host
 +          null, // port
 +          null);// memberName
 +    }
 +    
 +    private static String getBindAddressAsString(LocatorLauncher launcher) {
 +      if (InternalLocator.hasLocator()) {
 +        final InternalLocator locator = InternalLocator.getLocator();
 +        final InetAddress bindAddress = locator.getBindAddress();
 +        if (bindAddress != null) {
 +          if (StringUtils.isBlank(bindAddress.getHostAddress())) {
 +            return bindAddress.getHostAddress();
 +          }
 +        }
 +      }
 +      return launcher.getBindAddressAsString();
 +    }
 +
 +    private static String getLogFileCanonicalPath(LocatorLauncher launcher) {
 +      if (InternalLocator.hasLocator()) {
 +        final InternalLocator locator = InternalLocator.getLocator();
 +        final File logFile = locator.getLogFile();
 +
 +        if (logFile != null && logFile.isFile()) {
 +          final String logFileCanonicalPath = IOUtils.tryGetCanonicalPathElseGetAbsolutePath(logFile);
 +          if (!StringUtils.isBlank(logFileCanonicalPath)) { // this is probably not need but a safe check none-the-less.
 +            return logFileCanonicalPath;
 +          }
 +        }
 +      }
 +      return launcher.getLogFileCanonicalPath();
 +    }
 +
 +    private static String getPortAsString(LocatorLauncher launcher) {
 +      if (InternalLocator.hasLocator()) {
 +        final InternalLocator locator = InternalLocator.getLocator();
 +        final String portAsString =  String.valueOf(locator.getPort());
 +        if (!StringUtils.isBlank(portAsString)) {
 +          return portAsString;
 +        }
 +      }
 +      return launcher.getPortAsString();
 +    }
 +
 +    protected LocatorState(final Status status,
 +                           final String statusMessage,
 +                           final long timestamp,
 +                           final String locatorLocation,
 +                           final Integer pid,
 +                           final Long uptime,
 +                           final String workingDirectory,
 +                           final List<String> jvmArguments,
 +                           final String classpath,
 +                           final String gemfireVersion,
 +                           final String javaVersion,
 +                           final String logFile,
 +                           final String host,
 +                           final String port,
 +                           final String memberName)
 +    {
 +      super(status, statusMessage, timestamp, locatorLocation, pid, uptime, workingDirectory, jvmArguments, classpath,
 +        gemfireVersion, javaVersion, logFile, host, port, memberName);
 +    }
 +
 +    private LocatorState(final LocatorLauncher launcher, final Status status, final LocatorStatusResponse response) {
 +      this(status,
 +        launcher.statusMessage,
 +        System.currentTimeMillis(),
 +        launcher.getId(),
 +        response.getPid(),
 +        response.getUptime(),
 +        response.getWorkingDirectory(),
 +        response.getJvmArgs(),
 +        response.getClasspath(),
 +        response.getGemFireVersion(),
 +        response.getJavaVersion(),
 +        response.getLogFile(),
 +        response.getHost(),
 +        String.valueOf(response.getPort()),
 +        response.getName());
 +    }
 +
 +    @Override
 +    protected String getServiceName() {
 +      return LOCATOR_SERVICE_NAME;
 +    }
 +  }
 +
 +}


[013/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/RemoteQueryDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/RemoteQueryDUnitTest.java
index fc79893,0000000..09fd945
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/RemoteQueryDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/RemoteQueryDUnitTest.java
@@@ -1,1502 -1,0 +1,1502 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.dunit;
 +
 +import java.io.DataInput;
 +import java.io.DataOutput;
 +import java.io.IOException;
 +import java.util.Comparator;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.DataSerializable;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.Struct;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverAdapter;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
 +import com.gemstone.gemfire.cache.query.internal.ResultsBag;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.cache30.ClientServerTestCase;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +
 +import cacheRunner.Portfolio;
 +import cacheRunner.Position;
 +
 +/**
 + * Tests remote (client/server) query execution.
 + *
 + * @author Barry Oglesby
 + * @author Asif
 + * @since 5.0.1
 + */
 +public class RemoteQueryDUnitTest extends CacheTestCase {
 +
 +  /** The port on which the bridge server was started in this VM */
 +  private static int bridgeServerPort;
 +
 +  public RemoteQueryDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  ////////  Test Methods
 +
 +  @Override
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    disconnectAllFromDS();
 +  }
 +
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    disconnectAllFromDS();
 +  }
 +
 +  /**
 +   * Tests remote predicate query execution.
 +   */
 +  public void testRemotePredicateQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name, factory.create());
 +          Wait.pause(1000);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString = "ticker = 'ibm'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          assertTrue(results.getClass() == ResultsBag.class);
 +          assertTrue(results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "ticker = 'IBM'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(0, results.size());
 +          assertTrue(results.getClass() == ResultsBag.class);
 +          assertTrue(results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "price > 49";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries/2, results.size());
 +          assertTrue(results.getClass() == ResultsBag.class);
 +          assertTrue(results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "price = 50";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(results.getClass() == ResultsBag.class);
 +          assertTrue(results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "ticker = 'ibm' and price = 50";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(results.getClass() == ResultsBag.class);
 +          assertTrue(results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +
 +          /* Non-distinct order by query not yet supported
 +          queryString = "id < 101 ORDER BY id";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            fail("Failed executing " + queryString, e);
 +        }
 +          assertEquals(100, results.size());
 +          assertTrue(results instanceof ResultsCollectionWrapper);
 +          IdComparator comparator = new IdComparator();
 +          Object[] resultsArray = results.toArray();
 +          for (int i=0; i<resultsArray.length; i++) {
 +            if (i+1 != resultsArray.length) {
 +              // The id of the current element in the result set must be less
 +              // than the id of the next one to pass.
 +              assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], comparator.compare(resultsArray[i], resultsArray[i+1]) == -1);
 +            }
 +          }
 +          */
 +        }
 +      });
 +
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote import query execution.
 +   */
 +  public void testRemoteImportQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name, factory.create());
 +          Wait.pause(1000);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          
 +          ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct * from " + region.getFullPath();
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct * from " + region.getFullPath() + " where ticker = 'ibm'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct * from " + region.getFullPath() + " where ticker = 'IBM'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(0, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct * from " + region.getFullPath() + " where price > 49";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries/2, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct * from " + region.getFullPath() + " where price = 50";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct * from " + region.getFullPath() + " where ticker = 'ibm' and price = 50";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +        }
 +      });
 +
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote struct query execution.
 +   */
 +  public void testRemoteStructQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name, factory.create());
 +          Wait.pause(1000);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct ticker, price from " + region.getFullPath();
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct ticker, price from " + region.getFullPath() + " where ticker = 'ibm'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct ticker, price from " + region.getFullPath() + " where ticker = 'IBM'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(0, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct ticker, price from " + region.getFullPath() + " where price > 49";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries/2, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct ticker, price from " + region.getFullPath() + " where price = 50";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +          queryString = "import com.gemstone.gemfire.admin.RemoteQueryDUnitTest.TestObject; select distinct ticker, price from " + region.getFullPath() + " where ticker = 'ibm' and price = 50";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +        }
 +      });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote complex query execution.
 +   */
 +  public void __testRemoteComplexQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +//    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name, factory.create());
 +          Wait.pause(1000);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          Portfolio portfolio = null;
 +          Position position1 = null;
 +          Position position2 = null;
 +          Properties portfolioProperties= null;
 +          Properties position1Properties = null;
 +          Properties position2Properties = null;
 +
 +          // Create portfolio 1
 +          portfolio = new Portfolio();
 +          portfolioProperties = new Properties();
 +          portfolioProperties.put("id", new Integer(1));
 +          portfolioProperties.put("type", "type1");
 +          portfolioProperties.put("status", "active");
 +
 +          position1 = new Position();
 +          position1Properties = new Properties();
 +          position1Properties.put("secId", "SUN");
 +          position1Properties.put("qty", new Double(34000.0));
 +          position1Properties.put("mktValue", new Double(24.42));
 +          position1.init(position1Properties);
 +          portfolioProperties.put("position1", position1);
 +
 +          position2 = new Position();
 +          position2Properties = new Properties();
 +          position2Properties.put("secId", "IBM");
 +          position2Properties.put("qty", new Double(8765.0));
 +          position2Properties.put("mktValue", new Double(34.29));
 +          position2.init(position2Properties);
 +          portfolioProperties.put("position2", position2);
 +
 +          portfolio.init(portfolioProperties);
 +          region.put(new Integer(1), portfolio);
 +
 +          // Create portfolio 2
 +          portfolio = new Portfolio();
 +          portfolioProperties = new Properties();
 +          portfolioProperties.put("id", new Integer(2));
 +          portfolioProperties.put("type", "type2");
 +          portfolioProperties.put("status", "inactive");
 +
 +          position1 = new Position();
 +          position1Properties = new Properties();
 +          position1Properties.put("secId", "YHOO");
 +          position1Properties.put("qty", new Double(9834.0));
 +          position1Properties.put("mktValue", new Double(12.925));
 +          position1.init(position1Properties);
 +          portfolioProperties.put("position1", position1);
 +
 +          position2 = new Position();
 +          position2Properties = new Properties();
 +          position2Properties.put("secId", "GOOG");
 +          position2Properties.put("qty", new Double(12176.0));
 +          position2Properties.put("mktValue", new Double(21.972));
 +          position2.init(position2Properties);
 +          portfolioProperties.put("position2", position2);
 +
 +          portfolio.init(portfolioProperties);
 +          region.put(new Integer(2), portfolio);
 +
 +          // Create portfolio 3
 +          portfolio = new Portfolio();
 +          portfolioProperties = new Properties();
 +          portfolioProperties.put("id", new Integer(3));
 +          portfolioProperties.put("type", "type3");
 +          portfolioProperties.put("status", "active");
 +
 +          position1 = new Position();
 +          position1Properties = new Properties();
 +          position1Properties.put("secId", "MSFT");
 +          position1Properties.put("qty", new Double(98327.0));
 +          position1Properties.put("mktValue", new Double(23.32));
 +          position1.init(position1Properties);
 +          portfolioProperties.put("position1", position1);
 +
 +          position2 = new Position();
 +          position2Properties = new Properties();
 +          position2Properties.put("secId", "AOL");
 +          position2Properties.put("qty", new Double(978.0));
 +          position2Properties.put("mktValue", new Double(40.373));
 +          position2.init(position2Properties);
 +          portfolioProperties.put("position2", position2);
 +
 +          portfolio.init(portfolioProperties);
 +          region.put(new Integer(3), portfolio);
 +
 +          // Create portfolio 4
 +          portfolio = new Portfolio();
 +          portfolioProperties = new Properties();
 +          portfolioProperties.put("id", new Integer(4));
 +          portfolioProperties.put("type", "type1");
 +          portfolioProperties.put("status", "inactive");
 +
 +          position1 = new Position();
 +          position1Properties = new Properties();
 +          position1Properties.put("secId", "APPL");
 +          position1Properties.put("qty", new Double(90.0));
 +          position1Properties.put("mktValue", new Double(67.356572));
 +          position1.init(position1Properties);
 +          portfolioProperties.put("position1", position1);
 +
 +          position2 = new Position();
 +          position2Properties = new Properties();
 +          position2Properties.put("secId", "ORCL");
 +          position2Properties.put("qty", new Double(376.0));
 +          position2Properties.put("mktValue", new Double(101.34));
 +          position2.init(position2Properties);
 +          portfolioProperties.put("position2", position2);
 +
 +          portfolio.init(portfolioProperties);
 +          region.put(new Integer(4), portfolio);
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString =
 +            "IMPORT cacheRunner.Position; " +
 +            "SELECT DISTINCT id, status FROM " + region.getFullPath() +
 +            "WHERE NOT (SELECT DISTINCT * FROM positions.values posnVal TYPE Position " +
 +            "WHERE posnVal.secId='AOL' OR posnVal.secId='SAP').isEmpty";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          LogWriterUtils.getLogWriter().fine("size: " + results.size());
 +          //assertEquals(numberOfEntries, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +        }
 +      });
 +
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote full region query execution.
 +   */
 +  public void testRemoteFullRegionQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name, factory.create());
 +          Wait.pause(1000);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +          Comparator comparator = null;
 +          Object[] resultsArray = null;
 +
 +          // value query
 +          queryString = "SELECT DISTINCT itr.value FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +          assertTrue(results.asList().get(0) instanceof TestObject);
 +
 +          // key query
 +          queryString = "SELECT DISTINCT itr.key FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates());
 +          assertEquals("key-1", results.asList().get(0));
 +
 +          // order by value query
 +          queryString = "SELECT DISTINCT * FROM " + region.getFullPath() + " WHERE id < 101 ORDER BY id";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +        }
 +          assertEquals(numberOfEntries, results.size());
 +          // All order-by query results are stored in a ResultsCollectionWrapper
 +          // wrapping a list, so the assertion below is not correct even though
 +          // it should be.
 +          //assertTrue(!results.getCollectionType().allowsDuplicates());
 +          assertTrue(results.getCollectionType().isOrdered());
 +          comparator = new IdComparator();
 +          resultsArray = results.toArray();
 +          for (int i=0; i<resultsArray.length; i++) {
 +            if (i+1 != resultsArray.length) {
 +              // The id of the current element in the result set must be less
 +              // than the id of the next one to pass.
 +              assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], comparator.compare(resultsArray[i], resultsArray[i+1]) == -1);
 +            }
 +          }
 +
 +          // order by struct query
 +          queryString = "SELECT DISTINCT id, ticker, price FROM " + region.getFullPath() + " WHERE id < 101 ORDER BY id";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          // All order-by query results are stored in a ResultsCollectionWrapper
 +          // wrapping a list, so the assertion below is not correct even though
 +          // it should be.
 +          //assertTrue(!results.getCollectionType().allowsDuplicates());
 +          assertTrue(results.getCollectionType().isOrdered());
 +          comparator = new StructIdComparator();
 +          resultsArray = results.toArray();
 +          for (int i=0; i<resultsArray.length; i++) {
 +            if (i+1 != resultsArray.length) {
 +              // The id of the current element in the result set must be less
 +              // than the id of the next one to pass.
 +              assertTrue("The id for " + resultsArray[i] + " should be less than the id for " + resultsArray[i+1], comparator.compare(resultsArray[i], resultsArray[i+1]) == -1);
 +            }
 +          }
 +
 +          // size query
 +          queryString = "(SELECT DISTINCT * FROM " + region.getFullPath() + " WHERE id < 101).size";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          Object result = results.iterator().next();
 +          assertTrue(result instanceof Integer);
 +          int resultInt = ((Integer) result).intValue();
 +          assertEquals(resultInt, 100);
 +
 +          // query with leading/trailing spaces
 +          queryString = " SELECT DISTINCT itr.key FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1' ";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertEquals("key-1", results.asList().get(0));
 +        }
 +      });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote join query execution.
 +   */
 +  public void testRemoteJoinRegionQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name+"1", factory.create());
 +          createRegion(name+"2", factory.create());
 +          Wait.pause(1000);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region1 = getRootRegion().getSubregion(name+"1");
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region1.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +          Region region2 = getRootRegion().getSubregion(name+"2");
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region2.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          ClientServerTestCase.configureConnectionPool(factory, host0, port,-1, true, -1, -1, null);
 +          createRegion(name+"1", factory.create());
 +          createRegion(name+"2", factory.create());
 +        }
 +      });
 +
 +    // Execute client queries
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region1 = getRootRegion().getSubregion(name+"1");
 +          Region region2 = getRootRegion().getSubregion(name+"2");
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString =
 +            "select distinct a, b.price from " + region1.getFullPath() + " a, " + region2.getFullPath() + " b where a.price = b.price";
 +          try {
 +            results = region1.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(numberOfEntries, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +
 +          queryString =
 +            "select distinct a, b.price from " + region1.getFullPath() + " a, " + region2.getFullPath() + " b where a.price = b.price and a.price = 50";
 +          try {
 +            results = region1.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && results.getCollectionType().getElementType().isStructType());
 +        }
 +      });
 +
 +          // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests remote query execution using a BridgeClient as the CacheWriter
 +   * and CacheLoader.
 +   */
 +  public void testRemoteBridgeClientQueries() throws CacheException {
 +
 +    final String name = this.getName();
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    final int numberOfEntries = 100;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          createRegion(name, factory.create());
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +        }
 +      });
 +
 +    // Initialize server region
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          for (int i=0; i<numberOfEntries; i++) {
 +            region.put("key-"+i, new TestObject(i, "ibm"));
 +          }
 +        }
 +      });
 +
-     final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    // Create client region in VM1
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          PoolManager.createFactory().addServer(host0, port).setSubscriptionEnabled(true).create("clientPool");
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          factory.setPoolName("clientPool");
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Create client region in VM2
 +    vm2.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +          PoolManager.createFactory().addServer(host0, port).setSubscriptionEnabled(true).create("clientPool");
 +          getCache();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          factory.setPoolName("clientPool");
 +          createRegion(name, factory.create());
 +        }
 +      });
 +
 +    // Execute client queries in VM1
 +    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString = "SELECT DISTINCT itr.value FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +          assertTrue(results.asList().get(0) instanceof TestObject);
 +
 +          queryString = "SELECT DISTINCT itr.key FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +          assertEquals("key-1", results.asList().get(0));
 +        }
 +      });
 +
 +    // Execute client queries in VM2
 +    vm2.invoke(new CacheSerializableRunnable("Execute queries") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          String queryString = null;
 +          SelectResults results = null;
 +
 +          queryString = "SELECT DISTINCT itr.value FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +          assertTrue(results.asList().get(0) instanceof TestObject);
 +
 +          queryString = "SELECT DISTINCT itr.key FROM " + region.getFullPath() + ".entries itr where itr.key = 'key-1'";
 +          try {
 +            results = region.query(queryString);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString, e);
 +          }
 +          assertEquals(1, results.size());
 +          assertTrue(!results.getCollectionType().allowsDuplicates() && !results.getCollectionType().getElementType().isStructType());
 +          assertEquals("key-1", results.asList().get(0));
 +        }
 +      });
 +
 +      // Close client VM1
 +      vm1.invoke(new CacheSerializableRunnable("Close client") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          region.close();
 +          PoolManager.find("clientPool").destroy();
 +        }
 +      });
 +
 +      // Close client VM2
 +      vm2.invoke(new CacheSerializableRunnable("Close client") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          region.close();
 +          PoolManager.find("clientPool").destroy();
 +        }
 +      });
 +
 +    // Stop server
 +    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +      public void run() {
 +        stopBridgeServer(getCache());
 +      }
 +    });
 +  }
 +
 +
 +  /**
 +   * This the dunit test for the bug no : 36434
 +   * @throws Exception
 +   */
 +
 +   public void testBug36434() throws Exception
 +   {
 +     final String name = this.getName();
 +     final Host host = Host.getHost(0);
 +     VM vm0 = host.getVM(0);
 +     VM vm1 = host.getVM(1);
 +
 +     final int numberOfEntries = 100;
 +
 +     // Start server
 +     vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +         public void run2() throws CacheException {
 +           Properties config = new Properties();
 +           config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +           system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +           AttributesFactory factory = new AttributesFactory();
 +           factory.setScope(Scope.LOCAL);
 +           createRegion(name, factory.createRegionAttributes());
 +           try {
 +             startBridgeServer(0, false);
 +           } catch (Exception ex) {
 +             Assert.fail("While starting CacheServer", ex);
 +           }
 +         }
 +       });
 +
 +     // Initialize server region
 +     vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +         public void run2() throws CacheException {
 +           Region region = getRootRegion().getSubregion(name);
 +           for (int i=0; i<numberOfEntries; i++) {
 +             region.put("key-"+i, new TestObject(i, "ibm"));
 +           }
 +         }
 +       });
 +
-      final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++     final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +     final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +     // Create client region in VM1
 +     vm1.invoke(new CacheSerializableRunnable("Create region") {
 +         public void run2() throws CacheException {
 +           Properties config = new Properties();
 +           config.setProperty("mcast-port", "0");
 +           system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +           PoolManager.createFactory().addServer(host0, port).setSubscriptionEnabled(true).create("clientPool");
 +           getCache();
 +           AttributesFactory factory = new AttributesFactory();
 +           factory.setScope(Scope.LOCAL);
 +           factory.setPoolName("clientPool");
 +           createRegion(name, factory.createRegionAttributes());
 +         }
 +       });
 +
 +
 +     // Execute client queries in VM1
 +     vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +         public void run2() throws CacheException {
 +           Region region = getRootRegion().getSubregion(name);
 +           String queryStrings [] ={"id<9", "selection<9", "important<9","\"select\"<9" };
 +           for(int i =0 ; i <queryStrings.length;++i) {
 +             SelectResults results = null;
 +
 +             try {
 +               results = region.query(queryStrings[i]);
 +             } catch (Exception e) {
 +               Assert.fail("Failed executing " + queryStrings[i], e);
 +             }
 +             assertEquals(9, results.size());
 +             String msg = "results expected to be instance of ResultsBag,"
 +               + " but was found to be is instance of '";
 +             assertTrue(msg + results.getClass().getName() + "'",
 +                        results instanceof ResultsBag);
 +             assertTrue(results.asList().get(0) instanceof TestObject);
 +           }
 +         }
 +       });
 +
 +       // Close client VM1
 +       vm1.invoke(new CacheSerializableRunnable("Close client") {
 +         public void run2() throws CacheException {
 +           Region region = getRootRegion().getSubregion(name);
 +           region.close();
 +           PoolManager.find("clientPool").destroy();
 +         }
 +       });
 +
 +
 +     // Stop server
 +     vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +       public void run() {
 +         stopBridgeServer(getCache());
 +       }
 +     });
 +
 +
 +
 +   }
 +
 +  /**
 +    * This the dunit test for the bug no : 36969
 +    * @throws Exception
 +    */
 +
 +    public void testBug36969() throws Exception
 +    {
 +      final String name = this.getName();
 +      final Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
 +
 +      final int numberOfEntries = 100;
 +
 +      // Start server
 +      vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +          public void run2() throws CacheException {
 +            Properties config = new Properties();
 +            config.setProperty("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +            system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.LOCAL);
 +            final Region region = createRegion(name, factory.createRegionAttributes());
 +            QueryObserverHolder.setInstance(new QueryObserverAdapter() {
 +              public void afterQueryEvaluation(Object result) {
 +                //Destroy the region in the test
 +                region.close();
 +              }
 +
 +            });
 +            try {
 +              startBridgeServer(0, false);
 +            } catch (Exception ex) {
 +              Assert.fail("While starting CacheServer", ex);
 +            }
 +          }
 +        });
 +
 +      // Initialize server region
 +      vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +          public void run2() throws CacheException {
 +            Region region = getRootRegion().getSubregion(name);
 +            for (int i=0; i<numberOfEntries; i++) {
 +              region.put("key-"+i, new TestObject(i, "ibm"));
 +            }
 +          }
 +        });
 +
-       final int port = vm0.invokeInt(RemoteQueryDUnitTest.class, "getCacheServerPort");
++      final int port = vm0.invoke(() -> RemoteQueryDUnitTest.getCacheServerPort());
 +      final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +      // Create client region in VM1
 +      vm1.invoke(new CacheSerializableRunnable("Create region") {
 +          public void run2() throws CacheException {
 +            Properties config = new Properties();
 +            config.setProperty("mcast-port", "0");
 +            system = (InternalDistributedSystem) DistributedSystem.connect(config);
 +            PoolManager.createFactory().addServer(host0, port).setSubscriptionEnabled(true).create("clientPool");
 +            getCache();
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.LOCAL);
 +            factory.setPoolName("clientPool");
 +            createRegion(name, factory.createRegionAttributes());
 +          }
 +        });
 +
 +
 +      // Execute client queries in VM1
 +      vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +          public void run2() throws CacheException {
 +            Region region = getRootRegion().getSubregion(name);
 +            String queryStrings = "id<9";
 +//            SelectResults results = null;
 +              try {
 +                region.query(queryStrings);
 +                fail("The query should have experienced RegionDestroyedException");
 +              } catch (QueryInvocationTargetException qte) {
 +                //Ok test passed
 +              } catch(Exception e) {
 +                Assert.fail("Failed executing query " + queryStrings+ " due  to unexpected Excecption", e);
 +            }
 +          }
 +        });
 +
 +      // Start server
 +      vm0.invoke(new CacheSerializableRunnable("Create two regions") {
 +          public void run2() throws CacheException {
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.LOCAL);
 +            final Region region1 = createRegion(name, factory.createRegionAttributes());
 +            final Region region2 = createRegion(name+"_2", factory.createRegionAttributes());
 +            QueryObserverHolder.setInstance(new QueryObserverAdapter() {
 +              public void afterQueryEvaluation(Object result) {
 +                //Destroy the region in the test
 +                region1.close();
 +              }
 +
 +            });
 +            for (int i=0; i<numberOfEntries; i++) {
 +              region1.put("key-"+i, new TestObject(i, "ibm"));
 +              region2.put("key-"+i, new TestObject(i, "ibm"));
 +            }
 +
 +          }
 +        });
 +
 +   // Execute client queries in VM1
 +      vm1.invoke(new CacheSerializableRunnable("Execute queries") {
 +          public void run2() throws CacheException {
 +            Region region = getRootRegion().getSubregion(name);
 +            String queryString = "select distinct * from /"+name+",/"+name + "_2";
 +//            SelectResults results = null;
 +              try {
 +                region.query(queryString);
 +                fail("The query should have experienced RegionDestroyedException");
 +              } catch (QueryInvocationTargetException qte) {
 +                //Ok test passed
 +              } catch(Exception e) {
 +                Assert.fail("Failed executing query " + queryString+ " due  to unexpected Excecption", e);
 +            }
 +          }
 +        });
 +
 +        // Close client VM1
 +        vm1.invoke(new CacheSerializableRunnable("Close client") {
 +          public void run2() throws CacheException {
 +            Region region = getRootRegion().getSubregion(name);
 +            region.close();
 +            PoolManager.find("clientPool").destroy();
 +          }
 +        });
 +
 +
 +      // Stop server
 +      vm0.invoke(new SerializableRunnable("Stop CacheServer") {
 +        public void run() {
 +          QueryObserverHolder.setInstance(new QueryObserverAdapter());
 +          stopBridgeServer(getCache());
 +        }
 +      });
 +
 +
 +
 +    }
 +
 +
 +
 +  /**
 +   * Starts a bridge server on the given port, using the given
 +   * deserializeValues and notifyBySubscription to serve up the
 +   * given region.
 +   */
 +  protected void startBridgeServer(int port, boolean notifyBySubscription)
 +    throws IOException {
 +
 +    Cache cache = getCache();
 +    CacheServer bridge = cache.addCacheServer();
 +    bridge.setPort(port);
 +    bridge.setNotifyBySubscription(notifyBySubscription);
 +    bridge.start();
 +    bridgeServerPort = bridge.getPort();
 +  }
 +
 +  /**
 +   * Stops the bridge server that serves up the given cache.
 +   */
 +  protected void stopBridgeServer(Cache cache) {
 +    CacheServer bridge =
 +      (CacheServer) cache.getCacheServers().iterator().next();
 +    bridge.stop();
 +    assertFalse(bridge.isRunning());
 +  }
 +
 +  private static int getCacheServerPort() {
 +    return bridgeServerPort;
 +  }
 +
 +  public static class TestObject implements DataSerializable {
 +    protected String _ticker;
 +    protected int _price;
 +    public int id;
 +    public int important;
 +    public int selection;
 +    public int select;
 +
 +    public TestObject() {}
 +
 +    public TestObject(int id, String ticker) {
 +      this.id = id;
 +      this._ticker = ticker;
 +      this._price = id;
 +      this.important = id;
 +      this.selection =id;
 +      this.select =id;
 +    }
 +
 +    public int getId() {
 +      return this.id;
 +    }
 +
 +    public String getTicker() {
 +      return this._ticker;
 +    }
 +
 +    public int getPrice() {
 +      return this._price;
 +    }
 +
 +    public void toData(DataOutput out) throws IOException
 +    {
 +      //System.out.println("Is serializing in WAN: " + GatewayEventImpl.isSerializingValue());
 +      out.writeInt(this.id);
 +      DataSerializer.writeString(this._ticker, out);
 +      out.writeInt(this._price);
 +    }
 +
 +    public void fromData(DataInput in) throws IOException, ClassNotFoundException
 +    {
 +      //System.out.println("Is deserializing in WAN: " + GatewayEventImpl.isDeserializingValue());
 +      this.id = in.readInt();
 +      this._ticker = DataSerializer.readString(in);
 +      this._price = in.readInt();
 +    }
 +
 +    public String toString() {
 +      StringBuffer buffer = new StringBuffer();
 +      buffer
 +        .append("TestObject [")
 +        .append("id=")
 +        .append(this.id)
 +        .append("; ticker=")
 +        .append(this._ticker)
 +        .append("; price=")
 +        .append(this._price)
 +        .append("]");
 +      return buffer.toString();
 +    }
 +  }
 +
 +  public static class IdComparator implements Comparator {
 +
 +    public int compare(Object obj1, Object obj2) {
 +      int obj1Id = ((TestObject) obj1).getId();
 +      int obj2Id = ((TestObject) obj2).getId();
 +      if (obj1Id > obj2Id) {
 +        return 1;
 +      } else if (obj1Id < obj2Id) {
 +        return -1;
 +      } else {
 +        return 0;
 +      }
 +    }
 +  }
 +
 +  public static class StructIdComparator implements Comparator {
 +
 +    public int compare(Object obj1, Object obj2) {
 +      int obj1Id = ((Integer) ((Struct) obj1).get("id")).intValue();
 +      int obj2Id = ((Integer) ((Struct) obj2).get("id")).intValue();
 +      if (obj1Id > obj2Id) {
 +        return 1;
 +      } else if (obj1Id < obj2Id) {
 +        return -1;
 +      } else {
 +        return 0;
 +      }
 +    }
 +  }
 +}
 +
 +/*
 +    String queryString = "ticker = 'ibm'";
 +    SelectResults results = region.query(queryString);
 +
 +    String queryString = "ticker = 'ibm' and price = 50";
 +
 +    String queryString = "select distinct * from /trade";
 +
 +    String queryString = "import TestObject; select distinct * from /trade";
 +
 +    String queryString =
 +      "IMPORT cacheRunner.Position; " +
 +      "SELECT DISTINCT id, status FROM /root/portfolios " +
 +      "WHERE NOT (SELECT DISTINCT * FROM positions.values posnVal TYPE Position " +
 +      "WHERE posnVal.secId='AOL' OR posnVal.secId='SAP').isEmpty";
 +
 +    queryString = "SELECT DISTINCT itr.value FROM /trade.entries itr where itr.key = 'key-1'";
 +
 +    queryString = "SELECT DISTINCT itr.key FROM /trade.entries itr where itr.key = 'key-1'";
 +
 +    String queryString =
 +      "select distinct a, b.price from /generic/app1/Trade a, /generic/app1/Trade b where a.price = b.price";
 +
 +    String queryString =
 +        "SELECT DISTINCT a, b.unitPrice from /newegg/arinv a, /newegg/itemPriceSetting b where a.item = b.itemNumber and a.item = '26-106-934'";
 +
 +    String queryString =
 +        "SELECT DISTINCT a, UNDEFINED from /newegg/arinv a, /newegg/itemPriceSetting b where a.item = b.itemNumber and a.item = '26-106-934'";
 +
 +*/

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/QueryFromClauseCanonicalizationJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/QueryFromClauseCanonicalizationJUnitTest.java
index 0f13a31,0000000..f62fb8a
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/QueryFromClauseCanonicalizationJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/QueryFromClauseCanonicalizationJUnitTest.java
@@@ -1,264 -1,0 +1,257 @@@
 +/*
 + * 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.
 + */
 +/*
 + * IndexTest.java JUnit based test
 + * 
 + * Created on March 9, 2005, 3:30 PM
 + */
 +package com.gemstone.gemfire.cache.query.internal;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertTrue;
 +
 +import java.util.ArrayList;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import org.junit.After;
 +import org.junit.Assert;
 +import org.junit.Before;
 +import org.junit.Test;
 +import org.junit.experimental.categories.Category;
 +
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.query.CacheUtils;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.data.Portfolio;
 +import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
 +
 +/**
 + * 
 + * @author Asif
 + */
 +@Category(IntegrationTest.class)
 +public class QueryFromClauseCanonicalizationJUnitTest
 +{
- 
-   /*
-    * ========================================================================
-    * Copyright (C) GemStone Systems, Inc. 2000-2004. All Rights Reserved.
-    * 
-    * ========================================================================
-    */
 +  Region region = null;
 +
 +  QueryService qs = null;
 +
 +  static String queries[] = {
 +      "SELECT DISTINCT ID, value.secId FROM /pos, getPositions where status = 'active' and ID = 0",
 +      "SELECT DISTINCT ID, value.secId FROM /pos, positions where status = 'active' and ID = 0",
 +      "SELECT DISTINCT ID, value.secId FROM /pos, getPositions() where status = 'active' and ID = 0",
 +      "SELECT DISTINCT ID, p.value.secId FROM /pos, getPositions('true') p where status = 'active' and ID = 0",
 +      "SELECT DISTINCT * FROM /pos as a, a.collectionHolderMap['0'].arr as b where a.status = 'active' and a.ID = 0",
 +     /* "SELECT DISTINCT * FROM /pos as a, a.positions[a.collectionHolderMap['0'][1]] as b where a.status = 'active' and a.ID = 0",*/
 +
 +  };
 +
 +  @Before
 +  public void setUp() throws java.lang.Exception
 +  {
 +    CacheUtils.startCache();
 +    region = CacheUtils.createRegion("pos", Portfolio.class);
 +    region.put("0", new Portfolio(0));
 +    region.put("1", new Portfolio(1));
 +    region.put("2", new Portfolio(2));
 +    region.put("3", new Portfolio(3));
 +
 +    qs = CacheUtils.getQueryService();
 +  }
 +
 +  @After
 +  public void tearDown() throws java.lang.Exception
 +  {
 +    CacheUtils.closeCache();
 +  }
 +
 +  @Test
 +  public void testCanonicalizedFromClause() throws Throwable
 +  {  
 +
 +    boolean overallTestFailed = false;
 +    Query q = null;
 +    QueryObserverImpl observer = null;
 +    for (int j = 0; j < queries.length; j++) {
 +
 +      try {
 +        q = qs.newQuery(queries[j]);
 +        observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        q.execute();
 +      }
 +      catch (Exception e) {
 +        System.err
 +            .println("QueryFromClauseCanonicalizationJUnitTest::testCanonicalizedFromClause.Exception in running query number="
 +                + j + "  Exception=" + e);
 +        e.printStackTrace();
 +        overallTestFailed = true;
 +        continue;
 +      }
 +
 +      switch (j) {
 +      case 0:
 +      case 1:
 +      case 2:
 +        if (observer.clauses.get(0).toString().equals("/pos")
 +            && observer.clauses.get(1).toString().equals("iter1.positions")) {
 +          assertTrue(true);
 +        }
 +        else {
 +          overallTestFailed = true;
 +          System.err
 +              .println("QueryFromClauseCanonicalizationJUnitTest::testCanonicalizedFromClause.Failure in query number="
 +                  + j);
 +        }
 +        break;
 +      case 3:
 +        if (observer.clauses.get(0).toString().equals("/pos")
 +            && observer.clauses.get(1).toString().equals(
 +                "iter1.getPositions('true')")) {
 +          assertTrue(true);
 +        }
 +        else {
 +          overallTestFailed = true;
 +          System.err
 +              .println("QueryFromClauseCanonicalizationJUnitTest::testCanonicalizedFromClause.Failure in query number="
 +                  + j);
 +        }
 +        break;
 +      case 5:
 +        if (observer.clauses.get(0).toString().equals("/pos")
 +            && observer.clauses.get(1).toString().equals(
 +                "iter1.positions[iter1.collectionHolderMap[][]]")) {
 +          assertTrue(true);
 +        }
 +        else {
 +          overallTestFailed = true;
 +          System.err
 +              .println("QueryFromClauseCanonicalizationJUnitTest::testCanonicalizedFromClause.Failure in query number="
 +                  + j);
 +        }
 +        break;
 +      case 4:
 +        if (observer.clauses.get(0).toString().equals("/pos")
 +            && observer.clauses.get(1).toString().equals(
 +                "iter1.collectionHolderMap['0'].arr")) {
 +          assertTrue(true);
 +        }
 +        else {
 +          overallTestFailed = true;
 +          System.err
 +              .println("QueryFromClauseCanonicalizationJUnitTest::testCanonicalizedFromClause.Failure in query number="
 +                  + j);
 +        }
 +        break;
 +
 +      }
 +
 +    }
 +    if (overallTestFailed)
 +      Assert.fail();
 +
 +  }
 +
 +  @Test
 +  public void testCanonicalizationOfMethod() throws Exception
 +  {
 +    QCompiler compiler = new QCompiler();
 +    List list = compiler.compileFromClause("/pos pf");
 +    ExecutionContext context = new ExecutionContext(new Object[]{"bindkey"}, CacheUtils.getCache());
 +    context.newScope(context.assosciateScopeID());
 +
 +    Iterator iter = list.iterator();
 +    while (iter.hasNext()) {
 +      CompiledIteratorDef iterDef = (CompiledIteratorDef)iter.next();
 +      context.addDependencies(new CompiledID("dummy"), iterDef
 +          .computeDependencies(context));
 +      RuntimeIterator rIter = iterDef.getRuntimeIterator(context);
 +      context.bindIterator(rIter);
 +      context.addToIndependentRuntimeItrMap(iterDef);
 +    }
 +    CompiledPath cp = new CompiledPath(new CompiledID("pf"), "positions");
 +    CompiledLiteral cl = new CompiledLiteral("key1");
 +    List args = new ArrayList();
 +    args.add(cl);
 +    CompiledOperation cop = new CompiledOperation(cp, "get", args);
 +    StringBuffer sbuff = new StringBuffer();
 +    cop.generateCanonicalizedExpression(sbuff, context);
 +    assertEquals(sbuff.toString(),"iter1.positions.get('key1')");
 +    
 +//    cp = new CompiledPath(new CompiledID("pf"), "positions");
 +//    CompiledBindArgument cb = new CompiledBindArgument(1);
 +//    args = new ArrayList();
 +//    args.add(cb);
 +//    cop = new CompiledOperation(cp, "get", args);
 +////    context.setBindArguments(new Object[]{"bindkey"});
 +//    sbuff = new StringBuffer();
 +//    cop.generateCanonicalizedExpression(sbuff, context);
 +//    assertEquals(sbuff.toString(),"iter1.positions.get('bindkey')");
 +//    
 +    
 +//    cp = new CompiledPath(new CompiledID("pf"), "getPositions()");
 +//    cb = new CompiledBindArgument(1);
 +//    args = new ArrayList();
 +//    args.add(cb);
 +//    cop = new CompiledOperation(cp, "get", args);
 +//    sbuff = new StringBuffer();
 +//    cop.generateCanonicalizedExpression(sbuff, context);
 +//    assertEquals(sbuff.toString(),"iter1.positions().get('bindkey')");
 +//    
 +//    
 +//    cp = new CompiledPath(new CompiledID("pf"), "getPositions");
 +//    cb = new CompiledBindArgument(1);
 +//    args = new ArrayList();
 +//    args.add(cb);
 +//    cop = new CompiledOperation(cp, "get", args);
 +//    sbuff = new StringBuffer();
 +//    cop.generateCanonicalizedExpression(sbuff, context);
 +//    assertEquals(sbuff.toString(),"iter1.positions.get('bindkey')");
 +    
 +    cp = new CompiledPath(new CompiledID("pf"), "getPositions");
 +    CompiledPath cp1 = new CompiledPath(new CompiledID("pf"),"pkid");
 +    args = new ArrayList();
 +    args.add(cp1);
 +    cop = new CompiledOperation(cp, "get", args);
 +    sbuff = new StringBuffer();
 +    cop.generateCanonicalizedExpression(sbuff, context);
 +    assertEquals(sbuff.toString(),"iter1.positions.get(iter1.pkid)");
 +    
 +    
 +    cp = new CompiledPath(new CompiledID("pf"), "getPositions");
 +    cp1 = new CompiledPath(new CompiledID("pf"),"pkid");    
 +    CompiledIndexOperation ciop = new CompiledIndexOperation(cp,cp1);
 +    sbuff = new StringBuffer();
 +    ciop.generateCanonicalizedExpression(sbuff, context);
 +    assertEquals(sbuff.toString(),"iter1.positions[iter1.pkid]");
 +  } 
 +  
 +  
 +  class QueryObserverImpl extends QueryObserverAdapter
 +  {
 +    public List clauses = new ArrayList();
 +
 +    public void beforeIterationEvaluation(CompiledValue executer,
 +        Object currentObject)
 +    {
 +      clauses.add(((RuntimeIterator)executer).getDefinition());
 +
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/ResultsBagJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/ResultsBagJUnitTest.java
index e910e73,0000000..9758e04
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/ResultsBagJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/ResultsBagJUnitTest.java
@@@ -1,314 -1,0 +1,307 @@@
 +/*
 + * 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.
 + */
- //
- //  ResultsBagJUnitTest.java
- //  gemfire
- //
- //  Created by Eric Zoerner on 2/13/08.
- //  Copyright 2008 __MyCompanyName__. All rights reserved.
- //
 +package com.gemstone.gemfire.cache.query.internal;
 +
 +import java.util.*;
 +import java.io.*;
 +
 +import org.junit.experimental.categories.Category;
 +
 +import junit.framework.*;
 +
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.internal.types.ObjectTypeImpl;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.test.junit.categories.UnitTest;
 +
 +/**
 + * Test ResultsBag, including null elements
 + * @author ezoerner
 + */
 +@Category(UnitTest.class)
 +public class ResultsBagJUnitTest extends TestCase {
 +
 +  public ResultsBagJUnitTest(String testName) {
 +    super(testName);
 +  }
 +  
 +  public void testDuplicates() {
 +    ResultsBag bag = new ResultsBag();
 +    bag.add("one");
 +    bag.add("two");
 +    assertEquals(2, bag.size());
 +    bag.add("two");
 +    assertEquals(3, bag.size());
 +    assertEquals(1, bag.occurrences("one"));
 +    assertEquals(2, bag.occurrences("two"));
 +    
 +    assertTrue(bag.remove("two"));
 +    assertEquals(1, bag.occurrences("two"));
 +    assertTrue(bag.remove("one"));
 +    assertEquals(0, bag.occurrences("one"));
 +    assertTrue(!bag.remove("one"));
 +    assertEquals(0, bag.occurrences("one"));
 +    
 +  }
 +  
 +  public void testIteration() {
 +    ResultsBag bag = new ResultsBag();
 +    bag.add(new Integer(1));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(2));
 +    
 +    int numOnes = 0;
 +    int numTwos = 0;
 +    Integer one = new Integer(1);
 +    Integer two = new Integer(2);
 +    for (Iterator itr = bag.iterator(); itr.hasNext(); ) {
 +      Object n = itr.next();
 +      if (one.equals(n)) {
 +        numOnes++;
 +      }
 +      else if (two.equals(n)) {
 +        numTwos++;
 +      }
 +      else {
 +        fail(n + " did not equal 1 or 2");
 +      }
 +    }
 +    assertEquals(1, numOnes);
 +    assertEquals(2, numTwos);
 +  }
 +  
 +  public void testSerializingSetViewWithNulls()
 +  throws ClassNotFoundException, IOException {
 +    ResultsBag bag = new ResultsBag();
 +    bag.add(new Integer(4));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(42));
 +    bag.add(null);
 +    bag.add(null);
 +    bag.add(null);
 +    
 +    assertEquals(6, bag.size());
 +    assertEquals(1, bag.occurrences(new Integer(4)));
 +    assertEquals(3, bag.occurrences(null));
 +    
 +    Set set = bag.asSet();
 +    assertEquals(4, set.size());
 +    assertTrue(set.contains(new Integer(4)));
 +    assertTrue(set.contains(null));    
 +    
 +    ResultsCollectionWrapper w
 +      = new ResultsCollectionWrapper(new ObjectTypeImpl(Integer.class),
 +                                     set);
 +    
 +    HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
 +    DataSerializer.writeObject(w, hdos);
 +    DataInputStream in = new DataInputStream(hdos.getInputStream());
 +    SelectResults setCopy = (SelectResults)DataSerializer.readObject(in);
 +    
 +    assertEquals(4, setCopy.size());
 +    assertTrue(setCopy.contains(new Integer(4)));
 +    assertTrue(setCopy.contains(null));
 +  }
 +    
 +  public void testNulls() {
 +    ResultsBag bag = new ResultsBag();
 +    assertTrue(bag.isEmpty());
 +    bag.add(null);
 +    assertTrue(!bag.isEmpty());
 +    assertEquals(1, bag.size());
 +    assertEquals(1, bag.occurrences(null));
 +    
 +    bag.add(new Integer(1));
 +    assertEquals(2, bag.size());
 +    bag.add(new Integer(2));
 +    assertEquals(3, bag.size());
 +    bag.add(new Integer(2));
 +    assertEquals(4, bag.size());
 +    
 +    bag.add(null);
 +    assertEquals(5, bag.size());
 +    assertEquals(2, bag.occurrences(null));
 +    
 +    int numNulls = 0;
 +    int numOnes = 0;
 +    int numTwos = 0;
 +    Integer one = new Integer(1);
 +    Integer two = new Integer(2);
 +    for (Iterator itr = bag.iterator(); itr.hasNext(); ) {
 +      Object n = itr.next();
 +      if (one.equals(n)) {
 +        numOnes++;
 +      }
 +      else if (two.equals(n)) {
 +        numTwos++;
 +      }
 +      else if (n == null) {
 +        numNulls++;
 +      }
 +      else {
 +        fail(n + " was not null and did not equal 1 or 2");
 +      }
 +    }
 +    assertEquals(1, numOnes);
 +    assertEquals(2, numTwos);
 +    assertEquals(2, numNulls);
 +    
 +    // make sure toString doesn't blow up with nulls
 +    String s = bag.toString();
 +    assertTrue("toString didn't contain 'null': '" + s + "'", s.indexOf("null") > 0);
 +    
 +    assertTrue(bag.remove(null));
 +    assertEquals(1, bag.occurrences(null));
 +    assertTrue(bag.remove(null));
 +    assertEquals(0, bag.occurrences(null));
 +    assertTrue(!bag.remove(null));
 +    assertEquals(0, bag.occurrences(null));
 +  }
 +  
 +  public void testIterationNullRemoval() {
 +    ResultsBag bag = new ResultsBag();
 +    bag.add(null);
 +    bag.add(null);
 +
 +    bag.add(new Integer(1));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(2));
 +    assertEquals(5, bag.size());
 +    
 +    for (Iterator itr = bag.iterator(); itr.hasNext(); ) {
 +      Object n = itr.next();
 +      if (n == null) {
 +        itr.remove();
 +      }
 +    }
 +    assertEquals(3, bag.size());
 +    assertEquals(0, bag.occurrences(null));
 +  }
 +  
 +  public void testIterationRemoval() {
 +    ResultsBag bag = new ResultsBag();
 +    
 +    bag.add(new Integer(1));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(3));
 +    bag.add(new Integer(3));
 +    bag.add(new Integer(4));
 +    
 +    assertEquals(6, bag.size());
 +    
 +//    Integer one = new Integer(1);
 +//    Integer two = new Integer(2);
 +    Iterator itr = bag.iterator();
 +    for (int i = 0 ; i < 3; i++) {
 +      itr.next();
 +      itr.remove();
 +    }
 +    assertEquals(3, bag.size());
 +    
 +    for (int i = 0 ; i < 3; i++) {
 +      itr.next();
 +      itr.remove();
 +    }
 +    assertTrue(bag.isEmpty());
 +    assertEquals(0, bag.size());
 +  }
 +  
 +  public void testNoSuchElementException() {
 +    ResultsBag bag = new ResultsBag();
 +    
 +    bag.add(new Integer(1));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(3));
 +    bag.add(new Integer(3));
 +    bag.add(new Integer(4));
 +    
 +    assertEquals(6, bag.size());
 +    
 +    Iterator itr = bag.iterator();
 +    for (int i = 0 ; i < 6; i++) {
 +      itr.next();
 +    }
 +    try {
 +      itr.next();
 +      fail("should have thrown a NoSuchElementException");
 +    }
 +    catch (NoSuchElementException e) {
 +      // pass
 +    }
 +    
 +    // test with removes
 +    itr = bag.iterator();
 +    for (int i = 0 ; i < 6; i++) {
 +      itr.next();
 +      itr.remove();
 +    }
 +    assertEquals(0, bag.size());
 +    try {
 +      itr.next();
 +      fail("should have thrown a NoSuchElementException");
 +    }
 +    catch (NoSuchElementException e) {
 +      // pass
 +    }
 +    
 +    // test with nulls
 +    bag = new ResultsBag();
 +    
 +    bag.add(new Integer(1));
 +    bag.add(new Integer(2));
 +    bag.add(new Integer(2));
 +    bag.add(null);
 +    bag.add(null);
 +    bag.add(null);
 +    bag.add(new Integer(3));
 +    bag.add(new Integer(3));
 +    bag.add(new Integer(4));
 +    
 +    assertEquals(9, bag.size());
 +    
 +    itr = bag.iterator();
 +    for (int i = 0 ; i < 9; i++) {
 +      itr.next();
 +    }
 +    try {
 +      itr.next();
 +      fail("should have thrown a NoSuchElementException");
 +    }
 +    catch (NoSuchElementException e) {
 +      // pass
 +    }
 +    
 +    // test with removes
 +    itr = bag.iterator();
 +    for (int i = 0 ; i < 9; i++) {
 +      itr.next();
 +      itr.remove();
 +    }
 +    assertEquals(0, bag.size());
 +    try {
 +      itr.next();
 +      fail("should have thrown a NoSuchElementException");
 +    }
 +    catch (NoSuchElementException e) {
 +      // pass
 +    }
 +  }
 +}


[023/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/HyperLogLogPlus.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/HyperLogLogPlus.java
index 0000000,0000000..86b74ef
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/HyperLogLogPlus.java
@@@ -1,0 -1,0 +1,1053 @@@
++/*
++ * Copyright (C) 2011 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++import com.gemstone.gemfire.internal.redis.executor.hll.Varint;
++
++import java.io.ByteArrayInputStream;
++import java.io.ByteArrayOutputStream;
++import java.io.DataInput;
++import java.io.DataInputStream;
++import java.io.DataOutput;
++import java.io.DataOutputStream;
++import java.io.Externalizable;
++import java.io.IOException;
++import java.io.ObjectInput;
++import java.io.ObjectOutput;
++import java.io.Serializable;
++import java.util.ArrayList;
++import java.util.Collections;
++import java.util.Comparator;
++import java.util.List;
++import java.util.SortedMap;
++import java.util.TreeMap;
++
++
++/**
++ * Implementation of HyperLogLog++ described in
++ * <p/>
++ * <p>
++ * http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/40671.pdf
++ * </p>
++ * <p/>
++ * Brief HyperLogLog++ Overview
++ * <p/>
++ * Uses 64 bit hashing instead of 32
++ * Has two representation modes: sparse and normal
++ * <p/>
++ * 'normal' is approximately the same as regular hyperloglog (still uses 64 bits)
++ * <p/>
++ * 'sparse' handles lower cardinality values with a highly accurate but poorly scaling
++ * strategy and leverages data compression to compete with 'normal' for as long as possible
++ * (sparse has the advantage on accuracy per unit of memory at low cardinality but quickly falls behind).
++ */
++public class HyperLogLogPlus implements ICardinality, Serializable {
++
++  private static final long serialVersionUID = 7504952025744337762L;
++
++  private enum Format {
++    SPARSE, NORMAL
++  }
++
++  /**
++   * used to mark codec version for serialization
++   */
++  private static final int VERSION = 2;
++
++  // threshold and bias data taken from google's bias correction data set:  https://docs.google.com/document/d/1gyjfMHy43U9OWBXxfaeG-3MjGzejW1dlpyMwEYAAWEI/view?fullscreen#
++  static final double[] thresholdData = {10, 20, 40, 80, 220, 400, 900, 1800, 3100, 6500, 15500, 20000, 50000, 120000, 350000};
++
++  static final double[][] rawEstimateData = {
++    // precision 4
++    {11, 11.717, 12.207, 12.7896, 13.2882, 13.8204, 14.3772, 14.9342, 15.5202, 16.161, 16.7722, 17.4636, 18.0396, 18.6766, 19.3566, 20.0454, 20.7936, 21.4856, 22.2666, 22.9946, 23.766, 24.4692, 25.3638, 26.0764, 26.7864, 27.7602, 28.4814, 29.433, 30.2926, 31.0664, 31.9996, 32.7956, 33.5366, 34.5894, 35.5738, 36.2698, 37.3682, 38.0544, 39.2342, 40.0108, 40.7966, 41.9298, 42.8704, 43.6358, 44.5194, 45.773, 46.6772, 47.6174, 48.4888, 49.3304, 50.2506, 51.4996, 52.3824, 53.3078, 54.3984, 55.5838, 56.6618, 57.2174, 58.3514, 59.0802, 60.1482, 61.0376, 62.3598, 62.8078, 63.9744, 64.914, 65.781, 67.1806, 68.0594, 68.8446, 69.7928, 70.8248, 71.8324, 72.8598, 73.6246, 74.7014, 75.393, 76.6708, 77.2394,},
++    // precision 5
++    {23, 23.1194, 23.8208, 24.2318, 24.77, 25.2436, 25.7774, 26.2848, 26.8224, 27.3742, 27.9336, 28.503, 29.0494, 29.6292, 30.2124, 30.798, 31.367, 31.9728, 32.5944, 33.217, 33.8438, 34.3696, 35.0956, 35.7044, 36.324, 37.0668, 37.6698, 38.3644, 39.049, 39.6918, 40.4146, 41.082, 41.687, 42.5398, 43.2462, 43.857, 44.6606, 45.4168, 46.1248, 46.9222, 47.6804, 48.447, 49.3454, 49.9594, 50.7636, 51.5776, 52.331, 53.19, 53.9676, 54.7564, 55.5314, 56.4442, 57.3708, 57.9774, 58.9624, 59.8796, 60.755, 61.472, 62.2076, 63.1024, 63.8908, 64.7338, 65.7728, 66.629, 67.413, 68.3266, 69.1524, 70.2642, 71.1806, 72.0566, 72.9192, 73.7598, 74.3516, 75.5802, 76.4386, 77.4916, 78.1524, 79.1892, 79.8414, 80.8798, 81.8376, 82.4698, 83.7656, 84.331, 85.5914, 86.6012, 87.7016, 88.5582, 89.3394, 90.3544, 91.4912, 92.308, 93.3552, 93.9746, 95.2052, 95.727, 97.1322, 98.3944, 98.7588, 100.242, 101.1914, 102.2538, 102.8776, 103.6292, 105.1932, 105.9152, 107.0868, 107.6728, 108.7144, 110.3114, 110.8716, 111.245,
  112.7908, 113.7064, 114.636, 115.7464, 116.1788, 117.7464, 118.4896, 119.6166, 120.5082, 121.7798, 122.9028, 123.4426, 124.8854, 125.705, 126.4652, 128.3464, 128.3462, 130.0398, 131.0342, 131.0042, 132.4766, 133.511, 134.7252, 135.425, 136.5172, 138.0572, 138.6694, 139.3712, 140.8598, 141.4594, 142.554, 143.4006, 144.7374, 146.1634, 146.8994, 147.605, 147.9304, 149.1636, 150.2468, 151.5876, 152.2096, 153.7032, 154.7146, 155.807, 156.9228, 157.0372, 158.5852,},
++    // precision 6
++    {46, 46.1902, 47.271, 47.8358, 48.8142, 49.2854, 50.317, 51.354, 51.8924, 52.9436, 53.4596, 54.5262, 55.6248, 56.1574, 57.2822, 57.837, 58.9636, 60.074, 60.7042, 61.7976, 62.4772, 63.6564, 64.7942, 65.5004, 66.686, 67.291, 68.5672, 69.8556, 70.4982, 71.8204, 72.4252, 73.7744, 75.0786, 75.8344, 77.0294, 77.8098, 79.0794, 80.5732, 81.1878, 82.5648, 83.2902, 84.6784, 85.3352, 86.8946, 88.3712, 89.0852, 90.499, 91.2686, 92.6844, 94.2234, 94.9732, 96.3356, 97.2286, 98.7262, 100.3284, 101.1048, 102.5962, 103.3562, 105.1272, 106.4184, 107.4974, 109.0822, 109.856, 111.48, 113.2834, 114.0208, 115.637, 116.5174, 118.0576, 119.7476, 120.427, 122.1326, 123.2372, 125.2788, 126.6776, 127.7926, 129.1952, 129.9564, 131.6454, 133.87, 134.5428, 136.2, 137.0294, 138.6278, 139.6782, 141.792, 143.3516, 144.2832, 146.0394, 147.0748, 148.4912, 150.849, 151.696, 153.5404, 154.073, 156.3714, 157.7216, 158.7328, 160.4208, 161.4184, 163.9424, 165.2772, 166.411, 168.1308, 168.769, 170.9258, 172.6828, 173.
 7502, 175.706, 176.3886, 179.0186, 180.4518, 181.927, 183.4172, 184.4114, 186.033, 188.5124, 189.5564, 191.6008, 192.4172, 193.8044, 194.997, 197.4548, 198.8948, 200.2346, 202.3086, 203.1548, 204.8842, 206.6508, 206.6772, 209.7254, 210.4752, 212.7228, 214.6614, 215.1676, 217.793, 218.0006, 219.9052, 221.66, 223.5588, 225.1636, 225.6882, 227.7126, 229.4502, 231.1978, 232.9756, 233.1654, 236.727, 238.1974, 237.7474, 241.1346, 242.3048, 244.1948, 245.3134, 246.879, 249.1204, 249.853, 252.6792, 253.857, 254.4486, 257.2362, 257.9534, 260.0286, 260.5632, 262.663, 264.723, 265.7566, 267.2566, 267.1624, 270.62, 272.8216, 273.2166, 275.2056, 276.2202, 278.3726, 280.3344, 281.9284, 283.9728, 284.1924, 286.4872, 287.587, 289.807, 291.1206, 292.769, 294.8708, 296.665, 297.1182, 299.4012, 300.6352, 302.1354, 304.1756, 306.1606, 307.3462, 308.5214, 309.4134, 310.8352, 313.9684, 315.837, 316.7796, 318.9858,},
++    // precision 7
++    {92, 93.4934, 94.9758, 96.4574, 97.9718, 99.4954, 101.5302, 103.0756, 104.6374, 106.1782, 107.7888, 109.9522, 111.592, 113.2532, 114.9086, 116.5938, 118.9474, 120.6796, 122.4394, 124.2176, 125.9768, 128.4214, 130.2528, 132.0102, 133.8658, 135.7278, 138.3044, 140.1316, 142.093, 144.0032, 145.9092, 148.6306, 150.5294, 152.5756, 154.6508, 156.662, 159.552, 161.3724, 163.617, 165.5754, 167.7872, 169.8444, 172.7988, 174.8606, 177.2118, 179.3566, 181.4476, 184.5882, 186.6816, 189.0824, 191.0258, 193.6048, 196.4436, 198.7274, 200.957, 203.147, 205.4364, 208.7592, 211.3386, 213.781, 215.8028, 218.656, 221.6544, 223.996, 226.4718, 229.1544, 231.6098, 234.5956, 237.0616, 239.5758, 242.4878, 244.5244, 248.2146, 250.724, 252.8722, 255.5198, 258.0414, 261.941, 264.9048, 266.87, 269.4304, 272.028, 274.4708, 278.37, 281.0624, 283.4668, 286.5532, 289.4352, 293.2564, 295.2744, 298.2118, 300.7472, 304.1456, 307.2928, 309.7504, 312.5528, 315.979, 318.2102, 322.1834, 324.3494, 327.325, 330.6614, 3
 32.903, 337.2544, 339.9042, 343.215, 345.2864, 348.0814, 352.6764, 355.301, 357.139, 360.658, 363.1732, 366.5902, 369.9538, 373.0828, 375.922, 378.9902, 382.7328, 386.4538, 388.1136, 391.2234, 394.0878, 396.708, 401.1556, 404.1852, 406.6372, 409.6822, 412.7796, 416.6078, 418.4916, 422.131, 424.5376, 428.1988, 432.211, 434.4502, 438.5282, 440.912, 444.0448, 447.7432, 450.8524, 453.7988, 456.7858, 458.8868, 463.9886, 466.5064, 468.9124, 472.6616, 475.4682, 478.582, 481.304, 485.2738, 488.6894, 490.329, 496.106, 497.6908, 501.1374, 504.5322, 506.8848, 510.3324, 513.4512, 516.179, 520.4412, 522.6066, 526.167, 528.7794, 533.379, 536.067, 538.46, 542.9116, 545.692, 547.9546, 552.493, 555.2722, 557.335, 562.449, 564.2014, 569.0738, 571.0974, 574.8564, 578.2996, 581.409, 583.9704, 585.8098, 589.6528, 594.5998, 595.958, 600.068, 603.3278, 608.2016, 609.9632, 612.864, 615.43, 620.7794, 621.272, 625.8644, 629.206, 633.219, 634.5154, 638.6102,},
++    // precision 8
++    {184.2152, 187.2454, 190.2096, 193.6652, 196.6312, 199.6822, 203.249, 206.3296, 210.0038, 213.2074, 216.4612, 220.27, 223.5178, 227.4412, 230.8032, 234.1634, 238.1688, 241.6074, 245.6946, 249.2664, 252.8228, 257.0432, 260.6824, 264.9464, 268.6268, 272.2626, 276.8376, 280.4034, 284.8956, 288.8522, 292.7638, 297.3552, 301.3556, 305.7526, 309.9292, 313.8954, 318.8198, 322.7668, 327.298, 331.6688, 335.9466, 340.9746, 345.1672, 349.3474, 354.3028, 358.8912, 364.114, 368.4646, 372.9744, 378.4092, 382.6022, 387.843, 392.5684, 397.1652, 402.5426, 407.4152, 412.5388, 417.3592, 422.1366, 427.486, 432.3918, 437.5076, 442.509, 447.3834, 453.3498, 458.0668, 463.7346, 469.1228, 473.4528, 479.7, 484.644, 491.0518, 495.5774, 500.9068, 506.432, 512.1666, 517.434, 522.6644, 527.4894, 533.6312, 538.3804, 544.292, 550.5496, 556.0234, 562.8206, 566.6146, 572.4188, 579.117, 583.6762, 590.6576, 595.7864, 601.509, 607.5334, 612.9204, 619.772, 624.2924, 630.8654, 636.1836, 642.745, 649.1316, 655.0386, 
 660.0136, 666.6342, 671.6196, 678.1866, 684.4282, 689.3324, 695.4794, 702.5038, 708.129, 713.528, 720.3204, 726.463, 732.7928, 739.123, 744.7418, 751.2192, 756.5102, 762.6066, 769.0184, 775.2224, 781.4014, 787.7618, 794.1436, 798.6506, 805.6378, 811.766, 819.7514, 824.5776, 828.7322, 837.8048, 843.6302, 849.9336, 854.4798, 861.3388, 867.9894, 873.8196, 880.3136, 886.2308, 892.4588, 899.0816, 905.4076, 912.0064, 917.3878, 923.619, 929.998, 937.3482, 943.9506, 947.991, 955.1144, 962.203, 968.8222, 975.7324, 981.7826, 988.7666, 994.2648, 1000.3128, 1007.4082, 1013.7536, 1020.3376, 1026.7156, 1031.7478, 1037.4292, 1045.393, 1051.2278, 1058.3434, 1062.8726, 1071.884, 1076.806, 1082.9176, 1089.1678, 1095.5032, 1102.525, 1107.2264, 1115.315, 1120.93, 1127.252, 1134.1496, 1139.0408, 1147.5448, 1153.3296, 1158.1974, 1166.5262, 1174.3328, 1175.657, 1184.4222, 1190.9172, 1197.1292, 1204.4606, 1210.4578, 1218.8728, 1225.3336, 1226.6592, 1236.5768, 1241.363, 1249.4074, 1254.6566, 1260.8014, 1266
 .5454, 1274.5192,},
++    // precision 9
++    {369, 374.8294, 381.2452, 387.6698, 394.1464, 400.2024, 406.8782, 413.6598, 420.462, 427.2826, 433.7102, 440.7416, 447.9366, 455.1046, 462.285, 469.0668, 476.306, 483.8448, 491.301, 498.9886, 506.2422, 513.8138, 521.7074, 529.7428, 537.8402, 545.1664, 553.3534, 561.594, 569.6886, 577.7876, 585.65, 594.228, 602.8036, 611.1666, 620.0818, 628.0824, 637.2574, 646.302, 655.1644, 664.0056, 672.3802, 681.7192, 690.5234, 700.2084, 708.831, 718.485, 728.1112, 737.4764, 746.76, 756.3368, 766.5538, 775.5058, 785.2646, 795.5902, 804.3818, 814.8998, 824.9532, 835.2062, 845.2798, 854.4728, 864.9582, 875.3292, 886.171, 896.781, 906.5716, 916.7048, 927.5322, 937.875, 949.3972, 958.3464, 969.7274, 980.2834, 992.1444, 1003.4264, 1013.0166, 1024.018, 1035.0438, 1046.34, 1057.6856, 1068.9836, 1079.0312, 1091.677, 1102.3188, 1113.4846, 1124.4424, 1135.739, 1147.1488, 1158.9202, 1169.406, 1181.5342, 1193.2834, 1203.8954, 1216.3286, 1226.2146, 1239.6684, 1251.9946, 1262.123, 1275.4338, 1285.7378, 129
 6.076, 1308.9692, 1320.4964, 1333.0998, 1343.9864, 1357.7754, 1368.3208, 1380.4838, 1392.7388, 1406.0758, 1416.9098, 1428.9728, 1440.9228, 1453.9292, 1462.617, 1476.05, 1490.2996, 1500.6128, 1513.7392, 1524.5174, 1536.6322, 1548.2584, 1562.3766, 1572.423, 1587.1232, 1596.5164, 1610.5938, 1622.5972, 1633.1222, 1647.7674, 1658.5044, 1671.57, 1683.7044, 1695.4142, 1708.7102, 1720.6094, 1732.6522, 1747.841, 1756.4072, 1769.9786, 1782.3276, 1797.5216, 1808.3186, 1819.0694, 1834.354, 1844.575, 1856.2808, 1871.1288, 1880.7852, 1893.9622, 1906.3418, 1920.6548, 1932.9302, 1945.8584, 1955.473, 1968.8248, 1980.6446, 1995.9598, 2008.349, 2019.8556, 2033.0334, 2044.0206, 2059.3956, 2069.9174, 2082.6084, 2093.7036, 2106.6108, 2118.9124, 2132.301, 2144.7628, 2159.8422, 2171.0212, 2183.101, 2193.5112, 2208.052, 2221.3194, 2233.3282, 2247.295, 2257.7222, 2273.342, 2286.5638, 2299.6786, 2310.8114, 2322.3312, 2335.516, 2349.874, 2363.5968, 2373.865, 2387.1918, 2401.8328, 2414.8496, 2424.544, 2436.7592
 , 2447.1682, 2464.1958, 2474.3438, 2489.0006, 2497.4526, 2513.6586, 2527.19, 2540.7028, 2553.768,},
++    // precision 10
++    {738.1256, 750.4234, 763.1064, 775.4732, 788.4636, 801.0644, 814.488, 827.9654, 841.0832, 854.7864, 868.1992, 882.2176, 896.5228, 910.1716, 924.7752, 938.899, 953.6126, 968.6492, 982.9474, 998.5214, 1013.1064, 1028.6364, 1044.2468, 1059.4588, 1075.3832, 1091.0584, 1106.8606, 1123.3868, 1139.5062, 1156.1862, 1172.463, 1189.339, 1206.1936, 1223.1292, 1240.1854, 1257.2908, 1275.3324, 1292.8518, 1310.5204, 1328.4854, 1345.9318, 1364.552, 1381.4658, 1400.4256, 1419.849, 1438.152, 1456.8956, 1474.8792, 1494.118, 1513.62, 1532.5132, 1551.9322, 1570.7726, 1590.6086, 1610.5332, 1630.5918, 1650.4294, 1669.7662, 1690.4106, 1710.7338, 1730.9012, 1750.4486, 1770.1556, 1791.6338, 1812.7312, 1833.6264, 1853.9526, 1874.8742, 1896.8326, 1918.1966, 1939.5594, 1961.07, 1983.037, 2003.1804, 2026.071, 2047.4884, 2070.0848, 2091.2944, 2114.333, 2135.9626, 2158.2902, 2181.0814, 2202.0334, 2224.4832, 2246.39, 2269.7202, 2292.1714, 2314.2358, 2338.9346, 2360.891, 2384.0264, 2408.3834, 2430.1544, 2454.8
 684, 2476.9896, 2501.4368, 2522.8702, 2548.0408, 2570.6738, 2593.5208, 2617.0158, 2640.2302, 2664.0962, 2687.4986, 2714.2588, 2735.3914, 2759.6244, 2781.8378, 2808.0072, 2830.6516, 2856.2454, 2877.2136, 2903.4546, 2926.785, 2951.2294, 2976.468, 3000.867, 3023.6508, 3049.91, 3073.5984, 3098.162, 3121.5564, 3146.2328, 3170.9484, 3195.5902, 3221.3346, 3242.7032, 3271.6112, 3296.5546, 3317.7376, 3345.072, 3369.9518, 3394.326, 3418.1818, 3444.6926, 3469.086, 3494.2754, 3517.8698, 3544.248, 3565.3768, 3588.7234, 3616.979, 3643.7504, 3668.6812, 3695.72, 3719.7392, 3742.6224, 3770.4456, 3795.6602, 3819.9058, 3844.002, 3869.517, 3895.6824, 3920.8622, 3947.1364, 3973.985, 3995.4772, 4021.62, 4046.628, 4074.65, 4096.2256, 4121.831, 4146.6406, 4173.276, 4195.0744, 4223.9696, 4251.3708, 4272.9966, 4300.8046, 4326.302, 4353.1248, 4374.312, 4403.0322, 4426.819, 4450.0598, 4478.5206, 4504.8116, 4528.8928, 4553.9584, 4578.8712, 4603.8384, 4632.3872, 4655.5128, 4675.821, 4704.6222, 4731.9862, 4755.41
 74, 4781.2628, 4804.332, 4832.3048, 4862.8752, 4883.4148, 4906.9544, 4935.3516, 4954.3532, 4984.0248, 5011.217, 5035.3258, 5057.3672, 5084.1828,},
++    // precision 11
++    {1477, 1501.6014, 1526.5802, 1551.7942, 1577.3042, 1603.2062, 1629.8402, 1656.2292, 1682.9462, 1709.9926, 1737.3026, 1765.4252, 1793.0578, 1821.6092, 1849.626, 1878.5568, 1908.527, 1937.5154, 1967.1874, 1997.3878, 2027.37, 2058.1972, 2089.5728, 2120.1012, 2151.9668, 2183.292, 2216.0772, 2247.8578, 2280.6562, 2313.041, 2345.714, 2380.3112, 2414.1806, 2447.9854, 2481.656, 2516.346, 2551.5154, 2586.8378, 2621.7448, 2656.6722, 2693.5722, 2729.1462, 2765.4124, 2802.8728, 2838.898, 2876.408, 2913.4926, 2951.4938, 2989.6776, 3026.282, 3065.7704, 3104.1012, 3143.7388, 3181.6876, 3221.1872, 3261.5048, 3300.0214, 3339.806, 3381.409, 3421.4144, 3461.4294, 3502.2286, 3544.651, 3586.6156, 3627.337, 3670.083, 3711.1538, 3753.5094, 3797.01, 3838.6686, 3882.1678, 3922.8116, 3967.9978, 4009.9204, 4054.3286, 4097.5706, 4140.6014, 4185.544, 4229.5976, 4274.583, 4316.9438, 4361.672, 4406.2786, 4451.8628, 4496.1834, 4543.505, 4589.1816, 4632.5188, 4678.2294, 4724.8908, 4769.0194, 4817.052, 4861.458
 8, 4910.1596, 4956.4344, 5002.5238, 5048.13, 5093.6374, 5142.8162, 5187.7894, 5237.3984, 5285.6078, 5331.0858, 5379.1036, 5428.6258, 5474.6018, 5522.7618, 5571.5822, 5618.59, 5667.9992, 5714.88, 5763.454, 5808.6982, 5860.3644, 5910.2914, 5953.571, 6005.9232, 6055.1914, 6104.5882, 6154.5702, 6199.7036, 6251.1764, 6298.7596, 6350.0302, 6398.061, 6448.4694, 6495.933, 6548.0474, 6597.7166, 6646.9416, 6695.9208, 6742.6328, 6793.5276, 6842.1934, 6894.2372, 6945.3864, 6996.9228, 7044.2372, 7094.1374, 7142.2272, 7192.2942, 7238.8338, 7288.9006, 7344.0908, 7394.8544, 7443.5176, 7490.4148, 7542.9314, 7595.6738, 7641.9878, 7694.3688, 7743.0448, 7797.522, 7845.53, 7899.594, 7950.3132, 7996.455, 8050.9442, 8092.9114, 8153.1374, 8197.4472, 8252.8278, 8301.8728, 8348.6776, 8401.4698, 8453.551, 8504.6598, 8553.8944, 8604.1276, 8657.6514, 8710.3062, 8758.908, 8807.8706, 8862.1702, 8910.4668, 8960.77, 9007.2766, 9063.164, 9121.0534, 9164.1354, 9218.1594, 9267.767, 9319.0594, 9372.155, 9419.7126, 9474
 .3722, 9520.1338, 9572.368, 9622.7702, 9675.8448, 9726.5396, 9778.7378, 9827.6554, 9878.1922, 9928.7782, 9978.3984, 10026.578, 10076.5626, 10137.1618, 10177.5244, 10229.9176,},
++    // precision 12
++    {2954, 3003.4782, 3053.3568, 3104.3666, 3155.324, 3206.9598, 3259.648, 3312.539, 3366.1474, 3420.2576, 3474.8376, 3530.6076, 3586.451, 3643.38, 3700.4104, 3757.5638, 3815.9676, 3875.193, 3934.838, 3994.8548, 4055.018, 4117.1742, 4178.4482, 4241.1294, 4304.4776, 4367.4044, 4431.8724, 4496.3732, 4561.4304, 4627.5326, 4693.949, 4761.5532, 4828.7256, 4897.6182, 4965.5186, 5034.4528, 5104.865, 5174.7164, 5244.6828, 5316.6708, 5387.8312, 5459.9036, 5532.476, 5604.8652, 5679.6718, 5753.757, 5830.2072, 5905.2828, 5980.0434, 6056.6264, 6134.3192, 6211.5746, 6290.0816, 6367.1176, 6447.9796, 6526.5576, 6606.1858, 6686.9144, 6766.1142, 6847.0818, 6927.9664, 7010.9096, 7091.0816, 7175.3962, 7260.3454, 7344.018, 7426.4214, 7511.3106, 7596.0686, 7679.8094, 7765.818, 7852.4248, 7936.834, 8022.363, 8109.5066, 8200.4554, 8288.5832, 8373.366, 8463.4808, 8549.7682, 8642.0522, 8728.3288, 8820.9528, 8907.727, 9001.0794, 9091.2522, 9179.988, 9269.852, 9362.6394, 9453.642, 9546.9024, 9640.6616, 9732.6
 622, 9824.3254, 9917.7484, 10007.9392, 10106.7508, 10196.2152, 10289.8114, 10383.5494, 10482.3064, 10576.8734, 10668.7872, 10764.7156, 10862.0196, 10952.793, 11049.9748, 11146.0702, 11241.4492, 11339.2772, 11434.2336, 11530.741, 11627.6136, 11726.311, 11821.5964, 11918.837, 12015.3724, 12113.0162, 12213.0424, 12306.9804, 12408.4518, 12504.8968, 12604.586, 12700.9332, 12798.705, 12898.5142, 12997.0488, 13094.788, 13198.475, 13292.7764, 13392.9698, 13486.8574, 13590.1616, 13686.5838, 13783.6264, 13887.2638, 13992.0978, 14081.0844, 14189.9956, 14280.0912, 14382.4956, 14486.4384, 14588.1082, 14686.2392, 14782.276, 14888.0284, 14985.1864, 15088.8596, 15187.0998, 15285.027, 15383.6694, 15495.8266, 15591.3736, 15694.2008, 15790.3246, 15898.4116, 15997.4522, 16095.5014, 16198.8514, 16291.7492, 16402.6424, 16499.1266, 16606.2436, 16697.7186, 16796.3946, 16902.3376, 17005.7672, 17100.814, 17206.8282, 17305.8262, 17416.0744, 17508.4092, 17617.0178, 17715.4554, 17816.758, 17920.1748, 18012.9236
 , 18119.7984, 18223.2248, 18324.2482, 18426.6276, 18525.0932, 18629.8976, 18733.2588, 18831.0466, 18940.1366, 19032.2696, 19131.729, 19243.4864, 19349.6932, 19442.866, 19547.9448, 19653.2798, 19754.4034, 19854.0692, 19965.1224, 20065.1774, 20158.2212, 20253.353, 20366.3264, 20463.22,},
++    // precision 13
++    {5908.5052, 6007.2672, 6107.347, 6208.5794, 6311.2622, 6414.5514, 6519.3376, 6625.6952, 6732.5988, 6841.3552, 6950.5972, 7061.3082, 7173.5646, 7287.109, 7401.8216, 7516.4344, 7633.3802, 7751.2962, 7870.3784, 7990.292, 8110.79, 8233.4574, 8356.6036, 8482.2712, 8607.7708, 8735.099, 8863.1858, 8993.4746, 9123.8496, 9255.6794, 9388.5448, 9522.7516, 9657.3106, 9792.6094, 9930.5642, 10068.794, 10206.7256, 10347.81, 10490.3196, 10632.0778, 10775.9916, 10920.4662, 11066.124, 11213.073, 11358.0362, 11508.1006, 11659.1716, 11808.7514, 11959.4884, 12112.1314, 12265.037, 12420.3756, 12578.933, 12734.311, 12890.0006, 13047.2144, 13207.3096, 13368.5144, 13528.024, 13689.847, 13852.7528, 14018.3168, 14180.5372, 14346.9668, 14513.5074, 14677.867, 14846.2186, 15017.4186, 15184.9716, 15356.339, 15529.2972, 15697.3578, 15871.8686, 16042.187, 16216.4094, 16389.4188, 16565.9126, 16742.3272, 16919.0042, 17094.7592, 17273.965, 17451.8342, 17634.4254, 17810.5984, 17988.9242, 18171.051, 18354.7938, 185
 39.466, 18721.0408, 18904.9972, 19081.867, 19271.9118, 19451.8694, 19637.9816, 19821.2922, 20013.1292, 20199.3858, 20387.8726, 20572.9514, 20770.7764, 20955.1714, 21144.751, 21329.9952, 21520.709, 21712.7016, 21906.3868, 22096.2626, 22286.0524, 22475.051, 22665.5098, 22862.8492, 23055.5294, 23249.6138, 23437.848, 23636.273, 23826.093, 24020.3296, 24213.3896, 24411.7392, 24602.9614, 24805.7952, 24998.1552, 25193.9588, 25389.0166, 25585.8392, 25780.6976, 25981.2728, 26175.977, 26376.5252, 26570.1964, 26773.387, 26962.9812, 27163.0586, 27368.164, 27565.0534, 27758.7428, 27961.1276, 28163.2324, 28362.3816, 28565.7668, 28758.644, 28956.9768, 29163.4722, 29354.7026, 29561.1186, 29767.9948, 29959.9986, 30164.0492, 30366.9818, 30562.5338, 30762.9928, 30976.1592, 31166.274, 31376.722, 31570.3734, 31770.809, 31974.8934, 32179.5286, 32387.5442, 32582.3504, 32794.076, 32989.9528, 33191.842, 33392.4684, 33595.659, 33801.8672, 34000.3414, 34200.0922, 34402.6792, 34610.0638, 34804.0084, 35011.13, 
 35218.669, 35418.6634, 35619.0792, 35830.6534, 36028.4966, 36229.7902, 36438.6422, 36630.7764, 36833.3102, 37048.6728, 37247.3916, 37453.5904, 37669.3614, 37854.5526, 38059.305, 38268.0936, 38470.2516, 38674.7064, 38876.167, 39068.3794, 39281.9144, 39492.8566, 39684.8628, 39898.4108, 40093.1836, 40297.6858, 40489.7086, 40717.2424,},
++    // precision 14
++    {11817.475, 12015.0046, 12215.3792, 12417.7504, 12623.1814, 12830.0086, 13040.0072, 13252.503, 13466.178, 13683.2738, 13902.0344, 14123.9798, 14347.394, 14573.7784, 14802.6894, 15033.6824, 15266.9134, 15502.8624, 15741.4944, 15980.7956, 16223.8916, 16468.6316, 16715.733, 16965.5726, 17217.204, 17470.666, 17727.8516, 17986.7886, 18247.6902, 18510.9632, 18775.304, 19044.7486, 19314.4408, 19587.202, 19862.2576, 20135.924, 20417.0324, 20697.9788, 20979.6112, 21265.0274, 21550.723, 21841.6906, 22132.162, 22428.1406, 22722.127, 23020.5606, 23319.7394, 23620.4014, 23925.2728, 24226.9224, 24535.581, 24845.505, 25155.9618, 25470.3828, 25785.9702, 26103.7764, 26420.4132, 26742.0186, 27062.8852, 27388.415, 27714.6024, 28042.296, 28365.4494, 28701.1526, 29031.8008, 29364.2156, 29704.497, 30037.1458, 30380.111, 30723.8168, 31059.5114, 31404.9498, 31751.6752, 32095.2686, 32444.7792, 32794.767, 33145.204, 33498.4226, 33847.6502, 34209.006, 34560.849, 34919.4838, 35274.9778, 35635.1322, 35996.
 3266, 36359.1394, 36722.8266, 37082.8516, 37447.7354, 37815.9606, 38191.0692, 38559.4106, 38924.8112, 39294.6726, 39663.973, 40042.261, 40416.2036, 40779.2036, 41161.6436, 41540.9014, 41921.1998, 42294.7698, 42678.5264, 43061.3464, 43432.375, 43818.432, 44198.6598, 44583.0138, 44970.4794, 45353.924, 45729.858, 46118.2224, 46511.5724, 46900.7386, 47280.6964, 47668.1472, 48055.6796, 48446.9436, 48838.7146, 49217.7296, 49613.7796, 50010.7508, 50410.0208, 50793.7886, 51190.2456, 51583.1882, 51971.0796, 52376.5338, 52763.319, 53165.5534, 53556.5594, 53948.2702, 54346.352, 54748.7914, 55138.577, 55543.4824, 55941.1748, 56333.7746, 56745.1552, 57142.7944, 57545.2236, 57935.9956, 58348.5268, 58737.5474, 59158.5962, 59542.6896, 59958.8004, 60349.3788, 60755.0212, 61147.6144, 61548.194, 61946.0696, 62348.6042, 62763.603, 63162.781, 63560.635, 63974.3482, 64366.4908, 64771.5876, 65176.7346, 65597.3916, 65995.915, 66394.0384, 66822.9396, 67203.6336, 67612.2032, 68019.0078, 68420.0388, 68821.22,
  69235.8388, 69640.0724, 70055.155, 70466.357, 70863.4266, 71276.2482, 71677.0306, 72080.2006, 72493.0214, 72893.5952, 73314.5856, 73714.9852, 74125.3022, 74521.2122, 74933.6814, 75341.5904, 75743.0244, 76166.0278, 76572.1322, 76973.1028, 77381.6284, 77800.6092, 78189.328, 78607.0962, 79012.2508, 79407.8358, 79825.725, 80238.701, 80646.891, 81035.6436, 81460.0448, 81876.3884,},
++    // precision 15
++    {23635.0036, 24030.8034, 24431.4744, 24837.1524, 25246.7928, 25661.326, 26081.3532, 26505.2806, 26933.9892, 27367.7098, 27805.318, 28248.799, 28696.4382, 29148.8244, 29605.5138, 30066.8668, 30534.2344, 31006.32, 31480.778, 31962.2418, 32447.3324, 32938.0232, 33432.731, 33930.728, 34433.9896, 34944.1402, 35457.5588, 35974.5958, 36497.3296, 37021.9096, 37554.326, 38088.0826, 38628.8816, 39171.3192, 39723.2326, 40274.5554, 40832.3142, 41390.613, 41959.5908, 42532.5466, 43102.0344, 43683.5072, 44266.694, 44851.2822, 45440.7862, 46038.0586, 46640.3164, 47241.064, 47846.155, 48454.7396, 49076.9168, 49692.542, 50317.4778, 50939.65, 51572.5596, 52210.2906, 52843.7396, 53481.3996, 54127.236, 54770.406, 55422.6598, 56078.7958, 56736.7174, 57397.6784, 58064.5784, 58730.308, 59404.9784, 60077.0864, 60751.9158, 61444.1386, 62115.817, 62808.7742, 63501.4774, 64187.5454, 64883.6622, 65582.7468, 66274.5318, 66976.9276, 67688.7764, 68402.138, 69109.6274, 69822.9706, 70543.6108, 71265.5202, 7198
 3.3848, 72708.4656, 73433.384, 74158.4664, 74896.4868, 75620.9564, 76362.1434, 77098.3204, 77835.7662, 78582.6114, 79323.9902, 80067.8658, 80814.9246, 81567.0136, 82310.8536, 83061.9952, 83821.4096, 84580.8608, 85335.547, 86092.5802, 86851.6506, 87612.311, 88381.2016, 89146.3296, 89907.8974, 90676.846, 91451.4152, 92224.5518, 92995.8686, 93763.5066, 94551.2796, 95315.1944, 96096.1806, 96881.0918, 97665.679, 98442.68, 99229.3002, 100011.0994, 100790.6386, 101580.1564, 102377.7484, 103152.1392, 103944.2712, 104730.216, 105528.6336, 106324.9398, 107117.6706, 107890.3988, 108695.2266, 109485.238, 110294.7876, 111075.0958, 111878.0496, 112695.2864, 113464.5486, 114270.0474, 115068.608, 115884.3626, 116673.2588, 117483.3716, 118275.097, 119085.4092, 119879.2808, 120687.5868, 121499.9944, 122284.916, 123095.9254, 123912.5038, 124709.0454, 125503.7182, 126323.259, 127138.9412, 127943.8294, 128755.646, 129556.5354, 130375.3298, 131161.4734, 131971.1962, 132787.5458, 133588.1056, 134431.351, 
 135220.2906, 136023.398, 136846.6558, 137667.0004, 138463.663, 139283.7154, 140074.6146, 140901.3072, 141721.8548, 142543.2322, 143356.1096, 144173.7412, 144973.0948, 145794.3162, 146609.5714, 147420.003, 148237.9784, 149050.5696, 149854.761, 150663.1966, 151494.0754, 152313.1416, 153112.6902, 153935.7206, 154746.9262, 155559.547, 156401.9746, 157228.7036, 158008.7254, 158820.75, 159646.9184, 160470.4458, 161279.5348, 162093.3114, 162918.542, 163729.2842,},
++    // precision 16
++    {47271, 48062.3584, 48862.7074, 49673.152, 50492.8416, 51322.9514, 52161.03, 53009.407, 53867.6348, 54734.206, 55610.5144, 56496.2096, 57390.795, 58297.268, 59210.6448, 60134.665, 61068.0248, 62010.4472, 62962.5204, 63923.5742, 64895.0194, 65876.4182, 66862.6136, 67862.6968, 68868.8908, 69882.8544, 70911.271, 71944.0924, 72990.0326, 74040.692, 75100.6336, 76174.7826, 77252.5998, 78340.2974, 79438.2572, 80545.4976, 81657.2796, 82784.6336, 83915.515, 85059.7362, 86205.9368, 87364.4424, 88530.3358, 89707.3744, 90885.9638, 92080.197, 93275.5738, 94479.391, 95695.918, 96919.2236, 98148.4602, 99382.3474, 100625.6974, 101878.0284, 103141.6278, 104409.4588, 105686.2882, 106967.5402, 108261.6032, 109548.1578, 110852.0728, 112162.231, 113479.0072, 114806.2626, 116137.9072, 117469.5048, 118813.5186, 120165.4876, 121516.2556, 122875.766, 124250.5444, 125621.2222, 127003.2352, 128387.848, 129775.2644, 131181.7776, 132577.3086, 133979.9458, 135394.1132, 136800.9078, 138233.217, 139668.5308, 
 141085.212, 142535.2122, 143969.0684, 145420.2872, 146878.1542, 148332.7572, 149800.3202, 151269.66, 152743.6104, 154213.0948, 155690.288, 157169.4246, 158672.1756, 160160.059, 161650.6854, 163145.7772, 164645.6726, 166159.1952, 167682.1578, 169177.3328, 170700.0118, 172228.8964, 173732.6664, 175265.5556, 176787.799, 178317.111, 179856.6914, 181400.865, 182943.4612, 184486.742, 186033.4698, 187583.7886, 189148.1868, 190688.4526, 192250.1926, 193810.9042, 195354.2972, 196938.7682, 198493.5898, 200079.2824, 201618.912, 203205.5492, 204765.5798, 206356.1124, 207929.3064, 209498.7196, 211086.229, 212675.1324, 214256.7892, 215826.2392, 217412.8474, 218995.6724, 220618.6038, 222207.1166, 223781.0364, 225387.4332, 227005.7928, 228590.4336, 230217.8738, 231805.1054, 233408.9, 234995.3432, 236601.4956, 238190.7904, 239817.2548, 241411.2832, 243002.4066, 244640.1884, 246255.3128, 247849.3508, 249479.9734, 251106.8822, 252705.027, 254332.9242, 255935.129, 257526.9014, 259154.772, 260777.625, 2
 62390.253, 264004.4906, 265643.59, 267255.4076, 268873.426, 270470.7252, 272106.4804, 273722.4456, 275337.794, 276945.7038, 278592.9154, 280204.3726, 281841.1606, 283489.171, 285130.1716, 286735.3362, 288364.7164, 289961.1814, 291595.5524, 293285.683, 294899.6668, 296499.3434, 298128.0462, 299761.8946, 301394.2424, 302997.6748, 304615.1478, 306269.7724, 307886.114, 309543.1028, 311153.2862, 312782.8546, 314421.2008, 316033.2438, 317692.9636, 319305.2648, 320948.7406, 322566.3364, 324228.4224, 325847.1542,},
++    // precision 17
++    {94542, 96125.811, 97728.019, 99348.558, 100987.9705, 102646.7565, 104324.5125, 106021.7435, 107736.7865, 109469.272, 111223.9465, 112995.219, 114787.432, 116593.152, 118422.71, 120267.2345, 122134.6765, 124020.937, 125927.2705, 127851.255, 129788.9485, 131751.016, 133726.8225, 135722.592, 137736.789, 139770.568, 141821.518, 143891.343, 145982.1415, 148095.387, 150207.526, 152355.649, 154515.6415, 156696.05, 158887.7575, 161098.159, 163329.852, 165569.053, 167837.4005, 170121.6165, 172420.4595, 174732.6265, 177062.77, 179412.502, 181774.035, 184151.939, 186551.6895, 188965.691, 191402.8095, 193857.949, 196305.0775, 198774.6715, 201271.2585, 203764.78, 206299.3695, 208818.1365, 211373.115, 213946.7465, 216532.076, 219105.541, 221714.5375, 224337.5135, 226977.5125, 229613.0655, 232270.2685, 234952.2065, 237645.3555, 240331.1925, 243034.517, 245756.0725, 248517.6865, 251232.737, 254011.3955, 256785.995, 259556.44, 262368.335, 265156.911, 267965.266, 270785.583, 273616.0495, 276487
 .4835, 279346.639, 282202.509, 285074.3885, 287942.2855, 290856.018, 293774.0345, 296678.5145, 299603.6355, 302552.6575, 305492.9785, 308466.8605, 311392.581, 314347.538, 317319.4295, 320285.9785, 323301.7325, 326298.3235, 329301.3105, 332301.987, 335309.791, 338370.762, 341382.923, 344431.1265, 347464.1545, 350507.28, 353619.2345, 356631.2005, 359685.203, 362776.7845, 365886.488, 368958.2255, 372060.6825, 375165.4335, 378237.935, 381328.311, 384430.5225, 387576.425, 390683.242, 393839.648, 396977.8425, 400101.9805, 403271.296, 406409.8425, 409529.5485, 412678.7, 415847.423, 419020.8035, 422157.081, 425337.749, 428479.6165, 431700.902, 434893.1915, 438049.582, 441210.5415, 444379.2545, 447577.356, 450741.931, 453959.548, 457137.0935, 460329.846, 463537.4815, 466732.3345, 469960.5615, 473164.681, 476347.6345, 479496.173, 482813.1645, 486025.6995, 489249.4885, 492460.1945, 495675.8805, 498908.0075, 502131.802, 505374.3855, 508550.9915, 511806.7305, 515026.776, 518217.0005, 521523.9855
 , 524705.9855, 527950.997, 531210.0265, 534472.497, 537750.7315, 540926.922, 544207.094, 547429.4345, 550666.3745, 553975.3475, 557150.7185, 560399.6165, 563662.697, 566916.7395, 570146.1215, 573447.425, 576689.6245, 579874.5745, 583202.337, 586503.0255, 589715.635, 592910.161, 596214.3885, 599488.035, 602740.92, 605983.0685, 609248.67, 612491.3605, 615787.912, 619107.5245, 622307.9555, 625577.333, 628840.4385, 632085.2155, 635317.6135, 638691.7195, 641887.467, 645139.9405, 648441.546, 651666.252, 654941.845,},
++    // precision 18
++    {189084, 192250.913, 195456.774, 198696.946, 201977.762, 205294.444, 208651.754, 212042.099, 215472.269, 218941.91, 222443.912, 225996.845, 229568.199, 233193.568, 236844.457, 240543.233, 244279.475, 248044.27, 251854.588, 255693.2, 259583.619, 263494.621, 267445.385, 271454.061, 275468.769, 279549.456, 283646.446, 287788.198, 291966.099, 296181.164, 300431.469, 304718.618, 309024.004, 313393.508, 317760.803, 322209.731, 326675.061, 331160.627, 335654.47, 340241.442, 344841.833, 349467.132, 354130.629, 358819.432, 363574.626, 368296.587, 373118.482, 377914.93, 382782.301, 387680.669, 392601.981, 397544.323, 402529.115, 407546.018, 412593.658, 417638.657, 422762.865, 427886.169, 433017.167, 438213.273, 443441.254, 448692.421, 453937.533, 459239.049, 464529.569, 469910.083, 475274.03, 480684.473, 486070.26, 491515.237, 496995.651, 502476.617, 507973.609, 513497.19, 519083.233, 524726.509, 530305.505, 535945.728, 541584.404, 547274.055, 552967.236, 558667.862, 564360.216, 570128.1
 48, 575965.08, 581701.952, 587532.523, 593361.144, 599246.128, 605033.418, 610958.779, 616837.117, 622772.818, 628672.04, 634675.369, 640574.831, 646585.739, 652574.547, 658611.217, 664642.684, 670713.914, 676737.681, 682797.313, 688837.897, 694917.874, 701009.882, 707173.648, 713257.254, 719415.392, 725636.761, 731710.697, 737906.209, 744103.074, 750313.39, 756504.185, 762712.579, 768876.985, 775167.859, 781359, 787615.959, 793863.597, 800245.477, 806464.582, 812785.294, 819005.925, 825403.057, 831676.197, 837936.284, 844266.968, 850642.711, 856959.756, 863322.774, 869699.931, 876102.478, 882355.787, 888694.463, 895159.952, 901536.143, 907872.631, 914293.672, 920615.14, 927130.974, 933409.404, 939922.178, 946331.47, 952745.93, 959209.264, 965590.224, 972077.284, 978501.961, 984953.19, 991413.271, 997817.479, 1004222.658, 1010725.676, 1017177.138, 1023612.529, 1030098.236, 1036493.719, 1043112.207, 1049537.036, 1056008.096, 1062476.184, 1068942.337, 1075524.95, 1081932.864, 1088426.
 025, 1094776.005, 1101327.448, 1107901.673, 1114423.639, 1120884.602, 1127324.923, 1133794.24, 1140328.886, 1146849.376, 1153346.682, 1159836.502, 1166478.703, 1172953.304, 1179391.502, 1185950.982, 1192544.052, 1198913.41, 1205430.994, 1212015.525, 1218674.042, 1225121.683, 1231551.101, 1238126.379, 1244673.795, 1251260.649, 1257697.86, 1264320.983, 1270736.319, 1277274.694, 1283804.95, 1290211.514, 1296858.568, 1303455.691,}
++  };
++
++  static final double[][] biasData = {
++    // precision 4
++    {10, 9.717, 9.207, 8.7896, 8.2882, 7.8204, 7.3772, 6.9342, 6.5202, 6.161, 5.7722, 5.4636, 5.0396, 4.6766, 4.3566, 4.0454, 3.7936, 3.4856, 3.2666, 2.9946, 2.766, 2.4692, 2.3638, 2.0764, 1.7864, 1.7602, 1.4814, 1.433, 1.2926, 1.0664, 0.999600000000001, 0.7956, 0.5366, 0.589399999999998, 0.573799999999999, 0.269799999999996, 0.368200000000002, 0.0544000000000011, 0.234200000000001, 0.0108000000000033, -0.203400000000002, -0.0701999999999998, -0.129600000000003, -0.364199999999997, -0.480600000000003, -0.226999999999997, -0.322800000000001, -0.382599999999996, -0.511200000000002, -0.669600000000003, -0.749400000000001, -0.500399999999999, -0.617600000000003, -0.6922, -0.601599999999998, -0.416200000000003, -0.338200000000001, -0.782600000000002, -0.648600000000002, -0.919800000000002, -0.851799999999997, -0.962400000000002, -0.6402, -1.1922, -1.0256, -1.086, -1.21899999999999, -0.819400000000002, -0.940600000000003, -1.1554, -1.2072, -1.1752, -1.16759999999999, -1.14019999999999, -
 1.3754, -1.29859999999999, -1.607, -1.3292, -1.7606,},
++    // precision 5
++    {22, 21.1194, 20.8208, 20.2318, 19.77, 19.2436, 18.7774, 18.2848, 17.8224, 17.3742, 16.9336, 16.503, 16.0494, 15.6292, 15.2124, 14.798, 14.367, 13.9728, 13.5944, 13.217, 12.8438, 12.3696, 12.0956, 11.7044, 11.324, 11.0668, 10.6698, 10.3644, 10.049, 9.6918, 9.4146, 9.082, 8.687, 8.5398, 8.2462, 7.857, 7.6606, 7.4168, 7.1248, 6.9222, 6.6804, 6.447, 6.3454, 5.9594, 5.7636, 5.5776, 5.331, 5.19, 4.9676, 4.7564, 4.5314, 4.4442, 4.3708, 3.9774, 3.9624, 3.8796, 3.755, 3.472, 3.2076, 3.1024, 2.8908, 2.7338, 2.7728, 2.629, 2.413, 2.3266, 2.1524, 2.2642, 2.1806, 2.0566, 1.9192, 1.7598, 1.3516, 1.5802, 1.43859999999999, 1.49160000000001, 1.1524, 1.1892, 0.841399999999993, 0.879800000000003, 0.837599999999995, 0.469800000000006, 0.765600000000006, 0.331000000000003, 0.591399999999993, 0.601200000000006, 0.701599999999999, 0.558199999999999, 0.339399999999998, 0.354399999999998, 0.491200000000006, 0.308000000000007, 0.355199999999996, -0.0254000000000048, 0.205200000000005, -0.27299999999999
 6, 0.132199999999997, 0.394400000000005, -0.241200000000006, 0.242000000000004, 0.191400000000002, 0.253799999999998, -0.122399999999999, -0.370800000000003, 0.193200000000004, -0.0848000000000013, 0.0867999999999967, -0.327200000000005, -0.285600000000002, 0.311400000000006, -0.128399999999999, -0.754999999999995, -0.209199999999996, -0.293599999999998, -0.364000000000004, -0.253600000000006, -0.821200000000005, -0.253600000000006, -0.510400000000004, -0.383399999999995, -0.491799999999998, -0.220200000000006, -0.0972000000000008, -0.557400000000001, -0.114599999999996, -0.295000000000002, -0.534800000000004, 0.346399999999988, -0.65379999999999, 0.0398000000000138, 0.0341999999999985, -0.995800000000003, -0.523400000000009, -0.489000000000004, -0.274799999999999, -0.574999999999989, -0.482799999999997, 0.0571999999999946, -0.330600000000004, -0.628800000000012, -0.140199999999993, -0.540600000000012, -0.445999999999998, -0.599400000000003, -0.262599999999992, 0.163399999999996, -0
 .100599999999986, -0.39500000000001, -1.06960000000001, -0.836399999999998, -0.753199999999993, -0.412399999999991, -0.790400000000005, -0.29679999999999, -0.28540000000001, -0.193000000000012, -0.0772000000000048, -0.962799999999987, -0.414800000000014,},
++    // precision 6
++    {45, 44.1902, 43.271, 42.8358, 41.8142, 41.2854, 40.317, 39.354, 38.8924, 37.9436, 37.4596, 36.5262, 35.6248, 35.1574, 34.2822, 33.837, 32.9636, 32.074, 31.7042, 30.7976, 30.4772, 29.6564, 28.7942, 28.5004, 27.686, 27.291, 26.5672, 25.8556, 25.4982, 24.8204, 24.4252, 23.7744, 23.0786, 22.8344, 22.0294, 21.8098, 21.0794, 20.5732, 20.1878, 19.5648, 19.2902, 18.6784, 18.3352, 17.8946, 17.3712, 17.0852, 16.499, 16.2686, 15.6844, 15.2234, 14.9732, 14.3356, 14.2286, 13.7262, 13.3284, 13.1048, 12.5962, 12.3562, 12.1272, 11.4184, 11.4974, 11.0822, 10.856, 10.48, 10.2834, 10.0208, 9.637, 9.51739999999999, 9.05759999999999, 8.74760000000001, 8.42700000000001, 8.1326, 8.2372, 8.2788, 7.6776, 7.79259999999999, 7.1952, 6.9564, 6.6454, 6.87, 6.5428, 6.19999999999999, 6.02940000000001, 5.62780000000001, 5.6782, 5.792, 5.35159999999999, 5.28319999999999, 5.0394, 5.07480000000001, 4.49119999999999, 4.84899999999999, 4.696, 4.54040000000001, 4.07300000000001, 4.37139999999999, 3.7216, 3.7328, 3.
 42080000000001, 3.41839999999999, 3.94239999999999, 3.27719999999999, 3.411, 3.13079999999999, 2.76900000000001, 2.92580000000001, 2.68279999999999, 2.75020000000001, 2.70599999999999, 2.3886, 3.01859999999999, 2.45179999999999, 2.92699999999999, 2.41720000000001, 2.41139999999999, 2.03299999999999, 2.51240000000001, 2.5564, 2.60079999999999, 2.41720000000001, 1.80439999999999, 1.99700000000001, 2.45480000000001, 1.8948, 2.2346, 2.30860000000001, 2.15479999999999, 1.88419999999999, 1.6508, 0.677199999999999, 1.72540000000001, 1.4752, 1.72280000000001, 1.66139999999999, 1.16759999999999, 1.79300000000001, 1.00059999999999, 0.905200000000008, 0.659999999999997, 1.55879999999999, 1.1636, 0.688199999999995, 0.712600000000009, 0.450199999999995, 1.1978, 0.975599999999986, 0.165400000000005, 1.727, 1.19739999999999, -0.252600000000001, 1.13460000000001, 1.3048, 1.19479999999999, 0.313400000000001, 0.878999999999991, 1.12039999999999, 0.853000000000009, 1.67920000000001, 0.856999999999999,
  0.448599999999999, 1.2362, 0.953399999999988, 1.02859999999998, 0.563199999999995, 0.663000000000011, 0.723000000000013, 0.756599999999992, 0.256599999999992, -0.837600000000009, 0.620000000000005, 0.821599999999989, 0.216600000000028, 0.205600000000004, 0.220199999999977, 0.372599999999977, 0.334400000000016, 0.928400000000011, 0.972800000000007, 0.192400000000021, 0.487199999999973, -0.413000000000011, 0.807000000000016, 0.120600000000024, 0.769000000000005, 0.870799999999974, 0.66500000000002, 0.118200000000002, 0.401200000000017, 0.635199999999998, 0.135400000000004, 0.175599999999974, 1.16059999999999, 0.34620000000001, 0.521400000000028, -0.586599999999976, -1.16480000000001, 0.968399999999974, 0.836999999999989, 0.779600000000016, 0.985799999999983,},
++    // precision 7
++    {91, 89.4934, 87.9758, 86.4574, 84.9718, 83.4954, 81.5302, 80.0756, 78.6374, 77.1782, 75.7888, 73.9522, 72.592, 71.2532, 69.9086, 68.5938, 66.9474, 65.6796, 64.4394, 63.2176, 61.9768, 60.4214, 59.2528, 58.0102, 56.8658, 55.7278, 54.3044, 53.1316, 52.093, 51.0032, 49.9092, 48.6306, 47.5294, 46.5756, 45.6508, 44.662, 43.552, 42.3724, 41.617, 40.5754, 39.7872, 38.8444, 37.7988, 36.8606, 36.2118, 35.3566, 34.4476, 33.5882, 32.6816, 32.0824, 31.0258, 30.6048, 29.4436, 28.7274, 27.957, 27.147, 26.4364, 25.7592, 25.3386, 24.781, 23.8028, 23.656, 22.6544, 21.996, 21.4718, 21.1544, 20.6098, 19.5956, 19.0616, 18.5758, 18.4878, 17.5244, 17.2146, 16.724, 15.8722, 15.5198, 15.0414, 14.941, 14.9048, 13.87, 13.4304, 13.028, 12.4708, 12.37, 12.0624, 11.4668, 11.5532, 11.4352, 11.2564, 10.2744, 10.2118, 9.74720000000002, 10.1456, 9.2928, 8.75040000000001, 8.55279999999999, 8.97899999999998, 8.21019999999999, 8.18340000000001, 7.3494, 7.32499999999999, 7.66140000000001, 6.90300000000002, 7.25439
 999999998, 6.9042, 7.21499999999997, 6.28640000000001, 6.08139999999997, 6.6764, 6.30099999999999, 5.13900000000001, 5.65800000000002, 5.17320000000001, 4.59019999999998, 4.9538, 5.08280000000002, 4.92200000000003, 4.99020000000002, 4.7328, 5.4538, 4.11360000000002, 4.22340000000003, 4.08780000000002, 3.70800000000003, 4.15559999999999, 4.18520000000001, 3.63720000000001, 3.68220000000002, 3.77960000000002, 3.6078, 2.49160000000001, 3.13099999999997, 2.5376, 3.19880000000001, 3.21100000000001, 2.4502, 3.52820000000003, 2.91199999999998, 3.04480000000001, 2.7432, 2.85239999999999, 2.79880000000003, 2.78579999999999, 1.88679999999999, 2.98860000000002, 2.50639999999999, 1.91239999999999, 2.66160000000002, 2.46820000000002, 1.58199999999999, 1.30399999999997, 2.27379999999999, 2.68939999999998, 1.32900000000001, 3.10599999999999, 1.69080000000002, 2.13740000000001, 2.53219999999999, 1.88479999999998, 1.33240000000001, 1.45119999999997, 1.17899999999997, 2.44119999999998, 1.606599999999
 96, 2.16700000000003, 0.77940000000001, 2.37900000000002, 2.06700000000001, 1.46000000000004, 2.91160000000002, 1.69200000000001, 0.954600000000028, 2.49300000000005, 2.2722, 1.33500000000004, 2.44899999999996, 1.20140000000004, 3.07380000000001, 2.09739999999999, 2.85640000000001, 2.29960000000005, 2.40899999999999, 1.97040000000004, 0.809799999999996, 1.65279999999996, 2.59979999999996, 0.95799999999997, 2.06799999999998, 2.32780000000002, 4.20159999999998, 1.96320000000003, 1.86400000000003, 1.42999999999995, 3.77940000000001, 1.27200000000005, 1.86440000000005, 2.20600000000002, 3.21900000000005, 1.5154, 2.61019999999996,},
++    // precision 8
++    {183.2152, 180.2454, 177.2096, 173.6652, 170.6312, 167.6822, 164.249, 161.3296, 158.0038, 155.2074, 152.4612, 149.27, 146.5178, 143.4412, 140.8032, 138.1634, 135.1688, 132.6074, 129.6946, 127.2664, 124.8228, 122.0432, 119.6824, 116.9464, 114.6268, 112.2626, 109.8376, 107.4034, 104.8956, 102.8522, 100.7638, 98.3552, 96.3556, 93.7526, 91.9292, 89.8954, 87.8198, 85.7668, 83.298, 81.6688, 79.9466, 77.9746, 76.1672, 74.3474, 72.3028, 70.8912, 69.114, 67.4646, 65.9744, 64.4092, 62.6022, 60.843, 59.5684, 58.1652, 56.5426, 55.4152, 53.5388, 52.3592, 51.1366, 49.486, 48.3918, 46.5076, 45.509, 44.3834, 43.3498, 42.0668, 40.7346, 40.1228, 38.4528, 37.7, 36.644, 36.0518, 34.5774, 33.9068, 32.432, 32.1666, 30.434, 29.6644, 28.4894, 27.6312, 26.3804, 26.292, 25.5496000000001, 25.0234, 24.8206, 22.6146, 22.4188, 22.117, 20.6762, 20.6576, 19.7864, 19.509, 18.5334, 17.9204, 17.772, 16.2924, 16.8654, 15.1836, 15.745, 15.1316, 15.0386, 14.0136, 13.6342, 12.6196, 12.1866, 12.4281999999999, 11.3324
 , 10.4794000000001, 11.5038, 10.129, 9.52800000000002, 10.3203999999999, 9.46299999999997, 9.79280000000006, 9.12300000000005, 8.74180000000001, 9.2192, 7.51020000000005, 7.60659999999996, 7.01840000000004, 7.22239999999999, 7.40139999999997, 6.76179999999999, 7.14359999999999, 5.65060000000005, 5.63779999999997, 5.76599999999996, 6.75139999999999, 5.57759999999996, 3.73220000000003, 5.8048, 5.63019999999995, 4.93359999999996, 3.47979999999995, 4.33879999999999, 3.98940000000005, 3.81960000000004, 3.31359999999995, 3.23080000000004, 3.4588, 3.08159999999998, 3.4076, 3.00639999999999, 2.38779999999997, 2.61900000000003, 1.99800000000005, 3.34820000000002, 2.95060000000001, 0.990999999999985, 2.11440000000005, 2.20299999999997, 2.82219999999995, 2.73239999999998, 2.7826, 3.76660000000004, 2.26480000000004, 2.31280000000004, 2.40819999999997, 2.75360000000001, 3.33759999999995, 2.71559999999999, 1.7478000000001, 1.42920000000004, 2.39300000000003, 2.22779999999989, 2.34339999999997, 0.
 87259999999992, 3.88400000000001, 1.80600000000004, 1.91759999999999, 1.16779999999994, 1.50320000000011, 2.52500000000009, 0.226400000000012, 2.31500000000005, 0.930000000000064, 1.25199999999995, 2.14959999999996, 0.0407999999999902, 2.5447999999999, 1.32960000000003, 0.197400000000016, 2.52620000000002, 3.33279999999991, -1.34300000000007, 0.422199999999975, 0.917200000000093, 1.12920000000008, 1.46060000000011, 1.45779999999991, 2.8728000000001, 3.33359999999993, -1.34079999999994, 1.57680000000005, 0.363000000000056, 1.40740000000005, 0.656600000000026, 0.801400000000058, -0.454600000000028, 1.51919999999996,},
++    // precision 9
++    {368, 361.8294, 355.2452, 348.6698, 342.1464, 336.2024, 329.8782, 323.6598, 317.462, 311.2826, 305.7102, 299.7416, 293.9366, 288.1046, 282.285, 277.0668, 271.306, 265.8448, 260.301, 254.9886, 250.2422, 244.8138, 239.7074, 234.7428, 229.8402, 225.1664, 220.3534, 215.594, 210.6886, 205.7876, 201.65, 197.228, 192.8036, 188.1666, 184.0818, 180.0824, 176.2574, 172.302, 168.1644, 164.0056, 160.3802, 156.7192, 152.5234, 149.2084, 145.831, 142.485, 139.1112, 135.4764, 131.76, 129.3368, 126.5538, 122.5058, 119.2646, 116.5902, 113.3818, 110.8998, 107.9532, 105.2062, 102.2798, 99.4728, 96.9582, 94.3292, 92.171, 89.7809999999999, 87.5716, 84.7048, 82.5322, 79.875, 78.3972, 75.3464, 73.7274, 71.2834, 70.1444, 68.4263999999999, 66.0166, 64.018, 62.0437999999999, 60.3399999999999, 58.6856, 57.9836, 55.0311999999999, 54.6769999999999, 52.3188, 51.4846, 49.4423999999999, 47.739, 46.1487999999999, 44.9202, 43.4059999999999, 42.5342000000001, 41.2834, 38.8954000000001, 38.3286000000001, 36.2146, 
 36.6684, 35.9946, 33.123, 33.4338, 31.7378000000001, 29.076, 28.9692, 27.4964, 27.0998, 25.9864, 26.7754, 24.3208, 23.4838, 22.7388000000001, 24.0758000000001, 21.9097999999999, 20.9728, 19.9228000000001, 19.9292, 16.617, 17.05, 18.2996000000001, 15.6128000000001, 15.7392, 14.5174, 13.6322, 12.2583999999999, 13.3766000000001, 11.423, 13.1232, 9.51639999999998, 10.5938000000001, 9.59719999999993, 8.12220000000002, 9.76739999999995, 7.50440000000003, 7.56999999999994, 6.70440000000008, 6.41419999999994, 6.71019999999999, 5.60940000000005, 4.65219999999999, 6.84099999999989, 3.4072000000001, 3.97859999999991, 3.32760000000007, 5.52160000000003, 3.31860000000006, 2.06940000000009, 4.35400000000004, 1.57500000000005, 0.280799999999999, 2.12879999999996, -0.214799999999968, -0.0378000000000611, -0.658200000000079, 0.654800000000023, -0.0697999999999865, 0.858400000000074, -2.52700000000004, -2.1751999999999, -3.35539999999992, -1.04019999999991, -0.651000000000067, -2.14439999999991, -1.9
 6659999999997, -3.97939999999994, -0.604400000000169, -3.08260000000018, -3.39159999999993, -5.29640000000018, -5.38920000000007, -5.08759999999984, -4.69900000000007, -5.23720000000003, -3.15779999999995, -4.97879999999986, -4.89899999999989, -7.48880000000008, -5.94799999999987, -5.68060000000014, -6.67180000000008, -4.70499999999993, -7.27779999999984, -4.6579999999999, -4.4362000000001, -4.32139999999981, -5.18859999999995, -6.66879999999992, -6.48399999999992, -5.1260000000002, -4.4032000000002, -6.13500000000022, -5.80819999999994, -4.16719999999987, -4.15039999999999, -7.45600000000013, -7.24080000000004, -9.83179999999993, -5.80420000000004, -8.6561999999999, -6.99940000000015, -10.5473999999999, -7.34139999999979, -6.80999999999995, -6.29719999999998, -6.23199999999997,},
++    // precision 10
++    {737.1256, 724.4234, 711.1064, 698.4732, 685.4636, 673.0644, 660.488, 647.9654, 636.0832, 623.7864, 612.1992, 600.2176, 588.5228, 577.1716, 565.7752, 554.899, 543.6126, 532.6492, 521.9474, 511.5214, 501.1064, 490.6364, 480.2468, 470.4588, 460.3832, 451.0584, 440.8606, 431.3868, 422.5062, 413.1862, 404.463, 395.339, 386.1936, 378.1292, 369.1854, 361.2908, 353.3324, 344.8518, 337.5204, 329.4854, 321.9318, 314.552, 306.4658, 299.4256, 292.849, 286.152, 278.8956, 271.8792, 265.118, 258.62, 252.5132, 245.9322, 239.7726, 233.6086, 227.5332, 222.5918, 216.4294, 210.7662, 205.4106, 199.7338, 194.9012, 188.4486, 183.1556, 178.6338, 173.7312, 169.6264, 163.9526, 159.8742, 155.8326, 151.1966, 147.5594, 143.07, 140.037, 134.1804, 131.071, 127.4884, 124.0848, 120.2944, 117.333, 112.9626, 110.2902, 107.0814, 103.0334, 99.4832000000001, 96.3899999999999, 93.7202000000002, 90.1714000000002, 87.2357999999999, 85.9346, 82.8910000000001, 80.0264000000002, 78.3834000000002, 75.1543999999999, 73.86
 83999999998, 70.9895999999999, 69.4367999999999, 64.8701999999998, 65.0408000000002, 61.6738, 59.5207999999998, 57.0158000000001, 54.2302, 53.0962, 50.4985999999999, 52.2588000000001, 47.3914, 45.6244000000002, 42.8377999999998, 43.0072, 40.6516000000001, 40.2453999999998, 35.2136, 36.4546, 33.7849999999999, 33.2294000000002, 32.4679999999998, 30.8670000000002, 28.6507999999999, 28.9099999999999, 27.5983999999999, 26.1619999999998, 24.5563999999999, 23.2328000000002, 21.9484000000002, 21.5902000000001, 21.3346000000001, 17.7031999999999, 20.6111999999998, 19.5545999999999, 15.7375999999999, 17.0720000000001, 16.9517999999998, 15.326, 13.1817999999998, 14.6925999999999, 13.0859999999998, 13.2754, 10.8697999999999, 11.248, 7.3768, 4.72339999999986, 7.97899999999981, 8.7503999999999, 7.68119999999999, 9.7199999999998, 7.73919999999998, 5.6224000000002, 7.44560000000001, 6.6601999999998, 5.9058, 4.00199999999995, 4.51699999999983, 4.68240000000014, 3.86220000000003, 5.13639999999987, 5.
 98500000000013, 2.47719999999981, 2.61999999999989, 1.62800000000016, 4.65000000000009, 0.225599999999758, 0.831000000000131, -0.359400000000278, 1.27599999999984, -2.92559999999958, -0.0303999999996449, 2.37079999999969, -2.0033999999996, 0.804600000000391, 0.30199999999968, 1.1247999999996, -2.6880000000001, 0.0321999999996478, -1.18099999999959, -3.9402, -1.47940000000017, -0.188400000000001, -2.10720000000038, -2.04159999999956, -3.12880000000041, -4.16160000000036, -0.612799999999879, -3.48719999999958, -8.17900000000009, -5.37780000000021, -4.01379999999972, -5.58259999999973, -5.73719999999958, -7.66799999999967, -5.69520000000011, -1.1247999999996, -5.58520000000044, -8.04560000000038, -4.64840000000004, -11.6468000000004, -7.97519999999986, -5.78300000000036, -7.67420000000038, -10.6328000000003, -9.81720000000041,},
++    // precision 11
++    {1476, 1449.6014, 1423.5802, 1397.7942, 1372.3042, 1347.2062, 1321.8402, 1297.2292, 1272.9462, 1248.9926, 1225.3026, 1201.4252, 1178.0578, 1155.6092, 1132.626, 1110.5568, 1088.527, 1066.5154, 1045.1874, 1024.3878, 1003.37, 982.1972, 962.5728, 942.1012, 922.9668, 903.292, 884.0772, 864.8578, 846.6562, 828.041, 809.714, 792.3112, 775.1806, 757.9854, 740.656, 724.346, 707.5154, 691.8378, 675.7448, 659.6722, 645.5722, 630.1462, 614.4124, 600.8728, 585.898, 572.408, 558.4926, 544.4938, 531.6776, 517.282, 505.7704, 493.1012, 480.7388, 467.6876, 456.1872, 445.5048, 433.0214, 420.806, 411.409, 400.4144, 389.4294, 379.2286, 369.651, 360.6156, 350.337, 342.083, 332.1538, 322.5094, 315.01, 305.6686, 298.1678, 287.8116, 280.9978, 271.9204, 265.3286, 257.5706, 249.6014, 242.544, 235.5976, 229.583, 220.9438, 214.672, 208.2786, 201.8628, 195.1834, 191.505, 186.1816, 178.5188, 172.2294, 167.8908, 161.0194, 158.052, 151.4588, 148.1596, 143.4344, 138.5238, 133.13, 127.6374, 124.8162, 118.7894, 1
 17.3984, 114.6078, 109.0858, 105.1036, 103.6258, 98.6018000000004, 95.7618000000002, 93.5821999999998, 88.5900000000001, 86.9992000000002, 82.8800000000001, 80.4539999999997, 74.6981999999998, 74.3644000000004, 73.2914000000001, 65.5709999999999, 66.9232000000002, 65.1913999999997, 62.5882000000001, 61.5702000000001, 55.7035999999998, 56.1764000000003, 52.7596000000003, 53.0302000000001, 49.0609999999997, 48.4694, 44.933, 46.0474000000004, 44.7165999999997, 41.9416000000001, 39.9207999999999, 35.6328000000003, 35.5276000000003, 33.1934000000001, 33.2371999999996, 33.3864000000003, 33.9228000000003, 30.2371999999996, 29.1373999999996, 25.2272000000003, 24.2942000000003, 19.8338000000003, 18.9005999999999, 23.0907999999999, 21.8544000000002, 19.5176000000001, 15.4147999999996, 16.9314000000004, 18.6737999999996, 12.9877999999999, 14.3688000000002, 12.0447999999997, 15.5219999999999, 12.5299999999997, 14.5940000000001, 14.3131999999996, 9.45499999999993, 12.9441999999999, 3.91139999999
 996, 13.1373999999996, 5.44720000000052, 9.82779999999912, 7.87279999999919, 3.67760000000089, 5.46980000000076, 5.55099999999948, 5.65979999999945, 3.89439999999922, 3.1275999999998, 5.65140000000065, 6.3062000000009, 3.90799999999945, 1.87060000000019, 5.17020000000048, 2.46680000000015, 0.770000000000437, -3.72340000000077, 1.16400000000067, 8.05340000000069, 0.135399999999208, 2.15940000000046, 0.766999999999825, 1.0594000000001, 3.15500000000065, -0.287399999999252, 2.37219999999979, -2.86620000000039, -1.63199999999961, -2.22979999999916, -0.15519999999924, -1.46039999999994, -0.262199999999211, -2.34460000000036, -2.8078000000005, -3.22179999999935, -5.60159999999996, -8.42200000000048, -9.43740000000071, 0.161799999999857, -10.4755999999998, -10.0823999999993,},
++    // precision 12
++    {2953, 2900.4782, 2848.3568, 2796.3666, 2745.324, 2694.9598, 2644.648, 2595.539, 2546.1474, 2498.2576, 2450.8376, 2403.6076, 2357.451, 2311.38, 2266.4104, 2221.5638, 2176.9676, 2134.193, 2090.838, 2048.8548, 2007.018, 1966.1742, 1925.4482, 1885.1294, 1846.4776, 1807.4044, 1768.8724, 1731.3732, 1693.4304, 1657.5326, 1621.949, 1586.5532, 1551.7256, 1517.6182, 1483.5186, 1450.4528, 1417.865, 1385.7164, 1352.6828, 1322.6708, 1291.8312, 1260.9036, 1231.476, 1201.8652, 1173.6718, 1145.757, 1119.2072, 1092.2828, 1065.0434, 1038.6264, 1014.3192, 988.5746, 965.0816, 940.1176, 917.9796, 894.5576, 871.1858, 849.9144, 827.1142, 805.0818, 783.9664, 763.9096, 742.0816, 724.3962, 706.3454, 688.018, 667.4214, 650.3106, 633.0686, 613.8094, 597.818, 581.4248, 563.834, 547.363, 531.5066, 520.455400000001, 505.583199999999, 488.366, 476.480799999999, 459.7682, 450.0522, 434.328799999999, 423.952799999999, 408.727000000001, 399.079400000001, 387.252200000001, 373.987999999999, 360.852000000001, 351
 .6394, 339.642, 330.902400000001, 322.661599999999, 311.662200000001, 301.3254, 291.7484, 279.939200000001, 276.7508, 263.215200000001, 254.811400000001, 245.5494, 242.306399999999, 234.8734, 223.787200000001, 217.7156, 212.0196, 200.793, 195.9748, 189.0702, 182.449199999999, 177.2772, 170.2336, 164.741, 158.613600000001, 155.311, 147.5964, 142.837, 137.3724, 132.0162, 130.0424, 121.9804, 120.451800000001, 114.8968, 111.585999999999, 105.933199999999, 101.705, 98.5141999999996, 95.0488000000005, 89.7880000000005, 91.4750000000004, 83.7764000000006, 80.9698000000008, 72.8574000000008, 73.1615999999995, 67.5838000000003, 62.6263999999992, 63.2638000000006, 66.0977999999996, 52.0843999999997, 58.9956000000002, 47.0912000000008, 46.4956000000002, 48.4383999999991, 47.1082000000006, 43.2392, 37.2759999999998, 40.0283999999992, 35.1864000000005, 35.8595999999998, 32.0998, 28.027, 23.6694000000007, 33.8266000000003, 26.3736000000008, 27.2008000000005, 21.3245999999999, 26.4115999999995, 23
 .4521999999997, 19.5013999999992, 19.8513999999996, 10.7492000000002, 18.6424000000006, 13.1265999999996, 18.2436000000016, 6.71860000000015, 3.39459999999963, 6.33759999999893, 7.76719999999841, 0.813999999998487, 3.82819999999992, 0.826199999999517, 8.07440000000133, -1.59080000000176, 5.01780000000144, 0.455399999998917, -0.24199999999837, 0.174800000000687, -9.07640000000174, -4.20160000000033, -3.77520000000004, -4.75179999999818, -5.3724000000002, -8.90680000000066, -6.10239999999976, -5.74120000000039, -9.95339999999851, -3.86339999999836, -13.7304000000004, -16.2710000000006, -7.51359999999841, -3.30679999999847, -13.1339999999982, -10.0551999999989, -6.72019999999975, -8.59660000000076, -10.9307999999983, -1.8775999999998, -4.82259999999951, -13.7788, -21.6470000000008, -10.6735999999983, -15.7799999999988,},
++    // precision 13
++    {5907.5052, 5802.2672, 5697.347, 5593.5794, 5491.2622, 5390.5514, 5290.3376, 5191.6952, 5093.5988, 4997.3552, 4902.5972, 4808.3082, 4715.5646, 4624.109, 4533.8216, 4444.4344, 4356.3802, 4269.2962, 4183.3784, 4098.292, 4014.79, 3932.4574, 3850.6036, 3771.2712, 3691.7708, 3615.099, 3538.1858, 3463.4746, 3388.8496, 3315.6794, 3244.5448, 3173.7516, 3103.3106, 3033.6094, 2966.5642, 2900.794, 2833.7256, 2769.81, 2707.3196, 2644.0778, 2583.9916, 2523.4662, 2464.124, 2406.073, 2347.0362, 2292.1006, 2238.1716, 2182.7514, 2128.4884, 2077.1314, 2025.037, 1975.3756, 1928.933, 1879.311, 1831.0006, 1783.2144, 1738.3096, 1694.5144, 1649.024, 1606.847, 1564.7528, 1525.3168, 1482.5372, 1443.9668, 1406.5074, 1365.867, 1329.2186, 1295.4186, 1257.9716, 1225.339, 1193.2972, 1156.3578, 1125.8686, 1091.187, 1061.4094, 1029.4188, 1000.9126, 972.3272, 944.004199999999, 915.7592, 889.965, 862.834200000001, 840.4254, 812.598399999999, 785.924200000001, 763.050999999999, 741.793799999999, 721.466, 699.040
 799999999, 677.997200000002, 649.866999999998, 634.911800000002, 609.8694, 591.981599999999, 570.2922, 557.129199999999, 538.3858, 521.872599999999, 502.951400000002, 495.776399999999, 475.171399999999, 459.751, 439.995200000001, 426.708999999999, 413.7016, 402.3868, 387.262599999998, 372.0524, 357.050999999999, 342.5098, 334.849200000001, 322.529399999999, 311.613799999999, 295.848000000002, 289.273000000001, 274.093000000001, 263.329600000001, 251.389599999999, 245.7392, 231.9614, 229.7952, 217.155200000001, 208.9588, 199.016599999999, 190.839199999999, 180.6976, 176.272799999999, 166.976999999999, 162.5252, 151.196400000001, 149.386999999999, 133.981199999998, 130.0586, 130.164000000001, 122.053400000001, 110.7428, 108.1276, 106.232400000001, 100.381600000001, 98.7668000000012, 86.6440000000002, 79.9768000000004, 82.4722000000002, 68.7026000000005, 70.1186000000016, 71.9948000000004, 58.998599999999, 59.0492000000013, 56.9818000000014, 47.5338000000011, 42.9928, 51.1591999999982,
  37.2740000000013, 42.7220000000016, 31.3734000000004, 26.8090000000011, 25.8934000000008, 26.5286000000015, 29.5442000000003, 19.3503999999994, 26.0760000000009, 17.9527999999991, 14.8419999999969, 10.4683999999979, 8.65899999999965, 9.86720000000059, 4.34139999999752, -0.907800000000861, -3.32080000000133, -0.936199999996461, -11.9916000000012, -8.87000000000262, -6.33099999999831, -11.3366000000024, -15.9207999999999, -9.34659999999712, -15.5034000000014, -19.2097999999969, -15.357799999998, -28.2235999999975, -30.6898000000001, -19.3271999999997, -25.6083999999973, -24.409599999999, -13.6385999999984, -33.4473999999973, -32.6949999999997, -28.9063999999998, -31.7483999999968, -32.2935999999972, -35.8329999999987, -47.620600000002, -39.0855999999985, -33.1434000000008, -46.1371999999974, -37.5892000000022, -46.8164000000033, -47.3142000000007, -60.2914000000019, -37.7575999999972,},
++    // precision 14
++    {11816.475, 11605.0046, 11395.3792, 11188.7504, 10984.1814, 10782.0086, 10582.0072, 10384.503, 10189.178, 9996.2738, 9806.0344, 9617.9798, 9431.394, 9248.7784, 9067.6894, 8889.6824, 8712.9134, 8538.8624, 8368.4944, 8197.7956, 8031.8916, 7866.6316, 7703.733, 7544.5726, 7386.204, 7230.666, 7077.8516, 6926.7886, 6778.6902, 6631.9632, 6487.304, 6346.7486, 6206.4408, 6070.202, 5935.2576, 5799.924, 5671.0324, 5541.9788, 5414.6112, 5290.0274, 5166.723, 5047.6906, 4929.162, 4815.1406, 4699.127, 4588.5606, 4477.7394, 4369.4014, 4264.2728, 4155.9224, 4055.581, 3955.505, 3856.9618, 3761.3828, 3666.9702, 3575.7764, 3482.4132, 3395.0186, 3305.8852, 3221.415, 3138.6024, 3056.296, 2970.4494, 2896.1526, 2816.8008, 2740.2156, 2670.497, 2594.1458, 2527.111, 2460.8168, 2387.5114, 2322.9498, 2260.6752, 2194.2686, 2133.7792, 2074.767, 2015.204, 1959.4226, 1898.6502, 1850.006, 1792.849, 1741.4838, 1687.9778, 1638.1322, 1589.3266, 1543.1394, 1496.8266, 1447.8516, 1402.7354, 1361.9606, 1327.0692, 1285
 .4106, 1241.8112, 1201.6726, 1161.973, 1130.261, 1094.2036, 1048.2036, 1020.6436, 990.901400000002, 961.199800000002, 924.769800000002, 899.526400000002, 872.346400000002, 834.375, 810.432000000001, 780.659800000001, 756.013800000001, 733.479399999997, 707.923999999999, 673.858, 652.222399999999, 636.572399999997, 615.738599999997, 586.696400000001, 564.147199999999, 541.679600000003, 523.943599999999, 505.714599999999, 475.729599999999, 461.779600000002, 449.750800000002, 439.020799999998, 412.7886, 400.245600000002, 383.188199999997, 362.079599999997, 357.533799999997, 334.319000000003, 327.553399999997, 308.559399999998, 291.270199999999, 279.351999999999, 271.791400000002, 252.576999999997, 247.482400000001, 236.174800000001, 218.774599999997, 220.155200000001, 208.794399999999, 201.223599999998, 182.995600000002, 185.5268, 164.547400000003, 176.5962, 150.689599999998, 157.8004, 138.378799999999, 134.021200000003, 117.614399999999, 108.194000000003, 97.0696000000025, 89.60420000
 00016, 95.6030000000028, 84.7810000000027, 72.635000000002, 77.3482000000004, 59.4907999999996, 55.5875999999989, 50.7346000000034, 61.3916000000027, 50.9149999999936, 39.0384000000049, 58.9395999999979, 29.633600000001, 28.2032000000036, 26.0078000000067, 17.0387999999948, 9.22000000000116, 13.8387999999977, 8.07240000000456, 14.1549999999988, 15.3570000000036, 3.42660000000615, 6.24820000000182, -2.96940000000177, -8.79940000000352, -5.97860000000219, -14.4048000000039, -3.4143999999942, -13.0148000000045, -11.6977999999945, -25.7878000000055, -22.3185999999987, -24.409599999999, -31.9756000000052, -18.9722000000038, -22.8678000000073, -30.8972000000067, -32.3715999999986, -22.3907999999938, -43.6720000000059, -35.9038, -39.7492000000057, -54.1641999999993, -45.2749999999942, -42.2989999999991, -44.1089999999967, -64.3564000000042, -49.9551999999967, -42.6116000000038,},
++    // precision 15
++    {23634.0036, 23210.8034, 22792.4744, 22379.1524, 21969.7928, 21565.326, 21165.3532, 20770.2806, 20379.9892, 19994.7098, 19613.318, 19236.799, 18865.4382, 18498.8244, 18136.5138, 17778.8668, 17426.2344, 17079.32, 16734.778, 16397.2418, 16063.3324, 15734.0232, 15409.731, 15088.728, 14772.9896, 14464.1402, 14157.5588, 13855.5958, 13559.3296, 13264.9096, 12978.326, 12692.0826, 12413.8816, 12137.3192, 11870.2326, 11602.5554, 11340.3142, 11079.613, 10829.5908, 10583.5466, 10334.0344, 10095.5072, 9859.694, 9625.2822, 9395.7862, 9174.0586, 8957.3164, 8738.064, 8524.155, 8313.7396, 8116.9168, 7913.542, 7718.4778, 7521.65, 7335.5596, 7154.2906, 6968.7396, 6786.3996, 6613.236, 6437.406, 6270.6598, 6107.7958, 5945.7174, 5787.6784, 5635.5784, 5482.308, 5337.9784, 5190.0864, 5045.9158, 4919.1386, 4771.817, 4645.7742, 4518.4774, 4385.5454, 4262.6622, 4142.74679999999, 4015.5318, 3897.9276, 3790.7764, 3685.13800000001, 3573.6274, 3467.9706, 3368.61079999999, 3271.5202, 3170.3848, 3076.4656, 29
 82.38400000001, 2888.4664, 2806.4868, 2711.9564, 2634.1434, 2551.3204, 2469.7662, 2396.61139999999, 2318.9902, 2243.8658, 2171.9246, 2105.01360000001, 2028.8536, 1960.9952, 1901.4096, 1841.86079999999, 1777.54700000001, 1714.5802, 1654.65059999999, 1596.311, 1546.2016, 1492.3296, 1433.8974, 1383.84600000001, 1339.4152, 1293.5518, 1245.8686, 1193.50659999999, 1162.27959999999, 1107.19439999999, 1069.18060000001, 1035.09179999999, 999.679000000004, 957.679999999993, 925.300199999998, 888.099400000006, 848.638600000006, 818.156400000007, 796.748399999997, 752.139200000005, 725.271200000003, 692.216, 671.633600000001, 647.939799999993, 621.670599999998, 575.398799999995, 561.226599999995, 532.237999999998, 521.787599999996, 483.095799999996, 467.049599999998, 465.286399999997, 415.548599999995, 401.047399999996, 380.607999999993, 377.362599999993, 347.258799999996, 338.371599999999, 310.096999999994, 301.409199999995, 276.280799999993, 265.586800000005, 258.994399999996, 223.91599999999
 7, 215.925399999993, 213.503800000006, 191.045400000003, 166.718200000003, 166.259000000005, 162.941200000001, 148.829400000002, 141.645999999993, 123.535399999993, 122.329800000007, 89.473399999988, 80.1962000000058, 77.5457999999926, 59.1056000000099, 83.3509999999951, 52.2906000000075, 36.3979999999865, 40.6558000000077, 42.0003999999899, 19.6630000000005, 19.7153999999864, -8.38539999999921, -0.692799999989802, 0.854800000000978, 3.23219999999856, -3.89040000000386, -5.25880000001052, -24.9052000000083, -22.6837999999989, -26.4286000000138, -34.997000000003, -37.0216000000073, -43.430400000012, -58.2390000000014, -68.8034000000043, -56.9245999999985, -57.8583999999973, -77.3097999999882, -73.2793999999994, -81.0738000000129, -87.4530000000086, -65.0254000000132, -57.296399999992, -96.2746000000043, -103.25, -96.081600000005, -91.5542000000132, -102.465200000006, -107.688599999994, -101.458000000013, -109.715800000005,},
++    // precision 16
++    {47270, 46423.3584, 45585.7074, 44757.152, 43938.8416, 43130.9514, 42330.03, 41540.407, 40759.6348, 39988.206, 39226.5144, 38473.2096, 37729.795, 36997.268, 36272.6448, 35558.665, 34853.0248, 34157.4472, 33470.5204, 32793.5742, 32127.0194, 31469.4182, 30817.6136, 30178.6968, 29546.8908, 28922.8544, 28312.271, 27707.0924, 27114.0326, 26526.692, 25948.6336, 25383.7826, 24823.5998, 24272.2974, 23732.2572, 23201.4976, 22674.2796, 22163.6336, 21656.515, 21161.7362, 20669.9368, 20189.4424, 19717.3358, 19256.3744, 18795.9638, 18352.197, 17908.5738, 17474.391, 17052.918, 16637.2236, 16228.4602, 15823.3474, 15428.6974, 15043.0284, 14667.6278, 14297.4588, 13935.2882, 13578.5402, 13234.6032, 12882.1578, 12548.0728, 12219.231, 11898.0072, 11587.2626, 11279.9072, 10973.5048, 10678.5186, 10392.4876, 10105.2556, 9825.766, 9562.5444, 9294.2222, 9038.2352, 8784.848, 8533.2644, 8301.7776, 8058.30859999999, 7822.94579999999, 7599.11319999999, 7366.90779999999, 7161.217, 6957.53080000001, 6736.212
 , 6548.21220000001, 6343.06839999999, 6156.28719999999, 5975.15419999999, 5791.75719999999, 5621.32019999999, 5451.66, 5287.61040000001, 5118.09479999999, 4957.288, 4798.4246, 4662.17559999999, 4512.05900000001, 4364.68539999999, 4220.77720000001, 4082.67259999999, 3957.19519999999, 3842.15779999999, 3699.3328, 3583.01180000001, 3473.8964, 3338.66639999999, 3233.55559999999, 3117.799, 3008.111, 2909.69140000001, 2814.86499999999, 2719.46119999999, 2624.742, 2532.46979999999, 2444.7886, 2370.1868, 2272.45259999999, 2196.19260000001, 2117.90419999999, 2023.2972, 1969.76819999999, 1885.58979999999, 1833.2824, 1733.91200000001, 1682.54920000001, 1604.57980000001, 1556.11240000001, 1491.3064, 1421.71960000001, 1371.22899999999, 1322.1324, 1264.7892, 1196.23920000001, 1143.8474, 1088.67240000001, 1073.60380000001, 1023.11660000001, 959.036400000012, 927.433199999999, 906.792799999996, 853.433599999989, 841.873800000001, 791.1054, 756.899999999994, 704.343200000003, 672.495599999995, 622.7
 90399999998, 611.254799999995, 567.283200000005, 519.406599999988, 519.188400000014, 495.312800000014, 451.350799999986, 443.973399999988, 431.882199999993, 392.027000000002, 380.924200000009, 345.128999999986, 298.901400000002, 287.771999999997, 272.625, 247.253000000026, 222.490600000019, 223.590000000026, 196.407599999977, 176.425999999978, 134.725199999986, 132.4804, 110.445599999977, 86.7939999999944, 56.7038000000175, 64.915399999998, 38.3726000000024, 37.1606000000029, 46.170999999973, 49.1716000000015, 15.3362000000197, 6.71639999997569, -34.8185999999987, -39.4476000000141, 12.6830000000191, -12.3331999999937, -50.6565999999875, -59.9538000000175, -65.1054000000004, -70.7576000000117, -106.325200000021, -126.852200000023, -110.227599999984, -132.885999999999, -113.897200000007, -142.713800000027, -151.145399999979, -150.799200000009, -177.756200000003, -156.036399999983, -182.735199999996, -177.259399999981, -198.663600000029, -174.577600000019, -193.84580000001,},
++    // precision 17
++    {94541, 92848.811, 91174.019, 89517.558, 87879.9705, 86262.7565, 84663.5125, 83083.7435, 81521.7865, 79977.272, 78455.9465, 76950.219, 75465.432, 73994.152, 72546.71, 71115.2345, 69705.6765, 68314.937, 66944.2705, 65591.255, 64252.9485, 62938.016, 61636.8225, 60355.592, 59092.789, 57850.568, 56624.518, 55417.343, 54231.1415, 53067.387, 51903.526, 50774.649, 49657.6415, 48561.05, 47475.7575, 46410.159, 45364.852, 44327.053, 43318.4005, 42325.6165, 41348.4595, 40383.6265, 39436.77, 38509.502, 37594.035, 36695.939, 35818.6895, 34955.691, 34115.8095, 33293.949, 32465.0775, 31657.6715, 30877.2585, 30093.78, 29351.3695, 28594.1365, 27872.115, 27168.7465, 26477.076, 25774.541, 25106.5375, 24452.5135, 23815.5125, 23174.0655, 22555.2685, 21960.2065, 21376.3555, 20785.1925, 20211.517, 19657.0725, 19141.6865, 18579.737, 18081.3955, 17578.995, 17073.44, 16608.335, 16119.911, 15651.266, 15194.583, 14749.0495, 14343.4835, 13925.639, 13504.509, 13099.3885, 12691.2855, 12328.018, 11969.0345, 1
 1596.5145, 11245.6355, 10917.6575, 10580.9785, 10277.8605, 9926.58100000001, 9605.538, 9300.42950000003, 8989.97850000003, 8728.73249999998, 8448.3235, 8175.31050000002, 7898.98700000002, 7629.79100000003, 7413.76199999999, 7149.92300000001, 6921.12650000001, 6677.1545, 6443.28000000003, 6278.23450000002, 6014.20049999998, 5791.20299999998, 5605.78450000001, 5438.48800000001, 5234.2255, 5059.6825, 4887.43349999998, 4682.935, 4496.31099999999, 4322.52250000002, 4191.42499999999, 4021.24200000003, 3900.64799999999, 3762.84250000003, 3609.98050000001, 3502.29599999997, 3363.84250000003, 3206.54849999998, 3079.70000000001, 2971.42300000001, 2867.80349999998, 2727.08100000001, 2630.74900000001, 2496.6165, 2440.902, 2356.19150000002, 2235.58199999999, 2120.54149999999, 2012.25449999998, 1933.35600000003, 1820.93099999998, 1761.54800000001, 1663.09350000002, 1578.84600000002, 1509.48149999999, 1427.3345, 1379.56150000001, 1306.68099999998, 1212.63449999999, 1084.17300000001, 1124.164500000
 01, 1060.69949999999, 1007.48849999998, 941.194499999983, 879.880500000028, 836.007500000007, 782.802000000025, 748.385499999975, 647.991500000004, 626.730500000005, 570.776000000013, 484.000500000024, 513.98550000001, 418.985499999952, 386.996999999974, 370.026500000036, 355.496999999974, 356.731499999994, 255.92200000002, 259.094000000041, 205.434499999974, 165.374500000034, 197.347500000033, 95.718499999959, 67.6165000000037, 54.6970000000438, 31.7395000000251, -15.8784999999916, 8.42500000004657, -26.3754999999655, -118.425500000012, -66.6629999999423, -42.9745000000112, -107.364999999991, -189.839000000036, -162.611499999999, -164.964999999967, -189.079999999958, -223.931499999948, -235.329999999958, -269.639500000048, -249.087999999989, -206.475499999942, -283.04449999996, -290.667000000016, -304.561499999953, -336.784499999951, -380.386500000022, -283.280499999993, -364.533000000054, -389.059499999974, -364.454000000027, -415.748000000021, -417.155000000028,},
++    // precision 18
++    {189083, 185696.913, 182348.774, 179035.946, 175762.762, 172526.444, 169329.754, 166166.099, 163043.269, 159958.91, 156907.912, 153906.845, 150924.199, 147996.568, 145093.457, 142239.233, 139421.475, 136632.27, 133889.588, 131174.2, 128511.619, 125868.621, 123265.385, 120721.061, 118181.769, 115709.456, 113252.446, 110840.198, 108465.099, 106126.164, 103823.469, 101556.618, 99308.004, 97124.508, 94937.803, 92833.731, 90745.061, 88677.627, 86617.47, 84650.442, 82697.833, 80769.132, 78879.629, 77014.432, 75215.626, 73384.587, 71652.482, 69895.93, 68209.301, 66553.669, 64921.981, 63310.323, 61742.115, 60205.018, 58698.658, 57190.657, 55760.865, 54331.169, 52908.167, 51550.273, 50225.254, 48922.421, 47614.533, 46362.049, 45098.569, 43926.083, 42736.03, 41593.473, 40425.26, 39316.237, 38243.651, 37170.617, 36114.609, 35084.19, 34117.233, 33206.509, 32231.505, 31318.728, 30403.404, 29540.0550000001, 28679.236, 27825.862, 26965.216, 26179.148, 25462.08, 24645.952, 23922.523, 23198.144
 , 22529.128, 21762.4179999999, 21134.779, 20459.117, 19840.818, 19187.04, 18636.3689999999, 17982.831, 17439.7389999999, 16874.547, 16358.2169999999, 15835.684, 15352.914, 14823.681, 14329.313, 13816.897, 13342.874, 12880.882, 12491.648, 12021.254, 11625.392, 11293.7610000001, 10813.697, 10456.209, 10099.074, 9755.39000000001, 9393.18500000006, 9047.57900000003, 8657.98499999999, 8395.85900000005, 8033, 7736.95900000003, 7430.59699999995, 7258.47699999996, 6924.58200000005, 6691.29399999999, 6357.92500000005, 6202.05700000003, 5921.19700000004, 5628.28399999999, 5404.96799999999, 5226.71100000001, 4990.75600000005, 4799.77399999998, 4622.93099999998, 4472.478, 4171.78700000001, 3957.46299999999, 3868.95200000005, 3691.14300000004, 3474.63100000005, 3341.67200000002, 3109.14000000001, 3071.97400000005, 2796.40399999998, 2756.17799999996, 2611.46999999997, 2471.93000000005, 2382.26399999997, 2209.22400000005, 2142.28399999999, 2013.96100000001, 1911.18999999994, 1818.27099999995, 1668
 .47900000005, 1519.65800000005, 1469.67599999998, 1367.13800000004, 1248.52899999998, 1181.23600000003, 1022.71900000004, 1088.20700000005, 959.03600000008, 876.095999999903, 791.183999999892, 703.337000000058, 731.949999999953, 586.86400000006, 526.024999999907, 323.004999999888, 320.448000000091, 340.672999999952, 309.638999999966, 216.601999999955, 102.922999999952, 19.2399999999907, -0.114000000059605, -32.6240000000689, -89.3179999999702, -153.497999999905, -64.2970000000205, -143.695999999996, -259.497999999905, -253.017999999924, -213.948000000091, -397.590000000084, -434.006000000052, -403.475000000093, -297.958000000101, -404.317000000039, -528.898999999976, -506.621000000043, -513.205000000075, -479.351000000024, -596.139999999898, -527.016999999993, -664.681000000099, -680.306000000099, -704.050000000047, -850.486000000034, -757.43200000003, -713.308999999892,}
++  };
++
++  private Format format;
++  private RegisterSet registerSet;
++  private final int m;
++  private final int p;
++
++  //Sparse versions of m and p
++  private int sm;
++  private int sp;
++
++  private final double alphaMM;
++
++  //How big the sparse set is allowed to get before we convert to 'normal'
++  private int sparseSetThreshold;
++  //How big the temp list is allowed to get before we batch merge it into the sparse set
++  private int sortThreshold;
++
++  private int[] tmpSet;
++  private int tmpIndex = 0;
++  private int[] sparseSet;
++
++  /**
++   * This constructor disables the sparse set.  If the counter is likely to exceed
++   * the sparse set thresholds than using this constructor will help avoid the
++   * extra memory pressure created by maintaining the sparse set until that threshold is
++   * breached.
++   *
++   * @param p - the precision value for the normal set
++   */
++  public HyperLogLogPlus(int p) {
++    this(p, 0);
++  }
++
++  /**
++   * Basic constructor for creating a instance that supports sparse and normal
++   * representations. The values of <code>p</code> and
++   * <code>sp</code> define the precision of the Normal and Sparse set
++   * representations for the data structure.  <code>p</code> must be a value
++   * between 4 and <code>sp</code> and <code>sp</code> must be less than 32.
++   *
++   * @param p  - the precision value for the normal set
++   * @param sp - the precision value for the sparse set
++   */
++  public HyperLogLogPlus(int p, int sp) {
++    this(p, sp, null, null);
++  }
++
++  /**
++   * Constructor to support instances serialized with the legacy sparse
++   * encoding scheme.
++   *
++   * @param p            - the precision value for the normal set
++   * @param sp           - the precision value for the sparse set
++   * @param deltaByteSet - a list of varint byte arrays encoded using a delta encoding scheme
++   */
++  public HyperLogLogPlus(int p, int sp, List<byte[]> deltaByteSet) {
++    this(p, sp);
++    sparseSet = new int[deltaByteSet.size()];
++    int previousValue = 0;
++    for (int i = 0; i < deltaByteSet.size(); i++) {
++      int nextValue = Varint.readUnsignedVarInt(deltaByteSet.get(i));
++      sparseSet[i] = nextValue + previousValue;
++      previousValue = sparseSet[i];
++    }
++  }
++
++  // for constructing a sparse mode hllp
++  private HyperLogLogPlus(int p, int sp, int[] sparseSet) {
++    this(p, sp, sparseSet, null);
++  }
++
++  // for constructing a normal mode hllp
++  private HyperLogLogPlus(int p, int sp, RegisterSet registerSet) {
++    this(p, sp, null, registerSet);
++  }
++
++  private HyperLogLogPlus(int p, int sp, int[] sparseSet, RegisterSet registerSet) {
++    if (p < 4 || (p > sp && sp != 0)) {
++      throw new IllegalArgumentException("p must be between 4 and sp (inclusive)");
++    }
++    if (sp > 32) {
++      throw new IllegalArgumentException("sp values greater than 32 not supported");
++    }
++
++    this.p = p;
++    m = (int) Math.pow(2, p);
++    format = Format.NORMAL;
++    this.registerSet = registerSet;
++    if (registerSet == null) {
++      if (sp > 0) // Use sparse representation
++      {
++        format = Format.SPARSE;
++        this.sp = sp;
++        sm = (int) Math.pow(2, sp);
++        this.sparseSet = sparseSet;
++        sparseSetThreshold = (int) (m * 0.75);
++        sortThreshold = sparseSetThreshold / 4;
++      } else {
++        this.registerSet = new RegisterSet((int) Math.pow(2, p));
++      }
++    }
++
++    this.alphaMM = HyperLogLog.getAlphaMM(p, m);
++  }
++
++  @Override
++  public boolean offerHashed(long hashedLong) {
++    switch (format) {
++    case NORMAL:
++      // find first p bits of x
++      final long idx = hashedLong >>> (64 - p);
++      //Ignore the first p bits (the idx), and then find the number of leading zeros
++      //Push a 1 to where the bit string would have ended if we didnt just push the idx out of the way
++      //A one is always added to runLength for estimation calculation purposes
++      final int runLength = Long.numberOfLeadingZeros((hashedLong << this.p) | (1 << (this.p - 1))) + 1;
++      return registerSet.updateIfGreater((int) idx, runLength);
++    case SPARSE:
++      //Call the sparse encoding scheme which attempts to stuff as much helpful data into 32 bits as possible
++      int k = encodeHash(hashedLong, p, sp);
++      if (tmpSet == null) {
++        tmpSet = new int[sortThreshold + 1];
++      }
++      //Put the encoded data into the temp set
++      tmpSet[tmpIndex++] = k;
++      if (sparseSet != null && sparseSet.length > sparseSetThreshold) {
++        mergeTempList();
++        convertToNormal();
++      } else if (tmpIndex > sortThreshold) {
++        mergeTempList();
++      }
++      return true;
++    }
++    return false;
++  }
++
++  @Override
++  public boolean offerHashed(int hashedInt) {
++    throw new UnsupportedOperationException();
++  }
++
++  /**
++   * Add data to estimator based on the mode it is in
++   *
++   * @param o stream element
++   * @return Will almost always return true for sparse mode because the additions are batched in
++   */
++  @Override
++  public boolean offer(Object o) {
++    long x = MurmurHash.hash64(o);
++    return offerHashed(x);
++  }
++
++  /**
++   * Converts the mode of this estimator from 'sparse' to 'normal'.
++   * <p/>
++   * Each member of the set has its longer 'sparse precision (sp)' length idx
++   * truncated to length p and the associated run length is placed into a register.
++   * Collisions are resolved by merely taking the max.
++   */
++
++  private void convertToNormal() {
++    mergeTempList();
++    this.registerSet = new RegisterSet((int) Math.pow(2, p));
++    for (int k : sparseSet) {
++      int idx = getIndex(k, p);
++      int r = decodeRunLength(k);
++      registerSet.updateIfGreater(idx, r);
++    }
++    format = Format.NORMAL;
++    tmpSet = null;
++    sparseSet = null;
++  }
++
++  /**
++   * Encode the sp length idx and, if necessary, the run length.
++   * <p/>
++   * Start with the 64 bit hash as x.
++   * <p/>
++   * Find all the bits that belong in the first sp (roughly 25) bits. (This is idx')
++   * Get rid of the first p (roughly 18) bits of those. (Those were idx (not prime))
++   * <p/>
++   * If all the remaining bits are zero then we are going to need to find and encode the
++   * full run length of leading zeros, but this only happens once in 2 ^ (sp - p) or roughly
++   * 2 ^ 7 times.
++   * <p/>
++   * If at least one of them is not zero, then since the run length is determined by bits
++   * after p and the idx' contains the first (sp - p) bits of those, then just by putting idx'
++   * in the encoding, we will also be giving it all the information it needs to find the run length.
++   * <p/>
++   * The relationship looks like this:
++   * <p/>
++   * *******************************************************   <- hashed length of bits
++   * | p bits = idx ||     look for leading zeros here     |
++   * |      sp bits = idx'     |
++   * | all 0s? |
++   * <p/>
++   * If we have idx', we could theoretically scan it (as per zeroTest) when unencoding and therefore know whether
++   * to look for the extra run length information. However, for now we have followed the authors of
++   * the paper and put this information in a flag bit at the end of the encoding.
++   * <p/>
++   * Based on this flag, we know whether to adjust for the missing run length bits. We could also
++   * use this flag to compress all the zeros in "| all 0s? |", but saving a byte or so once in 128
++   * times is less than the 120 bits spent on the flag elsewhere. Of course, after compression, the losses
++   * are not quite so large either way.
++   * <p/>
++   * The encoding scheme now looks like:
++   * <p/>
++   * ********************************* <- smaller length of bits (half, but not to scale)
++   * | empty ||       sp bits     ||F|
++   * |  p bits  || has 1 ||0|
++   * <p/>
++   * <p/>
++   * or if the run length was needed (ie 'all 0s?' was indeed all 0s):
++   * <p/>
++   * *********************************
++   * |      sp bits    || run len ||F|
++   * |  p bits ||  0s  |           |1|
++   * <p/>
++   * <p/>
++   * The other notable encoding feature is the inversion of the run length, which just lets the lists
++   * be sorted in a convenient way. (Could alternatively sort in reverse, and use descending deltas).
++   *
++   * @param x  the hash bits
++   * @param p  the 'normal' mode precision
++   * @param sp the 'sparse' mode precision
++   * @return the encoded data as an integer
++   */
++  private int encodeHash(long x, int p, int sp) {
++    //Get the idx' (the first sp bits) by pushing the rest to the right (into oblivion >:D)
++    int idx = (int) (x >>> (64 - sp));
++    //Push to the left for all the spaces you know are between the start of your bits and the left 'wall'
++    //then push p bits off as well so we have just our friend "all 0s?"
++    int zeroTest = 0;
++    if (p < sp) {
++      zeroTest = idx << ((32 - sp) + p);
++    }
++    if (zeroTest == 0) {
++      //See offer
++      final int runLength = Long.numberOfLeadingZeros((x << this.p) | (1 << (this.p - 1))) + 1;
++      //Invert run length by xoring it with a bunch of 1s
++      int invrl = runLength ^ 63;
++      return (((idx
++          << 6)       //push the idx left 6 times to make room to put in the run length
++          | invrl)    //then merge in the run length
++          << 1)       //move left again to make room for the flag bit
++          | 1;        //merge in the flag bit (set to one because we needed the run length)
++    } else {
++      //Just push left once. A zero will appear by default and that's the flag we want.
++      return idx << 1;
++    }
++  }
++
++  /**
++   * More of less the opposite of the encoding function but just for getting out run lengths.
++   *
++   * @param k encoded int
++   * @return run length
++   */
++  private int decodeRunLength(int k) {
++    if ((k & 1) == 1) //checking the flag bit
++    {
++      //Smoosh the flag bit; it has served its purpose
++      //Then & with 63 to delete everything but the run length
++      //Then invert again to undo the inversion from before
++      return ((k >>> 1) & 63) ^ 63;
++    } else {
++      //In one of the encode diagrams there is a substring of bits
++      //labeled 'has 1'. This is where we find that one!
++
++      //First push left to clear out the empty space (that is 31-sp places)
++      //Then push left some more cause bits in precision p don't count for run length
++      //That is, push left p times.
++      //Lastly we add one because we love adding one to run lengths. Its our JAM
++      return Integer.numberOfLeadingZeros(k << p + (31 - sp)) + 1;
++    }
++  }
++
++  /**
++   * returns the hash portion of the of the integer value
++   *
++   * @param k - the encoded integer to extract the hash from
++   * @return the encoded hash value
++   */
++  private int getEncodedHash(int k) {
++    return (k << p + (31 - sp));
++  }
++
++  /**
++   * Get the idx' from an encoding
++   *
++   * @param k encoded data
++   * @return idx'
++   */
++  private static int getSparseIndex(int k) {
++    if ((k & 1) == 1) {
++      return k >>> 7;
++    } else {
++      return k >>> 1;
++    }
++  }
++
++  /**
++   * Gets the idx from an encoding (note this is idx and not idx prime)
++   *
++   * @param k encoded data
++   * @param p 'normal' precision
++   * @return index
++   */
++  private int getIndex(int k, int p) {
++    k = getSparseIndex(k);
++    return (k >>> (sp - p));
++  }
++
++  /**
++   * Gather the cardinality estimate from this estimator.
++   * <p/>
++   * Has two procedures based on current mode. 'Normal' mode works similar to HLL but has some
++   * new bias corrections. 'Sparse' mode is linear counting.
++   *
++   * @return cardinality
++   */
++  @Override
++  public long cardinality() {
++    switch (format) {
++    case NORMAL:
++      double registerSum = 0;
++      int count = registerSet.count;
++      double zeros = 0;
++      for (int j = 0; j < registerSet.count; j++) {
++        int val = registerSet.get(j);
++        registerSum += 1.0 / (1 << val);
++        if (val == 0) {
++          zeros++;
++        }
++      }
++
++      double estimate = alphaMM * (1 / registerSum);
++      double estimatePrime = estimate;
++      if (estimate <= (5 * m)) {
++        estimatePrime = estimate - getEstimateBias(estimate, p);
++      }
++      double H;
++      if (zeros > 0) {
++        H = HyperLogLog.linearCounting(count, zeros);
++      } else {
++        H = estimatePrime;
++      }
++      // when p is large the threshold is just 5*m
++      if ((p <= 18 && H < thresholdData[p - 4]) || (p > 18 && estimate <= 5 * m)) {
++        return Math.round(H);
++      } else {
++        return Math.round(estimatePrime);
++      }
++    case SPARSE:
++      mergeTempList();
++      return Math.round(HyperLogLog.linearCounting(sm, (sm - sparseSet.length)));
++    }
++    return 0;
++  }
++
++  private static double getEstimateBias(double estimate, int p) {
++    // get nearest neighbors for this estimate and precision
++    // above p = 18 there is no bias correction
++    if (p > 18) {
++      return 0;
++    }
++    double[] estimateVector = rawEstimateData[p - 4];
++    SortedMap<Double, Integer> estimateDistances = calcDistances(estimate, estimateVector);
++    int[] nearestNeighbors = getNearestNeighbors(estimateDistances);
++    return getBias(nearestNeighbors, p);
++  }
++
++  private static double getBias(int[] nearestNeighbors, int p) {
++    double[] biasVector = biasData[p - 4];
++    double biasTotal = 0.0d;
++    for (int nearestNeighbor : nearestNeighbors) {
++      biasTotal += biasVector[nearestNeighbor];
++    }
++    return biasTotal / (nearestNeighbors.length);
++  }
++
++  private static int[] getNearestNeighbors(SortedMap<Double, Integer> distanceMap) {
++    int[] nearest = new int[6];
++    int i = 0;
++    for (Integer index : distanceMap.values()) {
++      nearest[i++] = index;
++

<TRUNCATED>


[025/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheXmlGenerator.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheXmlGenerator.java
index 47c341c,0000000..4ba1409
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheXmlGenerator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheXmlGenerator.java
@@@ -1,2850 -1,0 +1,2877 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.xmlcache;
 +
 +import static com.gemstone.gemfire.internal.cache.xmlcache.XmlGeneratorUtils.*;
 +import static com.gemstone.gemfire.management.internal.configuration.utils.XmlConstants.*;
 +import static javax.xml.XMLConstants.*;
 +
 +import java.io.File;
 +import java.io.FileWriter;
 +import java.io.IOException;
 +import java.io.PrintWriter;
 +import java.net.InetSocketAddress;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Comparator;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.TreeSet;
 +
 +import javax.xml.transform.OutputKeys;
 +import javax.xml.transform.Result;
 +import javax.xml.transform.Source;
 +import javax.xml.transform.Transformer;
 +import javax.xml.transform.TransformerFactory;
 +import javax.xml.transform.sax.SAXSource;
 +import javax.xml.transform.stream.StreamResult;
 +
++import com.gemstone.gemfire.cache.wan.*;
 +import org.xml.sax.Attributes;
 +import org.xml.sax.ContentHandler;
 +import org.xml.sax.DTDHandler;
 +import org.xml.sax.EntityResolver;
 +import org.xml.sax.ErrorHandler;
 +import org.xml.sax.InputSource;
 +import org.xml.sax.SAXException;
 +import org.xml.sax.SAXNotRecognizedException;
 +import org.xml.sax.SAXNotSupportedException;
 +import org.xml.sax.XMLReader;
 +import org.xml.sax.ext.LexicalHandler;
 +import org.xml.sax.helpers.AttributesImpl;
 +
 +import com.gemstone.gemfire.InternalGemFireException;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.CustomExpiry;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.Declarable;
 +import com.gemstone.gemfire.cache.DiskStore;
 +import com.gemstone.gemfire.cache.DiskStoreFactory;
 +import com.gemstone.gemfire.cache.DiskWriteAttributes;
 +import com.gemstone.gemfire.cache.DynamicRegionFactory;
 +import com.gemstone.gemfire.cache.EvictionAction;
 +import com.gemstone.gemfire.cache.EvictionAlgorithm;
 +import com.gemstone.gemfire.cache.EvictionAttributes;
 +import com.gemstone.gemfire.cache.ExpirationAction;
 +import com.gemstone.gemfire.cache.ExpirationAttributes;
 +import com.gemstone.gemfire.cache.FixedPartitionAttributes;
 +import com.gemstone.gemfire.cache.InterestPolicy;
 +import com.gemstone.gemfire.cache.MembershipAttributes;
 +import com.gemstone.gemfire.cache.MirrorType;
 +import com.gemstone.gemfire.cache.PartitionAttributes;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.PartitionResolver;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.SubscriptionAttributes;
 +import com.gemstone.gemfire.cache.TransactionListener;
 +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
 +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.client.Pool;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.client.internal.PoolImpl;
 +import com.gemstone.gemfire.cache.execute.Function;
 +import com.gemstone.gemfire.cache.execute.FunctionService;
 +import com.gemstone.gemfire.cache.partition.PartitionListener;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.internal.index.HashIndex;
 +import com.gemstone.gemfire.cache.query.internal.index.PrimaryKeyIndex;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache.server.ServerLoadProbe;
 +import com.gemstone.gemfire.cache.util.ObjectSizer;
- import com.gemstone.gemfire.cache.wan.GatewayEventFilter;
- import com.gemstone.gemfire.cache.wan.GatewayReceiver;
- import com.gemstone.gemfire.cache.wan.GatewaySender;
- import com.gemstone.gemfire.cache.wan.GatewayTransportFilter;
 +import com.gemstone.gemfire.distributed.Role;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.cache.AbstractRegion;
 +import com.gemstone.gemfire.internal.cache.CacheConfig;
 +import com.gemstone.gemfire.internal.cache.ClientSubscriptionConfigImpl;
 +import com.gemstone.gemfire.internal.cache.ColocationHelper;
 +import com.gemstone.gemfire.internal.cache.DiskWriteAttributesImpl;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionAttributesImpl;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.control.MemoryThresholds;
 +import com.gemstone.gemfire.internal.cache.extension.Extensible;
 +import com.gemstone.gemfire.internal.cache.extension.Extension;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.size.SizeClassOnceObjectSizer;
 +import com.gemstone.gemfire.management.internal.configuration.utils.XmlConstants;
 +import com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer;
 +
 +/**
 + * Generates a declarative XML file that describes a given {@link
 + * Cache} instance.  This class was developed for testing purposes,
 + * but it is conceivable that it could be used in the product as well.
 + *
 + * @author David Whitlock
 + *
 + * @since 3.0
 + */
 +@SuppressWarnings("deprecation")
 +public class CacheXmlGenerator extends CacheXml implements XMLReader {
 +
 +  /** An empty <code>Attributes</code> */
 +  private static final Attributes EMPTY = new AttributesImpl();
 +
 +  /** The content handler to which SAX events are generated */
 +  private ContentHandler handler;
 +
 +  /////////////////////////  Instance Fields  ////////////////////////
 +
 +  /** The Cache that we're generating XML for */
 +  final private Cache cache;
 +
 +  /** Will the generated XML file reference an XML schema instead of
 +   * the DTD? */
 +  private boolean useSchema = true;
 +  private boolean includeKeysValues = true;
 +  private final boolean generateDefaults;
 +
 +//  final private int cacheLockLease;
 +//  final private int cacheLockTimeout;
 +//  final private int cacheSearchTimeout;
 +//  final private boolean isServer;
 +//  final private boolean copyOnRead;
 +
 +  /** The <code>CacheCreation</code> from which XML is generated */
 +  private final CacheCreation creation;
 +
 +  ///////////////////////  Static Methods  ///////////////////////
 +
 +
 +  /**
 +   * Examines the given <code>Cache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.  The
 +   * schema/dtd for the current version of GemFire is used.
 +   *
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? For versions 8.1 or newer this should be true,
 +   *        otherwise false.
 +   * @param version
 +   *        The version of GemFire whose DTD/schema should be used in
 +   *        the generated XML.  See {@link #VERSION_4_0}.
 +   *
 +   * @since 4.0
 +   */
 +  public static void generate(Cache cache, PrintWriter pw,
 +                              boolean useSchema, String version) {
 +    (new CacheXmlGenerator(cache, useSchema, version, true)).generate(pw);
 +  }
 +
 +  /**
 +   * Examines the given <code>Cache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.  The
 +   * schema/dtd for the current version of GemFire is used.
 +   *
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? As of 8.1 this value is ignored and always true.
 +   */
 +  public static void generate(Cache cache, PrintWriter pw,
 +                              boolean useSchema) {
 +    (new CacheXmlGenerator(cache, true /*latest version always true*/, VERSION_LATEST, true)).generate(pw);
 +  }
 +
 +  /**
 +   * Examines the given <code>Cache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.  The
 +   * schema/dtd for the current version of GemFire is used.
 +   *
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? As of 8.1 this value is ignored and always true.
 +   * @param includeKeysValues true if the xml should include keys and values
 +   *                          false otherwise
 +   */
 +  public static void generate(Cache cache, PrintWriter pw,
 +                              boolean useSchema, boolean includeKeysValues) {
 +    (new CacheXmlGenerator(cache, true /*latest version always true*/, VERSION_LATEST, includeKeysValues)).generate(pw);
 +  }
 +  /**
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? As of 8.1 this value is ignored and always true.
 +   * @param includeDefaults set to false to cause generated xml to not have defaults values.
 +   */
 +  public static void generate(Cache cache, PrintWriter pw,
 +      boolean useSchema, boolean includeKeysValues, boolean includeDefaults) {
 +    (new CacheXmlGenerator(cache, true /*latest version always true*/, VERSION_LATEST, includeKeysValues, includeDefaults)).generate(pw);
 +  }
 +
 +  /**
 +   * Examines the given <code>Cache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.
 +   */
 +  public static void generate(Cache cache, PrintWriter pw) {
 +    generate(cache, pw, true /* useSchema */);
 +  }
 +
 +  /**
 +   * Examines the given <code>ClientCache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.  The
 +   * schema/dtd for the current version of GemFire is used.
 +   *
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? For versions 8.1 or newer this should be true,
 +   *        otherwise false.
 +   * @param version
 +   *        The version of GemFire whose DTD/schema should be used in
 +   *        the generated XML.  See {@link #VERSION_4_0}.
 +   *
 +   * @since 6.5
 +   */
 +  public static void generate(ClientCache cache, PrintWriter pw,
 +                              boolean useSchema, String version) {
 +    (new CacheXmlGenerator(cache, useSchema, version, true)).generate(pw);
 +  }
 +
 +  /**
 +   * Examines the given <code>ClientCache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.  The
 +   * schema/dtd for the current version of GemFire is used.
 +   *
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? As of 8.1 this value is ignored and always true.
 +   */
 +  public static void generate(ClientCache cache, PrintWriter pw,
 +                              boolean useSchema) {
 +    (new CacheXmlGenerator(cache, true /*latest version always true*/, VERSION_LATEST, true)).generate(pw);
 +  }
 +
 +  /**
 +   * Examines the given <code>ClientCache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.  The
 +   * schema/dtd for the current version of GemFire is used.
 +   *
 +   * @param useSchema
 +   *        Should the generated XML reference a schema (as opposed to
 +   *        a DTD)? As of 8.1 this value is ignored and always true.
 +   * @param includeKeysValues true if the xml should include keys and values
 +   *                          false otherwise
 +   */
 +  public static void generate(ClientCache cache, PrintWriter pw,
 +                              boolean useSchema, boolean includeKeysValues) {
 +    (new CacheXmlGenerator(cache, true /*latest version always true*/, VERSION_LATEST, includeKeysValues)).generate(pw);
 +  }
 +
 +  /**
 +   * Examines the given <code>Cache</code> and from it generates XML
 +   * data that is written to the given <code>PrintWriter</code>.
 +   */
 +  public static void generate(ClientCache cache, PrintWriter pw) {
 +    generate(cache, pw, true /* useSchema */);
 +  }
 +  /**
 +   * Writes a default cache.xml to pw.
 +   */
 +  public static void generateDefault(PrintWriter pw) {
 +    (new CacheXmlGenerator()).generate(pw);
 +  }
 +
 +
 +  ////////////////////////  Constructors  ////////////////////////
 +
 +  /**
 +   * Creates a new <code>CacheXmlGenerator</code> that generates XML
 +   * for a given <code>Cache</code>.
 +   */
 +  private CacheXmlGenerator(Cache cache, boolean useSchema,
 +                            String version, boolean includeKeysValues) {
 +    this(cache, useSchema, version, includeKeysValues, true);
 +  }
 +  private CacheXmlGenerator(Cache cache, boolean useSchema,
 +        String version, boolean includeKeysValues, boolean generateDefaults) {
 +    this.cache = cache;
 +    this.useSchema = useSchema;
 +    this.version = CacheXmlVersion.valueForVersion(version);
 +    this.includeKeysValues = includeKeysValues;
 +    this.generateDefaults = generateDefaults;
 +
 +    if (cache instanceof CacheCreation) {
 +      this.creation = (CacheCreation) cache;
 +      this.creation.startingGenerate();
 +
 +    } else if (cache instanceof GemFireCacheImpl) {
 +      if (((GemFireCacheImpl)cache).isClient()) {
 +        this.creation = new ClientCacheCreation();
 +        if (generateDefaults() || cache.getCopyOnRead()) {
 +          this.creation.setCopyOnRead(cache.getCopyOnRead());
 +        }
 +      } else {
 +        // if we are not generating defaults then create the CacheCreation for parsing
 +        // so that we can fetch the actual PoolManager and not a fake.
 +        this.creation = new CacheCreation(!generateDefaults);
 +        if (generateDefaults() || cache.getLockLease() != GemFireCacheImpl.DEFAULT_LOCK_LEASE) {
 +          this.creation.setLockLease(cache.getLockLease());
 +        }
 +        if (generateDefaults() || cache.getLockTimeout() != GemFireCacheImpl.DEFAULT_LOCK_TIMEOUT) {
 +          this.creation.setLockTimeout(cache.getLockTimeout());
 +        }
 +        if (generateDefaults() || cache.getSearchTimeout() != GemFireCacheImpl.DEFAULT_SEARCH_TIMEOUT) {
 +          this.creation.setSearchTimeout(cache.getSearchTimeout());
 +        }
 +        if (generateDefaults() || cache.isServer()) {
 +          this.creation.setIsServer(cache.isServer());
 +        }
 +        if (generateDefaults() || cache.getCopyOnRead()) {
 +          this.creation.setCopyOnRead(cache.getCopyOnRead());
 +        }
 +      }
 +    } else {
 +      // if we are not generating defaults then create the CacheCreation for parsing
 +      // so that we can fetch the actual PoolManager and not a fake.
 +      this.creation = new CacheCreation(!generateDefaults);
 +      if (generateDefaults() || cache.getLockLease() != GemFireCacheImpl.DEFAULT_LOCK_LEASE) {
 +        this.creation.setLockLease(cache.getLockLease());
 +      }
 +      if (generateDefaults() || cache.getLockTimeout() != GemFireCacheImpl.DEFAULT_LOCK_TIMEOUT) {
 +        this.creation.setLockTimeout(cache.getLockTimeout());
 +      }
 +      if (generateDefaults() || cache.getSearchTimeout() != GemFireCacheImpl.DEFAULT_SEARCH_TIMEOUT) {
 +        this.creation.setSearchTimeout(cache.getSearchTimeout());
 +      }
 +      if (generateDefaults() || cache.isServer()) {
 +        this.creation.setIsServer(cache.isServer());
 +      }
 +      if (generateDefaults() || cache.getCopyOnRead()) {
 +        this.creation.setCopyOnRead(cache.getCopyOnRead());
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Creates a new <code>CacheXmlGenerator</code> that generates XML
 +   * for a given <code>ClientCache</code>.
 +   */
 +  private CacheXmlGenerator(ClientCache cache, boolean useSchema,
 +                            String version, boolean includeKeysValues) {
 +    this.cache = (Cache)cache;
 +    this.useSchema = useSchema;
 +    this.version = CacheXmlVersion.valueForVersion(version);
 +    this.includeKeysValues = includeKeysValues;
 +    this.generateDefaults = true;
 +
 +    if (cache instanceof ClientCacheCreation) {
 +      this.creation = (ClientCacheCreation) cache;
 +      this.creation.startingGenerate();
 +
 +    } else {
 +      this.creation = new ClientCacheCreation();
 +      if (generateDefaults() || cache.getCopyOnRead()) {
 +        this.creation.setCopyOnRead(cache.getCopyOnRead());
 +      }
 +    }
 +  }
 +  /**
 +   * return true if default values should be generated.
 +   */
 +  private boolean generateDefaults() {
 +    return this.generateDefaults;
 +  }
 +  /**
 +   * Creates a generator for a default cache.
 +   */
 +  private CacheXmlGenerator() {
 +    this.cache = null;
 +    this.useSchema = true;
 +    this.version = CacheXmlVersion.valueForVersion(VERSION_LATEST);
 +    this.generateDefaults = true;
 +
 +    this.creation = new CacheCreation();
 +    creation.setLockLease(GemFireCacheImpl.DEFAULT_LOCK_LEASE);
 +    creation.setLockTimeout(GemFireCacheImpl.DEFAULT_LOCK_TIMEOUT);
 +    creation.setSearchTimeout(GemFireCacheImpl.DEFAULT_SEARCH_TIMEOUT);
 +    // No cache proxy
 +    creation.setIsServer(false);
 +    creation.setCopyOnRead(GemFireCacheImpl.DEFAULT_COPY_ON_READ);
 +  }
 +
 +  //////////////////////  Instance Methods  //////////////////////
 +
 +  /**
 +   * Writes the generator's state to pw
 +   */
 +  private void generate(PrintWriter pw) {
 +    // Use JAXP's transformation API to turn SAX events into pretty
 +    // XML text
 +    try {
 +      Source src = new SAXSource(this, new InputSource());
 +      Result res = new StreamResult(pw);
 +
 +      TransformerFactory xFactory = TransformerFactory.newInstance();
 +      Transformer xform = xFactory.newTransformer();
 +      xform.setOutputProperty(OutputKeys.METHOD, "xml");
 +      xform.setOutputProperty(OutputKeys.INDENT, "yes");
 +      if (!useSchema) {
 +        // set the doctype system and public ids from version for older DTDs.
 +        xform.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, version.getSystemId());
 +        xform.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, version.getPublicId());
 +      }
 +      xform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
 +      xform.transform(src, res);
 +      pw.flush();
 +
 +    } catch (Exception ex) {
 +      RuntimeException ex2 = new RuntimeException(LocalizedStrings.CacheXmlGenerator_AN_EXCEPTION_WAS_THROWN_WHILE_GENERATING_XML.toLocalizedString());
 +      ex2.initCause(ex);
 +      throw ex2;
 +    }
 +  }
 +
 +  /**
 +   * Called by the transformer to parse the "input source".  We ignore
 +   * the input source and, instead, generate SAX events to the {@link
 +   * #setContentHandler ContentHandler}.
 +   */
 +  public void parse(InputSource input) throws SAXException {
 +    Assert.assertTrue(this.handler != null);
 +
 +    boolean isClientCache = this.creation instanceof ClientCacheCreation;
 +
 +    handler.startDocument();
 +
 +    AttributesImpl atts = new AttributesImpl();
 +    if (this.useSchema) {
 +      if (null == version.getSchemaLocation()) {
 +        // TODO jbarrett - localize
 +        throw new IllegalStateException("No schema for version " + version.getVersion());
 +      }
 +      // add schema location for cache schema.
 +      handler.startPrefixMapping(W3C_XML_SCHEMA_INSTANCE_PREFIX, W3C_XML_SCHEMA_INSTANCE_NS_URI);
 +      addAttribute(atts, W3C_XML_SCHEMA_INSTANCE_PREFIX, W3C_XML_SCHEMA_INSTANCE_ATTRIBUTE_SCHEMA_LOCATION, NAMESPACE + " " + version.getSchemaLocation());
 +      
 +      // add cache schema to default prefix.
 +      handler.startPrefixMapping(XmlConstants.DEFAULT_PREFIX, NAMESPACE);
 +      addAttribute(atts, VERSION, this.version.getVersion());
 +    }
 +
 +    // Don't generate XML for attributes that are not set.
 +
 +    if (creation.hasLockLease()) {
 +      atts.addAttribute("", "", LOCK_LEASE, "",
 +                        String.valueOf(creation.getLockLease()));
 +    }
 +    if (creation.hasLockTimeout()) {
 +      atts.addAttribute("", "", LOCK_TIMEOUT, "",
 +                        String.valueOf(creation.getLockTimeout()));
 +    }
 +    if (creation.hasSearchTimeout()) {
 +      atts.addAttribute("", "", SEARCH_TIMEOUT, "",
 +                        String.valueOf(creation.getSearchTimeout()));
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_5) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_8) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_6_0) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_6_5) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_7_0) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_7_0) >= 0) {
 +      // TODO
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_1) >= 0) {
 +      if (creation.hasMessageSyncInterval()) {
 +        atts.addAttribute("", "", MESSAGE_SYNC_INTERVAL, "", String
 +            .valueOf(creation.getMessageSyncInterval()));
 +      }
 +    }
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_4_0) >= 0) {
 +      if (creation.hasServer()) {
 +        atts.addAttribute("", "", IS_SERVER, "",
 +                          String.valueOf(creation.isServer()));
 +      }
 +      if (creation.hasCopyOnRead()) {
 +        atts.addAttribute("", "", COPY_ON_READ, "",
 +            String.valueOf(creation.getCopyOnRead()));
 +      }      
 +    }
 +    if (isClientCache) {
 +      handler.startElement("", CLIENT_CACHE, CLIENT_CACHE, atts);
 +    } else {
 +      handler.startElement("", CACHE, CACHE, atts);
 +    }
 +    if (this.cache != null) {
 +      if (!isClientCache) {
 +          generate(this.cache.getCacheTransactionManager());
 +      } else if(this.version.compareTo(CacheXmlVersion.VERSION_6_6) >= 0) {
 +        generate(this.cache.getCacheTransactionManager());
 +      }
 +
 +      generateDynamicRegionFactory(this.cache);
 +
 +      if (!isClientCache) {
 +        if (this.version.compareTo(CacheXmlVersion.VERSION_7_0) >= 0) {
 +          Set<GatewaySender> senderSet = cache.getGatewaySenders();
 +          for (GatewaySender sender : senderSet) {
 +            generateGatewaySender(sender);
 +          }
 +          generateGatewayReceiver(this.cache);
 +          generateAsyncEventQueue(this.cache);
 +        }
 +      }
 +      
 +      if (!isClientCache && this.version.compareTo(CacheXmlVersion.VERSION_7_0) >= 0) {
 +        if (this.cache.getGatewayConflictResolver() != null) {
 +          generate(GATEWAY_CONFLICT_RESOLVER, this.cache.getGatewayConflictResolver());
 +        }
 +      }
 +
 +      if (!isClientCache) {
 +        for (Iterator iter = this.cache.getCacheServers().iterator();
 +             iter.hasNext(); ) {
 +          CacheServer bridge = (CacheServer) iter.next();
 +          generate(bridge);
 +        }
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) >= 0) {
 +        Iterator pools;
 +        if (this.cache instanceof GemFireCacheImpl) {
 +          pools = PoolManager.getAll().values().iterator();
 +        } else {
 +          pools = this.creation.getPools().values().iterator();
 +        }
 +        while (pools.hasNext()) {
 +          Pool cp = (Pool)pools.next();
 +          generate(cp);
 +        }
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_6_5) >= 0) {
 +        if (this.cache instanceof GemFireCacheImpl) {
 +          GemFireCacheImpl gfc = (GemFireCacheImpl)this.cache;
 +          for (DiskStore ds: gfc.listDiskStores()) {
 +            generate(ds);
 +          }
 +        } else {
 +          for (DiskStore ds: this.creation.listDiskStores()) {
 +            generate(ds);
 +          }
 +        }
 +      }
 +      if(this.version.compareTo(CacheXmlVersion.VERSION_6_6) >= 0) {
 +        generatePdx();
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_4_1) >= 0) {
 +        Map namedAttributes = this.cache.listRegionAttributes();
 +        for (Iterator iter = namedAttributes.entrySet().iterator();
 +             iter.hasNext(); ) {
 +          Map.Entry entry = (Map.Entry) iter.next();
 +          String id = (String) entry.getKey();
 +          RegionAttributes attrs = (RegionAttributes) entry.getValue();
 +          // Since CacheCreation predefines these even in later versions
 +          // we need to exclude them in all versions.
 +          // It would be better if CacheCreation could only predefine them
 +          // for versions 6.5 and later but that is not easy to do
 +          /*if (this.version.compareTo(CacheXmlVersion.VERSION_6_5) >= 0)*/ {
 +            if (this.creation instanceof ClientCacheCreation) {
 +              try {
 +                ClientRegionShortcut.valueOf(id);
 +                // skip this guy since id mapped to one of the enum types
 +                continue; 
 +              } catch (IllegalArgumentException ignore) {
 +                // id is not a shortcut so go ahead and call generate
 +              }
 +            } else {
 +              try {
 +                RegionShortcut.valueOf(id);
 +                // skip this guy since id mapped to one of the enum types
 +                continue; 
 +              } catch (IllegalArgumentException ignore) {
 +                // id is not a shortcut so go ahead and call generate
 +              }
 +            }
 +          }
 +          generate(id, attrs);
 +        }
 +      }
 +
 +      if (cache instanceof GemFireCacheImpl) { 
 +    	  generateRegions(); 
 +      }
 +      else { 
 +        TreeSet rSet = new TreeSet(new RegionComparator());
 +        rSet.addAll(this.cache.rootRegions());
 +        Iterator it = rSet.iterator();
 +    	  while (it.hasNext()) { 
 +    		  Region root = (Region)it.next(); 
 +    		  generateRegion(root); 
 +    	  }
 +      }
 +
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_8) >= 0) {
 +        generateFunctionService();
 +      }
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_6_0) >= 0) {
 +        generateResourceManager();
 +        generateSerializerRegistration();
 +      }
 +      if (!isClientCache) {
 +        if (this.version.compareTo(CacheXmlVersion.VERSION_6_5) >= 0) {
 +          if (this.cache instanceof GemFireCacheImpl) {
 +            GemFireCacheImpl gfc = (GemFireCacheImpl)this.cache;
 +            for (File file : gfc.getBackupFiles()) {
 +              generateBackupFile(file);
 +            }
 +          } else {
 +            for (File file: this.creation.getBackupFiles()) {
 +              generateBackupFile(file);
 +            }
 +          }
 +        }
 +      }
 +      if(this.version.compareTo(CacheXmlVersion.VERSION_6_6) >= 0) {
 +        generateInitializer();
 +      }
 +    } else {
 +      if (handler instanceof LexicalHandler) {
 +        //LexicalHandler lex = (LexicalHandler) handler;
 +       //lex.comment(comment.toCharArray(), 0, comment.length());
 +      }
 +
 +    }
 +    
 +    if (cache instanceof Extensible) {
 +      @SuppressWarnings("unchecked")
 +      final Extensible<Cache> extensible = (Extensible<Cache>) cache;
 +      generate(extensible);
 +    }
 +    
 +    if (isClientCache) {
 +      handler.endElement("", CLIENT_CACHE, CLIENT_CACHE);
 +    } else {
 +      handler.endElement("", CACHE, CACHE);
 +    }
 +    handler.endDocument();
 +  }
 +
 +  private void generatePdx() throws SAXException {
 +    AttributesImpl atts = new AttributesImpl();
 +    CacheConfig config;
 +    if(this.cache instanceof CacheCreation) {
 +      config = ((CacheCreation) cache).getCacheConfig();
 +    } else {
 +      config = ((GemFireCacheImpl) cache).getCacheConfig();
 +    }
 +    if(config.pdxReadSerializedUserSet) {
 +      if (generateDefaults() || this.cache.getPdxReadSerialized())
 +      atts.addAttribute("", "", READ_SERIALIZED, "", Boolean.toString(this.cache.getPdxReadSerialized()));
 +    }
 +    if(config.pdxIgnoreUnreadFieldsUserSet) {
 +      if (generateDefaults() || this.cache.getPdxIgnoreUnreadFields())
 +      atts.addAttribute("", "", IGNORE_UNREAD_FIELDS, "", Boolean.toString(this.cache.getPdxIgnoreUnreadFields()));
 +    }
 +    if(config.pdxPersistentUserSet) {
 +      if (generateDefaults() || this.cache.getPdxPersistent())
 +      atts.addAttribute("", "", PERSISTENT, "", Boolean.toString(this.cache.getPdxPersistent()));
 +    }
 +    if(config.pdxDiskStoreUserSet) {
 +      if (generateDefaults() || this.cache.getPdxDiskStore() != null && !this.cache.getPdxDiskStore().equals(""))
 +      atts.addAttribute("", "", DISK_STORE_NAME, "", this.cache.getPdxDiskStore());
 +    }
 +    if(!generateDefaults() && this.cache.getPdxSerializer() == null && atts.getLength() == 0) {
 +      return;
 +    }
 +    handler.startElement("", PDX, PDX, atts);
 +    
 +    if(this.cache.getPdxSerializer() != null) {
 +      generate(PDX_SERIALIZER, this.cache.getPdxSerializer());
 +    }
 +    handler.endElement("", PDX, PDX);
 +  }
 +  
 +  private void generateInitializer() throws SAXException {
 +    if (this.cache.getInitializer() != null) {
 +      generate(INITIALIZER, this.cache.getInitializer(), this.cache.getInitializerProps());
 +    }
 +  }
 +
 +  private void generateRegion(Region root) throws SAXException {
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_0) >= 0) {
 +      generate(root, REGION);
 +    }
 +    else {
 +      generate(root, VM_ROOT_REGION);
 +    }
 +  }
 +  
 +  private void generateRegions() throws SAXException {
 +    Set<Region> colocatedChildRegions = new HashSet<Region>();
 +    Set<Region> generatedRegions = new HashSet<Region>();
 +
 +    //Merge from persist_Nov10 - iterate the regions in order for persistent recovery.
 +    TreeSet rSet = new TreeSet(new RegionComparator());
 +    rSet.addAll(this.cache.rootRegions());
 +    Iterator it = rSet.iterator();
 +    while (it.hasNext()) {
 +      Region root = (Region)it.next();
 +      Assert.assertTrue(root instanceof LocalRegion);
 +      if (root instanceof PartitionedRegion) {
 +        PartitionedRegion pr = (PartitionedRegion)root;
 +        if (pr.getColocatedWith() != null) {
 +          colocatedChildRegions.add(root);
 +        }
 +        else {
 +          generateRegion(root); // normal PR or root in colocated chain
 +          generatedRegions.add(root);
 +        }
 +      }
 +      else {
 +        // normal non pr regions, but they can have PR as subregions
 +        boolean found = false;
 +        for (Object object : root.subregions(false)) {
 +          Region subregion = (Region)object;
 +          Assert.assertTrue(subregion instanceof LocalRegion);
 +          if (subregion instanceof PartitionedRegion) {
 +            PartitionedRegion pr = (PartitionedRegion)subregion;
 +            if (pr.getColocatedWith() != null) {
 +              colocatedChildRegions.add(root);
 +              found = true;
 +              break;
 +            }
 +          }
 +        }
 +        if (!found) {
 +          generateRegion(root); // normal non pr regions
 +          generatedRegions.add(root);
 +        }
 +      }
 +    }
 +    TreeSet rColSet = new TreeSet(new RegionComparator());
 +    rColSet.addAll(colocatedChildRegions);
 +    Iterator colIter = rColSet.iterator();
 +    while (colIter.hasNext()) {
 +      Region root = (Region) colIter.next();
 +      Assert.assertTrue(root instanceof LocalRegion);
 +      if (root instanceof PartitionedRegion) {
 +        PartitionedRegion pr = (PartitionedRegion)root;
 +        PartitionedRegion colocatedWithPr = ColocationHelper
 +            .getColocatedRegion(pr);
 +        if (colocatedWithPr != null
 +            && !generatedRegions.contains(colocatedWithPr)) {
 +          generateRegion(colocatedWithPr);
 +          generatedRegions.add(colocatedWithPr);
 +        }
 +        if (!generatedRegions.contains(root)) {
 +          generateRegion(root);
 +          generatedRegions.add(root);
 +        }
 +      }
 +      else {
 +        generateRegion(root);
 +        generatedRegions.add(root);
 +      }
 +    }
 +  }
 +  /**
 +   * Generate a resource-manager element 
 +   */
 +  private void generateResourceManager() throws SAXException {
 +    AttributesImpl atts = new AttributesImpl();
 +    if (this.cache instanceof CacheCreation && this.creation.hasResourceManager()) {
 +      boolean generateIt = false;
 +      if (this.creation.getResourceManager().hasCriticalHeap()) {
 +        float chp = this.creation.getResourceManager().getCriticalHeapPercentage();
 +        if (generateDefaults() || chp != MemoryThresholds.DEFAULT_CRITICAL_PERCENTAGE) {
 +        atts.addAttribute("", "", CRITICAL_HEAP_PERCENTAGE, "",
 +            String.valueOf(chp));
 +        generateIt = true;
 +        }
 +      }
 +      if (this.creation.getResourceManager().hasEvictionHeap()) {
 +        float ehp = this.creation.getResourceManager().getEvictionHeapPercentage();
 +        if (generateDefaults() || ehp != MemoryThresholds.DEFAULT_EVICTION_PERCENTAGE) {
 +        atts.addAttribute("", "", EVICTION_HEAP_PERCENTAGE, "",
 +            String.valueOf(ehp));
 +        generateIt = true;
 +        }
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_9_0) >= 0) {
 +        if (this.creation.getResourceManager().hasCriticalOffHeap()) {
 +          float chp = this.creation.getResourceManager().getCriticalOffHeapPercentage();
 +          if (generateDefaults() || chp != MemoryThresholds.DEFAULT_CRITICAL_PERCENTAGE) {
 +            atts.addAttribute("", "", CRITICAL_OFF_HEAP_PERCENTAGE, "", String.valueOf(chp));
 +            generateIt = true;
 +          }
 +        }
 +        if (this.creation.getResourceManager().hasEvictionOffHeap()) {
 +          float ehp = this.creation.getResourceManager().getEvictionOffHeapPercentage();
 +          if (generateDefaults() || ehp != MemoryThresholds.DEFAULT_EVICTION_PERCENTAGE) {
 +            atts.addAttribute("", "", EVICTION_OFF_HEAP_PERCENTAGE, "", String.valueOf(ehp));
 +            generateIt = true;
 +          }
 +        }
 +      }
 +      if (generateIt) {
 +        generateResourceManagerElement(atts);
 +      }
 +    } else if (this.cache instanceof GemFireCacheImpl) {
 +      {
 +        int chp = (int)this.cache.getResourceManager().getCriticalHeapPercentage();
 +        if (generateDefaults() || chp != MemoryThresholds.DEFAULT_CRITICAL_PERCENTAGE)
 +
 +        atts.addAttribute("", "", CRITICAL_HEAP_PERCENTAGE, "",
 +            String.valueOf(chp));
 +      }
 +      {
 +        int ehp = (int)this.cache.getResourceManager().getEvictionHeapPercentage();
 +        if (generateDefaults() || ehp != MemoryThresholds.DEFAULT_EVICTION_PERCENTAGE)
 +        atts.addAttribute("", "", EVICTION_HEAP_PERCENTAGE, "",
 +            String.valueOf(ehp));
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_9_0) >= 0) {
 +        {
 +          int chp = (int)this.cache.getResourceManager().getCriticalOffHeapPercentage();
 +          if (generateDefaults() || chp != MemoryThresholds.DEFAULT_CRITICAL_PERCENTAGE)
 +  
 +          atts.addAttribute("", "", CRITICAL_OFF_HEAP_PERCENTAGE, "",
 +              String.valueOf(chp));
 +        }
 +        {
 +          int ehp = (int)this.cache.getResourceManager().getEvictionOffHeapPercentage();
 +          if (generateDefaults() || ehp != MemoryThresholds.DEFAULT_EVICTION_PERCENTAGE)
 +          atts.addAttribute("", "", EVICTION_OFF_HEAP_PERCENTAGE, "",
 +              String.valueOf(ehp));
 +        }
 +      }
 +      if (generateDefaults() || atts.getLength() > 0)
 +      generateResourceManagerElement(atts);
 +    }
 +  }
 +  private void generateResourceManagerElement(AttributesImpl atts) throws SAXException {
 +    handler.startElement("", RESOURCE_MANAGER, RESOURCE_MANAGER, atts);
 +    handler.endElement("", RESOURCE_MANAGER, RESOURCE_MANAGER);
 +  }
 +  
 +  private void generateBackupFile(File file) throws SAXException {
 +    handler.startElement("", BACKUP, BACKUP, EMPTY);
 +    handler.characters(file.getPath().toCharArray(), 0, file.getPath().length());
 +    handler.endElement("", BACKUP, BACKUP);
 +  }
 +
 +  /**
 +   * Generates the <code>serializer-registration</code> element.
 +   * @throws SAXException
 +   */
 +  private void generateSerializerRegistration() throws SAXException {
 +    final SerializerCreation sc = this.creation.getSerializerCreation();
 +    if(sc == null){
 +      return;
 +    }
 +    
 +    handler.startElement("", TOP_SERIALIZER_REGISTRATION, TOP_SERIALIZER_REGISTRATION, EMPTY);
 +    for(Class c : sc.getSerializerRegistrations()) {
 +      handler.startElement("", SERIALIZER_REGISTRATION, SERIALIZER_REGISTRATION, EMPTY);
 +      handler.startElement("", CLASS_NAME, CLASS_NAME, EMPTY);
 +      handler.characters(c.getName().toCharArray(), 0, c.getName().length());
 +      handler.endElement("", CLASS_NAME, CLASS_NAME);
 +      handler.endElement("", SERIALIZER_REGISTRATION, SERIALIZER_REGISTRATION);
 +    }
 +    
 +    for(Map.Entry<Class, Integer> e : sc.getInstantiatorRegistrations().entrySet()) {
 +      Class c = e.getKey();
 +      Integer i = e.getValue();
 +      
 +      AttributesImpl atts = new AttributesImpl();
 +      atts.addAttribute("", "", ID, "", i.toString());
 +      handler.startElement("", INSTANTIATOR_REGISTRATION, INSTANTIATOR_REGISTRATION, atts);
 +      handler.startElement("", CLASS_NAME, CLASS_NAME, EMPTY);
 +      handler.characters(c.getName().toCharArray(), 0, c.getName().length());
 +      handler.endElement("", CLASS_NAME, CLASS_NAME);
 +      handler.endElement("", INSTANTIATOR_REGISTRATION, INSTANTIATOR_REGISTRATION);      
 +    }
 +    
 +    handler.endElement("", TOP_SERIALIZER_REGISTRATION, TOP_SERIALIZER_REGISTRATION);
 +  }
 +
 +  /**
 +   * @throws SAXException 
 +   */
 +  private void generateFunctionService() throws SAXException {
 +    Map<String, Function> functions = FunctionService.getRegisteredFunctions();
 +    if (!generateDefaults() && functions.isEmpty()) {
 +      return;
 +    }
 +    handler.startElement("", FUNCTION_SERVICE, FUNCTION_SERVICE, EMPTY);
 +    for (Function function : functions.values()) {
 +      if (function instanceof Declarable) {
 +        handler.startElement("", FUNCTION, FUNCTION, EMPTY);
 +        generate((Declarable) function, false);
 +        handler.endElement("", FUNCTION, FUNCTION);
 +      }
 +    }
 +    handler.endElement("", FUNCTION_SERVICE, FUNCTION_SERVICE);
 +  }
 +
 +  /**
 +   * Generates XML for the client-subscription tag
 +   * @param bridge instance of <code>CacheServer</code>
 +   * 
 +   * @since 5.7
 +   */
 +  
 +  private void generateClientHaQueue(CacheServer bridge) throws SAXException {
 +    AttributesImpl atts = new AttributesImpl();
 +    ClientSubscriptionConfigImpl csc = (ClientSubscriptionConfigImpl)bridge.getClientSubscriptionConfig();
 +    try {
 +        atts.addAttribute("", "", CLIENT_SUBSCRIPTION_EVICTION_POLICY, "", csc.getEvictionPolicy());
 +        atts.addAttribute("", "", CLIENT_SUBSCRIPTION_CAPACITY, "", String.valueOf(csc.getCapacity()));
 +        if (this.version.compareTo(CacheXmlVersion.VERSION_6_5) >= 0) {
 +          String dsVal = csc.getDiskStoreName();
 +          if (dsVal != null) {
 +            atts.addAttribute("", "", DISK_STORE_NAME, "", dsVal);
 +          }
 +        }
 +        if (csc.getDiskStoreName() == null && csc.hasOverflowDirectory()) {
 +          atts.addAttribute("", "", OVERFLOW_DIRECTORY, "", csc.getOverflowDirectory());
 +        }
 +        handler.startElement("", CLIENT_SUBSCRIPTION, CLIENT_SUBSCRIPTION, atts);
 +        handler.endElement("", CLIENT_SUBSCRIPTION, CLIENT_SUBSCRIPTION);
 +      
 +    } catch (Exception ex) {
 +      ex.printStackTrace();
 +    }     
 +  }
 +
 +  /**
 +   * Generates XML for the given cache server
 +   *
 +   * @since 4.0
 +   */
 +  private void generate(CacheServer bridge) throws SAXException {
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_4_0) < 0) {
 +      return;
 +    }
 +    AttributesImpl atts = new AttributesImpl();
 +    try {
 +      if (generateDefaults() || bridge.getPort() != CacheServer.DEFAULT_PORT)
 +      atts.addAttribute("", "", PORT, "",
 +          String.valueOf(bridge.getPort()));
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_4_1) < 0) {
 +        return;
 +      }
 +      if (generateDefaults() || bridge.getMaximumTimeBetweenPings() != CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS)
 +      atts.addAttribute("", "", MAXIMUM_TIME_BETWEEN_PINGS, "",
 +          String.valueOf(bridge.getMaximumTimeBetweenPings()));
 +
 +      if (generateDefaults() || bridge.getNotifyBySubscription() != CacheServer.DEFAULT_NOTIFY_BY_SUBSCRIPTION)
 +      atts.addAttribute("", "", NOTIFY_BY_SUBSCRIPTION, "",
 +          String.valueOf(bridge.getNotifyBySubscription()));
 +
 +      if (generateDefaults() || bridge.getSocketBufferSize() != CacheServer.DEFAULT_SOCKET_BUFFER_SIZE)
 +      atts.addAttribute("", "", SOCKET_BUFFER_SIZE, "",
 +          String.valueOf(bridge.getSocketBufferSize()));
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_0) < 0) {
 +        return;
 +      }
 +      
 +      if (generateDefaults() || bridge.getMaxConnections() != CacheServer.DEFAULT_MAX_CONNECTIONS)
 +      atts.addAttribute("", "", MAX_CONNECTIONS, "",
 +          String.valueOf(bridge.getMaxConnections()));
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_1) < 0) {
 +        return;
 +      }
 +
 +      if (generateDefaults() || bridge.getMaxThreads() != CacheServer.DEFAULT_MAX_THREADS)
 +      atts.addAttribute("", "", MAX_THREADS, "",
 +          String.valueOf(bridge.getMaxThreads()));
 +      if (generateDefaults() || bridge.getMaximumMessageCount() != CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT)
 +      atts.addAttribute("", "", MAXIMUM_MESSAGE_COUNT, "",
 +          String.valueOf(bridge.getMaximumMessageCount()));
 +      
 +      if (generateDefaults() || bridge.getMessageTimeToLive() != CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE)
 +      atts.addAttribute("", "", MESSAGE_TIME_TO_LIVE, "",
 +          String.valueOf(bridge.getMessageTimeToLive()));
 +      
 +      
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) < 0) {
 +        return;
 +      }
 +      
 +      if(bridge.getBindAddress() != null) {
 +        if (generateDefaults() || bridge.getBindAddress() != CacheServer.DEFAULT_BIND_ADDRESS)
 +        atts.addAttribute("","",BIND_ADDRESS,"",bridge.getBindAddress());
 +      }
 +  
 +      if (bridge.getHostnameForClients() != null
 +          && !bridge.getHostnameForClients().equals("")) {
 +        atts.addAttribute("", "", HOSTNAME_FOR_CLIENTS, "", bridge.getHostnameForClients());
 +      }
 +      if (generateDefaults() || bridge.getLoadPollInterval() != CacheServer.DEFAULT_LOAD_POLL_INTERVAL)
 +      atts.addAttribute("", "", LOAD_POLL_INTERVAL, "", String.valueOf(bridge.getLoadPollInterval()));
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_8_0) < 0) {
 +        return;
 +      }
 +
 +      if (generateDefaults() || bridge.getTcpNoDelay() != CacheServer.DEFAULT_TCP_NO_DELAY) {
 +        atts.addAttribute("", "", TCP_NO_DELAY, "", ""+bridge.getTcpNoDelay());
 +      }
 +
 +    } finally {
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) >= 0) {
 +        handler.startElement("", CACHE_SERVER, CACHE_SERVER, atts);
 +      } else {
 +        handler.startElement("", BRIDGE_SERVER, BRIDGE_SERVER, atts);
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) >= 0) {
 +        String[] groups = bridge.getGroups();
 +        if (groups.length > 0) {
 +          for (int i = 0; i < groups.length; i++) {
 +            String group = groups[i];
 +            handler.startElement("", GROUP, GROUP, EMPTY);
 +            handler.characters(group.toCharArray(), 0, group.length());
 +            handler.endElement("", GROUP, GROUP);
 +          }
 +        }
 +        
 +        if(!bridge.getClientSubscriptionConfig().getEvictionPolicy().equals("none")){
 +          generateClientHaQueue(bridge);
 +        }
 +        
 +        ServerLoadProbe probe = bridge.getLoadProbe();
 +        if (generateDefaults() || !probe.equals(CacheServer.DEFAULT_LOAD_PROBE)) {
 +          generate(LOAD_PROBE, probe);
 +        }
 +        
 +        
 +      }
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) >= 0) {
 +        handler.endElement("", "", CACHE_SERVER);
 +      } else {
 +        handler.endElement("", "", BRIDGE_SERVER);
 +      }
 +    } 
 +  }
 +  
 +  /**
 +   * Generates XML for the given disk store
 +   *
 +   * @since prPersistSprint2
 +   */
 +  private void generate(DiskStore ds) throws SAXException {
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_6_5) < 0) {
 +      return;
 +    }
 +    AttributesImpl atts = new AttributesImpl();
 +    try {
 +      atts.addAttribute("", "", NAME, "", ds.getName());
 +
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasAutoCompact())) {
 +        if (generateDefaults() || ds.getAutoCompact() != DiskStoreFactory.DEFAULT_AUTO_COMPACT)
 +        atts.addAttribute("", "", AUTO_COMPACT, "", 
 +            String.valueOf(ds.getAutoCompact()));
 +      }
 +
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasAllowForceCompaction())) {
 +        if (generateDefaults() || ds.getAllowForceCompaction() != DiskStoreFactory.DEFAULT_ALLOW_FORCE_COMPACTION)
 +        atts.addAttribute("", "", ALLOW_FORCE_COMPACTION, "", 
 +            String.valueOf(ds.getAllowForceCompaction()));
 +      }
 +
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasCompactionThreshold())) {
 +        if (generateDefaults() || ds.getCompactionThreshold() != DiskStoreFactory.DEFAULT_COMPACTION_THRESHOLD)
 +        atts.addAttribute("", "", COMPACTION_THRESHOLD, "", 
 +            String.valueOf(ds.getCompactionThreshold()));
 +      }
 +      
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasMaxOplogSize())) {
 +        if (generateDefaults() || ds.getMaxOplogSize() != DiskStoreFactory.DEFAULT_MAX_OPLOG_SIZE)
 +        atts.addAttribute("", "", MAX_OPLOG_SIZE, "", 
 +            String.valueOf(ds.getMaxOplogSize()));
 +      }
 +
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasTimeInterval())) {
 +        if (generateDefaults() || ds.getTimeInterval() != DiskStoreFactory.DEFAULT_TIME_INTERVAL)
 +        atts.addAttribute("", "", TIME_INTERVAL, "", 
 +            String.valueOf(ds.getTimeInterval()));
 +      }
 +
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasWriteBufferSize())) {
 +        if (generateDefaults() || ds.getWriteBufferSize() != DiskStoreFactory.DEFAULT_WRITE_BUFFER_SIZE)
 +        atts.addAttribute("", "", WRITE_BUFFER_SIZE, "", 
 +            String.valueOf(ds.getWriteBufferSize()));
 +      }
 +      
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasQueueSize())) {
 +        if (generateDefaults() || ds.getQueueSize() != DiskStoreFactory.DEFAULT_QUEUE_SIZE)
 +        atts.addAttribute("", "", QUEUE_SIZE, "", 
 +            String.valueOf(ds.getQueueSize()));
 +      }
 +      
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_8_0) >= 0) {
 +        if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +            ((DiskStoreAttributesCreation) ds).hasDiskUsageWarningPercentage())) {
 +          if (generateDefaults() || ds.getDiskUsageWarningPercentage() != DiskStoreFactory.DEFAULT_DISK_USAGE_WARNING_PERCENTAGE)
 +          atts.addAttribute("", "", DISK_USAGE_WARNING_PERCENTAGE, "", 
 +              String.valueOf(ds.getDiskUsageWarningPercentage()));
 +        }
 +        
 +        if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +            ((DiskStoreAttributesCreation) ds).hasDiskUsageCriticalPercentage())) {
 +          if (generateDefaults() || ds.getDiskUsageCriticalPercentage() != DiskStoreFactory.DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE)
 +          atts.addAttribute("", "", DISK_USAGE_CRITICAL_PERCENTAGE, "", 
 +              String.valueOf(ds.getDiskUsageCriticalPercentage()));
 +        }
 +      }
 +    } finally {
 +      handler.startElement("", DISK_STORE, DISK_STORE, atts);
 +      
 +      if ((!(ds instanceof DiskStoreAttributesCreation) ||
 +          ((DiskStoreAttributesCreation) ds).hasDiskDirs())) {
 +        File[] diskDirs = ds.getDiskDirs();
 +        int[] diskSizes = ds.getDiskDirSizes();
 +        if (diskDirs != null && diskDirs.length > 0) {
 +          if (generateDefaults() || !Arrays.equals(diskDirs, DiskStoreFactory.DEFAULT_DISK_DIRS)
 +              || !Arrays.equals(diskSizes, DiskStoreFactory.DEFAULT_DISK_DIR_SIZES)) {
 +          handler.startElement("", DISK_DIRS, DISK_DIRS, EMPTY);
 +          for (int i = 0; i < diskDirs.length; i++) {
 +            AttributesImpl diskAtts = new AttributesImpl();
 +            if (diskSizes[i] != DiskStoreFactory.DEFAULT_DISK_DIR_SIZE) {
 +              diskAtts.addAttribute("", "", DIR_SIZE, "", String
 +                  .valueOf(diskSizes[i]));
 +            }
 +            handler.startElement("", DISK_DIR, DISK_DIR, diskAtts);
 +            File dir = diskDirs[i];
 +            String name = generateDefaults() ? dir.getAbsolutePath() : dir.getPath();
 +            handler.characters(name.toCharArray(), 0, name.length());
 +            handler.endElement("", DISK_DIR, DISK_DIR);
 +          }
 +          handler.endElement("", DISK_DIRS, DISK_DIRS);
 +          }
 +        }
 +      }
 +
 +      handler.endElement("", "", DISK_STORE);
 +    } 
 +  }
 +  
 +  /** Compare regions by name 
 +   * 
 +   * @author lynn
 +   *
 +   */
 +  class RegionComparator implements Comparator {
 +    public int compare(Object o1, Object o2) {
 +       return (((Region)o1).getFullPath().compareTo(((Region)o2).getFullPath()));
 +    }
 +    public boolean equals(Object anObj) {
 +       return ((Region)this).getFullPath().equals(((Region)anObj).getFullPath());
 +    }
 + }
 +
 +
 +  /**
 +   * Generates XML for the given connection pool
 +   *
 +   * @since 5.7
 +   */
 +  private void generate(Pool cp) throws SAXException {
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) < 0) {
 +      return;
 +    }
 +    if (((PoolImpl)cp).isUsedByGateway()) {
 +      // no need to generate xml for gateway pools
 +      return;
 +    }
 +    AttributesImpl atts = new AttributesImpl();
 +    try {
 +      atts.addAttribute("", "", NAME, "", cp.getName());
 +      if (generateDefaults() || cp.getFreeConnectionTimeout() != PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT)
 +      atts.addAttribute("", "", FREE_CONNECTION_TIMEOUT, "",
 +                        String.valueOf(cp.getFreeConnectionTimeout()));
 +      if (generateDefaults() || cp.getLoadConditioningInterval() != PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL)
 +      atts.addAttribute("", "", LOAD_CONDITIONING_INTERVAL, "",
 +                        String.valueOf(cp.getLoadConditioningInterval()));
 +      if (generateDefaults() || cp.getMinConnections() != PoolFactory.DEFAULT_MIN_CONNECTIONS)
 +      atts.addAttribute("", "", MIN_CONNECTIONS, "",
 +                        String.valueOf(cp.getMinConnections()));
 +      if (generateDefaults() || cp.getMaxConnections() != PoolFactory.DEFAULT_MAX_CONNECTIONS)
 +      atts.addAttribute("", "", MAX_CONNECTIONS, "",
 +          String.valueOf(cp.getMaxConnections()));
 +      if (generateDefaults() || cp.getRetryAttempts() != PoolFactory.DEFAULT_RETRY_ATTEMPTS)
 +      atts.addAttribute("", "", RETRY_ATTEMPTS, "",
 +          String.valueOf(cp.getRetryAttempts()));
 +      if (generateDefaults() || cp.getIdleTimeout() != PoolFactory.DEFAULT_IDLE_TIMEOUT)
 +      atts.addAttribute("", "", IDLE_TIMEOUT, "",
 +          String.valueOf(cp.getIdleTimeout()));
 +      if (generateDefaults() || cp.getPingInterval() != PoolFactory.DEFAULT_PING_INTERVAL)
 +      atts.addAttribute("", "", PING_INTERVAL, "",
 +          String.valueOf(cp.getPingInterval()));
 +      if (generateDefaults() || cp.getStatisticInterval() != PoolFactory.DEFAULT_STATISTIC_INTERVAL)
 +      atts.addAttribute("", "", STATISTIC_INTERVAL, "",
 +          String.valueOf(cp.getStatisticInterval()));
 +      if (generateDefaults() || cp.getSubscriptionAckInterval() != PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL)
 +      atts.addAttribute("", "", SUBSCRIPTION_ACK_INTERVAL, "",
 +          String.valueOf(cp.getSubscriptionAckInterval()));
 +      if (generateDefaults() || cp.getSubscriptionEnabled() != PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED)
 +      atts.addAttribute("", "", SUBSCRIPTION_ENABLED, "",
 +                        String.valueOf(cp.getSubscriptionEnabled()));
 +      if (generateDefaults() || cp.getSubscriptionMessageTrackingTimeout() != PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT)
 +      atts.addAttribute("", "", SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT, "",
 +                        String.valueOf(cp.getSubscriptionMessageTrackingTimeout()));
 +      if (generateDefaults() || cp.getSubscriptionRedundancy() != PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY)
 +      atts.addAttribute("", "", SUBSCRIPTION_REDUNDANCY, "",
 +                        String.valueOf(cp.getSubscriptionRedundancy()));
 +      if (generateDefaults() || cp.getReadTimeout() != PoolFactory.DEFAULT_READ_TIMEOUT)
 +      atts.addAttribute("", "", READ_TIMEOUT, "",
 +                        String.valueOf(cp.getReadTimeout()));
 +      if (cp.getServerGroup() != null && !cp.getServerGroup().equals("")) {
 +        atts.addAttribute("", "", SERVER_GROUP, "", cp.getServerGroup());
 +      }
 +      if (generateDefaults() || cp.getSocketBufferSize() != PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE)
 +      atts.addAttribute("", "", SOCKET_BUFFER_SIZE, "",
 +                        String.valueOf(cp.getSocketBufferSize()));
 +      if (generateDefaults() || cp.getThreadLocalConnections() != PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS)
 +      atts.addAttribute("", "", THREAD_LOCAL_CONNECTIONS, "",
 +                        String.valueOf(cp.getThreadLocalConnections()));
 +
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_6_1) > 0) {
 +        if (generateDefaults() || cp.getPRSingleHopEnabled() != PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED)
 +        atts.addAttribute("", "", PR_SINGLE_HOP_ENABLED, "",
 +            String.valueOf(cp.getPRSingleHopEnabled()));  
 +      }
 +
 +      if (this.version.compareTo(CacheXmlVersion.VERSION_6_1) > 0) {
 +        if (generateDefaults() || cp.getMultiuserAuthentication() != PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION)
 +        atts.addAttribute("", "", MULTIUSER_SECURE_MODE_ENABLED, "", String.valueOf(cp
 +            .getMultiuserAuthentication()));
 +      }
 +    } finally {
 +      handler.startElement("", CONNECTION_POOL, CONNECTION_POOL, atts);
 +      {
 +        Iterator/*<InetSocketAddress>*/ locators = cp.getLocators().iterator();
 +        while (locators.hasNext()) {
 +          InetSocketAddress addr = (InetSocketAddress)locators.next();
 +          AttributesImpl sAtts = new AttributesImpl();
 +          sAtts.addAttribute("", "", HOST, "", addr.getHostName());
 +          sAtts.addAttribute("", "", PORT, "", String.valueOf(addr.getPort()));
 +          handler.startElement("", LOCATOR, LOCATOR, sAtts);
 +          handler.endElement("", LOCATOR, LOCATOR);
 +        }
 +      }
 +      {
 +        Iterator/*<InetSocketAddress>*/ servers = cp.getServers().iterator();
 +        while (servers.hasNext()) {
 +          InetSocketAddress addr = (InetSocketAddress)servers.next();
 +          AttributesImpl sAtts = new AttributesImpl();
 +          sAtts.addAttribute("", "", HOST, "", addr.getHostName());
 +          sAtts.addAttribute("", "", PORT, "", String.valueOf(addr.getPort()));
 +          handler.startElement("", SERVER, SERVER, sAtts);
 +          handler.endElement("", SERVER, SERVER);
 +        }
 +      }
 +      handler.endElement("", "", CONNECTION_POOL);
 +    } 
 +  }
 +
 +  /**
 +   * Generates XML for a CacheTransactionManager
 +   *
 +   * @since 4.0
 +   */
 +  private void generate(CacheTransactionManager txMgr) throws SAXException {
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_4_0) < 0) {
 +      return;
 +    }
 +
 +    if (txMgr == null) {
 +      return;
 +    }
 +    if (!generateDefaults() && txMgr.getWriter() == null
 +        && txMgr.getListeners().length == 0) {
 +      return;
 +    }
 +
 +    handler.startElement("", TRANSACTION_MANAGER, TRANSACTION_MANAGER, EMPTY);
 +    {
 +      TransactionListener[] listeners = txMgr.getListeners();
 +      for (int i=0; i < listeners.length; i++) {
 +        generate(TRANSACTION_LISTENER, listeners[i]);
 +      }
 +      if(txMgr.getWriter()!=null) {
 +        generate(TRANSACTION_WRITER, txMgr.getWriter());
 +      }
 +    }
 +    handler.endElement("", TRANSACTION_MANAGER, TRANSACTION_MANAGER);
 +  }
 +
 +  /**
 +   * Generates XML for a DynamicRegionFactory.Config
 +   *
 +   * @since 4.3
 +   */
 +  private void generateDynamicRegionFactory(Cache c) throws SAXException {
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_4_1) < 0) {
 +      return;
 +    }
 +    DynamicRegionFactory.Config cfg;
 +    if (c instanceof CacheCreation) {
 +      cfg = ((CacheCreation)c).getDynamicRegionFactoryConfig();
 +    } else {
 +      DynamicRegionFactory drf = DynamicRegionFactory.get();
 +      if (drf == null || drf.isClosed()) {
 +        return;
 +      }
 +      cfg = drf.getConfig();
 +    }
 +    if (cfg == null) {
 +      return;
 +    }
 +    AttributesImpl atts = new AttributesImpl();
 +    if (!cfg.getPersistBackup())
 +      atts.addAttribute("", "", DISABLE_PERSIST_BACKUP, "", "true");
 +    if (!cfg.getRegisterInterest())
 +      atts.addAttribute("", "", DISABLE_REGISTER_INTEREST, "", "true");
 +    if(cfg.getPoolName() != null) {
 +      atts.addAttribute("", "", POOL_NAME, "", cfg.getPoolName());
 +    }
 +    handler.startElement("", DYNAMIC_REGION_FACTORY, DYNAMIC_REGION_FACTORY, atts);
 +    {
 +      File dir = cfg.getDiskDir();
 +      if (dir != null) {
 +        handler.startElement("", DISK_DIR, DISK_DIR, EMPTY);
 +        String name = generateDefaults() ? dir.getAbsolutePath() : dir.getPath();
 +        handler.characters(name.toCharArray(), 0, name.length());
 +        handler.endElement("", DISK_DIR, DISK_DIR);
 +      }
 +    }
 +    handler.endElement("", DYNAMIC_REGION_FACTORY, DYNAMIC_REGION_FACTORY);
 +  }
 +
 +  private void generateGatewaySender(GatewaySender sender) throws SAXException {
 +      AttributesImpl atts = new AttributesImpl();
 +      // id
 +      atts.addAttribute("", "", ID, "", sender.getId());
 +      // remote-distributed-system
 +      atts.addAttribute("", "", REMOTE_DISTRIBUTED_SYSTEM_ID, "", String
 +        .valueOf(sender.getRemoteDSId()));
 +      // parallel
 +      if (generateDefaults() || sender.isParallel() != GatewaySender.DEFAULT_IS_PARALLEL)
 +      atts.addAttribute("", "", PARALLEL, "", String.valueOf(sender.isParallel()));
 +      // manual-start
 +      if (generateDefaults() || sender.isManualStart() != GatewaySender.DEFAULT_MANUAL_START)
 +      atts.addAttribute("", "", MANUAL_START, "", String.valueOf(sender.isManualStart()));
 +      // socket-buffer-size
 +      if (generateDefaults() || sender.getSocketBufferSize() != GatewaySender.DEFAULT_SOCKET_BUFFER_SIZE)
 +      atts.addAttribute("", "", SOCKET_BUFFER_SIZE, "", String.valueOf(sender
 +          .getSocketBufferSize()));
 +      // socket-read-timeout
 +      if (generateDefaults() || sender.getSocketReadTimeout() != GatewaySender.DEFAULT_SOCKET_READ_TIMEOUT)
 +      atts.addAttribute("", "", SOCKET_READ_TIMEOUT, "", String.valueOf(sender
 +          .getSocketReadTimeout()));
 +      // enable-batch-conflation
 +      if (generateDefaults() || sender.isBatchConflationEnabled() != GatewaySender.DEFAULT_BATCH_CONFLATION)
 +      atts.addAttribute("", "", ENABLE_BATCH_CONFLATION, "", String.valueOf(sender
 +          .isBatchConflationEnabled())); // Should we use ENABLE-CONFLATION
 +      // batch-size
 +      if (generateDefaults() || sender.getBatchSize() != GatewaySender.DEFAULT_BATCH_SIZE)
 +      atts.addAttribute("", "", BATCH_SIZE, "", String.valueOf(sender
 +          .getBatchSize()));
 +      // batch-time-interval
 +      if (generateDefaults() || sender.getBatchTimeInterval() != GatewaySender.DEFAULT_BATCH_TIME_INTERVAL)
 +      atts.addAttribute("", "", BATCH_TIME_INTERVAL, "", String.valueOf(sender
 +          .getBatchTimeInterval()));
 +      // enable-persistence
 +      if (generateDefaults() || sender.isPersistenceEnabled() != GatewaySender.DEFAULT_PERSISTENCE_ENABLED)
 +      atts.addAttribute("", "", ENABLE_PERSISTENCE, "", String.valueOf(sender
 +          .isPersistenceEnabled()));
 +      // disk-store-name
 +      if (generateDefaults() || sender.getDiskStoreName() != null && !sender.getDiskStoreName().equals(""))
 +      atts.addAttribute("", "", DISK_STORE_NAME, "", String.valueOf(sender
 +          .getDiskStoreName()));
 +      // disk-synchronous
 +      if (generateDefaults() || sender.isDiskSynchronous() != GatewaySender.DEFAULT_DISK_SYNCHRONOUS)
 +      atts.addAttribute("", "", DISK_SYNCHRONOUS, "", String.valueOf(sender
 +          .isDiskSynchronous()));
 +      // maximum-queue-memory
 +      if (generateDefaults() || sender.getMaximumQueueMemory() != GatewaySender.DEFAULT_MAXIMUM_QUEUE_MEMORY)
 +      atts.addAttribute("", "", MAXIMUM_QUEUE_MEMORY, "", String.valueOf(sender
 +          .getMaximumQueueMemory()));
 +      // alert-threshold
 +      if (generateDefaults() || sender.getAlertThreshold() != GatewaySender.DEFAULT_ALERT_THRESHOLD)
 +      atts.addAttribute("", "", ALERT_THRESHOLD, "", String.valueOf(sender
 +          .getAlertThreshold()));
 +
 +      // dispatcher-threads
 +      if (generateDefaults() || sender.getDispatcherThreads() != GatewaySender.DEFAULT_DISPATCHER_THREADS)
 +      atts.addAttribute("", "", DISPATCHER_THREADS, "", String.valueOf(sender
 +          .getDispatcherThreads()));
 +      // order-policy
 +      if (sender.getOrderPolicy() != null) {
 +        if (generateDefaults() || !sender.getOrderPolicy().equals(GatewaySender.DEFAULT_ORDER_POLICY))
 +        atts.addAttribute("", "", ORDER_POLICY, "", String.valueOf(sender
 +          .getOrderPolicy()));
 +      }
 +      
 +      handler.startElement("", GATEWAY_SENDER, GATEWAY_SENDER, atts);
 +      
 +      for (GatewayEventFilter gef : sender.getGatewayEventFilters()) {
 +         generateGatewayEventFilter(gef);
 +      }
 +
++      if (this.version.compareTo(CacheXmlVersion.VERSION_8_0) >= 0) {
++        if (sender.getGatewayEventSubstitutionFilter() != null) {
++          generateGatewayEventSubstitutionFilter(sender.getGatewayEventSubstitutionFilter());
++        }
++      }
++
 +      for (GatewayTransportFilter gsf : sender.getGatewayTransportFilters()) {
 +        generateGatewayTransportFilter(gsf);
 +     }
 +
 +      handler.endElement("", GATEWAY_SENDER, GATEWAY_SENDER);
 +  }
 +
 +  private void generateAsyncEventQueue(Cache cache) throws SAXException {
 +    Set<AsyncEventQueue> asyncEventQueues = cache.getAsyncEventQueues();
 +    for (AsyncEventQueue asyncEventQueue : asyncEventQueues) {
 +      AttributesImpl atts = new AttributesImpl();
 +      // id
 +      atts.addAttribute("", "", ID, "", asyncEventQueue.getId());
 +      // parallel
 +      if (generateDefaults() || asyncEventQueue.isParallel() != GatewaySender.DEFAULT_IS_PARALLEL)
 +      atts.addAttribute("", "", PARALLEL, "", String.valueOf(asyncEventQueue.isParallel()));
 +      // batch-size
 +      if (generateDefaults() || asyncEventQueue.getBatchSize() != GatewaySender.DEFAULT_BATCH_SIZE)
 +      atts.addAttribute("", "", BATCH_SIZE, "", String.valueOf(asyncEventQueue
 +        .getBatchSize()));
 +      // batch-time-interval
 +      if (generateDefaults() || asyncEventQueue.getBatchTimeInterval() != GatewaySender.DEFAULT_BATCH_TIME_INTERVAL)
 +      atts.addAttribute("", "", BATCH_TIME_INTERVAL, "", String.valueOf(asyncEventQueue
 +          .getBatchTimeInterval()));
 +      // enable-batch-conflation
 +      if (generateDefaults() || asyncEventQueue.isBatchConflationEnabled() != GatewaySender.DEFAULT_BATCH_CONFLATION)
 +      atts.addAttribute("", "", ENABLE_BATCH_CONFLATION, "", String.valueOf(asyncEventQueue
 +          .isBatchConflationEnabled()));
 +      // maximum-queue-memory
 +      if (generateDefaults() || asyncEventQueue.getMaximumQueueMemory() != GatewaySender.DEFAULT_MAXIMUM_QUEUE_MEMORY)
 +      atts.addAttribute("", "", MAXIMUM_QUEUE_MEMORY, "", String.valueOf(asyncEventQueue
 +        .getMaximumQueueMemory()));
 +      // enable-persistence
 +      if (generateDefaults() || asyncEventQueue.isPersistent() != GatewaySender.DEFAULT_PERSISTENCE_ENABLED)
 +      atts.addAttribute("", "", PERSISTENT, "", String.valueOf(asyncEventQueue
 +        .isPersistent()));
 +      if (asyncEventQueue.isPersistent()) {
 +        //disk-store-name
 +        if (generateDefaults() || (asyncEventQueue.getDiskStoreName() != null && !asyncEventQueue.getDiskStoreName().equals("")))
 +        atts.addAttribute("", "", DISK_STORE_NAME, "", String.valueOf(asyncEventQueue
 +            .getDiskStoreName()));
 +      }
 +      // dispatcher-threads
 +      if (generateDefaults() || asyncEventQueue.getDispatcherThreads() != GatewaySender.DEFAULT_DISPATCHER_THREADS)
 +      atts.addAttribute("", "", DISPATCHER_THREADS, "", String.valueOf(asyncEventQueue
 +          .getDispatcherThreads()));
 +      // order-policy
 +      if (asyncEventQueue.getOrderPolicy() != null) {
 +        if (generateDefaults() || !asyncEventQueue.getOrderPolicy().equals(GatewaySender.DEFAULT_ORDER_POLICY))
 +        atts.addAttribute("", "", ORDER_POLICY, "", String.valueOf(asyncEventQueue
 +          .getOrderPolicy()));
 +      }
 +      // disk-synchronous
 +      if (generateDefaults() || asyncEventQueue.isDiskSynchronous() != GatewaySender.DEFAULT_DISK_SYNCHRONOUS)
 +      atts.addAttribute("", "", DISK_SYNCHRONOUS, "", String.valueOf(asyncEventQueue
 +          .isDiskSynchronous()));
 +      handler.startElement("", ASYNC_EVENT_QUEUE, ASYNC_EVENT_QUEUE, atts);
 +    
 +      List<GatewayEventFilter> eventFilters = asyncEventQueue.getGatewayEventFilters();
 +      if (eventFilters != null) {
 +    	  for (GatewayEventFilter eventFilter : eventFilters) {
 +    		generateGatewayEventFilter(eventFilter);
 +    	  }
 +      }
-       
++
++      if (this.version.compareTo(CacheXmlVersion.VERSION_8_0) >= 0) {
++        if (asyncEventQueue.getGatewayEventSubstitutionFilter() != null) {
++          generateGatewayEventSubstitutionFilter(asyncEventQueue.getGatewayEventSubstitutionFilter());
++        }
++      }
++
 +      AsyncEventListener asyncListener = asyncEventQueue.getAsyncEventListener();
 +      if (asyncListener != null) {
 +        generate(ASYNC_EVENT_LISTENER, asyncListener);
 +      }
 +      
 +      handler.endElement("", ASYNC_EVENT_QUEUE, ASYNC_EVENT_QUEUE);
 +    }
 +}
 +
 +  
 +  private void generateGatewayReceiver(Cache cache) throws SAXException {
 +    Set<GatewayReceiver> receiverList = cache.getGatewayReceivers();
 +    for (GatewayReceiver receiver : receiverList) {
 +      AttributesImpl atts = new AttributesImpl();
 +      try {
 +        // start port
 +        if (generateDefaults()
 +            || receiver.getStartPort() != GatewayReceiver.DEFAULT_START_PORT)
 +          atts.addAttribute("", "", START_PORT, "",
 +              String.valueOf(receiver.getStartPort()));
 +        // end port
 +        if (generateDefaults()
 +            || receiver.getEndPort() != GatewayReceiver.DEFAULT_END_PORT)
 +          atts.addAttribute("", "", END_PORT, "",
 +              String.valueOf(receiver.getEndPort()));
 +        // bind-address
 +        if (generateDefaults()
 +            || (receiver.getBindAddress() != null && !receiver.getBindAddress()
 +                .equals(GatewayReceiver.DEFAULT_BIND_ADDRESS)))
 +          atts.addAttribute("", "", BIND_ADDRESS, "", receiver.getBindAddress());
 +        // maximum-time-between-pings
 +        if (generateDefaults()
 +            || receiver.getMaximumTimeBetweenPings() != GatewayReceiver.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS)
 +          atts.addAttribute("", "", MAXIMUM_TIME_BETWEEN_PINGS, "",
 +              String.valueOf(receiver.getMaximumTimeBetweenPings()));
 +        // socket-buffer-size
 +        if (generateDefaults()
 +            || receiver.getSocketBufferSize() != GatewayReceiver.DEFAULT_SOCKET_BUFFER_SIZE)
 +          atts.addAttribute("", "", SOCKET_BUFFER_SIZE, "",
 +              String.valueOf(receiver.getSocketBufferSize()));
 +
 +        if (this.version.compareTo(CacheXmlVersion.VERSION_8_0) < 0) {
 +          return;
 +        }
 +        // manual-start
 +        if (generateDefaults()
 +            || receiver.isManualStart() != GatewayReceiver.DEFAULT_MANUAL_START)
 +          atts.addAttribute("", "", MANUAL_START, "",
 +              String.valueOf(receiver.isManualStart()));
 +
 +      }
 +      finally {
 +        handler.startElement("", GATEWAY_RECEIVER, GATEWAY_RECEIVER, atts);
 +        for (GatewayTransportFilter gsf : receiver.getGatewayTransportFilters()) {
 +          generateGatewayTransportFilter(gsf);
 +        }
 +        handler.endElement("", GATEWAY_RECEIVER, GATEWAY_RECEIVER);
 +      }
 +    }
 +  }
 +  
 +  private void generateGatewayEventFilter(GatewayEventFilter gef)
 +      throws SAXException {
 +
 +    handler.startElement("", GATEWAY_EVENT_FILTER, GATEWAY_EVENT_FILTER, EMPTY);
 +    String className = gef.getClass().getName();
 +
 +    handler.startElement("", CLASS_NAME, CLASS_NAME, EMPTY);
 +    handler.characters(className.toCharArray(), 0, className.length());
 +    handler.endElement("", CLASS_NAME, CLASS_NAME);
 +    Properties props = null;
 +    if (gef instanceof Declarable2) {
 +      props = ((Declarable2)gef).getConfig();
 +      generate(props, null);
 +    }
 +    handler.endElement("", GATEWAY_EVENT_FILTER, GATEWAY_EVENT_FILTER);
 +  }
 +
 +  private void generateGatewayTransportFilter(GatewayTransportFilter gef)
 +      throws SAXException {
 +
 +    handler.startElement("", GATEWAY_TRANSPORT_FILTER, GATEWAY_TRANSPORT_FILTER,
 +        EMPTY);
 +    String className = gef.getClass().getName();
 +
 +    handler.startElement("", CLASS_NAME, CLASS_NAME, EMPTY);
 +    handler.characters(className.toCharArray(), 0, className.length());
 +    handler.endElement("", CLASS_NAME, CLASS_NAME);
 +    Properties props = null;
 +    if (gef instanceof Declarable2) {
 +      props = ((Declarable2)gef).getConfig();
 +      generate(props, null);
 +    }
 +    handler.endElement("", GATEWAY_TRANSPORT_FILTER, GATEWAY_TRANSPORT_FILTER);
 +  }
++
++  private void generateGatewayEventSubstitutionFilter(GatewayEventSubstitutionFilter filter)
++      throws SAXException {
++
++    handler.startElement("", GATEWAY_EVENT_SUBSTITUTION_FILTER, GATEWAY_EVENT_SUBSTITUTION_FILTER,
++        EMPTY);
++    String className = filter.getClass().getName();
++
++    handler.startElement("", CLASS_NAME, CLASS_NAME, EMPTY);
++    handler.characters(className.toCharArray(), 0, className.length());
++    handler.endElement("", CLASS_NAME, CLASS_NAME);
++    Properties props = null;
++    if (filter instanceof Declarable2) {
++      props = ((Declarable2)filter).getConfig();
++      generate(props, null);
++    }
++    handler.endElement("", GATEWAY_EVENT_SUBSTITUTION_FILTER, GATEWAY_EVENT_SUBSTITUTION_FILTER);
++  }
 +//
 +//  private void generateGatewayEventListener(GatewayEventListener gef)
 +//      throws SAXException {
 +//
 +//    handler.startElement("", GATEWAY_EVENT_LISTENER, GATEWAY_EVENT_LISTENER,
 +//        EMPTY);
 +//    String className = gef.getClass().getName();
 +//
 +//    handler.startElement("", CLASS_NAME, CLASS_NAME, EMPTY);
 +//    handler.characters(className.toCharArray(), 0, className.length());
 +//    handler.endElement("", CLASS_NAME, CLASS_NAME);
 +//    Properties props = null;
 +//    if (gef instanceof Declarable2) {
 +//      props = ((Declarable2)gef).getConfig();
 +//      generate(props, null);
 +//    }
 +//    handler.endElement("", GATEWAY_EVENT_LISTENER, GATEWAY_EVENT_LISTENER);
 +//  }
 +  
 +  /**
 +   * Generates XML for a given region
 +   */
 +  private void generate(Region region, String elementName) throws SAXException {
 +    if (region == null) {
 +      return;
 +    }
 +
 +    AttributesImpl atts = new AttributesImpl();
 +    atts.addAttribute("", "", NAME, "", region.getName());
 +    if (region instanceof RegionCreation) {
 +      RegionCreation rc = (RegionCreation)region;
 +      String refId = rc.getRefid();
 +      if (refId != null) {
 +        atts.addAttribute("", "", REFID, "", refId);
 +      }
 +    }
 +    handler.startElement("", elementName, elementName, atts);
 +
 +    if (region instanceof RegionCreation) {
 +      RegionCreation rc = (RegionCreation)region;
 +      if (rc.hasAttributes()) {
 +        generate(null /* unknown id */, region.getAttributes());
 +      }
 +    } else {
 +      generate(null /* unknown id */, region.getAttributes());
 +    }
 +    
 +    //generate index data here
 +    Collection indexesForRegion = this.cache.getQueryService().getIndexes(region);
 +    if (indexesForRegion != null) {
 +      for (Object index: indexesForRegion) {
 +        generate((Index)index);
 +      }
 +    }
 +
 +    if (region instanceof PartitionedRegion) {
 +      if (includeKeysValues) {
 +        if (!region.isEmpty()) {
 +          for (Iterator iter = region.entrySet(false).iterator(); iter.hasNext();) {
 +            Region.Entry entry = (Region.Entry)iter.next();
 +            generate(entry);
 +          }
 +        }
 +      }
 +    }
 +    else {
 +      if (includeKeysValues) {
 +        for (Iterator iter = region.entrySet(false).iterator(); iter.hasNext();) {
 +          Region.Entry entry = (Region.Entry)iter.next();
 +          generate(entry);
 +        }
 +      }
 +    }
 +    
 +    TreeSet rSet = new TreeSet(new RegionComparator());
 +    rSet.addAll(region.subregions(false));
 +    for (Iterator iter = rSet.iterator(); iter.hasNext(); ) {
 +      Region subregion = (Region) iter.next();
 +      generate(subregion, REGION);
 +    }
 +
 +    if (region instanceof Extensible) {
 +      @SuppressWarnings({ "unchecked" })
 +      Extensible<Region<?, ?>> extensible = (Extensible<Region<?, ?>>) region;
 +      generate(extensible);
 +    }
 +
 +    handler.endElement("", elementName, elementName);
 +  }
 +
 +  /**
 +   * Generates XML for a region entry
 +   */
 +  private void generate(Region.Entry entry) throws SAXException {
 +    if ((entry == null)) {
 +      return;
 +    }
 +
 +    handler.startElement("", ENTRY, ENTRY, EMPTY);
 +
 +    handler.startElement("", KEY, KEY, EMPTY);
 +    generate(entry.getKey());
 +    handler.endElement("", KEY, KEY);
 +
 +    handler.startElement("", VALUE, VALUE, EMPTY);
 +    generate(entry.getValue());
 +    handler.endElement("", VALUE, VALUE);
 +
 +    handler.endElement("", ENTRY, ENTRY);
 +  }
 +
 +  /**
 +   * Generates XML for an index
 +   */
 +  private void generate(Index index) throws SAXException {
 +    if (index == null) {
 +      return;
 +    }
 +    AttributesImpl atts = new AttributesImpl();
 +
 +    if (index instanceof IndexCreationData) {
 +      IndexCreationData indexData = (IndexCreationData) index;
 +      atts.addAttribute("", "", NAME, "", indexData.getIndexName());
 +      String indexType = indexData.getIndexType();
 +      if (indexType.equals("KEY")) {
 +        atts.addAttribute("","", KEY_INDEX, "", "true");
 +      }
 +      else {
 +        //convert the indexType to the xml indexType
 +        if (indexType.equals("HASH")) {
 +          indexType = HASH_INDEX_TYPE;
 +        }
 +        else {
 +          indexType = RANGE_INDEX_TYPE;
 +        }
 +        atts.addAttribute("","", KEY_INDEX, "", "false");
 +        atts.addAttribute("", "", INDEX_TYPE, "", "" + indexType);
 +      }
 +      atts.addAttribute("", "", FROM_CLAUSE, "", indexData.getIndexFromClause());
 +      atts.addAttribute("", "", EXPRESSION, "",indexData.getIndexExpression());
 +    }
 +    else {
 +      atts.addAttribute("", "", NAME, "", index.getName());
 +      if (index instanceof PrimaryKeyIndex) {
 +        atts.addAttribute("","", KEY_INDEX, "", "true");
 +      }
 +      else {
 +        atts.addAttribute("","", KEY_INDEX, "", "false");
 +        String indexType = "range";
 +        if (index instanceof HashIndex) {
 +          indexType = "hash";
 +        }
 +        atts.addAttribute("", "", INDEX_TYPE, "", "" + indexType);
 +      }
 +      atts.addAttribute("", "", FROM_CLAUSE, "", index.getFromClause());
 +      atts.addAttribute("", "", EXPRESSION, "",index.getIndexedExpression());
 +    }
 +    handler.startElement("", INDEX, INDEX, atts);
 +
 +    handler.endElement("", INDEX, INDEX);
 +  }
 +  
 +  /**
 +   * Generates XML for region attributes.
 +   *
 +   * @param id
 +   *        The id of the named region attributes (may be
 +   *        <code>null</code>)
 +   */
 +  private void generate(String id, RegionAttributes attrs)
 +    throws SAXException {
 +    AttributesImpl atts = new AttributesImpl();
 +
 +    if (id != null) {
 +      atts.addAttribute("", "", ID, "", id);
 +    }
 +
 +    // Unless, the attrs is a "creation" instance, 
 +    // we have no way of generating a refid, because by this
 +    // point, the refid information is lost.  
 +    if (attrs instanceof RegionAttributesCreation) {
 +      String refId = ((RegionAttributesCreation) attrs).getRefid();
 +      if (refId != null) {
 +        atts.addAttribute("", "", REFID, "", refId);
 +      }
 +    }
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +        ((RegionAttributesCreation) attrs).hasScope())) {
 +      String scopeString;
 +      Scope scope = attrs.getScope();
 +      if (scope.equals(Scope.LOCAL)) {
 +        scopeString = LOCAL;
 +
 +      } else if (scope.equals(Scope.DISTRIBUTED_NO_ACK)) {
 +        scopeString = DISTRIBUTED_NO_ACK;
 +
 +      } else if (scope.equals(Scope.DISTRIBUTED_ACK)) {
 +        scopeString = DISTRIBUTED_ACK;
 +
 +      } else if (scope.equals(Scope.GLOBAL)) {
 +        scopeString = GLOBAL;
 +
 +      } else {
 +        throw new InternalGemFireException(LocalizedStrings.CacheXmlGenerator_UNKNOWN_SCOPE_0.toLocalizedString(scope));
 +      }
 +      
 +
 +      final boolean isPartitionedRegion;
 +      if (attrs instanceof RegionAttributesCreation) {
 +        RegionAttributesCreation rac = (RegionAttributesCreation) attrs;
 +        isPartitionedRegion = rac.getPartitionAttributes() != null || 
 +          (rac.hasDataPolicy() && rac.getDataPolicy().withPartitioning());
 +      } else {
 +        isPartitionedRegion = attrs.getPartitionAttributes() != null ||
 +          attrs.getDataPolicy().withPartitioning();
 +      }
 +
 +      if ( ! isPartitionedRegion) {
 +        // Partitioned Region don't support setting scope
 +        if (generateDefaults() || !scope.equals(AbstractRegion.DEFAULT_SCOPE))
 +        atts.addAttribute("", "", SCOPE, "", scopeString);
 +      } 
 +    } // hasScope
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasEarlyAck())) {
 +      if (generateDefaults() || attrs.getEarlyAck())
 +      atts.addAttribute("", "", EARLY_ACK, "",
 +                        String.valueOf(attrs.getEarlyAck()));
 +    }
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasMulticastEnabled())) {
 +      if (generateDefaults() || attrs.getMulticastEnabled())
 +      atts.addAttribute("", "", MULTICAST_ENABLED, "",
 +                        String.valueOf(attrs.getMulticastEnabled()));
 +    }
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasPublisher())) {
 +      if (generateDefaults() || attrs.getPublisher())
 +      atts.addAttribute("", "", PUBLISHER, "",
 +                        String.valueOf(attrs.getPublisher()));
 +    }
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasEnableAsyncConflation())) {
 +      if (generateDefaults() || attrs.getEnableAsyncConflation())
 +      atts.addAttribute("", "", ENABLE_ASYNC_CONFLATION, "",
 +                        String.valueOf(attrs.getEnableAsyncConflation()));
 +    }
 +
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_5_0) >= 0) {
 +      
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +           ((RegionAttributesCreation) attrs).hasEnableSubscriptionConflation())) {
 +        if (this.version.compareTo(CacheXmlVersion.VERSION_5_7) >= 0) {
 +          // starting with 5.7 it is enable-subscription-conflation
 +          if (generateDefaults() || attrs.getEnableSubscriptionConflation())
 +          atts.addAttribute("", "", ENABLE_SUBSCRIPTION_CONFLATION, "",
 +                            String.valueOf(attrs.getEnableSubscriptionConflation()));
 +        } else {
 +          // before 5.7 it was enable-bridge-conflation
 +          if (generateDefaults() || attrs.getEnableSubscriptionConflation())
 +          atts.addAttribute("", "", ENABLE_BRIDGE_CONFLATION, "",
 +                            String.valueOf(attrs.getEnableSubscriptionConflation()));
 +        }
 +      }
 +      
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +           ((RegionAttributesCreation) attrs).hasDataPolicy())) {
 +        String dpString;
 +        DataPolicy dp = attrs.getDataPolicy();
 +        if (dp.isEmpty()) {
 +          dpString = EMPTY_DP;
 +        } else if (dp.isNormal()) {
 +          dpString = NORMAL_DP;
 +        } else if (dp.isPreloaded()) {
 +          dpString = PRELOADED_DP;
 +        } else if (dp.isReplicate()) {
 +          dpString = REPLICATE_DP;
 +        } else if (dp == DataPolicy.PERSISTENT_REPLICATE) {
 +          dpString = PERSISTENT_REPLICATE_DP;
 +        } else if (dp == DataPolicy.PERSISTENT_PARTITION) {
 +          dpString = PERSISTENT_PARTITION_DP;
 +        } else if (dp.isPartition()) {
 +          if (this.version.compareTo(CacheXmlVersion.VERSION_5_1) >= 0) {
 +            dpString = PARTITION_DP;
 +          }
 +          else {
 +            // prior to 5.1 the data policy for partitioned regions was EMPTY
 +            dpString = EMPTY_DP;
 +          }
 +        } else {
 +          throw new InternalGemFireException(LocalizedStrings.CacheXmlGenerator_UNKNOWN_DATA_POLICY_0.toLocalizedString(dp));
 +        }
 +
 +        if (generateDefaults() || !dp.equals(DataPolicy.DEFAULT))
 +        atts.addAttribute("", "", DATA_POLICY, "", dpString);
 +      } // hasDataPolicy
 +    } // VERSION_5_0 >= 0
 +    else { // VERSION_5_0 < 0
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +          ((RegionAttributesCreation) attrs).hasEnableSubscriptionConflation())) {
 +       if (generateDefaults() || attrs.getEnableSubscriptionConflation())
 +       atts.addAttribute("", "", "enable-conflation", "",
 +                         String.valueOf(attrs.getEnableSubscriptionConflation()));
 +     }
 +      
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +           ((RegionAttributesCreation) attrs).hasMirrorType())) {
 +        String mirrorString;
 +        MirrorType mirror = attrs.getMirrorType();
 +        if (mirror.equals(MirrorType.NONE))
 +          mirrorString = NONE;
 +        else if (mirror.equals(MirrorType.KEYS))
 +          mirrorString = KEYS;
 +        else if (mirror.equals(MirrorType.KEYS_VALUES))
 +          mirrorString = KEYS_VALUES;
 +        else
 +          throw new InternalGemFireException(LocalizedStrings.CacheXmlGenerator_UNKNOWN_MIRROR_TYPE_0.toLocalizedString(mirror));
 +        atts.addAttribute("", "", MIRROR_TYPE, "", mirrorString);
 +      }
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +           ((RegionAttributesCreation) attrs).hasPersistBackup())) {
 +        atts.addAttribute("", "", PERSIST_BACKUP, "",
 +                          String.valueOf(attrs.getDataPolicy() == DataPolicy.PERSISTENT_REPLICATE));
 +      }
 +    } // VERSION_5_0 < 0
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasInitialCapacity())) {
 +      if (generateDefaults() || attrs.getInitialCapacity() != 16)
 +      atts.addAttribute("", "", INITIAL_CAPACITY, "",
 +                        String.valueOf(attrs.getInitialCapacity()));
 +    }
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasLoadFactor())) {
 +      if (generateDefaults() || attrs.getLoadFactor() != 0.75f)
 +      atts.addAttribute("", "", LOAD_FACTOR, "",
 +                        String.valueOf(attrs.getLoadFactor()));
 +    }
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasConcurrencyLevel())) {
 +      if (generateDefaults() || attrs.getConcurrencyLevel() != 16)
 +      atts.addAttribute("", "", CONCURRENCY_LEVEL, "",
 +                        String.valueOf(attrs.getConcurrencyLevel()));
 +    }
 +    
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_7_0) >= 0) {
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +          ((RegionAttributesCreation) attrs).hasConcurrencyChecksEnabled())) {
 +       if (generateDefaults() || attrs.getConcurrencyChecksEnabled() != true/*fixes bug 46654*/)
 +       atts.addAttribute("", "", CONCURRENCY_CHECKS_ENABLED, "",
 +                         String.valueOf(attrs.getConcurrencyChecksEnabled()));
 +      }
 +    }
 +   
 +    
 +
 +    if ((!(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation) attrs).hasStatisticsEnabled())) {
 +      if (generateDefaults() || attrs.getStatisticsEnabled())
 +      atts.addAttribute("", "", STATISTICS_ENABLED, "",
 +                        String.valueOf(attrs.getStatisticsEnabled()));
 +    }
 +
 +    if ( !(attrs instanceof RegionAttributesCreation) ||
 +         ((RegionAttributesCreation)attrs).hasIgnoreJTA() ) {
 +      if (generateDefaults() || attrs.getIgnoreJTA())
 +      atts.addAttribute("", "", IGNORE_JTA, "",
 +                        String.valueOf(attrs.getIgnoreJTA()));
 +    }
 +
 +    if (this.version.compareTo(CacheXmlVersion.VERSION_4_0) >= 0) {
 +      if ((!(attrs instanceof RegionAttributesCreation) ||
 +           ((RegionAttributesCreation) attrs).hasIsLockGrantor())) {
 +        if (generateDefaults() || attrs.isLockGrantor())
 +        atts.addAttribute("", "

<TRUNCATED>


[086/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
index 0000000,6fe60ce..699de2f
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
@@@ -1,0 -1,4164 +1,4164 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ 
+ import java.io.IOException;
+ import java.lang.reflect.Method;
+ import java.util.Collection;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.atomic.AtomicInteger;
+ 
+ import com.gemstone.gemfire.internal.cache.region.entry.RegionEntryFactoryBuilder;
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.GemFireIOException;
+ import com.gemstone.gemfire.InvalidDeltaException;
+ import com.gemstone.gemfire.cache.CacheRuntimeException;
+ import com.gemstone.gemfire.cache.CacheWriter;
+ import com.gemstone.gemfire.cache.CacheWriterException;
+ import com.gemstone.gemfire.cache.CustomEvictionAttributes;
+ import com.gemstone.gemfire.cache.DiskAccessException;
+ import com.gemstone.gemfire.cache.EntryExistsException;
+ import com.gemstone.gemfire.cache.EntryNotFoundException;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.TimeoutException;
+ import com.gemstone.gemfire.cache.TransactionId;
+ import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
+ import com.gemstone.gemfire.cache.query.QueryException;
+ import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexProtocol;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.ClassPathLoader;
+ import com.gemstone.gemfire.internal.cache.DiskInitFile.DiskRegionFlag;
+ import com.gemstone.gemfire.internal.cache.FilterRoutingInfo.FilterInfo;
+ import com.gemstone.gemfire.internal.cache.delta.Delta;
+ import com.gemstone.gemfire.internal.cache.ha.HAContainerWrapper;
+ import com.gemstone.gemfire.internal.cache.ha.HARegionQueue;
+ import com.gemstone.gemfire.internal.cache.lru.LRUEntry;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientNotifier;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.HAEventWrapper;
+ import com.gemstone.gemfire.internal.cache.versions.ConcurrentCacheModificationException;
+ import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
+ import com.gemstone.gemfire.internal.cache.versions.VersionHolder;
+ import com.gemstone.gemfire.internal.cache.versions.VersionSource;
+ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventImpl;
+ import com.gemstone.gemfire.internal.concurrent.MapCallbackAdapter;
+ import com.gemstone.gemfire.internal.concurrent.MapResult;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.OffHeapRegionEntryHelper;
+ import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.internal.sequencelog.EntryLogger;
+ import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap;
+ import com.gemstone.gemfire.pdx.PdxInstance;
+ import com.gemstone.gemfire.pdx.PdxSerializationException;
+ import com.gemstone.gemfire.pdx.internal.ConvertableToBytes;
+ 
+ /**
+  * Abstract implementation of {@link RegionMap}that has all the common
+  * behavior.
+  *
+  * @since 3.5.1
+  *
+  * @author Darrel Schneider
+  *
+  */
+ 
+ //Asif: In case of sqlFabric System, we are creating a different set of RegionEntry 
+ // which are derived from the concrete  GFE RegionEntry classes.
+ // In future if any new concrete  RegionEntry class is defined, the new  SqlFabric
+ // RegionEntry Classes need to be created. There is a junit test in sqlfabric
+ // which checks for RegionEntry classes of GFE and validates the same with its 
+ // own classes.
+ 
+ public abstract class AbstractRegionMap implements RegionMap {
+ 
+   private static final Logger logger = LogService.getLogger();
+   
+   /** The underlying map for this region. */
+   protected CustomEntryConcurrentHashMap<Object, Object> map;
+   /** An internal Listener for index maintenance for SQLFabric. */
+   private final IndexUpdater indexUpdater;
+ 
+   /**
+    * This test hook is used to force the conditions for defect 48182.
+    * This hook is used by Bug48182JUnitTest.
+    */
+   static Runnable testHookRunnableFor48182 =  null;
+   
+   private RegionEntryFactory entryFactory;
+   private Attributes attr;
+   private transient Object owner; // the region that owns this map
+   
+   protected AbstractRegionMap(InternalRegionArguments internalRegionArgs) {
+     if (internalRegionArgs != null) {
+       this.indexUpdater = internalRegionArgs.getIndexUpdater();
+     }
+     else {
+       this.indexUpdater = null;
+     }
+   }
+ 
+   public final IndexUpdater getIndexUpdater() {
+     return this.indexUpdater;
+   }
+ 
+   protected void initialize(Object owner,
+                             Attributes attr,
+                             InternalRegionArguments internalRegionArgs,
+                             boolean isLRU) {
+     _setAttributes(attr);
+     setOwner(owner);
+     _setMap(createConcurrentMap(attr.initialCapacity, attr.loadFactor,
+         attr.concurrencyLevel, false,
+         new AbstractRegionEntry.HashRegionEntryCreator()));
+ 
+     final GemFireCacheImpl cache;
+     boolean isDisk;
+     boolean withVersioning = false;
+     boolean offHeap = false;
+     if (owner instanceof LocalRegion) {
+       LocalRegion region = (LocalRegion)owner;
+       isDisk = region.getDiskRegion() != null;
+       cache = region.getGemFireCache();
+       withVersioning = region.getConcurrencyChecksEnabled();
+       offHeap = region.getOffHeap();
+     }
+     else if (owner instanceof PlaceHolderDiskRegion) {
+       offHeap = ((PlaceHolderDiskRegion) owner).getOffHeap();
+       isDisk = true;
+       withVersioning = ((PlaceHolderDiskRegion)owner).getFlags().contains(
+           DiskRegionFlag.IS_WITH_VERSIONING);
+       cache = GemFireCacheImpl.getInstance();
+     }
+     else {
+       throw new IllegalStateException(
+           "expected LocalRegion or PlaceHolderDiskRegion");
+     }
+ 
+     if (cache != null && cache.isSqlfSystem()) {
+       String provider = GemFireCacheImpl.SQLF_ENTRY_FACTORY_PROVIDER;
+       try {
+         Class<?> factoryProvider = ClassPathLoader.getLatest().forName(provider);
+         Method method = factoryProvider.getDeclaredMethod(
+             "getRegionEntryFactory", new Class[] { Boolean.TYPE, Boolean.TYPE,
+                 Boolean.TYPE, Object.class, InternalRegionArguments.class });
+         RegionEntryFactory ref = (RegionEntryFactory)method.invoke(null,
+             new Object[] { Boolean.valueOf(attr.statisticsEnabled),
+                 Boolean.valueOf(isLRU), Boolean.valueOf(isDisk), owner,
+                 internalRegionArgs });
+ 
+         // TODO need to have the SQLF entry factory support version stamp storage
+         setEntryFactory(ref);
+ 
+       }
+       catch (Exception e) {
+         throw new CacheRuntimeException(
+             "Exception in obtaining RegionEntry Factory" + " provider class ",
+             e) {
+         };
+       }
+     }
+     else {
+       setEntryFactory(new RegionEntryFactoryBuilder().getRegionEntryFactoryOrNull(attr.statisticsEnabled,isLRU,isDisk,withVersioning,offHeap));
+     }
+   }
+ 
+   protected CustomEntryConcurrentHashMap<Object, Object> createConcurrentMap(
+       int initialCapacity, float loadFactor, int concurrencyLevel,
+       boolean isIdentityMap,
+       CustomEntryConcurrentHashMap.HashEntryCreator<Object, Object> entryCreator) {
+     if (entryCreator != null) {
+       return new CustomEntryConcurrentHashMap<Object, Object>(initialCapacity, loadFactor,
+           concurrencyLevel, isIdentityMap, entryCreator);
+     }
+     else {
+       return new CustomEntryConcurrentHashMap<Object, Object>(initialCapacity,
+           loadFactor, concurrencyLevel, isIdentityMap);
+     }
+   }
+ 
+   public void changeOwner(LocalRegion r) {
+     if (r == _getOwnerObject()) {
+       return;
+     }
+     setOwner(r);
+   }
+ 
+   @Override
+   public final void setEntryFactory(RegionEntryFactory f) {
+     this.entryFactory = f;
+   }
+ 
+   public final RegionEntryFactory getEntryFactory() {
+     return this.entryFactory;
+   }
+ 
+   protected final void _setAttributes(Attributes a) {
+     this.attr = a;
+   }
+ 
+   public final Attributes getAttributes() {
+     return this.attr;
+   }
+   
+   protected final LocalRegion _getOwner() {
+     return (LocalRegion)this.owner;
+   }
+ 
+   protected boolean _isOwnerALocalRegion() {
+     return this.owner instanceof LocalRegion;
+   }
+ 
+   protected final Object _getOwnerObject() {
+     return this.owner;
+   }
+ 
+   public final void setOwner(Object r) {
+     this.owner = r;
+   }
+   
+   protected final CustomEntryConcurrentHashMap<Object, Object> _getMap() {
+     return this.map;
+   }
+ 
+   protected final void _setMap(CustomEntryConcurrentHashMap<Object, Object> m) {
+     this.map = m;
+   }
+ 
+   public int size()
+   {
+     return _getMap().size();
+   }
+ 
+   // this is currently used by stats and eviction
+   @Override
+   public int sizeInVM() {
+     return _getMap().size();
+   }
+ 
+   public boolean isEmpty()
+   {
+     return _getMap().isEmpty();
+   }
+ 
+   public Set keySet()
+   {
+     return _getMap().keySet();
+   }
+ 
+   @SuppressWarnings({ "unchecked", "rawtypes" })
+   public Collection<RegionEntry> regionEntries() {
+     return (Collection)_getMap().values();
+   }
+ 
+   @SuppressWarnings({ "unchecked", "rawtypes" })
+   @Override
+   public Collection<RegionEntry> regionEntriesInVM() {
+     return (Collection)_getMap().values();
+   }
+ 
+   public final boolean containsKey(Object key) {
+     RegionEntry re = getEntry(key);
+     if (re == null) {
+       return false;
+     }
+     if (re.isRemoved()) {
+       return false;
+     }
+     return true;
+   }
+ 
+   public RegionEntry getEntry(Object key) {
+     RegionEntry re = (RegionEntry)_getMap().get(key);
+     if (re != null && re.isMarkedForEviction()) {
+       // entry has been faulted in from HDFS
+       return null;
+     }
+     return re;
+   }
+ 
+   protected RegionEntry getEntry(EntryEventImpl event) {
+     return getEntry(event.getKey());
+   }
+ 
+ 
+   @Override
+   public final RegionEntry getEntryInVM(Object key) {
+     return (RegionEntry)_getMap().get(key);
+   }
+ 
+ 
+   public final RegionEntry putEntryIfAbsent(Object key, RegionEntry re) {
+     RegionEntry value = (RegionEntry)_getMap().putIfAbsent(key, re);
+     if (value == null && (re instanceof OffHeapRegionEntry) 
+         && _isOwnerALocalRegion() && _getOwner().isThisRegionBeingClosedOrDestroyed()) {
+       // prevent orphan during concurrent destroy (#48068)
+       if (_getMap().remove(key, re)) {
+         ((OffHeapRegionEntry)re).release();
+       }
+       _getOwner().checkReadiness(); // throw RegionDestroyedException
+     }
+     return value;
+   }
+ 
+   @Override
+   public final RegionEntry getOperationalEntryInVM(Object key) {
+     RegionEntry re = (RegionEntry)_getMap().get(key);
+     if (re != null && re.isMarkedForEviction()) {
+       // entry has been faulted in from HDFS
+       return null;
+     }
+     return re;
+   }
+  
+ 
+   public final void removeEntry(Object key, RegionEntry re, boolean updateStat) {
+     if (re.isTombstone() && _getMap().get(key) == re && !re.isMarkedForEviction()){
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.AbstractRegionMap_ATTEMPT_TO_REMOVE_TOMBSTONE), new Exception("stack trace"));
+       return; // can't remove tombstones except from the tombstone sweeper
+     }
+     if (_getMap().remove(key, re)) {
+       re.removePhase2();
+       if (updateStat) {
+         incEntryCount(-1);
+       }
+     }
+   }
+ 
+   public final void removeEntry(Object key, RegionEntry re, boolean updateStat,
+       EntryEventImpl event, final LocalRegion owner,
+       final IndexUpdater indexUpdater) {
+     boolean success = false;
+     if (re.isTombstone()&& _getMap().get(key) == re && !re.isMarkedForEviction()) {
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.AbstractRegionMap_ATTEMPT_TO_REMOVE_TOMBSTONE), new Exception("stack trace"));
+       return; // can't remove tombstones except from the tombstone sweeper
+     }
+     try {
+       if (indexUpdater != null) {
+         indexUpdater.onEvent(owner, event, re);
+       }
+ 
+       //This is messy, but custom eviction calls removeEntry
+       //rather than re.destroy I think to avoid firing callbacks, etc.
+       //However, the value still needs to be set to removePhase1
+       //in order to remove the entry from disk.
+       if(event.isCustomEviction() && !re.isRemoved()) {
+         try {
+           re.removePhase1(owner, false);
+         } catch (RegionClearedException e) {
+           //that's ok, we were just trying to do evict incoming eviction
+         }
+       }
+       
+       if (_getMap().remove(key, re)) {
+         re.removePhase2();
+         success = true;
+         if (updateStat) {
+           incEntryCount(-1);
+         }
+       }
+     } finally {
+       if (indexUpdater != null) {
+         indexUpdater.postEvent(owner, event, re, success);
+       }
+     }
+   }
+ 
+   protected final void incEntryCount(int delta) {
+     LocalRegion lr = _getOwner();
+     if (lr != null) {
+       CachePerfStats stats = lr.getCachePerfStats();
+       if (stats != null) {
+         stats.incEntryCount(delta);
+       }
+     }
+   }
+   
+   final void incClearCount(LocalRegion lr) {
+     if (lr != null && !(lr instanceof HARegion)) {
+       CachePerfStats stats = lr.getCachePerfStats();
+       if (stats != null) {
+         stats.incClearCount();
+       }
+     }
+   }
+ 
+   private void _mapClear() {
+     _getMap().clear();
+   }
+   
+   public void close() {
+     /*
+     for (SuspectEntryList l: this.suspectEntries.values()) {
+       for (EntryEventImpl e: l) {
+         e.release();
+       }
+     }
+     */
+     clear(null);
+   }
+   
+   /**
+    * Clear the region and, if an RVV is given, return a collection of the
+    * version sources in all remaining tags
+    */
+   public Set<VersionSource> clear(RegionVersionVector rvv)
+   {
+     Set<VersionSource> result = new HashSet<VersionSource>();
+     
+     if(!_isOwnerALocalRegion()) {
+       //Fix for #41333. Just clear the the map
+       //if we failed during initialization.
+       _mapClear();
+       return null;
+     }
+     if (logger.isDebugEnabled()) {
+       logger.debug("Clearing entries for {} rvv={}", _getOwner(), " rvv=" + rvv);
+     }
+     LocalRegion lr = _getOwner();
+     RegionVersionVector localRvv = lr.getVersionVector();
+     incClearCount(lr);
+     // lock for size calcs if the region might have tombstones
+     Object lockObj = lr.getConcurrencyChecksEnabled()? lr.getSizeGuard() : new Object();
+     synchronized (lockObj) {
+       if (rvv == null) {
+         int delta = 0;
+         try {
+           delta = sizeInVM(); // TODO soplog need to determine if stats should
+                               // reflect only size in memory or the complete thing
+         } catch (GemFireIOException e) {
+           // ignore rather than throwing an exception during cache close
+         }
+         int tombstones = lr.getTombstoneCount();
+         _mapClear();
+         _getOwner().updateSizeOnClearRegion(delta - tombstones);
+         _getOwner().incTombstoneCount(-tombstones);
+         if (delta != 0) {
+           incEntryCount(-delta);
+         }
+       } else {
+         int delta = 0;
+         int tombstones = 0;
+         VersionSource myId = _getOwner().getVersionMember();
+         if (localRvv != rvv) {
+           localRvv.recordGCVersions(rvv);
+         }
+         final boolean isTraceEnabled = logger.isTraceEnabled();
+         for (RegionEntry re : regionEntries()) {
+           synchronized(re) {
+             Token value = re.getValueAsToken();
+             // if it's already being removed or the entry is being created we leave it alone
+             if (value == Token.REMOVED_PHASE1 || value == Token.REMOVED_PHASE2) {
+               continue;
+             }
+             
+             VersionSource id = re.getVersionStamp().getMemberID();
+             if (id == null) {
+               id = myId;
+             }
+             if (rvv.contains(id, re.getVersionStamp().getRegionVersion())) {
+               if (isTraceEnabled) {
+                 logger.trace("region clear op is removing {} {}", re.getKey(), re.getVersionStamp());
+               }
+ 
+               boolean tombstone = re.isTombstone();
+               // note: it.remove() did not reliably remove the entry so we use remove(K,V) here
+               if (_getMap().remove(re.getKey(), re)) {
+                 if (OffHeapRegionEntryHelper.doesClearNeedToCheckForOffHeap()) {
+                   GatewaySenderEventImpl.release(re._getValue()); // OFFHEAP _getValue ok
+                 }
+                 //If this is an overflow only region, we need to free the entry on
+                 //disk at this point.
+                 try {
+                   re.removePhase1(lr, true);
+                 } catch (RegionClearedException e) {
+                   //do nothing, it's already cleared.
+                 }
+                 re.removePhase2();
+                 lruEntryDestroy(re);
+                 if (tombstone) {
+                   _getOwner().incTombstoneCount(-1);
+                   tombstones += 1;
+                 } else {
+                   delta += 1;
+                 }
+               }
+             } else { // rvv does not contain this entry so it is retained
+               result.add(id);
+             }
+           }
+         }
+         _getOwner().updateSizeOnClearRegion(delta);
+         incEntryCount(-delta);
+         incEntryCount(-tombstones);
+         if (logger.isDebugEnabled()) {
+           logger.debug("Size after clearing = {}", _getMap().size());
+         }
+         if (isTraceEnabled && _getMap().size() < 20) {
+           _getOwner().dumpBackingMap();
+         }
+       }
+     }
+     return result;
+   }
+   
+   public void lruUpdateCallback()
+   {
+     // By default do nothing; LRU maps needs to override this method
+   }
+   public void lruUpdateCallback(boolean b)
+   {
+     // By default do nothing; LRU maps needs to override this method
+   }
+   public void lruUpdateCallback(int i)
+   {
+     // By default do nothing; LRU maps needs to override this method
+   }
+ 
+   public boolean disableLruUpdateCallback()
+   {
+     // By default do nothing; LRU maps needs to override this method
+     return false;
+   }
+ 
+   public void enableLruUpdateCallback()
+   {
+     // By default do nothing; LRU maps needs to override this method
+   }
+ 
+   public void resetThreadLocals()
+   {
+     // By default do nothing; LRU maps needs to override this method
+   }
+ 
+   /**
+    * Tell an LRU that a new entry has been created
+    */
+   protected void lruEntryCreate(RegionEntry e)
+   {
+     // do nothing by default
+   }
+ 
+   /**
+    * Tell an LRU that an existing entry has been destroyed
+    */
+   protected void lruEntryDestroy(RegionEntry e)
+   {
+     // do nothing by default
+   }
+ 
+   /**
+    * Tell an LRU that an existing entry has been modified
+    */
+   protected void lruEntryUpdate(RegionEntry e)
+   {
+     // do nothing by default
+   }
+ 
+   @Override
+   public void decTxRefCount(RegionEntry e)
+   {
+     LocalRegion lr = null;
+     if (_isOwnerALocalRegion()) {
+       lr = _getOwner();
+     }
+     e.decRefCount(null, lr);
+   }
+ 
+   public boolean lruLimitExceeded() {
+     return false;
+   }
+ 
+   public void lruCloseStats() {
+     // do nothing by default
+   }
+   
+   public void lruEntryFaultIn(LRUEntry entry) {
+     // do nothing by default
+   }
+   
+   /**
+    * Process an incoming version tag for concurrent operation detection.
+    * This must be done before modifying the region entry.
+    * @param re the entry that is to be modified
+    * @param event the modification to the entry
+    * @throws InvalidDeltaException if the event contains a delta that cannot be applied
+    * @throws ConcurrentCacheModificationException if the event is in conflict
+    *    with a previously applied change
+    */
+   private void processVersionTag(RegionEntry re, EntryEventImpl event) {
+     if (re.getVersionStamp() != null) {
+       re.getVersionStamp().processVersionTag(event);
+       
+       // during initialization we record version tag info to detect ops the
+       // image provider hasn't seen
+       VersionTag<?> tag = event.getVersionTag();
+       if (tag != null && !event.getRegion().isInitialized()) {
+         ImageState is = event.getRegion().getImageState();
+         if (is != null && !event.getRegion().isUsedForPartitionedRegionBucket()) {
+           if (logger.isTraceEnabled()) {
+             logger.trace("recording version tag in image state: {}", tag);
+           }
+           is.addVersionTag(event.getKey(), tag);
+         }
+       }
+     }
+   }
+   
+   private void processVersionTagForGII(RegionEntry re, LocalRegion owner, VersionTag entryVersion, boolean isTombstone, InternalDistributedMember sender, boolean checkConflicts) {
+     
+     re.getVersionStamp().processVersionTag(_getOwner(), entryVersion, isTombstone, false, owner.getMyId(), sender, checkConflicts);
+   }
+ 
+   public void copyRecoveredEntries(RegionMap rm) {
+     //We need to sort the tombstones before scheduling them,
+     //so that they will be in the correct order.
+     OrderedTombstoneMap<RegionEntry> tombstones = new OrderedTombstoneMap<RegionEntry>();
+     if (rm != null) {
+       CustomEntryConcurrentHashMap<Object, Object> other = ((AbstractRegionMap)rm)._getMap();
+       Iterator<Map.Entry<Object, Object>> it = other
+           .entrySetWithReusableEntries().iterator();
+       while (it.hasNext()) {
+         Map.Entry<Object, Object> me = it.next();
+         it.remove(); // This removes the RegionEntry from "rm" but it does not decrement its refcount to an offheap value.
+         RegionEntry oldRe = (RegionEntry)me.getValue();
+         Object key = me.getKey();
+         
+         @Retained @Released Object value = oldRe._getValueRetain((RegionEntryContext) ((AbstractRegionMap) rm)._getOwnerObject(), true);
+ 
+         try {
+           if (value == Token.NOT_AVAILABLE) {
+             // fix for bug 43993
+             value = null;
+           }
+           if (value == Token.TOMBSTONE && !_getOwner().getConcurrencyChecksEnabled()) {
+             continue;
+           }
+           RegionEntry newRe = getEntryFactory().createEntry((RegionEntryContext) _getOwnerObject(), key, value);
+           copyRecoveredEntry(oldRe, newRe);
+           // newRe is now in this._getMap().
+           if (newRe.isTombstone()) {
+             VersionTag tag = newRe.getVersionStamp().asVersionTag();
+             tombstones.put(tag, newRe);
+           }
+           _getOwner().updateSizeOnCreate(key, _getOwner().calculateRegionEntryValueSize(newRe));
+           incEntryCount(1);
+           lruEntryUpdate(newRe);
+         } finally {
+           if (OffHeapHelper.release(value)) {
+             ((OffHeapRegionEntry)oldRe).release();
+           }
+         }
+         lruUpdateCallback();
+       }
+     } else {
+       incEntryCount(size());
+       for (Iterator<RegionEntry> iter = regionEntries().iterator(); iter.hasNext(); ) {
+         RegionEntry re = iter.next();
+         if (re.isTombstone()) {
+           if (re.getVersionStamp() == null) { // bug #50992 - recovery from versioned to non-versioned
+             incEntryCount(-1);
+             iter.remove();
+             continue;
+           } else {
+             tombstones.put(re.getVersionStamp().asVersionTag(), re);
+           }
+         }
+         _getOwner().updateSizeOnCreate(re.getKey(), _getOwner().calculateRegionEntryValueSize(re));
+       }
+       // Since lru was not being done during recovery call it now.
+       lruUpdateCallback();
+     }
+     
+     //Schedule all of the tombstones, now that we have sorted them
+     Map.Entry<VersionTag, RegionEntry> entry;
+     while((entry = tombstones.take()) != null) {
+       // refresh the tombstone so it doesn't time out too soon
+       _getOwner().scheduleTombstone(entry.getValue(), entry.getKey());
+     }
+     
+   }
+   
+   protected void copyRecoveredEntry(RegionEntry oldRe, RegionEntry newRe) {
+     if(newRe.getVersionStamp() != null) {
+       newRe.getVersionStamp().setMemberID(oldRe.getVersionStamp().getMemberID());
+       newRe.getVersionStamp().setVersions(oldRe.getVersionStamp().asVersionTag());
+     }
+     
+     if (newRe instanceof AbstractOplogDiskRegionEntry) {
+       ((AbstractOplogDiskRegionEntry)newRe).setDiskId(oldRe);
+       _getOwner().getDiskRegion().replaceIncompatibleEntry((DiskEntry) oldRe, (DiskEntry) newRe);
+     }
+     _getMap().put(newRe.getKey(), newRe);
+   }
+ 
+   @Retained     // Region entry may contain an off-heap value
+   public final RegionEntry initRecoveredEntry(Object key, DiskEntry.RecoveredEntry value) {
+     boolean needsCallback = false;
+     @Retained RegionEntry newRe = getEntryFactory().createEntry((RegionEntryContext) _getOwnerObject(), key, value);
+     synchronized (newRe) {
+       if (value.getVersionTag()!=null && newRe.getVersionStamp()!=null) {
+         newRe.getVersionStamp().setVersions(value.getVersionTag());
+       }
+       RegionEntry oldRe = putEntryIfAbsent(key, newRe);
+       while (oldRe != null) {
+         synchronized (oldRe) {
+           if (oldRe.isRemoved() && !oldRe.isTombstone()) {
+             oldRe = putEntryIfAbsent(key, newRe);
+             if (oldRe != null) {
+               if (_isOwnerALocalRegion()) {
+                 _getOwner().getCachePerfStats().incRetries();
+               }
+             }
+           } 
+           /*
+            * Entry already exists which should be impossible.
+            * Free the current entry (if off-heap) and
+            * throw an exception.
+            */
+           else {
+             if (newRe instanceof OffHeapRegionEntry) {
+               ((OffHeapRegionEntry) newRe).release();
+             }
+ 
+             throw new IllegalStateException("Could not recover entry for key " + key + ".  The entry already exists!");
+           }
+         } // synchronized
+       }
+       if (_isOwnerALocalRegion()) {
+         _getOwner().updateSizeOnCreate(key, _getOwner().calculateRegionEntryValueSize(newRe));
+         if (newRe.isTombstone()) {
+           // refresh the tombstone so it doesn't time out too soon
+           _getOwner().scheduleTombstone(newRe, newRe.getVersionStamp().asVersionTag());
+         }
+         
+         incEntryCount(1); // we are creating an entry that was recovered from disk including tombstone
+       }
+       lruEntryUpdate(newRe);
+       needsCallback = true;
+     }
+     if (needsCallback) {
+       lruUpdateCallback();
+     }
+     
+     EntryLogger.logRecovery(_getOwnerObject(), key, value);
+     
+     return newRe;
+   }
+   
+   public final RegionEntry updateRecoveredEntry(Object key, DiskEntry.RecoveredEntry value) {
+     boolean needsCallback = false;
+     RegionEntry re = getEntry(key);
+     if (re == null) {
+       return null;
+     }
+     synchronized (re) {
+       if (re.isRemoved() && !re.isTombstone()) {
+         return null;
+       }
+       if (value.getVersionTag()!=null && re.getVersionStamp()!=null) {
+         re.getVersionStamp().setVersions(value.getVersionTag());
+       }
+       try {
+         if (_isOwnerALocalRegion()) {
+           if (re.isTombstone()) {
+             // when a tombstone is to be overwritten, unschedule it first
+             _getOwner().unscheduleTombstone(re);
+           }
+           final int oldSize = _getOwner().calculateRegionEntryValueSize(re);
+           re.setValue(_getOwner(), value); // OFFHEAP no need to call AbstractRegionMap.prepareValueForCache because setValue is overridden for disk and that code takes apart value (RecoveredEntry) and prepares its nested value for the cache
+           if (re.isTombstone()) {
+             _getOwner().scheduleTombstone(re, re.getVersionStamp().asVersionTag());
+           }
+           _getOwner().updateSizeOnPut(key, oldSize, _getOwner().calculateRegionEntryValueSize(re));
+         } else {
+           DiskEntry.Helper.updateRecoveredEntry((PlaceHolderDiskRegion)_getOwnerObject(),
+               (DiskEntry)re, value, (RegionEntryContext) _getOwnerObject());
+         }
+       } catch (RegionClearedException rce) {
+         throw new IllegalStateException("RegionClearedException should never happen in this context", rce);
+       }
+       lruEntryUpdate(re);
+       needsCallback = true;
+     }
+     if (needsCallback) {
+       lruUpdateCallback();
+     }
+     
+     EntryLogger.logRecovery(_getOwnerObject(), key, value);
+     
+     return re;
+   }
+ 
+   public final boolean initialImagePut(final Object key,
+                                        final long lastModified,
+                                        Object newValue,
+                                        final boolean wasRecovered,
+                                        boolean deferLRUCallback,
+                                        VersionTag entryVersion, InternalDistributedMember sender, boolean isSynchronizing)
+   {
+     boolean result = false;
+     boolean done = false;
+     boolean cleared = false;
+     final LocalRegion owner = _getOwner();
+     
+     if (newValue == Token.TOMBSTONE && !owner.getConcurrencyChecksEnabled()) {
+       return false;
+     }
+ 
+     if (owner instanceof HARegion && newValue instanceof CachedDeserializable) {
+       Object actualVal = ((CachedDeserializable)newValue)
+         .getDeserializedValue(null, null);
+       if (actualVal instanceof HAEventWrapper) {
+         HAEventWrapper haEventWrapper = (HAEventWrapper)actualVal;
+         // Key was removed at sender side so not putting it into the HARegion
+         if (haEventWrapper.getClientUpdateMessage() == null) {
+           return false;
+         }
+         // Getting the instance from singleton CCN..This assumes only one bridge
+         // server in the VM
+         HAContainerWrapper haContainer = (HAContainerWrapper)CacheClientNotifier
+             .getInstance().getHaContainer();
+         Map.Entry entry = null;
+         HAEventWrapper original = null;
+         synchronized (haContainer) {
+           entry = (Map.Entry)haContainer.getEntry(haEventWrapper);
+           if (entry != null) {
+             original = (HAEventWrapper)entry.getKey();
+             original.incAndGetReferenceCount();
+           }
+           else {
+             haEventWrapper.incAndGetReferenceCount();
+             haEventWrapper.setHAContainer(haContainer);
+             haContainer.put(haEventWrapper, haEventWrapper
+                 .getClientUpdateMessage());
+             haEventWrapper.setClientUpdateMessage(null);
+             haEventWrapper.setIsRefFromHAContainer(true);
+           }
+         }
+         if (entry != null) {
+           HARegionQueue.addClientCQsAndInterestList(entry, haEventWrapper,
+               haContainer, owner.getName());
+           haEventWrapper.setClientUpdateMessage(null);
+           newValue = CachedDeserializableFactory.create(original,
+               ((CachedDeserializable)newValue).getSizeInBytes());
+         }
+       }
+     }
+     
+     try {
+       RegionEntry newRe = getEntryFactory().createEntry(owner, key,
+           Token.REMOVED_PHASE1);
+       EntryEventImpl event = null;
+       
+       @Retained @Released Object oldValue = null;
+       
+       try {
+       RegionEntry oldRe = null;
+       synchronized (newRe) {
+         try {
+           oldRe = putEntryIfAbsent(key, newRe);
+           while (!done && oldRe != null) {
+             synchronized (oldRe) {
+               if (oldRe.isRemovedPhase2()) {
+                 oldRe = putEntryIfAbsent(key, newRe);
+                 if (oldRe != null) {
+                   owner.getCachePerfStats().incRetries();
+                 }
+               }
+               else {
+                 boolean acceptedVersionTag = false;
+                 if (entryVersion != null && owner.concurrencyChecksEnabled) {
+                   Assert.assertTrue(entryVersion.getMemberID() != null, "GII entry versions must have identifiers");
+                   try {
+                     boolean isTombstone = (newValue == Token.TOMBSTONE);
+                     // don't reschedule the tombstone if it hasn't changed
+                     boolean isSameTombstone = oldRe.isTombstone() && isTombstone
+                               && oldRe.getVersionStamp().asVersionTag()
+                                 .equals(entryVersion);
+                     if (isSameTombstone) {
+                       return true;
+                     }
+                     processVersionTagForGII(oldRe, owner, entryVersion, isTombstone, sender, !wasRecovered || isSynchronizing);
+                     acceptedVersionTag = true;
+                   } catch (ConcurrentCacheModificationException e) {
+                     return false;
+                   }
+                 }
+                 final boolean oldIsTombstone = oldRe.isTombstone();
+                 final int oldSize = owner.calculateRegionEntryValueSize(oldRe);
+                 // Neeraj: The below if block is to handle the special
+                 // scenario witnessed in SqlFabric for now. (Though its
+                 // a general scenario). The scenario is that during GII
+                 // it is possible that updates start coming before the
+                 // base value reaches through GII. In that scenario the deltas
+                 // for that particular key is kept on being added to a list
+                 // of deltas. When the base value arrives through this path
+                 // of GII the oldValue will be that list of deltas. When the
+                 // base values arrives the deltas are applied one by one on that list.
+                 // The same scenario is applicable for GemFire also but the below 
+                 // code will be executed only in case of sqlfabric now. Probably
+                 // the code can be made more generic for both SQL Fabric and GemFire.
+                 if (indexUpdater != null) {
+                   oldValue = oldRe.getValueInVM(owner); // OFFHEAP: ListOfDeltas
+                   if (oldValue instanceof ListOfDeltas) {
+                   // apply the deltas on this new value. update index
+                   // Make a new event object
+                   // make it an insert operation
+                   LocalRegion rgn = owner;
+                   if (owner instanceof BucketRegion) {
+                     rgn = ((BucketRegion)owner).getPartitionedRegion();
+                   }
+                   event = EntryEventImpl.create(rgn, Operation.CREATE, key, null,
+                       Boolean.TRUE /* indicate that GII is in progress */,
+                       false, null);
+                   try {
+                   event.setOldValue(newValue);
+                   if (logger.isDebugEnabled()) {
+                     logger.debug("initialImagePut: received base value for list of deltas; event: {}", event);
+                   }
+                   ((ListOfDeltas)oldValue).apply(event);
+                   Object preparedNewValue =oldRe.prepareValueForCache(owner,
+                       event.getNewValueAsOffHeapDeserializedOrRaw(), true);
 -                  if(preparedNewValue instanceof Chunk) {
++                  if(preparedNewValue instanceof ObjectChunk) {
+                     event.setNewValue(preparedNewValue);
+                   }
+                   oldRe.setValue(owner, preparedNewValue, event);
+                   //event.setNewValue(event.getOldValue());
+                   event.setOldValue(null);
+                   try {
+                     indexUpdater.onEvent(owner, event, oldRe);
+                     lruEntryUpdate(oldRe);
+                     owner.updateSizeOnPut(key, oldSize, owner.calculateRegionEntryValueSize(oldRe));
+                     EntryLogger.logInitialImagePut(_getOwnerObject(), key, newValue);
+                     result = true;
+                     done = true;
+                     break;
+                   } finally {
+                     // this must be done within the oldRe sync block
+                     indexUpdater.postEvent(owner, event, oldRe, done);
+                   }
+                   } finally {
+                     if (event != null) {
+                       event.release();
+                       event = null;
+                     }
+                   }
+                   }
+                 }
+                 try {
+                   if (indexUpdater != null) {
+                     event = EntryEventImpl.create(owner, Operation.CREATE, key,
+                         newValue,
+                         Boolean.TRUE /* indicate that GII is in progress */,
+                         false, null);
+                     indexUpdater.onEvent(owner, event, oldRe);
+                   }
+                   result = oldRe.initialImagePut(owner, lastModified, newValue, wasRecovered, acceptedVersionTag);
+                   if (result) {
+                     if (oldIsTombstone) {
+                       owner.unscheduleTombstone(oldRe);
+                       if (newValue != Token.TOMBSTONE){
+                         lruEntryCreate(oldRe);
+                       } else {
+                         lruEntryUpdate(oldRe);
+                       }
+                     }
+                     if (newValue == Token.TOMBSTONE) {
+                       if (owner.getServerProxy() == null &&
+                           owner.getVersionVector().isTombstoneTooOld(entryVersion.getMemberID(), entryVersion.getRegionVersion())) {
+                         // the received tombstone has already been reaped, so don't retain it
+                         removeTombstone(oldRe, entryVersion, false, false);
+                         return false;
+                       } else {
+                         owner.scheduleTombstone(oldRe, entryVersion);
+                         lruEntryDestroy(oldRe);
+                       }
+                     } else {
+                       int newSize = owner.calculateRegionEntryValueSize(oldRe);
+                       if(!oldIsTombstone) {
+                         owner.updateSizeOnPut(key, oldSize, newSize);
+                       } else {
+                         owner.updateSizeOnCreate(key, newSize);
+                       }
+                       EntryLogger.logInitialImagePut(_getOwnerObject(), key, newValue);
+                     }
+                   }
+                   if (owner.getIndexManager() != null) {
+                     owner.getIndexManager().updateIndexes(oldRe, oldRe.isRemoved() ? IndexManager.ADD_ENTRY : IndexManager.UPDATE_ENTRY, 
+                         oldRe.isRemoved() ? IndexProtocol.OTHER_OP : IndexProtocol.AFTER_UPDATE_OP);
+                   }
+                   done = true;
+                 } finally {
+                   if (indexUpdater != null) {
+                     indexUpdater.postEvent(owner, event, oldRe, result);
+                   }
+                   if (event != null) {
+                     event.release();
+                     event = null;
+                   }
+                 }
+               }
+             }
+           }
+           if (!done) {
+             boolean versionTagAccepted = false;
+             if (entryVersion != null && owner.concurrencyChecksEnabled) {
+               Assert.assertTrue(entryVersion.getMemberID() != null, "GII entry versions must have identifiers");
+               try {
+                 boolean isTombstone = (newValue == Token.TOMBSTONE);
+                 processVersionTagForGII(newRe, owner, entryVersion, isTombstone, sender, !wasRecovered || isSynchronizing);
+                 versionTagAccepted = true;
+               } catch (ConcurrentCacheModificationException e) {
+                 return false;
+               }
+             }
+             result = newRe.initialImageInit(owner, lastModified, newValue,
+                 true, wasRecovered, versionTagAccepted);
+             try {
+               if (result) {
+                 if (indexUpdater != null) {
+                   event = EntryEventImpl.create(owner, Operation.CREATE, key,
+                       newValue,
+                       Boolean.TRUE /* indicate that GII is in progress */,
+                       false, null);
+                   indexUpdater.onEvent(owner, event, newRe);
+                 }
+                 if (newValue == Token.TOMBSTONE) {
+                   owner.scheduleTombstone(newRe, entryVersion);
+                 } else {
+                   owner.updateSizeOnCreate(key, owner.calculateRegionEntryValueSize(newRe));
+                   EntryLogger.logInitialImagePut(_getOwnerObject(), key, newValue);
+                   lruEntryCreate(newRe);
+                 }
+                 incEntryCount(1);
+               }
+               //Update local indexes
+               if (owner.getIndexManager() != null) {
+                 owner.getIndexManager().updateIndexes(newRe, newRe.isRemoved() ? IndexManager.REMOVE_ENTRY : IndexManager.UPDATE_ENTRY, 
+                     newRe.isRemoved() ? IndexProtocol.OTHER_OP : IndexProtocol.AFTER_UPDATE_OP);
+               }
+               done = true;
+             } finally {
+               if (result && indexUpdater != null) {
+                 indexUpdater.postEvent(owner, event, newRe, done);
+               }
+               if (event != null) {
+                 event.release();
+                 event = null;
+               }
+             }
+           }
+         }
+         finally {
+           if (done && result) {
+             initialImagePutEntry(newRe);
+           }
+           if (!done) {
+             removeEntry(key, newRe, false);
+             if (owner.getIndexManager() != null) {
+               owner.getIndexManager().updateIndexes(newRe, IndexManager.REMOVE_ENTRY, IndexProtocol.OTHER_OP);
+             }
+           }
+        } 
+       } // synchronized
+       } finally {
+         if (event != null) event.release();
+         OffHeapHelper.release(oldValue);
+       }
+     } catch(RegionClearedException rce) {
+       //Asif: do not issue any sort of callbacks
+       done = false;
+       cleared= true;
+     }catch(QueryException qe) {
+       done = false;
+       cleared= true;
+     }
+     finally {
+       if (done && !deferLRUCallback) {
+         lruUpdateCallback();
+       }
+       else if (!cleared) {
+         resetThreadLocals();
+       }
+     }
+     return result;
+   }
+ 
+   protected void initialImagePutEntry(RegionEntry newRe) {
+   }
+ 
+   boolean confirmEvictionDestroy(RegionEntry re)
+   {
+     /* We arn't in an LRU context, and should never get here */
+     Assert.assertTrue(false,
+         "Not an LRU region, can not confirm LRU eviction operation");
+     return true;
+   }
+ 
+   public final boolean destroy(EntryEventImpl event,
+                                boolean inTokenMode,
+                                boolean duringRI,
+                                boolean cacheWrite,
+                                boolean isEviction,
+                                Object expectedOldValue,
+                                boolean removeRecoveredEntry)
+   throws CacheWriterException, EntryNotFoundException, TimeoutException {
+     
+     final LocalRegion owner = _getOwner();
+ 
+     if (owner == null) {
+       Assert.assertTrue(false, "The owner for RegionMap " + this    // "fix" for bug 32440
+           + " is null for event " + event);
+     }
+     
+     boolean retry = true;
+     
+     while (retry) {
+       retry = false;
+ 
+       boolean opCompleted = false;
+       boolean doPart3 = false;
+ 
+       // We need to acquire the region entry while holding the lock to avoid #45620.
+       // However, we also want to release the lock before distribution to prevent
+       // potential deadlocks.  The outer try/finally ensures that the lock will be
+       // released without fail.  I'm avoiding indenting just to preserve the ability
+       // to track diffs since the code is fairly complex.
+       boolean doUnlock = true;
+       lockForCacheModification(owner, event);
+       try {
+ 
+ 
+         RegionEntry re = getOrCreateRegionEntry(owner, event, Token.REMOVED_PHASE1, null, true, true); 
+         RegionEntry tombstone = null;
+         boolean haveTombstone = false;
+         /*
+          * Execute the test hook runnable inline (not threaded) if it is not null. 
+          */
+         if(null != testHookRunnableFor48182) {
+           testHookRunnableFor48182.run();
+         }    
+ 
+         try {
+           if (logger.isTraceEnabled(LogMarker.LRU_TOMBSTONE_COUNT) && !(owner instanceof HARegion)) {
+             logger.trace(LogMarker.LRU_TOMBSTONE_COUNT,
+                 "ARM.destroy() inTokenMode={}; duringRI={}; riLocalDestroy={}; withRepl={}; fromServer={}; concurrencyEnabled={}; isOriginRemote={}; isEviction={}; operation={}; re={}",
+                 inTokenMode, duringRI, event.isFromRILocalDestroy(), owner.dataPolicy.withReplication(), event.isFromServer(),
+                 owner.concurrencyChecksEnabled, event.isOriginRemote(), isEviction, event.getOperation(), re);
+           }
+           if (event.isFromRILocalDestroy()) {
+             // for RI local-destroy we don't want to keep tombstones.
+             // In order to simplify things we just set this recovery
+             // flag to true to force the entry to be removed
+             removeRecoveredEntry = true;
+           }
+           // the logic in this method is already very involved, and adding tombstone
+           // permutations to (re != null) greatly complicates it.  So, we check
+           // for a tombstone here and, if found, pretend for a bit that the entry is null
+           if (re != null && re.isTombstone() && !removeRecoveredEntry) {
+             tombstone = re;
+             haveTombstone = true;
+             re = null;
+           }
+           IndexManager oqlIndexManager = owner.getIndexManager() ; 
+           if (re == null) {
+             // we need to create an entry if in token mode or if we've received
+             // a destroy from a peer or WAN gateway and we need to retain version
+             // information for concurrency checks
+             boolean retainForConcurrency = (!haveTombstone
+                 && (owner.dataPolicy.withReplication() || event.isFromServer())
+                 && owner.concurrencyChecksEnabled
+                 && (event.isOriginRemote() /* destroy received from other must create tombstone */
+                     || event.isFromWANAndVersioned() /* wan event must create a tombstone */
+                     || event.isBridgeEvent())); /* event from client must create a tombstone so client has a version # */ 
+             if (inTokenMode
+                 || retainForConcurrency) { 
+               // removeRecoveredEntry should be false in this case
+               RegionEntry newRe = getEntryFactory().createEntry(owner,
+                   event.getKey(),
+                   Token.REMOVED_PHASE1);
+               // Fix for Bug #44431. We do NOT want to update the region and wait
+               // later for index INIT as region.clear() can cause inconsistency if
+               // happened in parallel as it also does index INIT.
+               if (oqlIndexManager != null) {
+                 oqlIndexManager.waitForIndexInit();
+               }
+               try {
+                 synchronized (newRe) {
+                   RegionEntry oldRe = putEntryIfAbsent(event.getKey(), newRe);
+                   while (!opCompleted && oldRe != null) {
+                     synchronized (oldRe) {
+                       if (oldRe.isRemovedPhase2()) {
+                         oldRe = putEntryIfAbsent(event.getKey(), newRe);
+                         if (oldRe != null) {
+                           owner.getCachePerfStats().incRetries();
+                         }
+                       } else {
+                         event.setRegionEntry(oldRe);
+ 
+                         // Last transaction related eviction check. This should
+                         // prevent
+                         // transaction conflict (caused by eviction) when the entry
+                         // is being added to transaction state.
+                         if (isEviction) {
+                           if (!confirmEvictionDestroy(oldRe) || (owner.getEvictionCriteria() != null && !owner.getEvictionCriteria().doEvict(event))) {
+                             opCompleted = false;
+                             return opCompleted;
+                           }
+                         }
+                         try {
+                           //if concurrency checks are enabled, destroy will
+                           //set the version tag
+                           boolean destroyed = destroyEntry(oldRe, event, inTokenMode, cacheWrite, expectedOldValue, false, removeRecoveredEntry);
+                           if (destroyed) {
+                             if (retainForConcurrency) {
+                               owner.basicDestroyBeforeRemoval(oldRe, event);
+                             }
+                             owner.basicDestroyPart2(oldRe, event, inTokenMode,
+                                 false /* conflict with clear */, duringRI, true);
+                             lruEntryDestroy(oldRe);
+                             doPart3 = true;
+                           }
+                         }
+                         catch (RegionClearedException rce) {
+                           // Ignore. The exception will ensure that we do not update
+                           // the LRU List
+                           owner.basicDestroyPart2(oldRe, event, inTokenMode,
+                               true/* conflict with clear */, duringRI, true);
+                           doPart3 = true;
+                         } catch (ConcurrentCacheModificationException ccme) {
+                           VersionTag tag = event.getVersionTag();
+                           if (tag != null && tag.isTimeStampUpdated()) {
+                             // Notify gateways of new time-stamp.
+                             owner.notifyTimestampsToGateways(event);
+                           }
+                           throw ccme;
+                         }
+                         re = oldRe;
+                         opCompleted = true;
+                       }
+                     } // synchronized oldRe
+                   } // while
+                   if (!opCompleted) {
+                     // The following try has a finally that cleans up the newRe.
+                     // This is only needed if newRe was added to the map which only
+                     // happens if we didn't get completed with oldRe in the above while loop.
+                     try {
+                       re = newRe;
+                       event.setRegionEntry(newRe);
+ 
+                       try {
+                         //if concurrency checks are enabled, destroy will
+                         //set the version tag
+                         if (isEviction) {
+                           opCompleted = false;
+                           return opCompleted; 
+                         }
+                         opCompleted = destroyEntry(newRe, event, inTokenMode, cacheWrite, expectedOldValue, true, removeRecoveredEntry);
+                         if (opCompleted) {
+                           // This is a new entry that was created because we are in
+                           // token mode or are accepting a destroy operation by adding
+                           // a tombstone.  There is no oldValue, so we don't need to
+                           // call updateSizeOnRemove
+                           //                    owner.recordEvent(event);
+                           event.setIsRedestroyedEntry(true);  // native clients need to know if the entry didn't exist
+                           if (retainForConcurrency) {
+                             owner.basicDestroyBeforeRemoval(oldRe, event);
+                           }
+                           owner.basicDestroyPart2(newRe, event, inTokenMode,
+                               false /* conflict with clear */, duringRI, true);
+                           doPart3 = true;
+                         }
+                       }
+                       catch (RegionClearedException rce) {
+                         // Ignore. The exception will ensure that we do not update
+                         // the LRU List
+                         opCompleted = true;
+                         EntryLogger.logDestroy(event);
+                         owner.basicDestroyPart2(newRe, event, inTokenMode, true /* conflict with clear*/, duringRI, true);
+                         doPart3 = true;
+                       } catch (ConcurrentCacheModificationException ccme) {
+                         VersionTag tag = event.getVersionTag();
+                         if (tag != null && tag.isTimeStampUpdated()) {
+                           // Notify gateways of new time-stamp.
+                           owner.notifyTimestampsToGateways(event);
+                         }
+                         throw ccme;
+                       }
+                       // Note no need for LRU work since the entry is destroyed
+                       // and will be removed when gii completes
+                     } finally {
+                       if (!opCompleted && !haveTombstone  /* to fix bug 51583 do this for all operations */ ) {
+                         removeEntry(event.getKey(), newRe, false);
+                       }
+                       if (!opCompleted && isEviction) {
+                         removeEntry(event.getKey(), newRe, false);
+                       }
+                     }
+                   } // !opCompleted
+                 } // synchronized newRe
+               } finally {
+                 if (oqlIndexManager != null) {
+                   oqlIndexManager.countDownIndexUpdaters();
+                 }
+               }
+             } // inTokenMode or tombstone creation
+             else {
+               if (!isEviction || owner.concurrencyChecksEnabled) {                                 
+                 // The following ensures that there is not a concurrent operation
+                 // on the entry and leaves behind a tombstone if concurrencyChecksEnabled.
+                 // It fixes bug #32467 by propagating the destroy to the server even though
+                 // the entry isn't in the client
+                 RegionEntry newRe = haveTombstone? tombstone : getEntryFactory().createEntry(owner, event.getKey(),
+                     Token.REMOVED_PHASE1);
+                 synchronized(newRe) {
+                   if (haveTombstone && !tombstone.isTombstone()) {
+                     // we have to check this again under synchronization since it may have changed
+                     retry = true;
+                     //retryEntry = tombstone; // leave this in place for debugging
+                     continue;
+                   }
+                   re = (RegionEntry)_getMap().putIfAbsent(event.getKey(), newRe);
+                   if (re != null && re != tombstone) {
+                     // concurrent change - try again
+                     retry = true;
+                     //retryEntry = tombstone; // leave this in place for debugging
+                     continue;
+                   }
+                   else if (!isEviction) {
+                     boolean throwex = false;
+                     EntryNotFoundException ex =  null;
+                     try {
+                       if (!cacheWrite) {
+                         throwex = true;
+                       } else {
+                         try {
+                           if (!removeRecoveredEntry) {
+                             throwex = !owner.bridgeWriteBeforeDestroy(event, expectedOldValue);
+                           }
+                         } catch (EntryNotFoundException e) {
+                           throwex = true;
+                           ex = e; 
+                         }
+                       }
+                       if (throwex) {
+                         if (!event.isOriginRemote() && !event.getOperation().isLocal() &&
+                             (event.isFromBridgeAndVersioned() ||  // if this is a replayed client event that already has a version
+                                 event.isFromWANAndVersioned())) { // or if this is a WAN event that has been applied in another system
+                           // we must distribute these since they will update the version information in peers
+                           if (logger.isDebugEnabled()) {
+                             logger.debug("ARM.destroy is allowing wan/client destroy of {} to continue", event.getKey());
+                           }
+                           throwex = false;
+                           event.setIsRedestroyedEntry(true);
+                           // Distribution of this op happens on re and re might me null here before
+                           // distributing this destroy op.
+                           if (re == null) {
+                             re = newRe;
+                           }
+                           doPart3 = true;
+                         }
+                       }
+                       if (throwex) {                    
+                         if (ex == null) {
+                           // Fix for 48182, check cache state and/or region state before sending entry not found.
+                           // this is from the server and any exceptions will propogate to the client
+                           owner.checkEntryNotFound(event.getKey());
+                         } else {
+                           throw ex;
+                         }
+                       }
+                     } finally {
+                       // either remove the entry or leave a tombstone
+                       try {
+                         if (!event.isOriginRemote() && event.getVersionTag() != null && owner.concurrencyChecksEnabled) {
+                           // this shouldn't fail since we just created the entry.
+                           // it will either generate a tag or apply a server's version tag
+                           processVersionTag(newRe, event);
+                           if (doPart3) {
+                             owner.generateAndSetVersionTag(event, newRe);
+                           }
+                           try {
+                             owner.recordEvent(event);
+                             newRe.makeTombstone(owner, event.getVersionTag());
+                           } catch (RegionClearedException e) {
+                             // that's okay - when writing a tombstone into a disk, the
+                             // region has been cleared (including this tombstone)
+                           }
+                           opCompleted = true;
+                           //                    lruEntryCreate(newRe);
+                         } else if (!haveTombstone) {
+                           try {
+                             assert newRe != tombstone;
+                             newRe.setValue(owner, Token.REMOVED_PHASE2);
+                             removeEntry(event.getKey(), newRe, false);
+                           } catch (RegionClearedException e) {
+                             // that's okay - we just need to remove the new entry
+                           }
+                         } else if (event.getVersionTag() != null ) { // haveTombstone - update the tombstone version info
+                           processVersionTag(tombstone, event);
+                           if (doPart3) {
+                             owner.generateAndSetVersionTag(event, newRe);
+                           }
+                           // This is not conflict, we need to persist the tombstone again with new version tag 
+                           try {
+                             tombstone.setValue(owner, Token.TOMBSTONE);
+                           } catch (RegionClearedException e) {
+                             // that's okay - when writing a tombstone into a disk, the
+                             // region has been cleared (including this tombstone)
+                           }
+                           owner.recordEvent(event);
+                           owner.rescheduleTombstone(tombstone, event.getVersionTag());
+                           owner.basicDestroyPart2(tombstone, event, inTokenMode, true /* conflict with clear*/, duringRI, true);
+                           opCompleted = true;
+                         }
+                       } catch (ConcurrentCacheModificationException ccme) {
+                         VersionTag tag = event.getVersionTag();
+                         if (tag != null && tag.isTimeStampUpdated()) {
+                           // Notify gateways of new time-stamp.
+                           owner.notifyTimestampsToGateways(event);
+                         }
+                         throw ccme;
+                       }
+                     }
+                   }
+                 } // synchronized(newRe)
+               }
+             }
+           } // no current entry
+           else { // current entry exists
+             if (oqlIndexManager != null) {
+               oqlIndexManager.waitForIndexInit();
+             }
+             try {
+               synchronized (re) {
+                 // if the entry is a tombstone and the event is from a peer or a client
+                 // then we allow the operation to be performed so that we can update the
+                 // version stamp.  Otherwise we would retain an old version stamp and may allow
+                 // an operation that is older than the destroy() to be applied to the cache
+                 // Bug 45170: If removeRecoveredEntry, we treat tombstone as regular entry to be deleted
+                 boolean createTombstoneForConflictChecks = (owner.concurrencyChecksEnabled
+                     && (event.isOriginRemote() || event.getContext() != null || removeRecoveredEntry));
+                 if (!re.isRemoved() || createTombstoneForConflictChecks) {
+                   if (re.isRemovedPhase2()) {
+                     retry = true;
+                     continue;
+                   }
+                   if (!event.isOriginRemote() && event.getOperation().isExpiration()) {
+                     // If this expiration started locally then only do it if the RE is not being used by a tx.
+                     if (re.isInUseByTransaction()) {
+                       opCompleted = false;
+                       return opCompleted;
+                     }
+                   }
+                   event.setRegionEntry(re);
+ 
+                   // See comment above about eviction checks
+                   if (isEviction) {
+                     assert expectedOldValue == null;
+                     if (!confirmEvictionDestroy(re) || (owner.getEvictionCriteria() != null && !owner.getEvictionCriteria().doEvict(event))) {
+                       opCompleted = false;
+                       return opCompleted;
+                     }
+                   }
+ 
+                   boolean removed = false;
+                   try {
+                     opCompleted = destroyEntry(re, event, inTokenMode, cacheWrite, expectedOldValue, false, removeRecoveredEntry);
+                     if (opCompleted) {
+                       // It is very, very important for Partitioned Regions to keep
+                       // the entry in the map until after distribution occurs so that other
+                       // threads performing a create on this entry wait until the destroy
+                       // distribution is finished.
+                       // keeping backup copies consistent. Fix for bug 35906.
+                       // -- mthomas 07/02/2007 <-- how about that date, kinda cool eh?
+                       owner.basicDestroyBeforeRemoval(re, event);
+ 
+                       // do this before basicDestroyPart2 to fix bug 31786
+                       if (!inTokenMode) {
+                         if ( re.getVersionStamp() == null) {
+                           re.removePhase2();
+                           removeEntry(event.getKey(), re, true, event, owner,
+                               indexUpdater);
+                           removed = true;
+                         }
+                       }
+                       if (inTokenMode && !duringRI) {
+                         event.inhibitCacheListenerNotification(true);
+                       }
+                       doPart3 = true;
+                       owner.basicDestroyPart2(re, event, inTokenMode, false /* conflict with clear*/, duringRI, true);
+                       //                  if (!re.isTombstone() || isEviction) {
+                       lruEntryDestroy(re);
+                       //                  } else {
+                       //                    lruEntryUpdate(re);
+                       //                    lruUpdateCallback = true;
+                       //                  }
+                     } else {
+                       if (!inTokenMode) {
+                         EntryLogger.logDestroy(event);
+                         owner.recordEvent(event);
+                         if (re.getVersionStamp() == null) {
+                           re.removePhase2();
+                           removeEntry(event.getKey(), re, true, event, owner,
+                               indexUpdater);
+                           lruEntryDestroy(re);
+                         } else {
+                           if (re.isTombstone()) {
+                             // the entry is already a tombstone, but we're destroying it
+                             // again, so we need to reschedule the tombstone's expiration
+                             if (event.isOriginRemote()) {
+                               owner.rescheduleTombstone(re, re.getVersionStamp().asVersionTag());
+                             }
+                           }
+                         }
+                         lruEntryDestroy(re);
+                         opCompleted = true;
+                       }
+                     }
+                   }
+                   catch (RegionClearedException rce) {
+                     // Ignore. The exception will ensure that we do not update
+                     // the LRU List
+                     opCompleted = true;
+                     owner.recordEvent(event);
+                     if (inTokenMode && !duringRI) {
+                       event.inhibitCacheListenerNotification(true);
+                     }
+                     owner.basicDestroyPart2(re, event, inTokenMode, true /*conflict with clear*/, duringRI, true);
+                     doPart3 = true;
+                   }
+                   finally {
+                     if (re.isRemoved() && !re.isTombstone()) {
+                       if (!removed) {
+                         removeEntry(event.getKey(), re, true, event, owner,
+                             indexUpdater);
+                       }
+                     }
+                   }
+                 } // !isRemoved
+                 else { // already removed
+                   if (owner.isHDFSReadWriteRegion() && re.isRemovedPhase2()) {
+                     // For HDFS region there may be a race with eviction
+                     // so retry the operation. fixes bug 49150
+                     retry = true;
+                     continue;
+                   }
+                   if (re.isTombstone() && event.getVersionTag() != null) {
+                     // if we're dealing with a tombstone and this is a remote event
+                     // (e.g., from cache client update thread) we need to update
+                     // the tombstone's version information
+                     // TODO use destroyEntry() here
+                     processVersionTag(re, event);
+                     try {
+                       re.makeTombstone(owner, event.getVersionTag());
+                     } catch (RegionClearedException e) {
+                       // that's okay - when writing a tombstone into a disk, the
+                       // region has been cleared (including this tombstone)
+                     }
+                   }
+                   if (expectedOldValue != null) {
+                     // if re is removed then there is no old value, so return false
+                     return false;
+                   }
+ 
+                   if (!inTokenMode && !isEviction) {
+                     owner.checkEntryNotFound(event.getKey());
+                   }
+                 }
+               } // synchronized re
+             }  catch (ConcurrentCacheModificationException ccme) {
+               VersionTag tag = event.getVersionTag();
+               if (tag != null && tag.isTimeStampUpdated()) {
+                 // Notify gateways of new time-stamp.
+                 owner.notifyTimestampsToGateways(event);
+               }
+               throw ccme;
+             } finally {
+               if (oqlIndexManager != null) {
+                 oqlIndexManager.countDownIndexUpdaters();
+               }
+             }
+             // No need to call lruUpdateCallback since the only lru action
+             // we may have taken was lruEntryDestroy. This fixes bug 31759.
+ 
+           } // current entry exists
+           if(opCompleted) {
+             EntryLogger.logDestroy(event);
+           }
+           return opCompleted;
+         }
+         finally {
+           releaseCacheModificationLock(owner, event);
+           doUnlock = false;
+ 
+           try {
+             // If concurrency conflict is there and event contains gateway version tag then
+             // do NOT distribute.
+             if (event.isConcurrencyConflict() &&
+                 (event.getVersionTag() != null && event.getVersionTag().isGatewayTag())) {
+               doPart3 = false;
+             }
+             // distribution and listener notification
+             if (doPart3) {
+               owner.basicDestroyPart3(re, event, inTokenMode, duringRI, true, expectedOldValue);
+             }
+           } finally {
+             if (opCompleted) {
+               if (re != null) {
+                 owner.cancelExpiryTask(re);
+               } else if (tombstone != null) {
+                 owner.cancelExpiryTask(tombstone);
+               }
+             }
+           }
+         }
+ 
+       } finally { // failsafe on the read lock...see comment above
+         if (doUnlock) {
+           releaseCacheModificationLock(owner, event);
+         }
+       }
+     } // retry loop
+     return false;
+   }
+ 
+   public final void txApplyDestroy(Object key, TransactionId txId,
+       TXRmtEvent txEvent, boolean inTokenMode, boolean inRI, Operation op, 
+       EventID eventId, Object aCallbackArgument,List<EntryEventImpl> pendingCallbacks,FilterRoutingInfo filterRoutingInfo,ClientProxyMembershipID bridgeContext,
+       boolean isOriginRemote, TXEntryState txEntryState, VersionTag versionTag, long tailKey)
+   {
+     final boolean isDebugEnabled = logger.isDebugEnabled();
+     
+     final LocalRegion owner = _getOwner();
+     owner.checkBeforeEntrySync(txEvent);
+ 
+     final boolean isRegionReady = !inTokenMode;
+     final boolean hasRemoteOrigin = !((TXId)txId).getMemberId().equals(owner.getMyId());
+     boolean cbEventInPending = false;
+     lockForTXCacheModification(owner, versionTag);
+     IndexManager oqlIndexManager = owner.getIndexManager() ; 
+     try {
+       RegionEntry re = getEntry(key);
+       if (re != null) {
+         // Fix for Bug #44431. We do NOT want to update the region and wait
+         // later for index INIT as region.clear() can cause inconsistency if
+         // happened in parallel as it also does index INIT.
+         if (oqlIndexManager != null) {
+           oqlIndexManager.waitForIndexInit();
+         }
+         try {
+           synchronized (re) {
+             if (!re.isRemoved() || re.isTombstone()) {
+               EntryEventImpl sqlfEvent = null;
+               @Retained @Released Object oldValue = re.getValueInVM(owner);
+               try {
+               final int oldSize = owner.calculateRegionEntryValueSize(re);
+               // Create an entry event only if the calling context is
+               // a receipt of a TXCommitMessage AND there are callbacks installed
+               // for this region
+               boolean invokeCallbacks = shouldCreateCBEvent(owner, false/*isInvalidate*/, isRegionReady || inRI);
+               EntryEventImpl cbEvent = createCBEvent(owner, op,
+                   key, null, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
+               try {
+               
+               if (/* owner.isUsedForPartitionedRegionBucket() && */ 
+                   indexUpdater != null) {
+                  sqlfEvent = cbEvent;
+               } else {
+                 if (owner.isUsedForPartitionedRegionBucket()) {
+                   txHandleWANEvent(owner, cbEvent, txEntryState);
+                 }
+                 cbEvent.setRegionEntry(re);
+               }
+               cbEvent.setOldValue(oldValue);
+               if (isDebugEnabled) {
+                 logger.debug("txApplyDestroy cbEvent={}", cbEvent);
+               }
+               
+               txRemoveOldIndexEntry(Operation.DESTROY, re);
+               if (txEvent != null) {
+                 txEvent.addDestroy(owner, re, re.getKey(),aCallbackArgument);
+               }
+               boolean clearOccured = false;
+               try {
+                 processAndGenerateTXVersionTag(owner, cbEvent, re, txEntryState);
+                 if (inTokenMode) {
+                   if (oldValue == Token.TOMBSTONE) {
+                     owner.unscheduleTombstone(re);
+                   }
+                   re.setValue(owner, Token.DESTROYED);
+                 }
+                 else {
+                   if (!re.isTombstone()) {
+                     if (sqlfEvent != null) {
+                       re.removePhase1(owner, false); // fix for bug 43063
+                       re.removePhase2();
+                       removeEntry(key, re, true, sqlfEvent, owner, indexUpdater);
+                     } else {
+                       if (shouldPerformConcurrencyChecks(owner, cbEvent) && cbEvent.getVersionTag() != null) {
+                         re.makeTombstone(owner, cbEvent.getVersionTag());
+                       } else {
+                         re.removePhase1(owner, false); // fix for bug 43063
+                         re.removePhase2();
+                         removeEntry(key, re, false);
+                       }
+                     }
+                   } else {
+                     owner.rescheduleTombstone(re, re.getVersionStamp().asVersionTag());
+                   }
+                 }
+                 EntryLogger.logTXDestroy(_getOwnerObject(), key);
+                 owner.updateSizeOnRemove(key, oldSize);
+               }
+               catch (RegionClearedException rce) {
+                 clearOccured = true;
+               }
+               owner.txApplyDestroyPart2(re, re.getKey(), inTokenMode,
+                   clearOccured /* Clear Conflciting with the operation */);
+               if (invokeCallbacks) {
+                 switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
+                 if(pendingCallbacks==null) {
+                   owner.invokeTXCallbacks(EnumListenerEvent.AFTER_DESTROY,
+                       cbEvent, true/*callDispatchListenerEvent*/);
+                 } else {
+                   pendingCallbacks.add(cbEvent);
+                   cbEventInPending = true;
+                 }
+               }
+               if (!clearOccured) {
+                 lruEntryDestroy(re);
+               }
+               if (owner.concurrencyChecksEnabled && txEntryState != null && cbEvent!= null) {
+                 txEntryState.setVersionTag(cbEvent.getVersionTag());
+               }
+               } finally {
+                 if (!cbEventInPending) cbEvent.release();
+               }
+               } finally {
+                 OffHeapHelper.release(oldValue);
+               }
+             }
+           }
+         } finally {
+           if (oqlIndexManager != null) {
+             oqlIndexManager.countDownIndexUpdaters();
+           }
+         }
+       } else if (inTokenMode || owner.concurrencyChecksEnabled) {
+         // treating tokenMode and re == null as same, since we now want to
+         // generate versions and Tombstones for destroys
+         boolean dispatchListenerEvent = inTokenMode;
+         boolean opCompleted = false;
+         RegionEntry newRe = getEntryFactory().createEntry(owner, key,
+             Token.DESTROYED);
+         if ( oqlIndexManager != null) {
+           oqlIndexManager.waitForIndexInit();
+         }
+         EntryEventImpl cbEvent = null;
+         try {
+           synchronized (newRe) {
+             RegionEntry oldRe = putEntryIfAbsent(key, newRe);
+             while (!opCompleted && oldRe != null) {
+               synchronized (oldRe) {
+                 if (oldRe.isRemovedPhase2()) {
+                   oldRe = putEntryIfAbsent(key, newRe);
+                   if (oldRe != null) {
+                     owner.getCachePerfStats().incRetries();
+                   }
+                 }
+                 else {
+                   try {
+                     boolean invokeCallbacks = shouldCreateCBEvent(owner, false, isRegionReady || inRI);
+                     cbEvent = createCBEvent(owner, op,
+                         key, null, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
+                     try {
+                     cbEvent.setRegionEntry(oldRe);
+                     cbEvent.setOldValue(Token.NOT_AVAILABLE);
+                     if (isDebugEnabled) {
+                       logger.debug("txApplyDestroy token mode cbEvent={}", cbEvent);
+                     }
+                     if (owner.isUsedForPartitionedRegionBucket()) {
+                       txHandleWANEvent(owner, cbEvent, txEntryState);
+                     }
+                     processAndGenerateTXVersionTag(owner, cbEvent, oldRe, txEntryState);
+                     if (invokeCallbacks) {
+                       switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
+                       if(pendingCallbacks==null) {
+                         owner.invokeTXCallbacks(EnumListenerEvent.AFTER_DESTROY,
+                             cbEvent, dispatchListenerEvent);
+                       } else {
+                         pendingCallbacks.add(cbEvent);
+                         cbEventInPending = true;
+                       }
+                     }
+                     int oldSize = 0;
+                     boolean wasTombstone = oldRe.isTombstone();
+                     {
+                       if (!wasTombstone) {
+                         oldSize = owner.calculateRegionEntryValueSize(oldRe);
+                       }
+                     }
+                     oldRe.setValue(owner, Token.DESTROYED);
+                     EntryLogger.logTXDestroy(_getOwnerObject(), key);
+                     if (wasTombstone) {
+                       owner.unscheduleTombstone(oldRe);
+                     }
+                     owner.updateSizeOnRemove(oldRe.getKey(), oldSize);
+                     owner.txApplyDestroyPart2(oldRe, oldRe.getKey(), inTokenMode,
+                         false /* Clear Conflicting with the operation */);
+                     lruEntryDestroy(oldRe);
+                     } finally {
+                       if (!cbEventInPending) cbEvent.release();
+                     }
+                   }
+                   catch (RegionClearedException rce) {
+                     owner.txApplyDestroyPart2(oldRe, oldRe.getKey(), inTokenMode,
+                         true /* Clear Conflicting with the operation */);
+                   }
+                   if (shouldPerformConcurrencyChecks(owner, cbEvent) && cbEvent.getVersionTag() != null) {
+                     oldRe.makeTombstone(owner, cbEvent.getVersionTag());
+                   } else if (!inTokenMode) {
+                     // only remove for NORMAL regions if they do not generate versions see 51781
+                     oldRe.removePhase1(owner, false); // fix for bug 43063
+                     oldRe.removePhase2();
+                     removeEntry(key, oldRe, false);
+                   }
+                   opCompleted = true;
+                 }
+               }
+             }
+             if (!opCompleted) {
+               // already has value set to Token.DESTROYED
+               opCompleted = true;
+               boolean invokeCallbacks = shouldCreateCBEvent(owner, false, isRegionReady || inRI);
+               cbEvent = createCBEvent(owner, op,
+                   key, null, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
+               try {
+               cbEvent.setRegionEntry(newRe);
+               cbEvent.setOldValue(Token.NOT_AVAILABLE);
+               if (isDebugEnabled) {
+                 logger.debug("txApplyDestroy token mode cbEvent={}", cbEvent);
+               }
+               if (owner.isUsedForPartitionedRegionBucket()) {
+                 txHandleWANEvent(owner, cbEvent, txEntryState);
+               }
+               processAndGenerateTXVersionTag(owner, cbEvent, newRe, txEntryState);
+               if (invokeCallbacks) {
+                 switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
+                 if(pendingCallbacks==null) {
+                   owner.invokeTXCallbacks(EnumListenerEvent.AFTER_DESTROY,
+                       cbEvent, dispatchListenerEvent);
+                 } else {
+                   pendingCallbacks.add(cbEvent);
+                   cbEventInPending = true;
+                 }
+               }
+               EntryLogger.logTXDestroy(_getOwnerObject(), key);
+               owner.updateSizeOnCreate(newRe.getKey(), 0);
+               if (shouldPerformConcurrencyChecks(owner, cbEvent) && cbEvent.getVersionTag() != null) {
+                 newRe.makeTombstone(owner, cbEvent.getVersionTag());
+               } else if (!inTokenMode) {
+                 // only remove for NORMAL regions if they do not generate versions see 51781
+                 newRe.removePhase1(owner, false); // fix for bug 43063
+                 newRe.removePhase2();
+                 removeEntry(key, newRe, false);
+               }
+               owner
+                   .txApplyDestroyPart2(newRe, newRe.getKey(), inTokenMode,
+                       false /*clearConflict*/);
+               // Note no need for LRU work since the entry is destroyed
+               // and will be removed when gii completes
+               } finally {
+                 if (!cbEventInPending) cbEvent.release();
+               }
+             }
+             if (owner.concurrencyChecksEnabled && txEntryState != null && cbEvent != null) {
+               txEntryState.setVersionTag(cbEvent.getVersionTag());
+             }
+           }
+         } catch (RegionClearedException e) {
+           // TODO 
+         } finally {
+           if (oqlIndexManager != null) {
+             oqlIndexManager.countDownIndexUpdaters();
+           }
+         }
+       } else if (re == null) {
+         // Fix bug#43594
+         // In cases where bucket region is re-created, it may so happen that 
+         // the destroy is already applied on the Initial image provider, thus 
+         // causing region entry to be absent. 
+         // Notify clients with client events.
+         EntryEventImpl cbEvent = createCBEvent(owner, op,
+             key, null, txId, txEvent, eventId, aCallbackArgument, 
+             filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
+         try {
+         if (owner.isUsedForPartitionedRegionBucket()) {
+           txHandleWANEvent(owner, cbEvent, txEntryState);
+         }
+         switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
+         if (pendingCallbacks == null) {
+           owner.invokeTXCallbacks(EnumListenerEvent.AFTER_DESTROY,cbEvent,false);
+         } else {
+           pendingCallbacks.add(cbEvent);
+           cbEventInPending = true;
+         }
+         } finally {
+           if (!cbEventInPending) cbEvent.release();
+         }
+       }
+     } catch( DiskAccessException dae) {
+       owner.handleDiskAccessException(dae);
+       throw dae;
+     }
+     finally {
+       releaseTXCacheModificationLock(owner, versionTag);
+     }
+   }
+ 
+   /**
+    * If true then invalidates that throw EntryNotFoundException
+    * or that are already invalid will first call afterInvalidate on CacheListeners. 
+    * The old value on the event passed to afterInvalidate will be null.
+    */
+   public static boolean FORCE_INVALIDATE_EVENT = Boolean.getBoolean("gemfire.FORCE_INVALIDATE_EVENT");
+ 
+   /**
+    * If the FORCE_INVALIDATE_EVENT flag is true
+    * then invoke callbacks on the given event.
+    */
+   void forceInvalidateEvent(EntryEventImpl event) {
+     if (FORCE_INVALIDATE_EVENT) {
+       event.invokeCallbacks(_getOwner(), false, false);
+     }
+   }
+   
+   public final boolean invalidate(EntryEventImpl event,
+       boolean invokeCallbacks, boolean forceNewEntry, boolean forceCallbacks)
+       throws EntryNotFoundException
+   {
+     final boolean isDebugEnabled = logger.isDebugEnabled();
+     
+     final LocalRegion owner = _getOwner();
+     if (owner == null) {
+       // "fix" for bug 32440
+       Ass

<TRUNCATED>


[006/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/PartitionedRegionDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/PartitionedRegionDUnitTest.java
index 0408eb7,0000000..bc631bd
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/PartitionedRegionDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/PartitionedRegionDUnitTest.java
@@@ -1,554 -1,0 +1,554 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.io.Serializable;
 +import java.util.Collection;
 +import java.util.Iterator;
 +import java.util.Random;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.EntryExistsException;
 +import com.gemstone.gemfire.cache.InterestPolicy;
 +import com.gemstone.gemfire.cache.PartitionAttributes;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.SubscriptionAttributes;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegionException;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.internal.logging.PureLogWriter;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * This class tests the functionality of a cache {@link Region region}
 + * that has a scope of {@link Scope#DISTRIBUTED_ACK distributed ACK}
 + * and {@link PartitionAttributes partition-attributes}.
 + *
 + * @author Bruce Schuchardt
 + * @since 5.1
 + */
 +public class PartitionedRegionDUnitTest extends MultiVMRegionTestCase {
 +  
 +  static int oldLogLevel;
 +
 +  public PartitionedRegionDUnitTest(String name) {
 +    super(name);
 +  }
 +  
 +  /*
 +   * (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache30.RegionTestCase#supportsSubregions()
 +   */
 +  protected boolean supportsSubregions() { return false; }
 +  
 +  /*
 +   * (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache30.MultiVMRegionTestCase#supportsNetLoad()
 +   */
 +  protected boolean supportsNetLoad() { return false; }
 +
 +  /*
 +   * (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache30.MultiVMRegionTestCase#supportsReplication()
 +   */
 +  protected boolean supportsReplication() { return false; }
 +  
 +  /*
 +   * (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache30.MultiVMRegionTestCase#supportsTransactions()
 +   */
 +  protected boolean supportsTransactions() { return false; }
 +  
 +  /*
 +   * (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache30.RegionTestCase#supportsLocalDestroyAndLocalInvalidate()
 +   */
 +  protected boolean supportsLocalDestroyAndLocalInvalidate() { return false; }
 +  
 +  public void testCacheLoaderModifyingArgument() throws InterruptedException {
 +    // TODO, implement a specific PR related test that properly reflects primary allocation
 +    // and event deliver based on that allocation
 +  }
 +
 +  public void testLocalAndRemoteCacheWriters() throws InterruptedException {
 +    // TODO, implement a specific PR related test that properly reflects primary allocation
 +    // and event deliver based on that allocation
 +  }
 +
 +  public void testLocalCacheLoader() {
 +    // TODO, implement a specific PR related test that properly reflects primary allocation
 +    // and event deliver based on that allocation
 +  }
 +  
 +
 +  /**
 +   * Returns region attributes for a partitioned region with distributed-ack scope
 +   */
 +  protected RegionAttributes getRegionAttributes() {
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setEarlyAck(false);
 +    factory.setPartitionAttributes((new PartitionAttributesFactory()).create());
 +    return factory.create();
 +  }
 +
 +  /**
 +   * Returns region attributes with a distributed-ack scope
 +   */
 +  protected RegionAttributes getNonPRRegionAttributes() {
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_ACK);
 +    factory.setEarlyAck(false);
 +    return factory.create();
 +  }
 +
 +  public static int setLogLevel(LogWriter l, int logLevl) {
 +    int ret = -1;
 +    if (l instanceof PureLogWriter) {
 +        PureLogWriter pl = (PureLogWriter) l;
 +        ret = pl.getLogWriterLevel();
 +        pl.setLevel(logLevl);
 +    }
 +    return ret;
 +  }
 +
 +  void setVMInfoLogLevel() {
 +    SerializableRunnable runnable = new SerializableRunnable() {
 +      public void run() {
 +        oldLogLevel = setLogLevel(getCache().getLogger(), InternalLogWriter.INFO_LEVEL);
 +      }
 +    };
 +    for (int i=0; i<4; i++) {
 +      Host.getHost(0).getVM(i).invoke(runnable);
 +    }
 +  }
 +    
 +  void resetVMLogLevel() {
 +    SerializableRunnable runnable = new SerializableRunnable() {
 +      public void run() {
 +        setLogLevel(getCache().getLogger(), oldLogLevel);
 +      }
 +    };
 +    for (int i=0; i<4; i++) {
 +      Host.getHost(0).getVM(i).invoke(runnable);
 +    }
 +  }
 +    
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  public static boolean InvalidateInvoked = false;
 +  
 +  /**
 +   * Bug #47235 concerns assertion failures being thrown when there is a
 +   * member that receives adjunct messages (as in a WAN gateway, a peer
 +   * with clients, etc).
 +   * 
 +   * @throws Exception
 +   */
 +  public void testRegionInvalidationWithAdjunctMessages() throws Exception {
 +    final String name = getUniqueName();
 +    VM vm1 = Host.getHost(0).getVM(1);
 +    Cache cache = getCache();
 +    RegionFactory fact = getCache().createRegionFactory(RegionShortcut.PARTITION);
 +    Region pr = fact.create(name+"Region");
 +    pr.put("Object1", "Value1");
 +    
 +    vm1.invoke(new SerializableRunnable("create PR") {
 +      @Override
 +      public void run() {
 +        RegionFactory fact = getCache().createRegionFactory(RegionShortcut.PARTITION);
 +        fact.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
 +        fact.addCacheListener(new CacheListenerAdapter(){
 +          @Override
 +          public void afterInvalidate(EntryEvent event) {
 +            com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("afterInvalidate invoked with " + event);
 +            InvalidateInvoked = true;
 +          }
 +        });
 +        fact.create(name+"Region");
 +      }
 +    });
 +    try {
 +      pr.invalidateRegion();
 +      assertTrue("vm1 should have invoked the listener for an invalidateRegion operation",
 +          (Boolean)vm1.invoke(new SerializableCallable("getStatus") {
 +            public Object call() {
 +              return InvalidateInvoked;
 +            }
 +          }));
 +    } finally {
 +      disconnectAllFromDS();
 +    }
 +  }
 +
 +  /**
 +   * Tests the compatibility of creating certain kinds of subregions
 +   * of a local region.
 +   *
 +   * @see Region#createSubregion
 +   */
 +  public void testIncompatibleSubregions()
 +    throws CacheException, InterruptedException {
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    final String name = this.getUniqueName() + "-PR";
 +    vm0.invoke(new SerializableRunnable("Create partitioned Region") {
 +        public void run() {
 +          try {
 +            
 +            createRegion(name, "INCOMPATIBLE_ROOT", getRegionAttributes());
 +          } catch (CacheException ex) {
 +            Assert.fail("While creating Partitioned region", ex);
 +          }
 +        }
 +      });
 +
 +    vm1.invoke(new SerializableRunnable("Create non-partitioned Region") {
 +        public void run() {
 +          try {
 +            AttributesFactory factory =
 +              new AttributesFactory(getNonPRRegionAttributes());
 +            try {
 +              createRegion(name, "INCOMPATIBLE_ROOT", factory.create());
 +              fail("Should have thrown an IllegalStateException");
 +            } catch (IllegalStateException ex) {
 +              // pass...
 +            }
 +
 +          } catch (CacheException ex) {
 +            Assert.fail("While creating Partitioned Region", ex);
 +          }
 +        }
 +      });
 +  } 
 +  
 +
 +  private void setupExtendedTest(final String regionName, final int numVals) {
 +    Host host = Host.getHost(0);
 +    SerializableRunnable createPR = new SerializableRunnable("createPartitionedRegion") {
 +        public void run() {
 +          try {
 +            createRegion(regionName, "root", getRegionAttributes());
 +          } catch (CacheException ex) {
 +            Assert.fail("While creating Partitioned region", ex);
 +          }
 +        }
 +    };
 +    for (int i=1; i<4; i++) {
 +      host.getVM(i).invoke(createPR);
 +    }
 +    VM vm0 = host.getVM(0);
 +    vm0.invoke(new SerializableRunnable("Populate Partitioned Region") {
 +        public void run() {
 +          Region region = null;
 +          try {
 +            region = createRegion(regionName, "root", getRegionAttributes());
 +            // since random keys are being used, we might hit duplicates
 +            region.getCache().getLogger().info("<ExpectedException action=add>"
 +                + "com.gemstone.gemfire.cache.EntryExistsException"
 +                + "</ExpectedException>");
 +            java.util.Random rand = new java.util.Random(System.currentTimeMillis());
 +            for (int i=0; i<numVals; i++) {
 +              boolean created = false;
 +              while (!created) {
 +                try {
 +                  int val = rand.nextInt(100000000);
 +                  String key = String.valueOf(val);
 +                  region.create(key, new Integer(val));
 +                  created = true;
 +                }
 +                catch (EntryExistsException eee) {
 +                  // loop to try again
 +                }
 +              }
 +            }
 +          }
 +          catch (Exception ex) {
 +            Assert.fail("while creating or populating partitioned region", ex);
 +          }
 +          finally {
 +            if (region != null) {
 +              region.getCache().getLogger().info("<ExpectedException action=remove>"
 +                + "com.gemstone.gemfire.cache.EntryExistsException"
 +                + "</ExpectedException>");
 +            }
 +          }
 +        }
 +    });
 +  }
 +  
 +  /**
 +   * test with multiple vms and a decent spread of keys
 +   */
 +  public void testExtendedKeysValues() {
 +    final String regionName = getUniqueName();
 +    final int numEntries = 20000;
 +
 +    // since this test has to create a lot of entries, info log level is used.
 +    // comment out the setting of this and rerun if there are problems
 +    setVMInfoLogLevel();
 +    try {
 +      setupExtendedTest(regionName, numEntries);
 +      
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      vm0.invoke(new SerializableRunnable("exercise Region.values") {
 +          public void run() {
 +            try {
 +              Region region = getRootRegion().getSubregion(regionName);
 +              Collection values = region.values();
 +              Set keys = region.keySet();
 +              Set entries = region.entrySet();
 +              assertEquals("value collection size was not the expected value", numEntries, values.size());
 +              assertEquals("key set size was not the expected value", numEntries, keys.size());
 +              assertEquals("entry set size was not the expected value", numEntries, entries.size());
 +              assertEquals("region size was not the expected value", numEntries, region.size());
 +              Iterator valuesIt = values.iterator();
 +              Iterator keysIt = keys.iterator();
 +              Iterator entriesIt = entries.iterator();
 +              for (int i=0; i<numEntries; i++) {
 +                assertTrue(valuesIt.hasNext());
 +                Integer value = (Integer)valuesIt.next();
 +                assertNotNull("value was null", value);
 +  
 +                assertTrue(keysIt.hasNext());
 +                String key = (String)keysIt.next();
 +                assertNotNull("key was null", key);
 +  
 +                assertTrue(entriesIt.hasNext());
 +                Region.Entry entry = (Region.Entry)entriesIt.next();
 +                assertNotNull("entry was null", entry);
 +                assertNotNull("entry key was null", entry.getKey());
 +                assertNotNull("entry value was null", entry.getValue());
 +              }
 +              assertTrue("should have been end of values iteration", !valuesIt.hasNext());
 +              assertTrue("should have been end of keys iteration", !keysIt.hasNext());
 +              assertTrue("should have been end of entries iteration", !entriesIt.hasNext());
 +            }
 +            catch (Exception ex) {
 +              try {
 +                getRootRegion().getSubregion(regionName).destroyRegion();
 +              }
 +              catch (Exception ex2) {
 +              }
 +              Assert.fail("Unexpected exception", ex);
 +            }
 +          }
 +      });
 +    }
 +    finally {
 +      resetVMLogLevel();
 +    }
 +  }
 +  
 +  // these tests make no sense for partitioned regions
 +  public void testDefinedEntryUpdated() {
 +    unimplemented();
 +  }
 +  public void testRemoteCacheListener() {
 +    unimplemented();
 +  }
 +  
 +  
 +  // these tests require getEntry support - need an alternative way of checking
 +  // the results that can be overridden here
 +//  public void testDistributedUpdate() {
 +//    unimplemented();
 +//  }
 +//  public void testDistributedPutNoUpdate() {
 +//    unimplemented();
 +//  }
 +//  public void testDistributedInvalidate() {
 +//    unimplemented();
 +//  }
 +//  public void testDistributedInvalidate4() {
 +//    unimplemented();
 +//  }
 +//  public void testContainsKey() {
 +//    unimplemented();
 +//  }
 +//  public void testBadRegionAccess() {
 +//    unimplemented();
 +//  }
 +//  public void testPutNonExistentEntry() {
 +//    unimplemented();
 +//  }
 +//  public void testDestroyEntry() {
 +//    unimplemented();
 +//  }
 +//  public void testInvalidateEntry() {
 +//    unimplemented();
 +//  }
 +//  public void testDistributedDestroy() {
 +//    unimplemented();
 +//  }
 +  
 +
 +  // user attributes aren't supported in partitioned regions at this time (5.1)
 +  public void testEntryUserAttribute() {
 +    unimplemented();
 +  }
 +
 +  
 +  // these tests require misc Region operations not currently supported by PRs
 +  public void testInvalidateRegion() {
 +    unimplemented();
 +  }
 +  public void testLocalDestroyRegion() {
 +    unimplemented();
 +  }
 +  public void testLocalInvalidateRegion() {
 +    unimplemented();
 +  }
 +  public void testSnapshot() {
 +    unimplemented();
 +  }
 +  public void testRootSnapshot() {
 +    unimplemented();
 +  }
 +
 +  private void unimplemented() {
 +//    StackTraceElement stack[] = new Exception("dummy").getStackTrace();
 +//    getLogWriter().info(stack[1].getClassName() + "." + stack[1].getMethodName()
 +//        + ": this test is not implemented for PartitionedRegions at this time");
 +  }
 +  static class PoisonedKey implements Serializable {
 +    static volatile boolean poisoned = false;
 +    static volatile boolean poisonDetected = false;
 +    
 +    /**
 +     * Accessed via reflection
 +     * @return true if poison found
 +     */
 +    public static boolean poisonFound() {
 +      boolean result = poisonDetected;
 +      poisonDetected = false; // restore default static value
 +      return result;
 +    }
 +    
 +    public int hashCode() {
 +      int result = k.hashCode();
 +      synchronized (PoisonedKey.class) {
 +        if (poisoned) {
 +          result += (new Random()).nextInt();
 +        }
 +      }
 +      return result;
 +    }
 +
 +    final String k;
 +    
 +    PoisonedKey(String s) {
 +      this.k = s;
 +    }
 +    
 +    public boolean equals(Object o) {
 +      if (o == null) {
 +        return false;
 +      }
 +      if (!(o instanceof PoisonedKey)) {
 +        return false;
 +      }
 +      PoisonedKey po = (PoisonedKey)o;
 +      if (k == null) {
 +        return po.k == null;
 +      }
 +      return k.equals(po.k);
 +    }
 +  }
 +  
 +  public void testBadHash() {
 +    final String regionName = getUniqueName();
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    SerializableRunnable createPR = new SerializableRunnable("createPartitionedRegion") {
 +        public void run() {
 +          try {
 +            createRegion(regionName, "root", getRegionAttributes());
 +          } catch (CacheException ex) {
 +            Assert.fail("While creating Partitioned region", ex);
 +          }
 +        }
 +    };
 +    vm0.invoke(createPR);
 +    vm1.invoke(createPR);
 +
 +    vm0.invoke(new SerializableRunnable("Populate 1") { 
 +      public void run() {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        for (int i = 0; i < 10; i ++) {
 +          String st = Integer.toString(i);
 +          PoisonedKey pk = new PoisonedKey(st);
 +          region.create(pk, st);
 +        }
 +      }
 +    });
 +    
 +    // Verify values are readily accessible
 +    vm1.invoke(new SerializableRunnable("Read 1") { 
 +      public void run() {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        for (int i = 0; i < 10; i ++) {
 +          String st = Integer.toString(i);
 +          PoisonedKey pk = new PoisonedKey(st);
 +          assertTrue("Keys screwed up too early", region.get(pk).equals(st));
 +        }
 +      }
 +    });
 +    
 +    // Bucket ID's will be screwed up with these creates.
 +    vm0.invoke(new SerializableRunnable("Populate 2") { 
 +      public void run() {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        PoisonedKey.poisoned = true;
 +        try {
 +          for (int i = 10; i < 20; i ++) {
 +            String st = Integer.toString(i);
 +            PoisonedKey pk = new PoisonedKey(st);
 +            region.create(pk, st);
 +          }
 +        }
 +        catch (PartitionedRegionException e) {
 +          PoisonedKey.poisonDetected = true;
 +        } finally {
 +          PoisonedKey.poisoned = false; // restore default static value
 +        }
 +      }
 +    });
 +    
-     boolean success = vm0.invokeBoolean(PoisonedKey.class, "poisonFound");
++    boolean success = vm0.invoke(() -> PoisonedKey.poisonFound());
 +    assertTrue("Hash mismatch not found", success);
 +  }
 +}
 +

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ProxyDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ProxyDUnitTest.java
index 54554ab,0000000..8d6c14c
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ProxyDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ProxyDUnitTest.java
@@@ -1,546 -1,0 +1,546 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.HashMap;
 +import java.util.Map;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.AttributesMutator;
 +import com.gemstone.gemfire.cache.CacheEvent;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.InterestPolicy;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionEvent;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.SubscriptionAttributes;
 +import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.DMStats;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * Make sure that operations are distributed and done in
 + * regions remote from a PROXY
 + *
 + * @author darrel
 + * @since 5.0
 + */
 +public class ProxyDUnitTest extends CacheTestCase {
 +
 +  private transient Region r;
 +  private transient DistributedMember otherId;
 +  protected transient int clInvokeCount;
 +  protected transient CacheEvent clLastEvent;
 +  
 +  public ProxyDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  private VM getOtherVm() {
 +    Host host = Host.getHost(0);
 +    return host.getVM(0);
 +  }
 +    
 +  private void initOtherId() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("Connect") {
 +        public void run2() throws CacheException {
 +          getCache();
 +        }
 +      });
-     this.otherId = (DistributedMember)vm.invoke(ProxyDUnitTest.class, "getVMDistributedMember");
++    this.otherId = (DistributedMember)vm.invoke(() -> ProxyDUnitTest.getVMDistributedMember());
 +  }
 +  private void doCreateOtherVm() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("create root") {
 +        public void run2() throws CacheException {
 +          AttributesFactory af = new AttributesFactory();
 +          af.setDataPolicy(DataPolicy.REPLICATE);
 +          af.setScope(Scope.DISTRIBUTED_ACK);
 +          createRootRegion("ProxyDUnitTest", af.create());
 +        }
 +      });
 +  }
 +
 +  public static DistributedMember getVMDistributedMember() {
 +    return InternalDistributedSystem.getAnyInstance().getDistributedMember();
 +  }
 +  
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  /**
 +   * check distributed ops that originate in a PROXY are correctly distributed
 +   * to non-proxy regions.
 +   */
 +  private void distributedOps(DataPolicy dp, InterestPolicy ip) throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(dp);
 +    af.setSubscriptionAttributes(new SubscriptionAttributes(ip));
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    Region r = createRootRegion("ProxyDUnitTest", af.create());
 +
 +    doCreateOtherVm();
 +
 +    r.put("putkey", "putvalue1");
 +    
 +    getOtherVm().invoke(new CacheSerializableRunnable("check put") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(true, r.containsKey("putkey"));
 +          assertEquals("putvalue1", r.getEntry("putkey").getValue());
 +          r.put("putkey", "putvalue2");
 +        }
 +      });
 +    
 +    assertEquals(false, r.containsKey("putkey"));
 +    assertEquals("putvalue2", r.get("putkey")); // netsearch
 +
 +    r.invalidate("putkey");
 +
 +    getOtherVm().invoke(new CacheSerializableRunnable("check invalidate") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(true, r.containsKey("putkey"));
 +          assertEquals(null, r.getEntry("putkey").getValue());
 +        }
 +      });
 +    assertEquals(null, r.get("putkey")); // invalid so total miss
 +
 +    r.destroy("putkey");
 +
 +    getOtherVm().invoke(new CacheSerializableRunnable("check destroy") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(false, r.containsKey("putkey"));
 +        }
 +      });
 +    
 +    assertEquals(null, r.get("putkey")); // total miss
 +
 +    r.create("createKey", "createValue1");
 +    getOtherVm().invoke(new CacheSerializableRunnable("check create") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(true, r.containsKey("createKey"));
 +          assertEquals("createValue1", r.getEntry("createKey").getValue());
 +        }
 +      });
 +    {
 +      Map m = new HashMap();
 +      m.put("putAllKey1", "putAllValue1");
 +      m.put("putAllKey2", "putAllValue2");
 +      r.putAll(m, "putAllCallback");
 +    }
 +    getOtherVm().invoke(new CacheSerializableRunnable("check putAll") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(true, r.containsKey("putAllKey1"));
 +          assertEquals("putAllValue1", r.getEntry("putAllKey1").getValue());
 +          assertEquals(true, r.containsKey("putAllKey2"));
 +          assertEquals("putAllValue2", r.getEntry("putAllKey2").getValue());
 +        }
 +      });
 +    r.clear();
 +    getOtherVm().invoke(new CacheSerializableRunnable("check clear") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(0, r.size());
 +        }
 +      });
 +
 +    getOtherVm().invoke(new CacheSerializableRunnable("install CacheWriter") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          AttributesMutator am = r.getAttributesMutator();
 +          CacheWriter cw = new CacheWriterAdapter() {
 +              public void beforeCreate(EntryEvent event) throws CacheWriterException {
 +                throw new CacheWriterException("expected");
 +              }
 +            };
 +          am.setCacheWriter(cw);
 +        }
 +      });
 +    try {
 +      r.put("putkey", "putvalue");
 +      fail("expected CacheWriterException");
 +    } catch (CacheWriterException expected) {
 +    }
 +    getOtherVm().invoke(new CacheSerializableRunnable("check clear") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(0, r.size());
 +        }
 +      });
 +
 +    assertEquals(null, r.get("loadkey")); // total miss
 +    getOtherVm().invoke(new CacheSerializableRunnable("install CacheLoader") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          AttributesMutator am = r.getAttributesMutator();
 +          am.setCacheWriter(null); // clear csche writer
 +          CacheLoader cl = new CacheLoader() {
 +              public Object load(LoaderHelper helper) throws CacheLoaderException {
 +                if (helper.getKey().equals("loadkey")) {
 +                  return "loadvalue";
 +                } else if (helper.getKey().equals("loadexception")) {
 +                  throw new CacheLoaderException("expected");
 +                } else {
 +                  return null;
 +                }
 +              }
 +              public void close() {
 +              }
 +            };
 +          am.setCacheLoader(cl);
 +        }
 +      });
 +    assertEquals("loadvalue", r.get("loadkey")); // net load
 +    assertEquals(null, r.get("foobar")); // total miss
 +    try {
 +      r.get("loadexception");
 +      fail("expected CacheLoaderException");
 +    } catch (CacheLoaderException expected) {
 +    }
 +    r.destroyRegion();
 +    getOtherVm().invoke(new CacheSerializableRunnable("check clear") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals(null, r);
 +        }
 +      });
 +  }
 +  /**
 +   * Gets the DMStats for the vm's DM
 +   */
 +  private DMStats getDMStats() {
 +    return ((InternalDistributedSystem)getCache().getDistributedSystem())
 +      .getDistributionManager().getStats();
 +  }
 +  /**
 +   * check remote ops done in a normal vm are correctly distributed to PROXY regions
 +   */
 +  private void remoteOriginOps(DataPolicy dp, InterestPolicy ip) throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(dp);
 +    af.setSubscriptionAttributes(new SubscriptionAttributes(ip));
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    CacheListener cl1 = new CacheListener() {
 +        public void afterUpdate(EntryEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterCreate(EntryEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterInvalidate(EntryEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterDestroy(EntryEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterRegionInvalidate(RegionEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterRegionDestroy(RegionEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterRegionClear(RegionEvent e) {
 +          clLastEvent = e;
 +          clInvokeCount++;
 +        }
 +        public void afterRegionCreate(RegionEvent e) {
 +        }
 +        public void afterRegionLive(RegionEvent e) {
 +        }
 +        public void close() {
 +        }
 +      };
 +    af.addCacheListener(cl1);
 +    Region r = createRootRegion("ProxyDUnitTest", af.create());
 +    this.clInvokeCount = 0;
 +
 +    doCreateOtherVm();
 +
 +    DMStats stats = getDMStats();
 +    long receivedMsgs = stats.getReceivedMessages();
 +
 +    if (ip.isAll()) {
 +      getOtherVm().invoke(new CacheSerializableRunnable("do put") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            r.put("p", "v");
 +          }
 +        });
 +      assertEquals(1, this.clInvokeCount);
 +      assertEquals(Operation.CREATE, this.clLastEvent.getOperation());
 +      assertEquals(true, this.clLastEvent.isOriginRemote());
 +      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getOldValue());
 +      assertEquals(false, ((EntryEvent)this.clLastEvent).isOldValueAvailable()); // failure
 +      assertEquals("v", ((EntryEvent)this.clLastEvent).getNewValue());
 +      assertEquals("p", ((EntryEvent)this.clLastEvent).getKey());
 +      this.clInvokeCount = 0;
 +      
 +      getOtherVm().invoke(new CacheSerializableRunnable("do create") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            r.create("c", "v");
 +          }
 +        });
 +      assertEquals(1, this.clInvokeCount);
 +      assertEquals(Operation.CREATE, this.clLastEvent.getOperation());
 +      assertEquals(true, this.clLastEvent.isOriginRemote());
 +      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getOldValue());
 +      assertEquals(false, ((EntryEvent)this.clLastEvent).isOldValueAvailable());
 +      assertEquals("v", ((EntryEvent)this.clLastEvent).getNewValue());
 +      assertEquals("c", ((EntryEvent)this.clLastEvent).getKey());
 +      this.clInvokeCount = 0;
 +      
 +      getOtherVm().invoke(new CacheSerializableRunnable("do update") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            r.put("c", "v2");
 +          }
 +        });
 +      assertEquals(1, this.clInvokeCount);
 +      assertEquals(Operation.UPDATE, this.clLastEvent.getOperation());
 +      assertEquals(true, this.clLastEvent.isOriginRemote());
 +      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getOldValue());
 +      assertEquals(false, ((EntryEvent)this.clLastEvent).isOldValueAvailable());
 +      assertEquals("v2", ((EntryEvent)this.clLastEvent).getNewValue());
 +      assertEquals("c", ((EntryEvent)this.clLastEvent).getKey());
 +      this.clInvokeCount = 0;
 +
 +      getOtherVm().invoke(new CacheSerializableRunnable("do invalidate") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            r.invalidate("c");
 +          }
 +        });
 +      assertEquals(1, this.clInvokeCount);
 +      assertEquals(Operation.INVALIDATE, this.clLastEvent.getOperation());
 +      assertEquals(true, this.clLastEvent.isOriginRemote());
 +      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getOldValue());
 +      assertEquals(false, ((EntryEvent)this.clLastEvent).isOldValueAvailable());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getNewValue());
 +      assertEquals("c", ((EntryEvent)this.clLastEvent).getKey());
 +      this.clInvokeCount = 0;
 +      
 +      getOtherVm().invoke(new CacheSerializableRunnable("do destroy") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            r.destroy("c");
 +          }
 +        });
 +      assertEquals(1, this.clInvokeCount);
 +      assertEquals(Operation.DESTROY, this.clLastEvent.getOperation());
 +      assertEquals(true, this.clLastEvent.isOriginRemote());
 +      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getOldValue());
 +      assertEquals(false, ((EntryEvent)this.clLastEvent).isOldValueAvailable());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getNewValue());
 +      assertEquals("c", ((EntryEvent)this.clLastEvent).getKey());
 +      this.clInvokeCount = 0;
 +      
 +      getOtherVm().invoke(new CacheSerializableRunnable("do putAll") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            Map m = new HashMap();
 +            m.put("putAllKey1", "putAllValue1");
 +            m.put("putAllKey2", "putAllValue2");
 +            r.putAll(m);
 +          }
 +        });
 +      assertEquals(2, this.clInvokeCount);
 +      // @todo darrel; check putAll events
 +      this.clInvokeCount = 0;
 +
 +      getOtherVm().invoke(new CacheSerializableRunnable("do netsearch") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            assertEquals(null, r.get("loadkey")); // total miss
 +          }
 +        });
 +      assertEquals(0, this.clInvokeCount);
 +      
 +    } else {
 +      getOtherVm().invoke(new CacheSerializableRunnable("do entry ops") {
 +          public void run2() throws CacheException {
 +            Region r = getRootRegion("ProxyDUnitTest");
 +            r.put("p", "v");
 +            r.create("c", "v");
 +            r.put("c", "v"); // update
 +            r.invalidate("c");
 +            r.destroy("c");
 +            {
 +              Map m = new HashMap();
 +              m.put("putAllKey1", "putAllValue1");
 +              m.put("putAllKey2", "putAllValue2");
 +              r.putAll(m);
 +            }
 +            assertEquals(null, r.get("loadkey")); // total miss
 +          }
 +        });
 +
 +      assertEquals(0, this.clInvokeCount);
 +      assertEquals(0, r.size());
 +      // check the stats to make sure none of the above sent up messages
 +      assertEquals(receivedMsgs, stats.getReceivedMessages());
 +    }
 +
 +    {
 +      AttributesMutator am = r.getAttributesMutator();
 +      CacheLoader cl = new CacheLoader() {
 +          public Object load(LoaderHelper helper) throws CacheLoaderException {
 +            if (helper.getKey().equals("loadkey")) {
 +              return "loadvalue";
 +            } else if (helper.getKey().equals("loadexception")) {
 +              throw new CacheLoaderException("expected");
 +            } else {
 +              return null;
 +            }
 +          }
 +          public void close() {
 +          }
 +        };
 +      am.setCacheLoader(cl);
 +    }
 +
 +    receivedMsgs = stats.getReceivedMessages();
 +    getOtherVm().invoke(new CacheSerializableRunnable("check net loader") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          assertEquals("loadvalue", r.get("loadkey")); // net load
 +          assertEquals(null, r.get("foobar")); // total miss
 +          try {
 +            r.get("loadexception");
 +            fail("expected CacheLoaderException");
 +          } catch (CacheLoaderException expected) {
 +          }
 +        }
 +      });
 +    assertTrue(stats.getReceivedMessages() > receivedMsgs);
 +    if (ip.isAll()) {
 +      assertEquals(1, this.clInvokeCount);
 +      assertEquals(Operation.NET_LOAD_CREATE, this.clLastEvent.getOperation());
 +      assertEquals(true, this.clLastEvent.isOriginRemote());
 +      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +      assertEquals(null, ((EntryEvent)this.clLastEvent).getOldValue());
 +      assertEquals(false, ((EntryEvent)this.clLastEvent).isOldValueAvailable());
 +      this.clInvokeCount = 0;
 +    } else {
 +      assertEquals(0, this.clInvokeCount);
 +    }
 +
 +    {
 +      AttributesMutator am = r.getAttributesMutator();
 +      am.setCacheLoader(null);
 +      CacheWriter cw = new CacheWriterAdapter() {
 +          public void beforeCreate(EntryEvent event) throws CacheWriterException {
 +            throw new CacheWriterException("expected");
 +          }
 +        };
 +      am.setCacheWriter(cw);
 +    }
 +    receivedMsgs = stats.getReceivedMessages();
 +    getOtherVm().invoke(new CacheSerializableRunnable("check net write") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          try {
 +            r.put("putkey", "putvalue");
 +            fail("expected CacheWriterException");
 +          } catch (CacheWriterException expected) {
 +          }
 +        }
 +      });
 +    assertTrue(stats.getReceivedMessages() > receivedMsgs);
 +    {
 +      AttributesMutator am = r.getAttributesMutator();
 +      am.setCacheWriter(null);
 +    }
 +    assertEquals(0, this.clInvokeCount);
 +    this.clLastEvent = null;
 +    getOtherVm().invoke(new CacheSerializableRunnable("check region invalidate") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          r.invalidateRegion();
 +        }
 +      });
 +    assertEquals(1, this.clInvokeCount);
 +    assertEquals(Operation.REGION_INVALIDATE, this.clLastEvent.getOperation());
 +    assertEquals(true, this.clLastEvent.isOriginRemote());
 +    assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +
 +    this.clLastEvent = null;
 +    getOtherVm().invoke(new CacheSerializableRunnable("check region clear") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          r.clear();
 +        }
 +      });
 +    assertEquals(2, this.clInvokeCount);
 +    assertEquals(Operation.REGION_CLEAR, this.clLastEvent.getOperation());
 +    assertEquals(true, this.clLastEvent.isOriginRemote());
 +    assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +
 +    this.clLastEvent = null;
 +    getOtherVm().invoke(new CacheSerializableRunnable("check region destroy") {
 +        public void run2() throws CacheException {
 +          Region r = getRootRegion("ProxyDUnitTest");
 +          r.destroyRegion();
 +        }
 +      });
 +    assertEquals(3, this.clInvokeCount);
 +    assertEquals(Operation.REGION_DESTROY, this.clLastEvent.getOperation());
 +    assertEquals(true, this.clLastEvent.isOriginRemote());
 +    assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
 +    assertTrue(r.isDestroyed());
 +  }
 +  
 +  public void testDistributedOpsPROXY() throws CacheException {
 +    distributedOps(DataPolicy.EMPTY, InterestPolicy.CACHE_CONTENT);
 +  }
 +
 +  public void testRemoteOriginOpsPROXY() throws CacheException {
 +    remoteOriginOps(DataPolicy.EMPTY, InterestPolicy.CACHE_CONTENT);
 +  }
 +  public void testRemoteOriginOpsPROXY_ALL() throws CacheException {
 +    remoteOriginOps(DataPolicy.EMPTY, InterestPolicy.ALL);
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkRemoteVMDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkRemoteVMDUnitTest.java
index caa8333,0000000..01a1f42
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkRemoteVMDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkRemoteVMDUnitTest.java
@@@ -1,401 -1,0 +1,401 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * PutAllCallBkRemoteVMDUnitTest.java
 + *
 + * Created on September 2, 2005, 2:49 PM
 +*/
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + *
 + * @author vjadhav
 + */
 +public class PutAllCallBkRemoteVMDUnitTest extends DistributedTestCase {
 +    
 +    /** Creates a new instance of PutAllCallBkRemoteVMDUnitTest */
 +    public PutAllCallBkRemoteVMDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    static volatile Cache cache;
 +    static Properties props = new Properties();
 +    static Properties propsWork = new Properties();
 +    static volatile DistributedSystem ds = null;
 +    static volatile Region region;
 +    static volatile Region paperRegion;
 +    static boolean afterCreate=false;
 +    static boolean afterUpdate=false;
 +    static int putAllcounter = 0;
 +    static int afterUpdateputAllcounter = 0;
 +    static boolean beforeCreate=false;
 +    static boolean beforeUpdate=false;
 +    static int forCreate = 0;
 +    static int forUpdate = 0;
 +    static int beforeCreateputAllcounter = 0;
 +    static int beforeUpdateputAllcounter = 0;
 +    static boolean notified = false;
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(PutAllCallBkRemoteVMDUnitTest.class, "createCacheForVM0");
-       vm1.invoke(PutAllCallBkRemoteVMDUnitTest.class, "createCacheForVM1");
++      vm0.invoke(() -> PutAllCallBkRemoteVMDUnitTest.createCacheForVM0());
++      vm1.invoke(() -> PutAllCallBkRemoteVMDUnitTest.createCacheForVM1());
 +      LogWriterUtils.getLogWriter().info("Cache created successfully");
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(PutAllCallBkRemoteVMDUnitTest.class, "closeCache");
-       vm1.invoke(PutAllCallBkRemoteVMDUnitTest.class, "closeCache");
++      vm0.invoke(() -> PutAllCallBkRemoteVMDUnitTest.closeCache());
++      vm1.invoke(() -> PutAllCallBkRemoteVMDUnitTest.closeCache());
 +    }
 +    
 +    public static synchronized void createCacheForVM0(){
 +        try{
 +            ds = (new PutAllCallBkRemoteVMDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr1 = factory.create();
 +            paperRegion = cache.createRegion("paper", attr1);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +              
 +        } catch (CacheException ex){
 +            throw new RuntimeException("vm0 cache creation exception", ex);
 +        }
 +    }
 +    
 +    public static void createCacheForVM1(){
 +        try{
 +            CacheListener aListener = new AfterCreateCallback();
 +            CacheWriter aWriter = new BeforeCreateCallback();
 +            
 +            ds = (new PutAllCallBkRemoteVMDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr1 = factory.create();
 +            paperRegion = cache.createRegion("paper", attr1);
 +            factory.setCacheWriter(aWriter);
 +            factory.addCacheListener(aListener);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +        } catch (CacheException ex){
 +            throw new RuntimeException("vm1 cache creation exception", ex);
 +        }
 +    }
 +    
 +    
 +    public static synchronized void closeCache(){
 +      paperRegion = null;
 +      region = null;
 +      if (cache != null) {
 +        cache.close();
 +        cache = null;
 +      }
 +      if (ds != null) {
 +        ds.disconnect();
 +        ds = null;
 +      }
 +    }
 +    
 +    //test methods
 +    
 +    public void testputAllRemoteVM(){
 +        
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        ////////////////testing create call backs//////////////
 +        
 +        vm0.invoke(new CacheSerializableRunnable("put entries"){
 +            public void run2() throws CacheException{
 +                Map m = new HashMap();
 +                paperRegion.put("callbackCame","false");
 +                try{
 +                    for(int i=1; i<21; i++){
 +                        m.put(new Integer(i), java.lang.Integer.toString(i));
 +                    }
 +                    region.putAll(m);
 +                    
 +                }catch (Exception ex){
 +                    throw new RuntimeException("exception putting entries", ex);
 +                }
 +                LogWriterUtils.getLogWriter().info("****************paperRegion.get(afterCreate)***************"+paperRegion.get("afterCreate"));
 +
 +                WaitCriterion ev = new WaitCriterion() {
 +                  public boolean done() {
 +                    int size = region.size();
 +                    if (size != ((Integer)paperRegion.get("afterCreate")).intValue()-1) {
 +                      return false;
 +                    }
 +                    if (size != ((Integer)paperRegion.get("beforeCreate")).intValue()-1) {
 +                      return false;
 +                    }
 +                    return true;
 +                  }
 +                  public String description() {
 +                    return "Waiting for event";
 +                  }
 +                };
 +                Wait.waitForCriterion(ev, 3000, 200, true);
 +            }
 +        });
 +        
 +        
 +        vm1.invoke(new CacheSerializableRunnable("validate callbacks"){
 +            public void run2() throws CacheException{
 +                if(!notified){
 +                    try{
 +                        synchronized(PutAllCallBkRemoteVMDUnitTest.class){
 +                            this.wait();
 +                        }
 +                    } catch(Exception e){
 +                        
 +                    }
 +                }
 +                if(!paperRegion.get("callbackCame").equals("true")){
 +                    fail("Failed in aftercreate call back :: PutAllCallBkRemoteVMDUnitTest ");
 +                }
 +    
 +            }
 +        });
 +        
 +        
 +        //to test afterUpdate
 +        
 +    }
 +    
 +    public void testPutAllAfterUpdateCallbacks(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        vm0.invoke(new CacheSerializableRunnable("put and then update"){
 +            public void run2() throws CacheException{
 +                paperRegion.put("callbackCame","false");             
 +                //to invoke afterUpdate we should make sure that entries are already present
 +                for(int i=0; i<5; i++){
 +                    region.put(new Integer(i), new String("region"+i));
 +                }
 +                
 +                Map m = new HashMap();
 +                for(int i=0; i<5; i++){
 +                    m.put(new Integer(i), new String("map"+i));
 +                }
 +                
 +                region.putAll(m);
 +                
 +//                 try{
 +//                     Thread.sleep(3000);
 +//                 }catch(InterruptedException ex){
 +//                     //
 +//                 }
 +                
 +                assertEquals(region.size(), ((Integer)paperRegion.get("beforeUpdate")).intValue()-1);
 +                assertEquals(region.size(), ((Integer)paperRegion.get("afterUpdate")).intValue()-1);
 +            }
 +        }
 +        );
 +        
 +        vm1.invoke(new CacheSerializableRunnable("validate callbacks"){
 +            public void run2() throws CacheException{
 +                
 +                if(!notified){
 +                    try{
 +                        synchronized(PutAllCallBkRemoteVMDUnitTest.class){
 +                            this.wait();
 +                        }
 +                    } catch(Exception e){
 +                        
 +                    }
 +                }
 +                
 +                if(!paperRegion.get("callbackCame").equals("true")){
 +                    fail("Failed in afterUpdate call back :: PutAllCallBkRemoteVMDUnitTest");
 +                }
 +                
 +            }
 +        }
 +        );
 +        
 +    }//end of test case1
 +    
 +    
 +    public static Object putMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            if(ob != null){
 +                String str = "first";
 +                obj = region.put(ob, str);
 +            }
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.put");
 +        }
 +        return obj;
 +    }//end of putMethod
 +    
 +    public static void putAllMethod(){
 +        Map m = new HashMap();
 +        int i = 5, cntr = 0;
 +        try{
 +            while(cntr<20){
 +                m.put(new Integer(i), new String("map"+i));
 +                i++;
 +                cntr++;
 +            }
 +            
 +            region.putAll(m);
 +            
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.putAll");
 +        }
 +    }//end of putAllMethod
 +    
 +    
 +    public static Object getMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.get(ob);
 +        } catch(Exception ex){
 +            fail("Failed while region.get");
 +        }
 +        return obj;
 +    }
 +    
 +    
 +    public static int sizeMethod(){
 +        int i=0;
 +        try{
 +            i = region.size();
 +        }catch(Exception ex){
 +            fail("Failed while region.size");
 +        }
 +        return i;
 +    }
 +    
 +    public static void clearMethod(){
 +        try{
 +            region.clear();
 +        } catch(Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    static class AfterCreateCallback extends CacheListenerAdapter {
 +        public void afterCreate(EntryEvent event){
 +            paperRegion.put("callbackCame","true");
 +            Integer counter = (Integer)paperRegion.get("afterCreate");
 +            if(counter==null) counter = new Integer(1);
 +            paperRegion.put("afterCreate",new Integer(counter.intValue()+1));
 +            
 +            LogWriterUtils.getLogWriter().info("In afterCreate"+putAllcounter);
 +            if(putAllcounter == forCreate){
 +                LogWriterUtils.getLogWriter().info("performingtrue");
 +                afterCreate = true;
 +            }
 +            try{
 +                synchronized(PutAllCallBkRemoteVMDUnitTest.class){
 +                    this.notify();
 +                }
 +            } catch(Exception e){
 +                
 +            }
 +            notified = true;
 +            LogWriterUtils.getLogWriter().info("*******afterCreate***** Key :"+event.getKey()+ " Value :"+event.getNewValue());
 +        }
 +        
 +        public void afterUpdate(EntryEvent event){
 +            paperRegion.put("callbackCame","true");
 +            Integer counter = (Integer)paperRegion.get("afterUpdate");
 +            if(counter==null) counter = new Integer(1);
 +            paperRegion.put("afterUpdate",new Integer(counter.intValue()+1));
 +            LogWriterUtils.getLogWriter().info("In afterUpdate"+afterUpdateputAllcounter);
 +            if(afterUpdateputAllcounter == forUpdate){
 +                LogWriterUtils.getLogWriter().info("performingtrue afterUpdate");
 +                afterUpdate = true;
 +            }
 +            try{
 +                synchronized(PutAllCallBkRemoteVMDUnitTest.class){
 +                    this.notify();
 +                }
 +            } catch(Exception e){
 +                
 +            }
 +            
 +            notified = true;
 +            
 +            LogWriterUtils.getLogWriter().info("*******afterUpdate***** Key :"+event.getKey()+ " Value :"+event.getNewValue());
 +            
 +        }
 +    }
 +    static class BeforeCreateCallback extends CacheWriterAdapter {
 +        //    static class BeforeCreateCallback extends CapacityControllerAdapter {
 +        public void beforeCreate(EntryEvent event){
 +            Integer counter = (Integer)paperRegion.get("beforeCreate");
 +            if(counter==null) counter = new Integer(1);
 +            paperRegion.put("beforeCreate",new Integer(counter.intValue()+1));
 +            LogWriterUtils.getLogWriter().info("*******BeforeCreate***** event="+event);
 +        }
 +        
 +        public void beforeUpdate(EntryEvent event) {
 +            Integer counter = (Integer)paperRegion.get("beforeUpdate");
 +            if(counter==null) counter = new Integer(1);
 +            paperRegion.put("beforeUpdate",new Integer(counter.intValue()+1));
 +            LogWriterUtils.getLogWriter().info("In beforeUpdate"+beforeUpdateputAllcounter);
 +            LogWriterUtils.getLogWriter().info("*******BeforeUpdate***** event="+event);
 +        }
 +    }
 +}// end of test class

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkSingleVMDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkSingleVMDUnitTest.java
index 8c85ebd,0000000..12337cd
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkSingleVMDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllCallBkSingleVMDUnitTest.java
@@@ -1,321 -1,0 +1,321 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * PutAllCallBkSingleVMDUnitTest.java
 + *
 + * Created on August 31, 2005, 4:17 PM
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +public class PutAllCallBkSingleVMDUnitTest extends DistributedTestCase{
 +    
 +    /** Creates a new instance of PutAllCallBkSingleVMDUnitTest */
 +    public PutAllCallBkSingleVMDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    static volatile Cache cache;
 +    static Properties props = new Properties();
 +    static Properties propsWork = new Properties();
 +    static volatile DistributedSystem ds = null;
 +    static volatile Region region;
 +    static boolean afterCreate=false;
 +    static boolean afterUpdate=false;
 +    static int putAllcounter = 0;
 +    static int afterUpdateputAllcounter = 0;
 +    static boolean beforeCreate=false;
 +    static boolean beforeUpdate=false;
 +    static int beforeCreateputAllcounter = 0;
 +    static int beforeUpdateputAllcounter = 0;
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(PutAllCallBkSingleVMDUnitTest.class, "createCache");
-       vm1.invoke(PutAllCallBkSingleVMDUnitTest.class, "createCache");
++      vm0.invoke(() -> PutAllCallBkSingleVMDUnitTest.createCache());
++      vm1.invoke(() -> PutAllCallBkSingleVMDUnitTest.createCache());
 +      LogWriterUtils.getLogWriter().fine("Cache created in successfully");
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(PutAllCallBkSingleVMDUnitTest.class, "closeCache");
-       vm1.invoke(PutAllCallBkSingleVMDUnitTest.class, "closeCache");
++      vm0.invoke(() -> PutAllCallBkSingleVMDUnitTest.closeCache());
++      vm1.invoke(() -> PutAllCallBkSingleVMDUnitTest.closeCache());
 +    }
 +    
 +    public static synchronized void createCache(){
 +        try{
 +            CacheListener aListener = new AfterCreateCallback();
 +            CacheWriter aWriter = new BeforeCreateCallback();            
 +            ds = (new PutAllCallBkSingleVMDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setCacheWriter(aWriter);
 +            factory.setCacheListener(aListener);
 +            RegionAttributes attr = factory.create();
 +            
 +            region = cache.createRegion("map", attr);
 +            
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static synchronized void closeCache(){
 +      region = null;
 +      if (cache != null) {
 +        cache.close();
 +        cache = null;
 +      }
 +      if (ds != null) {
 +        ds.disconnect();
 +        ds = null;
 +      }
 +    }
 +
 +    //test methods
 +    public void testputAllSingleVM(){
 +        
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        
 +//        Object obj2;
 +        Object[] objArr = new Object[1];
 +        for (int i=0; i<5; i++){
 +            objArr[0] = ""+i;
 +            vm0.invoke(PutAllCallBkSingleVMDUnitTest.class, "putMethod", objArr);
 +            
 +        }
 +        
-         vm0.invoke(PutAllCallBkSingleVMDUnitTest.class, "putAllMethod");
++        vm0.invoke(() -> PutAllCallBkSingleVMDUnitTest.putAllMethod());
 +        
 +        vm0.invoke(new CacheSerializableRunnable("temp1"){
 +            public void run2() throws CacheException{
 +                if(!afterCreate){
 +                    fail("FAILED in aftercreate call back");
 +                }
 +                assertEquals(region.size(), putAllcounter); 
 +                assertEquals(region.size(), beforeCreateputAllcounter);
 +            }
 +        });
 +        
 +        vm0.invoke(new CacheSerializableRunnable("abc"){
 +            public void run2() throws CacheException{
 +                CacheListener bListener = new AfterUpdateCallback();  
 +                CacheWriter bWriter =new BeforeUpdateCallback();
 +                AttributesFactory factory  = new AttributesFactory();
 +                factory.setScope(Scope.DISTRIBUTED_ACK);
 +                factory.setCacheWriter(bWriter);
 +                factory.setCacheListener(bListener);
 +                RegionAttributes attr = factory.create();                
 +                Region tempRegion = cache.createRegion("temp", attr);                
 +                
 +                //to invoke afterUpdate we should make sure that entries are already present
 +                for(int i=0; i<5; i++){
 +                    tempRegion.put(new Integer(i), new String("region"+i));
 +                }
 +                
 +                Map m = new HashMap();
 +                for(int i=0; i<5; i++){
 +                    m.put(new Integer(i), new String("map"+i));
 +                }
 +                
 +                tempRegion.putAll(m, "putAllAfterUpdateCallback");
 +                
 +                //now, verifying callbacks
 +                if(!afterUpdate){
 +                    fail("FAILED in afterupdate call back");
 +                }
 +                assertEquals(tempRegion.size(), afterUpdateputAllcounter);
 +                assertEquals(tempRegion.size(), beforeUpdateputAllcounter); 
 +            }
 +        }
 +        );
 +        
 +    }//end of test case1
 +    
 +   
 +    public static Object putMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            if(ob != null){
 +                String str = "first";
 +                obj = region.put(ob, str);
 +            }
 +        }catch(Exception ex){
 +            Assert.fail("Failed while region.put", ex);
 +        }
 +        return obj;
 +    }//end of putMethod
 +    
 +    public static void putAllMethod(){
 +        Map m = new HashMap();
 +        int i = 5, cntr = 0;
 +        try{
 +            while(cntr<21){
 +                m.put(new Integer(i), new String("map"+i));
 +                i++;
 +                cntr++;
 +            }
 +            
 +            region.putAll(m, "putAllCreateCallback");
 +            
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.putAll");
 +        }
 +    }//end of putAllMethod
 +    
 +    public static void putAllAfterUpdate(){
 +        Map m = new HashMap();
 +        int cntr = 0;
 +        try{
 +            for(int i=0; i<5; i++){
 +                m.put(""+i, new String("map_AfterUpdate"+i));
 +                cntr++;
 +            }
 +            region.putAll(m, "putAllAfterUpdateCallback");
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.putAll");
 +        }
 +    }//end of putAllAfterUpdate
 +    
 +    public static Object getMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.get(ob);
 +        } catch(Exception ex){
 +            fail("Failed while region.get");
 +        }
 +        return obj;
 +    }
 +    
 +    public static boolean containsValueMethod(Object ob){
 +        boolean flag = false;
 +        try{
 +            flag = region.containsValue(ob);
 +        }catch(Exception ex){
 +            fail("Failed while region.containsValueMethod");
 +        }
 +        return flag;
 +    }
 +    
 +    public static int sizeMethod(){
 +        int i=0;
 +        try{
 +            i = region.size();
 +        }catch(Exception ex){
 +            fail("Failed while region.size");
 +        }
 +        return i;
 +    }
 +    
 +    public static void clearMethod(){
 +        try{
 +            region.clear();
 +        } catch(Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    static class AfterCreateCallback extends CacheListenerAdapter {
 +        public void afterCreate(EntryEvent event){            
 +            putAllcounter++;
 +            LogWriterUtils.getLogWriter().fine("In afterCreate"+putAllcounter);
 +            if (event.getOperation().isPutAll()) {
 +              assertEquals("putAllCreateCallback", event.getCallbackArgument());
 +            }
 +            if(putAllcounter == 25){
 +                LogWriterUtils.getLogWriter().fine("performingtrue");
 +                afterCreate = true;
 +            }            
 +        }
 +    }
 +    
 +    static class AfterUpdateCallback extends CacheListenerAdapter {
 +        public void afterUpdate(EntryEvent event){            
 +            afterUpdateputAllcounter++;
 +            LogWriterUtils.getLogWriter().fine("In afterUpdate"+afterUpdateputAllcounter);
 +            if (event.getOperation().isPutAll()) {
 +              assertEquals("putAllAfterUpdateCallback", event.getCallbackArgument());
 +            }
 +            if(afterUpdateputAllcounter == 5){
 +                LogWriterUtils.getLogWriter().fine("performingtrue afterUpdate");
 +                afterUpdate = true;
 +            }            
 +        }
 +    }
 +    static class BeforeCreateCallback extends CacheWriterAdapter {
 +          public void beforeCreate(EntryEvent event){            
 +            beforeCreateputAllcounter++;
 +            LogWriterUtils.getLogWriter().fine("In beforeCreate"+beforeCreateputAllcounter);
 +            if (event.getOperation().isPutAll()) {
 +              assertEquals("putAllCreateCallback", event.getCallbackArgument());
 +            }
 +            if(beforeCreateputAllcounter == 25){
 +                LogWriterUtils.getLogWriter().fine("performingtrue beforeCreateputAll");
 +                beforeCreate = true;
 +            }            
 +        }
 +     }   
 +      static class BeforeUpdateCallback extends CacheWriterAdapter {
 +        public void beforeUpdate(EntryEvent event){            
 +            beforeUpdateputAllcounter++;
 +            LogWriterUtils.getLogWriter().fine("In beforeUpdate"+beforeUpdateputAllcounter);
 +            if (event.getOperation().isPutAll()) {
 +              assertEquals("putAllAfterUpdateCallback", event.getCallbackArgument());
 +            }
 +            if(beforeUpdateputAllcounter == 5){
 +                LogWriterUtils.getLogWriter().fine("performingtrue beforeUpdate");
 +                beforeUpdate = true;
 +            }            
 +        }
 +    }
 +    
 +}//end of class

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllMultiVmDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllMultiVmDUnitTest.java
index 5a37ebf,0000000..4ec8054
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllMultiVmDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/PutAllMultiVmDUnitTest.java
@@@ -1,366 -1,0 +1,366 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * PutAllMultiVmDUnitTest.java
 + *
 + * Created on September 1, 2005, 12:19 PM
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.TreeMap;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + *
 + * @author  prafulla
 + */
 +public class PutAllMultiVmDUnitTest extends DistributedTestCase{
 +    
 +    /** Creates a new instance of PutAllMultiVmDUnitTest */
 +    public PutAllMultiVmDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    static Cache cache;
 +    static Properties props = new Properties();
 +    static Properties propsWork = new Properties();
 +    static DistributedSystem ds = null;
 +    static Region region;
 +    static Region mirroredRegion;
 +    static CacheTransactionManager cacheTxnMgr;
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(PutAllMultiVmDUnitTest.class, "createCache");
-       vm1.invoke(PutAllMultiVmDUnitTest.class, "createCache");
++      vm0.invoke(() -> PutAllMultiVmDUnitTest.createCache());
++      vm1.invoke(() -> PutAllMultiVmDUnitTest.createCache());
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(PutAllMultiVmDUnitTest.class, "closeCache");
-       vm1.invoke(PutAllMultiVmDUnitTest.class, "closeCache");
++      vm0.invoke(() -> PutAllMultiVmDUnitTest.closeCache());
++      vm1.invoke(() -> PutAllMultiVmDUnitTest.closeCache());
 +      cache = null;
 +      Invoke.invokeInEveryVM(new SerializableRunnable() { public void run() { cache = null; } });
 +    }
 +    
 +    public static void createCache(){
 +        try{
 +            ds = (new PutAllMultiVmDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of createCache
 +    
 +    public static void createMirroredRegion(){
 +        try{
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr = factory.create();
 +            mirroredRegion = cache.createRegion("mirrored", attr);
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of createCache
 +    
 +    public static void closeCache(){
 +        try{
 +            //System.out.println("closing cache cache cache cache cache 33333333");
 +            cache.close();
 +            ds.disconnect();
 +            //System.out.println("closed cache cache cache cache cache 44444444");
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of closeCache
 +    
 +    
 +    //tests methods
 +    
 +    public void testSimplePutAll(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        SerializableRunnable clear = new CacheSerializableRunnable("clear"){
 +            public void run2() throws CacheException {
 +                try{
 +                    region.clear();
 +                }catch(Exception ex){
 +                    ex.printStackTrace();
 +                }
 +            }
 +        };//end of clear
 +        
 +        vm0.invoke(new CacheSerializableRunnable("testSimplePutAll1"){
 +            public void run2() throws CacheException {
 +                int cntr = 0, cntr1 = 0;
 +                for(int i=1; i<6; i++) {
 +                    region.put(new Integer(i), new String("testSimplePutAll"+i));
 +                    cntr++;
 +                }
 +                
 +                int size1 = region.size();
 +                Map m = new HashMap();
 +                for(int i=6; i<27; i++) {
 +                    m.put(new Integer(i), new String("map"+i));
 +                    cntr++;
 +                    cntr1++;
 +                }
 +                
 +                region.putAll(m);
 +                int size2 = region.size();
 +                
 +                assertEquals(cntr, region.size());
 +                assertEquals(cntr1, (size2 - size1));
 +                assertEquals(true, region.containsKey(new Integer(10)));
 +                assertEquals(true, region.containsValue(new String("map12")));
 +            }
 +        } );
 +        
 +        vm0.invoke(clear);
 +        
 +        vm1.invoke(new CacheSerializableRunnable("create mirrored region"){
 +            public void run2() throws CacheException {
 +                createMirroredRegion();
 +            }
 +        }
 +        );
 +        
 +        vm0.invoke(new CacheSerializableRunnable("testSimplePutAll2"){
 +            public void run2() throws CacheException {
 +                //assertEquals(0, region.size());
 +                createMirroredRegion();
 +                cacheTxnMgr = cache.getCacheTransactionManager();
 +                int cntr = 0;
 +                for(int i=1; i<6; i++) {
 +                    mirroredRegion.put(new Integer(i), new String("testSimplePutAll"+i));
 +                    cntr++;
 +                }
 +                
 +                int size1 = mirroredRegion.size();
 +                Map m = new HashMap();
 +                for(int i=6; i<27; i++) {
 +                    m.put(new Integer(i), new String("map"+i));
 +                    cntr++;
 +                }
 +                
 +                //Disabled until putAll works in tx
 +                //cacheTxnMgr.begin();
 +                //mirroredRegion.putAll(m);
 +                //cacheTxnMgr.rollback();
 +                
 +                assertEquals(size1, mirroredRegion.size());
 +                assertEquals(false, mirroredRegion.containsKey(new Integer(10)));
 +                assertEquals(false, mirroredRegion.containsValue(new String("map12")));
 +                
 +                //cacheTxnMgr.begin();
 +                mirroredRegion.putAll(m);
 +                //cacheTxnMgr.commit();
 +                
 +//                int size2 = mirroredRegion.size();
 +                
 +                assertEquals(cntr, mirroredRegion.size());
 +                assertEquals(true, mirroredRegion.containsKey(new Integer(10)));
 +                assertEquals(true, mirroredRegion.containsValue(new String("map12")));
 +                
 +                //sharing the size of region of vm0 in vm1
 +                mirroredRegion.put("size", new Integer(mirroredRegion.size()));
 +            }
 +        } );
 +        
 +        vm1.invoke(new CacheSerializableRunnable("testSimplePutAll3"){
 +            public void run2() throws CacheException {
 +                Integer i = (Integer) mirroredRegion.get("size");
 +                int cntr = i.intValue();
 +                assertEquals(cntr, (mirroredRegion.size()-1));
 +                assertEquals(true, mirroredRegion.containsKey(new Integer(10)));
 +                assertEquals(true, mirroredRegion.containsValue(new String("map12")));
 +            }
 +        } );
 +        
 +    }//end of testSimplePutAll
 +    
 +    public void testPutAllExceptions(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        vm0.invoke(new CacheSerializableRunnable("testPutAllExceptions1"){
 +            public void run2() throws CacheException {
 +                int cntr = 0;
 +//                int cntr1 = 0;
 +                for(int i=1; i<6; i++) {
 +                    region.put(new Integer(i), new String("testSimplePutAll"+i));
 +                    cntr++;
 +                }
 +                
 +                Map m = new TreeMap();//to verify the assertions
 +                for(int i=6; i<27; i++) {
 +                    if(i == 16){
 +                        m.put(new Integer(i), null);
 +                    }
 +                    else {
 +                        m.put(new Integer(i), new String("map"+i));
 +                    }
 +                }
 +                
 +                try{
 +                    region.putAll(m);
 +                    fail("Expect NullPointerException");
 +                } catch (NullPointerException ex){
 +                    //do nothing
 +                }
 +                
 +                assertEquals(5, region.size());
 +                assertEquals(false, region.containsKey(new Integer(10)));
 +                assertEquals(false, region.containsValue(new String("map12")));
 +                assertEquals(false, region.containsKey(new Integer(20)));
 +                assertEquals(false, region.containsValue(new String("map21")));
 +            }
 +        } );
 +        
 +        
 +        vm1.invoke(new CacheSerializableRunnable("create mirrored region"){
 +            public void run2() throws CacheException {
 +                createMirroredRegion();
 +            }
 +        }
 +        );
 +        
 +        
 +        vm0.invoke(new CacheSerializableRunnable("testPutAllExceptions2"){
 +            public void run2() throws CacheException {
 +                //assertEquals(0, region.size());
 +                createMirroredRegion();
 +                
 +                for(int i=1; i<6; i++) {
 +                    mirroredRegion.put(new Integer(i), new String("testSimplePutAll"+i));
 +                }
 +                
 +                Map m = new TreeMap();//to verify the assertions
 +                for(int i=6; i<27; i++) {
 +                    if(i == 16){
 +                        m.put(new Integer(i), null);
 +                    }
 +                    else {
 +                        m.put(new Integer(i), new String("map"+i));
 +                    }
 +                }
 +                
 +                try{
 +                    mirroredRegion.putAll(m);
 +                    fail("Expect NullPointerException");
 +                } catch (NullPointerException ex){
 +                    //do nothing
 +                }
 +               
 +                assertEquals(5, mirroredRegion.size());
 +                assertEquals(false, mirroredRegion.containsKey(new Integer(10)));
 +                assertEquals(false, mirroredRegion.containsValue(new String("map12")));
 +                assertEquals(false, region.containsKey(new Integer(20)));
 +                assertEquals(false, region.containsValue(new String("map21")));
 +
 +                //sharing the size of region of vm0 in vm1
 +                mirroredRegion.put("size", new Integer(mirroredRegion.size()));
 +            }
 +        } );
 +        
 +        vm1.invoke(new CacheSerializableRunnable("testPutAllExceptions3"){
 +            public void run2() throws CacheException {
 +                Integer i = (Integer) mirroredRegion.get("size");
 +                int cntr = i.intValue();
 +                assertEquals(cntr, (mirroredRegion.size()-1));
 +                assertEquals(false, mirroredRegion.containsKey(new Integer(10)));
 +                assertEquals(false, mirroredRegion.containsValue(new String("map12")));
 +                assertEquals(false, mirroredRegion.containsKey(new Integer(20)));
 +                assertEquals(false, mirroredRegion.containsValue(new String("map21")));
 +            }
 +        } );
 +        
 +        
 +    }//end of testPutAllExceptions
 +    
 +    public void testPutAllExceptionHandling(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +//        VM vm1 = host.getVM(1);
 +        
 +        vm0.invoke(new CacheSerializableRunnable("testPutAllExceptionHandling1"){
 +            public void run2() throws CacheException {
 +                Map m = new HashMap();
 +                m = null;
 +                try{
 +                    region.putAll(m);
 +                    fail("Should have thrown NullPointerException");
 +                }catch (NullPointerException ex){
 +                    //pass
 +                }
 +                
 +                region.localDestroyRegion();
 +                try{
 +                    Map m1 = new HashMap();
 +                    for(int i=1; i<21; i++) {
 +                        m1.put(new Integer(i), Integer.toString(i));
 +                    }
 +                    
 +                    region.putAll(m1);
 +                    fail("Should have thrown RegionDestroyedException");
 +                }catch (RegionDestroyedException ex){
 +                    //pass
 +                }
 +                
 +            }
 +        });
 +        
 +    }//testPutAllExceptionHandling
 +    
 +    
 +}//end of PutAllMultiVmDUnitTest


[046/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/SequenceFileHoplog.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/SequenceFileHoplog.java
index 04cbb05,0000000..fbb8f14
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/SequenceFileHoplog.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/SequenceFileHoplog.java
@@@ -1,396 -1,0 +1,396 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.hdfs.internal.hoplog;
 +  
 +import java.io.Closeable;
 +import java.io.EOFException;
 +import java.io.IOException;
 +import java.nio.ByteBuffer;
 +import java.util.EnumMap;
 +
++import com.gemstone.gemfire.internal.hll.ICardinality;
 +import org.apache.hadoop.conf.Configuration;
 +import org.apache.hadoop.fs.FSDataOutputStream;
 +import org.apache.hadoop.fs.FileSystem;
 +import org.apache.hadoop.fs.Path;
 +import org.apache.hadoop.io.BytesWritable;
 +import org.apache.hadoop.io.IOUtils;
 +import org.apache.hadoop.io.Text;
 +
 +import com.gemstone.gemfire.cache.hdfs.HDFSIOException;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.ICardinality;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HoplogSetReader.HoplogIterator;
 +import com.gemstone.gemfire.cache.hdfs.internal.org.apache.hadoop.io.SequenceFile;
 +import com.gemstone.gemfire.cache.hdfs.internal.org.apache.hadoop.io.SequenceFile.Reader;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.SortedOplogStatistics;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.Version;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +/**
 + * Implements Sequence file based {@link Hoplog}
 + * 
 + * @author hemantb
 + *
 + */
 +public class SequenceFileHoplog extends AbstractHoplog{
 +  
 +   public SequenceFileHoplog(FileSystem inputFS, Path filePath,  
 +      SortedOplogStatistics stats)
 +  throws IOException
 +  {
 +     super(inputFS, filePath, stats);
 +  }
 +  @Override
 +  public void close() throws IOException {
 +    // Nothing to do 
 +  }
 +
 +  @Override
 +  public HoplogReader getReader() throws IOException {
 +    return new SequenceFileReader();
 +  }
 +
 +  @Override
 +  /**
 +   * gets the writer for sequence file. 
 +   * 
 +   * @param keys is not used for SequenceFileHoplog class 
 +   */
 +  public HoplogWriter createWriter(int keys) throws IOException {
 +    return new SequenceFileHoplogWriter();
 +  }
 +
 +  @Override
 +  public boolean isClosed() {
 +    return false;
 +  }
 +  
 +  @Override
 +  public void close(boolean clearCache) throws IOException {
 +    // Nothing to do 
 +  }
 +
 +  /**
 +   * Currently, hsync does not update the file size on namenode. So, if last time the 
 +   * process died after calling hsync but before calling file close, the file is 
 +   * left with an inconsistent file size. This is a workaround that - open the file stream in append 
 +   * mode and close it. This fixes the file size on the namenode.
 +   * 
 +   * @throws IOException
 +   * @return true if the file size was fixed 
 +   */
 +  public boolean fixFileSize() throws IOException {
 +    // Try to fix the file size
 +    // Loop so that the expected expceptions can be ignored 3
 +   // times
 +    if (logger.isDebugEnabled())
 +      logger.debug("{}Fixing size of hoplog " + path, logPrefix);
 +    Exception e = null;
 +    boolean exceptionThrown = false;
 +    for (int i =0; i < 3; i++) {
 +      try {
 +        FSDataOutputStream stream = fsProvider.getFS().append(path);
 +        stream.close();
 +        stream = null;
 +      } catch (IOException ie) {
 +        exceptionThrown = true;
 +        e = ie;
 +        if (logger.isDebugEnabled())
 +        logger.debug("{}Retry run " + (i + 1) + ": Hoplog " + path + " is still a temporary " +
 +            "hoplog because the node managing it wasn't shutdown properly last time. Failed to " +
 +            "fix the hoplog because an exception was thrown " + e, logPrefix );
 +      }
 +      // As either RecoveryInProgressException was thrown or 
 +      // Already being created exception was thrown, wait for 
 +      // sometime before next retry. 
 +      if (exceptionThrown) {
 +        try {
 +          Thread.sleep(5000);
 +        } catch (InterruptedException e1) {
 +        } 
 +        exceptionThrown = false;
 +      } else {
 +        // no exception was thrown, break;
 +        return true;
 +      }
 +    }
 +    logger.info (logPrefix, LocalizedMessage.create(LocalizedStrings.DEBUG, "Hoplog " + path + " is still a temporary " +
 +        "hoplog because the node managing it wasn't shutdown properly last time. Failed to " +
 +        "fix the hoplog because an exception was thrown " + e));
 +    
 +    return false;
 +  }
 +  
 +  @Override
 +  public String toString() {
 +    return "SequenceFileHplog[" + getFileName() + "]";
 +  }
 +  
 +  private class SequenceFileHoplogWriter implements HoplogWriter {
 +    
 +    private SequenceFile.Writer writer = null;
 +    
 +    public SequenceFileHoplogWriter() throws IOException{
 +      writer = AbstractHoplog.getSequenceFileWriter(path, conf, logger);
 +    }
 +   
 +    @Override
 +    public void close() throws IOException {
 +      writer.close();
 +      if (logger.isDebugEnabled())
 +        logger.debug("{}Completed creating hoplog " + path, logPrefix);
 +    }
 +    
 +    @Override
 +    public void hsync() throws IOException {
 +      writer.hsyncWithSizeUpdate();
 +      if (logger.isDebugEnabled())
 +        logger.debug("{}hsync'ed a batch of data to hoplog " + path, logPrefix);
 +    }
 +    
 +    @Override
 +    public void append(byte[] key, byte[] value) throws IOException {
 +      writer.append(new BytesWritable(key), new BytesWritable(value));
 +    }
 +
 +    @Override
 +    public void append(ByteBuffer key, ByteBuffer value) throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public void close(EnumMap<Meta, byte[]> metadata) throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +    @Override
 +    public long getCurrentSize() throws IOException {
 +      return writer.getLength();
 +    }
 +    
 +  }
 +  /**
 +   * Sequence file reader. This is currently to be used only by MapReduce jobs and 
 +   * test functions
 +   * 
 +   */
 +  public class SequenceFileReader implements HoplogReader, Closeable {
 +    @Override
 +    public byte[] read(byte[] key) throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan()
 +        throws IOException {
 +      return  new SequenceFileIterator(fsProvider.getFS(), path, 0, Long.MAX_VALUE, conf, logger);
 +    }
 +
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan(
 +        byte[] from, byte[] to) throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +    
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan(
 +        long startOffset, long length) throws IOException {
 +      return  new SequenceFileIterator(fsProvider.getFS(), path, startOffset, length, conf, logger);
 +    }
 +    
 +    @Override
 +    public HoplogIterator<byte[], byte[]> scan(
 +        byte[] from, boolean fromInclusive, byte[] to, boolean toInclusive)
 +        throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public boolean isClosed() {
 +      throw new UnsupportedOperationException("Not supported for Sequence files.");
 +    }
 +    
 +    @Override
 +    public void close() throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files. Close the iterator instead.");
 +    }
 +
 +    @Override
 +    public ByteBuffer get(byte[] key) throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public BloomFilter getBloomFilter() throws IOException {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public long getEntryCount() {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public ICardinality getCardinalityEstimator() {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public long sizeEstimate() {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +
 +  }
 +  
 +  /**
 +   * Sequence file iterator. This is currently to be used only by MapReduce jobs and 
 +   * test functions
 +   * 
 +   */
 +  public static class SequenceFileIterator implements HoplogIterator<byte[], byte[]> {
 +    
 +    SequenceFile.Reader reader = null;
 +    private BytesWritable prefetchedKey = null;
 +    private BytesWritable prefetchedValue = null;
 +    private byte[] currentKey;
 +    private byte[] currentValue;
 +    boolean hasNext = false;
 +    Logger logger; 
 +    Path path;
 +    private long start;
 +    private long end;
 +    
 +    public SequenceFileIterator(FileSystem fs, Path path, long startOffset, 
 +        long length, Configuration conf, Logger logger) 
 +        throws IOException {
 +      Reader.Option optPath = SequenceFile.Reader.file(path);
 +      
 +      // Hadoop has a configuration parameter io.serializations that is a list of serialization 
 +      // classes which can be used for obtaining serializers and deserializers. This parameter 
 +      // by default contains avro classes. When a sequence file is created, it calls 
 +      // SerializationFactory.getSerializer(keyclass). This internally creates objects using 
 +      // reflection of all the classes that were part of io.serializations. But since, there is 
 +      // no avro class available it throws an exception. 
 +      // Before creating a sequenceFile, override the io.serializations parameter and pass only the classes 
 +      // that are important to us. 
 +      String serializations[] = conf.getStrings("io.serializations",
 +          new String[]{"org.apache.hadoop.io.serializer.WritableSerialization"});
 +      conf.setStrings("io.serializations",
 +          new String[]{"org.apache.hadoop.io.serializer.WritableSerialization"});
 +      // create reader
 +      boolean emptyFile = false;
 +      try {
 +        reader = new SequenceFile.Reader(conf, optPath);
 +      }catch (EOFException e) {
 +        // this is ok as the file has ended. just return false that no more records available
 +        emptyFile = true;
 +      }
 +      // reset the configuration to its original value 
 +      conf.setStrings("io.serializations", serializations);
 +      this.logger = logger;
 +      this.path = path;
 +      
 +      if (emptyFile) {
 +        hasNext = false;
 +      } else {
 +        // The file should be read from the first sync marker after the start position and 
 +        // until the first sync marker after the end position is seen. 
 +        this.end = startOffset + length;
 +        if (startOffset > reader.getPosition()) {
 +          reader.sync(startOffset);                  // sync to start
 +        }
 +        this.start = reader.getPosition();
 +        this.hasNext = this.start < this.end;
 +        if (hasNext)
 +          readNext();
 +      } 
 +    }
 +  
 +
 +    public Version getVersion(){
 +      String version = reader.getMetadata().get(new Text(Meta.GEMFIRE_VERSION.name())).toString();
 +      return Version.fromOrdinalOrCurrent(Short.parseShort(version)); 
 +    }
 +    @Override
 +    public boolean hasNext() {
 +      return hasNext;
 +    }
 +
 +    @Override
 +    public byte[] next() {
 +      currentKey = prefetchedKey.getBytes();
 +      currentValue = prefetchedValue.getBytes();
 +      
 +      readNext();
 +
 +      return currentKey;
 +    }
 +    
 +    private void readNext() {
 +      try {
 +        long pos = reader.getPosition();
 +        prefetchedKey = new BytesWritable();
 +        prefetchedValue = new BytesWritable();
 +        hasNext = reader.next(prefetchedKey, prefetchedValue);
 +        // The file should be read from the first sync marker after the start position and 
 +        // until the first sync marker after the end position is seen. 
 +        if (pos >= end && reader.syncSeen()) {
 +          hasNext = false;
 +        }
 +      } catch (EOFException e) {
 +        // this is ok as the file has ended. just return false that no more records available
 +        hasNext = false;
 +      } 
 +      catch (IOException e) {
 +        hasNext = false;
 +        logger.error(LocalizedMessage.create(LocalizedStrings.HOPLOG_FAILED_TO_READ_HDFS_FILE, path), e);
 +        throw new HDFSIOException(
 +            LocalizedStrings.HOPLOG_FAILED_TO_READ_HDFS_FILE.toLocalizedString(path), e);
 +      }
 +    }
 +    @Override
 +    public void remove() {
 +      throw new UnsupportedOperationException("Not supported for Sequence files");
 +    }
 +
 +    @Override
 +    public void close() {
 +      IOUtils.closeStream(reader);
 +    }
 +
 +    @Override
 +    public byte[] getKey() {
 +      return currentKey;
 +    }
 +
 +    @Override
 +    public byte[] getValue() {
 +      return currentValue;
 +    }
 +    
 +    /** Returns true iff the previous call to next passed a sync mark.*/
 +    public boolean syncSeen() { return reader.syncSeen(); }
 +
 +    /** Return the current byte position in the input file. */
 +    public synchronized long getPosition() throws IOException {
 +      return reader.getPosition();
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
index b94f975,0000000..de694a4
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
@@@ -1,333 -1,0 +1,361 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.internal.index;
 +
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Iterator;
 +import java.util.NoSuchElementException;
 +
 +/**
 + * A wrapper around an object array for storing values in index data structure
 + * with minimal set of operations supported and the maximum size of 128 elements  
 + * 
 + * @author Tejas Nomulwar
 + * @since 7.0
 + */
 +public class IndexElemArray implements Iterable, Collection {
 +
 +  private Object[] elementData;
 +  private volatile byte size;
 +
++  /* lock for making size and data changes atomically. */
++  private Object lock = new Object();
++
 +  public IndexElemArray(int initialCapacity) {
 +    if (initialCapacity < 0) {
 +      throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
 +    }
 +    this.elementData = new Object[initialCapacity];
 +  }
 +
 +  /**
 +   * Constructs an empty list with an initial capacity of ten.
 +   */
 +  public IndexElemArray() {
 +    this(IndexManager.INDEX_ELEMARRAY_SIZE);
 +  }
 +
 +  /**
 +   * Increases the capacity of this <tt>ArrayList</tt> instance, if necessary,
 +   * to ensure that it can hold at least the number of elements specified by the
 +   * minimum capacity argument.
 +   * 
 +   * @param minCapacity
 +   *          the desired minimum capacity
 +   */
 +  private void ensureCapacity(int minCapacity) {
 +    int oldCapacity = elementData.length;
 +    if (minCapacity > oldCapacity) {
 +      int newCapacity = oldCapacity + 5;
 +      if (newCapacity < minCapacity) {
 +        newCapacity = minCapacity;
 +      }
 +      // minCapacity is usually close to size, so this is a win:
 +      Object[] newElementData = new Object[newCapacity];
 +      System.arraycopy(this.elementData, 0, newElementData, 0,
 +          this.elementData.length);
 +      elementData = newElementData;
 +    }
 +  }
 +
 +  /**
 +   * Returns the number of elements in this list. (Warning: May not return
 +   * correct size always, as remove operation is not atomic)
 +   * 
 +   * @return the number of elements in this list
 +   */
 +  public int size() {
 +    return size;
 +  }
 +
 +  /**
 +   * Returns <tt>true</tt> if this list contains no elements.
 +   * 
 +   * @return <tt>true</tt> if this list contains no elements
 +   */
 +  public boolean isEmpty() {
 +    return size == 0;
 +  }
 +
 +  /**
 +   * Returns <tt>true</tt> if this list contains the specified element. More
 +   * formally, returns <tt>true</tt> if and only if this list contains at least
 +   * one element <tt>e</tt> such that
 +   * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
 +   * 
 +   * @param o
 +   *          element whose presence in this list is to be tested
 +   * @return <tt>true</tt> if this list contains the specified element
 +   */
 +  public boolean contains(Object o) {
 +    return indexOf(o) >= 0;
 +  }
 +
 +  /**
 +   * Returns the index of the first occurrence of the specified element in this
 +   * list, or -1 if this list does not contain the element. More formally,
 +   * returns the lowest index <tt>i</tt> such that
 +   * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
 +   * or -1 if there is no such index.
 +   */
 +  public int indexOf(Object o) {
-     if (o == null) {
-       for (int i = 0; i < size; i++)
-         if (elementData[i] == null)
-           return i;
-     } else {
-       for (int i = 0; i < size; i++)
-         if (o.equals(elementData[i]))
-           return i;
++    synchronized (lock) {
++      if (o == null) {
++        for (int i = 0; i < size; i++)
++          if (elementData[i] == null)
++            return i;
++      } else {
++        for (int i = 0; i < size; i++)
++          if (o.equals(elementData[i]))
++            return i;
++      }
 +    }
 +    return -1;
 +  }
 +
 +  /**
 +   * Returns the element at the specified position in this list.
 +   * 
 +   * @param index
 +   *          index of the element to return
 +   * @return the element at the specified position in this list
 +   * @throws IndexOutOfBoundsException
 +   *          
 +   */
 +  public Object get(int index) {
-     RangeCheck(index);
-     return elementData[index];
++    synchronized (lock) {
++      RangeCheck(index);
++      return elementData[index];
++    }
 +  }
 +
 +  /**
 +   * Replaces the element at the specified position in this list with the
 +   * specified element.
 +   * 
 +   * @param index
 +   *          index of the element to replace
 +   * @param element
 +   *          element to be stored at the specified position
 +   * @return the element previously at the specified position
 +   * @throws IndexOutOfBoundsException
 +   *           
 +   */
 +  public Object set(int index, Object element) {
-     RangeCheck(index);
++    synchronized (lock) {
++      RangeCheck(index);
 +
-     Object oldValue = (Object) elementData[index];
-     elementData[index] = element;
-     return oldValue;
++      Object oldValue = (Object) elementData[index];
++      elementData[index] = element;
++      return oldValue;
++    }
 +  }
 +
 +  /**
 +   * Appends the specified element to the end of this array.
 +   * If the array is full, creates a new array with 
 +   * new capacity = old capacity + 5
 +   * 
 +   * @param e
 +   *          element to be appended to this list
 +   * @return <tt>true</tt> (as specified by {@link Collection#add})
 +   * @throws ArrayIndexOutOfBoundsException
 +   */
-   public synchronized boolean add(Object e) {
-     ensureCapacity(size + 1);
-     elementData[size] = e;
-     ++size;
++  public boolean add(Object e) {
++    synchronized (lock) {
++      ensureCapacity(size + 1);
++      elementData[size] = e;
++      ++size;
++    }
 +    return true;
 +  }
 +
 +  /**
 +   * Removes the first occurrence of the specified element from this list, if it
 +   * is present. If the list does not contain the element, it is unchanged. More
 +   * formally, removes the element with the lowest index <tt>i</tt> such that
 +   * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
 +   * (if such an element exists). Returns <tt>true</tt> if this list contained
 +   * the specified element (or equivalently, if this list changed as a result of
 +   * the call).
 +   * 
 +   * @param o
 +   *          element to be removed from this list, if present
 +   * @return <tt>true</tt> if this list contained the specified element
 +   */
-   public synchronized boolean remove(Object o) {
++  public boolean remove(Object o) {
 +    if (o == null) {
 +      for (int index = 0; index < size; index++)
 +        if (elementData[index] == null) {
 +          fastRemove(index);
 +          return true;
 +        }
 +    } else {
 +      for (int index = 0; index < size; index++)
 +        if (o.equals(elementData[index])) {
 +          fastRemove(index);
 +          return true;
 +        }
 +    }
 +    return false;
 +  }
 +
 +  /*
 +   * Private remove method that skips bounds checking and does not return the
 +   * value removed.
 +   */
 +  private void fastRemove(int index) {
 +    int len = elementData.length;
 +    Object[] newArray = new Object[len - 1];
 +    System.arraycopy(elementData, 0, newArray, 0, index);
 +    int numMoved = len - index - 1;
 +    if (numMoved > 0)
 +      System.arraycopy(elementData, index + 1, newArray, index, numMoved);
-     elementData = newArray;
-     --size;
++
++    synchronized (lock) {
++      elementData = newArray;
++      --size;
++    }
 +  }
 +
 +  /**
 +   * Removes all of the elements from this list. The list will be empty after
 +   * this call returns.
 +   */
 +  public void clear() {
 +    // Let gc do its work
-     for (int i = 0; i < size; i++) {
-       elementData[i] = null;
++    synchronized (lock) {
++      for (int i = 0; i < size; i++) {
++        elementData[i] = null;
++      }
++      size = 0;
 +    }
-     size = 0;
 +  }
 +
 +  /**
 +   * Checks if the given index is in range. If not, throws an appropriate
 +   * runtime exception. This method does *not* check if the index is negative:
 +   * It is always used immediately prior to an array access, which throws an
 +   * ArrayIndexOutOfBoundsException if index is negative.
 +   */
 +  private void RangeCheck(int index) {
 +    if (index >= size) {
 +      throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
 +    }
 +  }
 +
 +  @Override
-   public synchronized boolean addAll(Collection c) {
++  public boolean addAll(Collection c) {
 +    Object[] a = c.toArray();
 +    int numNew = a.length;
-     ensureCapacity(size + numNew);
-     System.arraycopy(a, 0, elementData, size, numNew);
-     size += numNew;
++    synchronized (lock) {
++      ensureCapacity(size + numNew);
++      System.arraycopy(a, 0, elementData, size, numNew);
++      size += numNew;
++    }
 +    return numNew != 0;
 +  }
 +
 +  @Override
 +  public Object[] toArray() {
 +    return Arrays.copyOf(elementData, size);
 +  }
 +
 +  @Override
 +  public Iterator iterator() {
 +    return new IndexArrayListIterator();
 +  }
 +
 +  private class IndexArrayListIterator implements Iterator {
 +    private byte current;
 +    private Object currentEntry;
++    private Object[] elements;
++    private int len;
++
++    IndexArrayListIterator() {
++      synchronized (lock) {
++        elements = elementData;
++        len = size;
++      }
++    }
 +    
 +    /**
 +     * Checks if the array has next element, stores reference to the current
 +     * element and increments cursor. This is required since an element may be
 +     * removed between hasNext() and next() method calls
 +     * 
 +     */
 +    @Override
 +    public boolean hasNext() {
-       return current < size;
++      return current < len;
 +    }
 +
 +    /**
 +     * Returns next element. But does not increment the cursor.
 +     * Always use hasNext() before this method call
 +     */
 +    @Override
 +    public Object next() {
 +      try {
-         currentEntry = elementData[current++];
++        currentEntry = elements[current++];
 +      } catch (IndexOutOfBoundsException e) {
-         // Following exception must never be thrown.
-         //throw new NoSuchElementException();
-         return null;
++        // We should not be coming here as element-data and
++        // size are updated atomically.
++        throw new NoSuchElementException();
++        //return null;
 +      }
 +      return currentEntry;
 +    }
 +
 +    @Override
 +    public void remove() {
 +      throw new UnsupportedOperationException(
 +          "remove() method is not supported");
 +    }
 +
 +  }
 +
 +  @Override
 +  public Object[] toArray(Object[] a) {
 +    throw new UnsupportedOperationException(
 +        "toArray(Object[] a) method is not supported");
 +  }
 +
 +  @Override
 +  public boolean containsAll(Collection c) {
 +    throw new UnsupportedOperationException(
 +        "containsAll() method is not supported");
 +  }
 +
 +  @Override
 +  public boolean removeAll(Collection c) {
 +    throw new UnsupportedOperationException(
 +        "removeAll() method is not supported");
 +  }
 +
 +  @Override
 +  public boolean retainAll(Collection c) {
 +    throw new UnsupportedOperationException(
 +        "retainAll() method is not supported");
 +  }
 +
 +  //for internal testing only
 +  public Object[] getElementData() {
 +    return elementData;
 +  }
 +}


[016/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/PdxStringQueryDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/PdxStringQueryDUnitTest.java
index 42459c9,0000000..934798c
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/PdxStringQueryDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/dunit/PdxStringQueryDUnitTest.java
@@@ -1,1987 -1,0 +1,1987 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.dunit;
 +
 +import java.io.IOException;
 +import java.util.HashMap;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.PartitionAttributes;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.Struct;
 +import com.gemstone.gemfire.cache.query.data.Portfolio;
 +import com.gemstone.gemfire.cache.query.data.PortfolioPdx;
 +import com.gemstone.gemfire.cache.query.data.PositionPdx;
 +import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
 +import com.gemstone.gemfire.cache.query.internal.index.CompactRangeIndex;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexStore.IndexStoreEntry;
 +import com.gemstone.gemfire.cache.query.internal.index.PartitionedIndex;
 +import com.gemstone.gemfire.cache.query.internal.index.RangeIndex;
 +import com.gemstone.gemfire.cache.query.types.CollectionType;
 +import com.gemstone.gemfire.cache.query.types.ObjectType;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.ClientServerTestCase;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.persistence.query.CloseableIterator;
 +import com.gemstone.gemfire.pdx.internal.PdxString;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +public class PdxStringQueryDUnitTest extends CacheTestCase{
 +  private static int bridgeServerPort;
 +
 +  public PdxStringQueryDUnitTest(String name) {
 +    super(name);
 +   }
 +
 +  private final String rootRegionName = "root";
 +  private final String regionName = "PdxTest";
 +  private final String regName = "/" + rootRegionName + "/" + regionName;
 +  private final static int orderByQueryIndex = 11;
 +  private final static int [] groupByQueryIndex = new int[]{7, 8, 9,10};
 +  
 +  private final String[] queryString = new String[] { 
 +      "SELECT pos.secId FROM " + regName + " p, p.positions.values pos WHERE pos.secId LIKE '%L'",//0
 +      "SELECT pos.secId FROM " + regName + " p, p.positions.values pos where pos.secId = 'IBM'",//1
 +      "SELECT pos.secId, p.status FROM " + regName + " p, p.positions.values pos where pos.secId > 'APPL'",//2
 +      "SELECT pos.secId FROM " + regName + " p, p.positions.values pos WHERE pos.secId > 'APPL' and pos.secId < 'SUN'",//3
 +      "select pos.secId from " + regName + " p, p.positions.values pos where pos.secId  IN SET ('YHOO', 'VMW')",//4
 +      "select pos.secId from " + regName + " p, p.positions.values pos where NOT (pos.secId = 'VMW')",//5
 +      "select pos.secId from " + regName + " p, p.positions.values pos where NOT (pos.secId IN SET('SUN', 'ORCL')) ",//6
 +      "select pos.secId , count(pos.id) from " + regName + " p, p.positions.values pos where  pos.secId > 'APPL' group by pos.secId ",//7
 +      "select pos.secId , sum(pos.id) from " + regName + " p, p.positions.values pos where  pos.secId > 'APPL' group by pos.secId ",//8,
 +      "select pos.secId , count(distinct pos.secId) from " + regName + " p, p.positions.values pos where  pos.secId > 'APPL' group by pos.secId ",//9
 +      "select  count(distinct pos.secId) from " + regName + " p, p.positions.values pos where  pos.secId > 'APPL' ",//10
 +      "SELECT distinct pos.secId FROM " + regName + " p, p.positions.values pos order by pos.secId",//11
 +      "SELECT distinct pos.secId FROM " + regName + " p, p.positions.values pos WHERE p.ID > 1 order by pos.secId limit 5",//12
 + };
 +
 + private final String[] queryString2 = new String[] { 
 +      "SELECT pos.secIdIndexed FROM " + regName + " p, p.positions.values pos WHERE pos.secIdIndexed LIKE '%L'",//0
 +      "SELECT pos.secIdIndexed FROM " + regName + " p, p.positions.values pos where pos.secIdIndexed = 'IBM'",//1
 +      "SELECT pos.secIdIndexed, p.status FROM " + regName + " p, p.positions.values pos where pos.secIdIndexed > 'APPL'",//2
 +      "SELECT pos.secIdIndexed FROM " + regName + " p, p.positions.values pos WHERE pos.secIdIndexed > 'APPL' and pos.secIdIndexed < 'SUN'",//3
 +      "select pos.secIdIndexed from " + regName + " p, p.positions.values pos where pos.secIdIndexed  IN SET ('YHOO', 'VMW')",//4
 +      "select pos.secIdIndexed from " + regName + " p, p.positions.values pos where NOT (pos.secIdIndexed = 'VMW')",//5
 +      "select pos.secIdIndexed from " + regName + " p, p.positions.values pos where NOT (pos.secIdIndexed IN SET('SUN', 'ORCL')) ",//6
 +      "select pos.secIdIndexed , count(pos.id) from " + regName + " p, p.positions.values pos where  pos.secIdIndexed > 'APPL' group by pos.secIdIndexed ",//7
 +      "select pos.secIdIndexed , sum(pos.id) from " + regName + " p, p.positions.values pos where  pos.secIdIndexed > 'APPL' group by pos.secIdIndexed ",//8
 +      "select pos.secIdIndexed , count(distinct pos.secIdIndexed) from " + regName + " p, p.positions.values pos where  pos.secIdIndexed > 'APPL' group by pos.secIdIndexed ",//9
 +      "select  count(distinct pos.secIdIndexed) from " + regName + " p, p.positions.values pos where  pos.secIdIndexed > 'APPL'  ",//10
 +      "SELECT distinct pos.secIdIndexed FROM " + regName + " p, p.positions.values pos order by pos.secIdIndexed",//11
 +      "SELECT distinct pos.secIdIndexed FROM " + regName + " p, p.positions.values pos WHERE p.ID > 1 order by pos.secIdIndexed limit 5",//12
 + };
 +
 +  public void testReplicatedRegionNoIndex() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +        Index index = null;
 +        // create an index on statusIndexed is created
 +         try {
 +           index = localQueryService.createIndex("secIdIndex2", "pos.secIdIndexed", regName  + " p, p.positions.values pos");
 +             if(!(index instanceof RangeIndex)){
 +               fail("Range Index should have been created instead of " + index.getClass());
 +             }
 +            } catch (Exception ex) {
 +           fail("Failed to create index." + ex.getMessage());
 +         }
 +      }
 +    });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new PortfolioPdx(i));
 +         }
 +      }
 +    });
 +    
 +     // Execute queries from client to server and locally on client
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +        SelectResults[] resWithoutIndexRemote = new SelectResults[queryString.length];
 +        SelectResults[] resWithIndexRemote = new SelectResults[queryString2.length];
 +        SelectResults[] resWithoutIndexLocal = new SelectResults[queryString.length];
 +        SelectResults[] resWithIndexLocal = new SelectResults[queryString2.length];
 +
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server:" + queryString[i]);
 +            Query query = remoteQueryService.newQuery(queryString[i]);
 +            rs[0][0] = (SelectResults)query.execute();
 +            resWithoutIndexRemote[i] = rs[0][0];
 +            LogWriterUtils.getLogWriter().info("RR remote indexType: no index  size of resultset: "+ rs[0][0].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][0].asList(), queryString[i]);
 +            
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on client:" + queryString[i]);
 +            query = localQueryService.newQuery(queryString[i]);
 +            rs[0][1] = (SelectResults)query.execute();
 +            resWithoutIndexLocal[i] = rs[0][1];
 +            LogWriterUtils.getLogWriter().info("RR  client local indexType:no index size of resultset: "+ rs[0][1].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][1].asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +          try{
 +            // to compare remote query results with and without index
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server for region2:" + queryString2[i]);
 +            Query query = remoteQueryService.newQuery(queryString2[i]);
 +            resWithIndexRemote[i] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR  remote region2 size of resultset: "+ resWithIndexRemote[i].size() + " for query: " + queryString2[i]);;
 +            checkForPdxString(resWithIndexRemote[i].asList(), queryString2[i]);
 +
 +           // to compare local query results with and without index
 +            LogWriterUtils.getLogWriter().info("### Executing Query on local for region2:" + queryString2[i]);
 +            query = localQueryService.newQuery(queryString2[i]);
 +            resWithIndexLocal[i] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR  local region2 size of resultset: "+ resWithIndexLocal[i].size() + " for query: " + queryString2[i]);;
 +            checkForPdxString(resWithIndexLocal[i].asList(), queryString2[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString2[i], e);
 +          }
 +
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Local and Remote Query Results are not matching for query :" + queryString[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, false);
 +            }
 +          
 +        }
 +        // compare remote query results with and without index
 +           for (int i=0; i < queryString.length; i++){
 +            rs[0][0] = resWithoutIndexRemote[i]; 
 +            rs[0][1] = resWithIndexRemote[i];
 +            if(i < orderByQueryIndex){
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Results with and without index are not matching for query :" + queryString2[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, false);
 +            }
 +          }
 +           // compare local query results with and without index
 +          for (int i=0; i < queryString.length; i++){
 +            rs[0][0] = resWithoutIndexLocal[i]; 
 +            rs[0][1] = resWithIndexLocal[i];
 +            if(i < orderByQueryIndex){
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Results with and without index are not matching for query :" + queryString2[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, false);
 +            }
 +          }
 +        
 +       }
 +    };
 +
 +    client.invoke(executeQueries);
 +
 +    // Put Non Pdx objects on server execute queries locally 
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +
 +        LogWriterUtils.getLogWriter().info("Put Objects locally on server");
 +        for (int i=numberOfEntries; i<numberOfEntries*2; i++) {
 +          region.put("key-"+i, new Portfolio(i));
 +         }
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local indexType: no  size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +          try{
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString2[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local indexType: no size of resultset: " + rs.size() + " for query: " + queryString2[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString2[i]);
 +          }catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString2[i], e);
 +          }
 +        }
 +       }
 +    });
 +    
 +   // test for readSerialized flag
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("isPR: false server local readSerializedTrue: indexType: false size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    // test for readSerialized flag on client
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService  remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +
 +        // Query server1 remotely to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) remoteQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server remote readSerializedTrue: indexType: false size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +
 +  public void testRepliacatedRegionCompactRangeIndex() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +        // Verify the type of index created  
 +        Index index = null;
 +         try {
 +           index = localQueryService.createIndex("statusIndex", "status", regName);
 +             if(!(index instanceof CompactRangeIndex)){
 +               fail("CompactRange Index should have been created instead of " + index.getClass());
 +             }
 +            } catch (Exception ex) {
 +           fail("Failed to create index." + ex.getMessage());
 +         }
 +      }
 +    });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new PortfolioPdx(i));
 +         }
 +      }
 +    });
 +    
 +    //Verify if all the index keys are PdxStrings
 +    server0.invoke(new CacheSerializableRunnable("Create Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        Index index = localQueryService.getIndex(region, "statusIndex");
 +        CloseableIterator<IndexStoreEntry> iter = ((CompactRangeIndex) index)
 +            .getIndexStorage().iterator(null);
 +        while (iter.hasNext()) {
 +          Object key = iter.next().getDeserializedKey();
 +          if (!(key instanceof PdxString)) {
 +            fail("All keys of the CompactRangeIndex should be PdxStrings and not "
 +                + key.getClass());
 +          }
 +        }
 +      }
 +    });
 + 
 +    // Execute queries from client to server and locally on client
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server:" + queryString[i]);
 +            Query query = remoteQueryService.newQuery(queryString[i]);
 +            rs[0][0] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR remote indexType: CompactRange size of resultset: "+ rs[0][0].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][0].asList(), queryString[i]);
 +             
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on client:" + queryString[i]);
 +            query = localQueryService.newQuery(queryString[i]);
 +            rs[0][1] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR  client local indexType: CompactRange size of resultset: "+ rs[0][1].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][1].asList(), queryString[i]);
 +             
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Local and Remote Query Results are not matching for query :" + queryString[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, false);
 +            }
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +        
 +        }
 +    };
 +
 +    client.invoke(executeQueries);
 +    
 +    // Put Non Pdx objects on server execute queries locally 
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +
 +        LogWriterUtils.getLogWriter().info("Put Objects locally on server");
 +        for (int i=numberOfEntries; i<numberOfEntries*2; i++) {
 +          region.put("key-"+i, new Portfolio(i));
 +         }
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local indexType:Range  size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +       }
 +    });
 +   
 +    // test for readSerialized flag
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService localQueryService = getCache().getQueryService();
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local readSerializedTrue: indexType: CompactRange size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    // test for readSerialized flag on client
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService  remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +
 +        // Query server1 remotely to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) remoteQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server remote readSerializedTrue: indexType:CompactRange size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +  
 +  public void testReplicatedRegionRangeIndex() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +        // Verify the type of index created  
 +        Index index = null;
 +          try {
 +           index = localQueryService.createIndex("secIdIndex", "pos.secId", regName  + " p, p.positions.values pos");
 +            if(!(index instanceof RangeIndex) ){
 +               fail("Range Index should have been created instead of "+ index.getClass());
 +             }
 +          } catch (Exception ex) {
 +             fail("Failed to create index." + ex.getMessage());
 +          }
 +       }
 +    });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(false,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new PortfolioPdx(i));
 +         }
 +      }
 +    });
 +    
 +    //Verify if all the index keys are PdxStrings
 +    server0.invoke(new CacheSerializableRunnable("Create Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        QueryService localQueryService = getCache().getQueryService();
 +          Index index = localQueryService.getIndex(region, "secIdIndex");
 +            for(Object key: ((RangeIndex)index).getValueToEntriesMap().keySet()){
 +              if(!(key instanceof PdxString)){
 +                fail("All keys of the RangeIndex should be PdxStrings and not " + key.getClass());
 +              }
 +            }
 +      }
 +    });
 + 
 +    // Execute queries from client to server and locally on client
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server:" + queryString[i]);
 +            Query query = remoteQueryService.newQuery(queryString[i]);
 +            rs[0][0] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR remote indexType: Range size of resultset: "+ rs[0][0].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][0].asList(), queryString[i]);
 +           
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on client:" + queryString[i]);
 +            query = localQueryService.newQuery(queryString[i]);
 +            rs[0][1] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR  client local indexType: Range size of resultset: "+ rs[0][1].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][1].asList(), queryString[i]);
 +            
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Local and Remote Query Results are not matching for query :" + queryString[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, false);
 +            }
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +        }
 +    };
 +
 +    client.invoke(executeQueries);
 +    
 +    // Put Non Pdx objects on server execute queries locally 
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +
 +        LogWriterUtils.getLogWriter().info("Put Objects locally on server");
 +        for (int i=numberOfEntries; i<numberOfEntries*2; i++) {
 +          region.put("key-"+i, new Portfolio(i));
 +         }
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local indexType:Range  size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +       }
 +    });
 +    // test for readSerialized flag
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService localQueryService = getCache().getQueryService();
 +       // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR  server local readSerializedTrue: indexType: Range size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    // test for readSerialized flag on client
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService  remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +        // Query server1 remotely to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) remoteQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server remote readSerializedTrue: indexType: Range size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +  
 +  public void testPartitionRegionNoIndex() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    final boolean isPr = true;
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +       
 +        Index index = null;
 +        // In the NO_INDEX case where no indexes are used an index on another field statusIndexed is created
 +         try {
 +           index = localQueryService.createIndex("secIdIndex", "pos.secIdIndexed", regName  + " p, p.positions.values pos");
 +           if(index instanceof PartitionedIndex){
 +               for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                 if(!(o instanceof RangeIndex) ){
 +                   fail("RangeIndex Index should have been created instead of "+ index.getClass());
 +                 }
 +               }
 +             }
 +             else{
 +               fail("Partitioned index expected");
 +             }
 +            } catch (Exception ex) {
 +           fail("Failed to create index." + ex.getMessage());
 +         }
 +      }
 +    });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new PortfolioPdx(i));
 +         }
 +      }
 +    });
 +    
 +    // Execute queries from client to server and locally on client
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +        SelectResults[] resWithoutIndexRemote = new SelectResults[queryString.length];
 +        SelectResults[] resWithIndexRemote = new SelectResults[queryString.length];
 +        SelectResults[] resWithoutIndexLocal = new SelectResults[queryString.length];
 +        SelectResults[] resWithIndexLocal = new SelectResults[queryString.length];
 +
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server:" + queryString[i]);
 +            Query query = remoteQueryService.newQuery(queryString[i]);
 +            rs[0][0] = (SelectResults)query.execute();
 +            resWithoutIndexRemote[i] = rs[0][0];
 +            LogWriterUtils.getLogWriter().info("RR remote no index size of resultset: "+ rs[0][0].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][0].asList(), queryString[i]);
 +
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on client:" + queryString[i]);
 +            query = localQueryService.newQuery(queryString[i]);
 +            rs[0][1] = (SelectResults)query.execute();
 +            resWithoutIndexLocal[i] = rs[0][1];
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ "  client local indexType:no index size of resultset: "+ rs[0][1].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][1].asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +          try{  
 +            // to compare remote query results with and without index
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server for region2:" + queryString2[i]);
 +            Query query = remoteQueryService.newQuery(queryString2[i]);
 +            resWithIndexRemote[i] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ "  remote region2 size of resultset: "+ resWithIndexRemote[i].size() + " for query: " + queryString2[i]);;
 +            checkForPdxString(resWithIndexRemote[i].asList(), queryString2[i]);
 +
 +           // to compare local query results with and without index
 +            LogWriterUtils.getLogWriter().info("### Executing Query on local for region2:" + queryString2[i]);
 +            query = localQueryService.newQuery(queryString2[i]);
 +            resWithIndexLocal[i] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ "  local region2 size of resultset: "+ resWithIndexLocal[i].size() + " for query: " + queryString2[i]);;
 +            checkForPdxString(resWithIndexLocal[i].asList(), queryString2[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString2[i], e);
 +          }
 +
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +                LogWriterUtils.getLogWriter().info("result0="+rs[0][0].asList());
 +                LogWriterUtils.getLogWriter().info("result1="+rs[0][1].asList());
 +               fail("Local and Remote Query Results are not matching for query :" + queryString[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, isPr);
 +            }
 +        }
 +        
 +          for (int i=0; i < queryString.length; i++){
 +            rs[0][0] = resWithoutIndexRemote[i]; 
 +            rs[0][1] = resWithIndexRemote[i];
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Results with and without index are not matching for query :" + queryString2[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, isPr);
 +            }
 +          }
 +          
 +          for (int i=0; i < queryString.length; i++){
 +            rs[0][0] = resWithoutIndexLocal[i]; 
 +            rs[0][1] = resWithIndexLocal[i];
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Results with and without index are not matching for query :" + queryString2[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, isPr);
 +            }
 +          }
 +       }
 +    };
 +    client.invoke(executeQueries);
 +
 +    // Put Non Pdx objects on server execute queries locally 
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +
 +        LogWriterUtils.getLogWriter().info("Put Objects locally on server");
 +        for (int i=numberOfEntries; i<numberOfEntries*2; i++) {
 +          region.put("key-"+i, new Portfolio(i));
 +         }
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("PR server local indexType:no  size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +          try{
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString2[i]).execute();
 +            LogWriterUtils.getLogWriter().info("PR server local indexType: no size of resultset: " + rs.size() + " for query: " + queryString2[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString2[i]);
 +          }catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString2[i], e);
 +          }
 +
 +        }
 +       }
 +    });
 +   
 +    // test for readSerialized flag
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService localQueryService = getCache().getQueryService();
 +       // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ " server local readSerializedTrue: indexType: no index size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    // test for readSerialized flag on client
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService  remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +        // Query server1 remotely to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) remoteQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server remote readSerializedTrue: indexType:no index size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +  
 +  public void testPartitionRegionCompactRangeIndex() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    final boolean isPr = true;
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +        // Verify the type of index created  
 +        Index index = null;
 +          try {
 +           index = localQueryService.createIndex("statusIndex", "status", regName);
 +             if(index instanceof PartitionedIndex){
 +               for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                 if(!(o instanceof CompactRangeIndex) ){
 +                   fail("CompactRangeIndex Index should have been created instead of "+ index.getClass());
 +                 }
 +               }
 +             }
 +             else{
 +               fail("Partitioned index expected");
 +             }
 +         } catch (Exception ex) {
 +           fail("Failed to create index." + ex.getMessage());
 +         }
 +       }
 +    });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new PortfolioPdx(i));
 +         }
 +      }
 +    });
 +    
 +    //Verify if all the index keys are PdxStrings
 +    server0.invoke(new CacheSerializableRunnable("Create Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        QueryService localQueryService = getCache().getQueryService();
 +         Index index = localQueryService.getIndex(region, "statusIndex");
 +            if(index instanceof PartitionedIndex){
 +              for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                CloseableIterator<IndexStoreEntry> iter = ((CompactRangeIndex) o)
 +                    .getIndexStorage().iterator(null);
 +                while (iter.hasNext()) {
 +                  Object key = iter.next().getDeserializedKey();
 +                  if (!(key instanceof PdxString)) {
 +                    fail("All keys of the CompactRangeIndex in the Partitioned index should be PdxStrings and not "
 +                        + key.getClass());
 +                  }
 +                }
 +              }
 +            }
 +            else{
 +              fail("Partitioned index expected");
 +            }
 +      }
 +    });
 + 
 +    // Execute queries from client to server and locally on client
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server:" + queryString[i]);
 +            Query query = remoteQueryService.newQuery(queryString[i]);
 +            rs[0][0] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR remote indexType:CompactRange size of resultset: "+ rs[0][0].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][0].asList(), queryString[i]);
 +           
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on client:" + queryString[i]);
 +            query = localQueryService.newQuery(queryString[i]);
 +            rs[0][1] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ "  client local indexType:CompactRange size of resultset: "+ rs[0][1].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][1].asList(), queryString[i]);
 + 
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +               fail("Local and Remote Query Results are not matching for query :" + queryString[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, isPr);
 +            }
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }       
 +     };
 +
 +    client.invoke(executeQueries);
 +    // Put Non Pdx objects on server execute queries locally 
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +
 +        LogWriterUtils.getLogWriter().info("Put Objects locally on server");
 +        for (int i=numberOfEntries; i<numberOfEntries*2; i++) {
 +          region.put("key-"+i, new Portfolio(i));
 +         }
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local indexType:Range  size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +       }
 +    });
 +    
 +    // test for readSerialized flag
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ " server local readSerializedTrue: indexType:CompactRange size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    // test for readSerialized flag on client
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService  remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +
 +        // Query server1 remotely to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) remoteQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server remote readSerializedTrue: indexType: indexType:CompactRange size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +  
 +  public void testPartitionRegionRangeIndex() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    final boolean isPr = true;
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +        // Verify the type of index created  
 +        Index index = null;
 +          try {
 +           index = localQueryService.createIndex("secIdIndex", "pos.secId", regName  + " p, p.positions.values pos");
 +            if(index instanceof PartitionedIndex){
 +               for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                 if(!(o instanceof RangeIndex) ){
 +                   fail("Range Index should have been created instead of "+ index.getClass());
 +                 }
 +               }
 +             }
 +             else{
 +               fail("Partitioned index expected");
 +             }
 +          } catch (Exception ex) {
 +             fail("Failed to create index." + ex.getMessage());
 +          }
 +        }
 +  });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        for (int i=0; i<numberOfEntries; i++) {
 +          region.put("key-"+i, new PortfolioPdx(i));
 +         }
 +      }
 +    });
 +    
 +    //Verify if all the index keys are PdxStrings
 +    server0.invoke(new CacheSerializableRunnable("Create Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        QueryService localQueryService = getCache().getQueryService();
 +        
 +          Index index = localQueryService.getIndex(region, "secIdIndex");
 +             if(index instanceof PartitionedIndex){
 +              for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                for(Object key: ((RangeIndex)o).getValueToEntriesMap().keySet()){
 +                  if(!(key instanceof PdxString)){
 +                    fail("All keys of the RangeIndex in the Partitioned index should be PdxStrings and not " + key.getClass());
 +                  }
 +                }
 +              }
 +            }
 +            else{
 +              fail("Partitioned index expected");
 +            }
 +      }
 +    });
 + 
 +    // Execute queries from client to server and locally on client
 +    SerializableRunnable executeQueries = new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 + 
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        for (int i=0; i < queryString.length; i++){
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query on remote server:" + queryString[i]);
 +            Query query = remoteQueryService.newQuery(queryString[i]);
 +            rs[0][0] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("RR remote indexType: Range size of resultset: "+ rs[0][0].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][0].asList(), queryString[i]);
 +                      
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on client:" + queryString[i]);
 +            query = localQueryService.newQuery(queryString[i]);
 +            rs[0][1] = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ "  client local indexType: Range size of resultset: "+ rs[0][1].size() + " for query: " + queryString[i]);;
 +            checkForPdxString(rs[0][1].asList(), queryString[i]);
 +                   
 +            if(i < orderByQueryIndex){
 +              // Compare local and remote query results.
 +              if (!compareResultsOfWithAndWithoutIndex(rs)){
 +                LogWriterUtils.getLogWriter().info("result0="+rs[0][0].asList());
 +                LogWriterUtils.getLogWriter().info("result1="+rs[0][1].asList());
 +               fail("Local and Remote Query Results are not matching for query :" + queryString[i]);  
 +              }
 +            }
 +            else{
 +              //compare the order of results returned 
 +              compareResultsOrder(rs, isPr);
 +            }
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +       }
 +    };
 +
 +    client.invoke(executeQueries);
 +
 +    // Put Non Pdx objects on server execute queries locally 
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +
 +        LogWriterUtils.getLogWriter().info("Put Objects locally on server");
 +        for (int i=numberOfEntries; i<numberOfEntries*2; i++) {
 +          region.put("key-"+i, new Portfolio(i));
 +         }
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server local indexType:Range  size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +       }
 +    });
 +    
 +    // test for readSerialized flag
 +    server0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService localQueryService = getCache().getQueryService();
 +
 +        // Query server1 locally to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) localQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("isPR: " + isPr+ " server local readSerializedTrue: indexType: Range size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    // test for readSerialized flag on client
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
 +        cache.setReadSerialized(true);
 +        QueryService  remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +
 +        // Query server1 remotely to check if PdxString is not being returned
 +        for (int i = 0; i < queryString.length; i++) {
 +          try {
 +            LogWriterUtils.getLogWriter().info("### Executing Query locally on server:" + queryString[i]);
 +            SelectResults rs = (SelectResults) remoteQueryService.newQuery(queryString[i]).execute();
 +            LogWriterUtils.getLogWriter().info("RR server remote readSerializedTrue: indexType: Range size of resultset: " + rs.size() + " for query: " + queryString[i]);
 +            // The results should not be PdxString
 +            checkForPdxString(rs.asList(), queryString[i]);
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + queryString[i], e);
 +          }
 +        }
 +      }
 +    });
 +    
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +
 +  public void testNullPdxString() throws CacheException {
 +    final Host host = Host.getHost(0);
 +    VM server0 = host.getVM(0);
 +    VM server1 = host.getVM(1);
 +    VM server2 = host.getVM(2);
 +    VM client = host.getVM(3);
 +    final int numberOfEntries = 10;
 +    final boolean isPr = true;
 +    // Start server1 and create index
 +    server0.invoke(new CacheSerializableRunnable("Create Server1") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false,false);
 +        // create a local query service
 +        QueryService localQueryService = null;
 +        try {
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        } 
 +        // Verify the type of index created  
 +        Index index = null;
 +          try {
 +           index = localQueryService.createIndex("statusIndex", "status", regName);
 +             if(index instanceof PartitionedIndex){
 +               for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                 if(!(o instanceof CompactRangeIndex) ){
 +                   fail("CompactRangeIndex Index should have been created instead of "+ index.getClass());
 +                 }
 +               }
 +             }
 +             else{
 +               fail("Partitioned index expected");
 +             }
 +         } catch (Exception ex) {
 +           fail("Failed to create index." + ex.getMessage());
 +         }
 +       }
 +    });
 +
 +    // Start server2
 +    server1.invoke(new CacheSerializableRunnable("Create Server2") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +    
 +    // Start server3
 +    server2.invoke(new CacheSerializableRunnable("Create Server3") {
 +      public void run2() throws CacheException {
 +        configAndStartBridgeServer(isPr,false, false);
 +        Region region = getRootRegion().getSubregion(regionName);
 +      }
 +    });
 +
 +    // Client pool.
-     final int port0 = server0.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port1 = server1.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
-     final int port2 = server2.invokeInt(PdxStringQueryDUnitTest.class, "getCacheServerPort");
++    final int port0 = server0.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port1 = server1.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
++    final int port2 = server2.invoke(() -> PdxStringQueryDUnitTest.getCacheServerPort());
 +
 +    final String host0 = NetworkUtils.getServerHostName(server0.getHost());
 +
 +    // Create client pool.
 +    final String poolName = "testClientServerQueryPool"; 
 +    createPool(client, poolName, new String[]{host0}, new int[]{port0, port1, port2}, true);
 +
 +    // Create client region and put PortfolioPdx objects (PdxInstances)
 +    client.invoke(new CacheSerializableRunnable("Create client") {
 +      public void run2() throws CacheException {
 +        AttributesFactory factory = new AttributesFactory();
 +        factory.setScope(Scope.LOCAL);
 +        ClientServerTestCase.configureConnectionPool(factory, host0, port1,-1, true, -1, -1, null);
 +        Region region = createRegion(regionName, rootRegionName,  factory.create());
 +      
 +        LogWriterUtils.getLogWriter().info("Put PortfolioPdx");
 +        // Put some PortfolioPdx objects with null Status and secIds 
 +        for (int i=0; i<numberOfEntries*2; i++) {
 +          PortfolioPdx portfolioPdx = new PortfolioPdx(i);
 +          portfolioPdx.status = null; // this will create NULL PdxStrings
 +          portfolioPdx.positions = new HashMap();
 +          portfolioPdx.positions.put(null, new PositionPdx(null, PositionPdx.cnt * 1000));
 +          region.put("key-"+i, portfolioPdx);
 +         }
 +        // Put some PortfolioPdx with non null status to reproduce bug#45351
 +        for (int i=0; i<numberOfEntries; i++) {
 +          PortfolioPdx portfolioPdx = new PortfolioPdx(i);
 +          region.put("key-"+i, portfolioPdx);
 +         }
 +      }
 +    });
 +    
 +    //Verify if all the index keys are PdxStrings
 +    server0.invoke(new CacheSerializableRunnable("Create Server") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion().getSubregion(regionName);
 +        QueryService localQueryService = getCache().getQueryService();
 +         Index index = localQueryService.getIndex(region, "statusIndex");
 +             if(index instanceof PartitionedIndex){
 +              for(Object o : ((PartitionedIndex)index).getBucketIndexes()){
 +                CloseableIterator<IndexStoreEntry> iter = ((CompactRangeIndex) o).getIndexStorage().iterator(null);
 +                while (iter.hasNext()) {
 +                  Object key = iter.next().getDeserializedKey();
 +                  if (!(key instanceof PdxString) && !(key == IndexManager.NULL)) {
 +                    fail("All keys of the CompactRangeIndex in the Partitioned index should be PdxStrings and not "
 +                        + key.getClass());
 +                  }
 +                }
 +              }
 +            }
 +            else{
 +              fail("Partitioned index expected");
 +            }
 +       }
 +    });
 + 
 +    // Execute queries from client to server and locally on client
 +    client.invoke( new CacheSerializableRunnable("Execute queries") {
 +      public void run2() throws CacheException {
 +        QueryService remoteQueryService = null;
 +        QueryService localQueryService = null;
 +        SelectResults[][] rs = new SelectResults[1][2];
 +
 +        try {
 +          remoteQueryService = (PoolManager.find(poolName)).getQueryService();
 +          localQueryService = getCache().getQueryService();
 +        } catch (Exception e) {
 +          Assert.fail("Failed to get QueryService.", e);
 +        }
 +        
 +        // Querying the fields with null values
 +        String[] qs = {"SELECT pos.secId FROM " + regName + "  p, p.positions.values pos where p.status = null",
 +                      "SELECT p.pkid FROM " + regName + "  p, p.positions.values pos where pos.secId = null"};
 +        
 +        for(int i = 0; i <2; i++){
 +          try {
 +            Query query = remoteQueryService.newQuery(qs[i]);
 +            SelectResults res = (SelectResults)query.execute();
 +            LogWriterUtils.getLogWriter().info("PR NULL Pdxstring test size of resultset: "+ res.size() + " for query: " + qs[i]);;
 +            if(i == 0){
 +              for(Object o : res){
 +                if(o != null){
 +                  fail("Query : " + qs[i] + " should have returned null and not " + o);
 +                }
 +              }
 +            }else{
 +              checkForPdxString(res.asList(), qs[i]);
 +            }
 +          } catch (Exception e) {
 +            Assert.fail("Failed executing " + qs[i], e);
 +          }
 +        }
 +      }
 +     });
 + 
 +    this.closeClient(server2);
 +    this.closeClient(client);
 +    this.closeClient(server1);
 +    this.closeClient(server0);
 +  }
 +  
 + 
 +    private void compareResultsOrder(SelectResults[][] r, boolean isPr){
 +    for (int j = 0; j < r.length; j++) {
 +      Object []r1 = (r[j][0]).toArray();
 +      Object []r2 = (r[j][1]).toArray();
 +      if(r1.length != r2.length){
 +        fail("Size of results not equal: " + r1.length + " vs " + r2.length);
 +      }
 +      for (int i = 0, k=0; i < r1.length && k < r2.length; i++,k++) {
 +        System.out.println("r1: " + r1[i] +  " r2: " + r2[k]);
 +        if(!r1[i].equals(r2[k])){
 +          fail("Order not equal: " + r1[i] + " : " +r2[k] + " isPR: " + isPr );
 +        }
 +      }
 +    }
 +  }
 +  
 +  private void checkForPdxString(List results, String query) {
 +    boolean isGroupByQuery = false;
 +    for (int i : groupByQueryIndex) {
 +      if (query.equals(queryString[i]) || query.equals(queryString2[i])) {
 +        isGroupByQuery = true;
 +        break;
 +      }
 +    }
 +    for (Object o : results) {
 +      if (o instanceof Struct) {
 +        if (!isGroupByQuery) {
 +          Object o1 = ((Struct) o).getFieldValues()[0];
 +          Object o2 = ((Struct) o).getFieldValues()[1];
 +          if (!(o1 instanceof String)) {
 +            fail("Returned instance of " + o1.getClass()
 +                + " instead of String for query: " + query);
 +          }
 +
 +          if (!(o2 instanceof String)) {
 +            fail("Returned instance of " + o2.getClass()
 +                + " instead of String for query: " + query);
 +          }
 +        }
 +      } else {
 +        if (!isGroupByQuery) {
 +          if (!(o instanceof String)) {
 +            fail("Returned instance of " + o.getClass()
 +                + " instead of String for query: " + query);
 +          }
 +        }
 +      }
 +    }
 +  }
 +
 +  public boolean compareResultsOfWithAndWithoutIndex(SelectResults[][] r ) { 
 +    boolean ok = true; 
 +    Set set1 = null; 
 +    Set set2 = null; 
 +    Iterator itert1 = null; 
 +    Iterator itert2 = null; 
 +    ObjectType type1, type2; 
 +    outer:  for (int j = 0; j < r.length; j++) { 
 +      CollectionType collType1 = r[j][0].getCollectionType(); 
 +      CollectionType collType2 = r[j][1].getCollectionType(); 
 +      type1 = collType1.getElementType(); 
 +      type2 = collType2.getElementType(); 
 +    
 +        if (r[j][0].size() == r[j][1].size()) { 
 +        System.out.println("Both SelectResults are of Same

<TRUNCATED>

[034/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerImpl.java
index cd4f3e4,0000000..000120b
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerImpl.java
@@@ -1,821 -1,0 +1,832 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.File;
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.HashSet;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Set;
 +import java.util.concurrent.atomic.AtomicInteger;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelCriterion;
 +import com.gemstone.gemfire.GemFireIOException;
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.InvalidValueException;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.ClientSession;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.DiskStore;
 +import com.gemstone.gemfire.cache.DiskStoreFactory;
 +import com.gemstone.gemfire.cache.DynamicRegionFactory;
 +import com.gemstone.gemfire.cache.EvictionAction;
 +import com.gemstone.gemfire.cache.ExpirationAction;
 +import com.gemstone.gemfire.cache.ExpirationAttributes;
 +import com.gemstone.gemfire.cache.InterestRegistrationListener;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionExistsException;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig;
 +import com.gemstone.gemfire.cache.server.ServerLoadProbe;
 +import com.gemstone.gemfire.cache.server.internal.LoadMonitor;
 +import com.gemstone.gemfire.cache.wan.GatewayTransportFilter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.DM;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisee;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor;
 +import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.ResourceEvent;
 +import com.gemstone.gemfire.distributed.internal.ServerLocation;
 +import com.gemstone.gemfire.distributed.internal.membership.MemberAttributes;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.OSProcess;
 +import com.gemstone.gemfire.internal.admin.ClientHealthMonitoringRegion;
 +import com.gemstone.gemfire.internal.cache.CacheServerAdvisor.CacheServerProfile;
 +import com.gemstone.gemfire.internal.cache.ha.HARegionQueue;
 +import com.gemstone.gemfire.internal.cache.tier.Acceptor;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientNotifier;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.management.membership.ClientMembership;
 +import com.gemstone.gemfire.management.membership.ClientMembershipListener;
 +
 +/**
 + * An implementation of the <code>CacheServer</code> interface that delegates
 + * most of the heavy lifting to an {@link Acceptor}.
 + * 
 + * @author David Whitlock
 + * @since 4.0
 + */
 +@SuppressWarnings("deprecation")
 +public class CacheServerImpl
 +  extends AbstractCacheServer
 +  implements DistributionAdvisee {
 +
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  private static final int FORCE_LOAD_UPDATE_FREQUENCY= Integer.getInteger("gemfire.BridgeServer.FORCE_LOAD_UPDATE_FREQUENCY", 10).intValue();
 +  
 +  /** The acceptor that does the actual serving */
 +  private volatile AcceptorImpl acceptor;
 +
 +  /**
 +   * The advisor used by this cache server.
 +   * @since 5.7
 +   */
 +  private volatile CacheServerAdvisor advisor;
 +
 +  /**
 +   * The monitor used to monitor load on this
 +   * bridge server and distribute load to the locators
 +   * @since 5.7
 +   */
 +  private volatile LoadMonitor loadMonitor;
 +
 +  /**
 +   * boolean that represents whether this server is a GatewayReceiver or a simple BridgeServer
 +   */
 +  private boolean isGatewayReceiver;
 +  
 +  private List<GatewayTransportFilter> gatewayTransportFilters = Collections.EMPTY_LIST;
 +  
++  /** is this a server created by a launcher as opposed to by an application or XML? */
++  private boolean isDefaultServer;
++  
 +  /**
 +   * Needed because this guy is an advisee
 +   * @since 5.7
 +   */
 +  private int serialNumber; // changed on each start
 +
 +  public static final boolean ENABLE_NOTIFY_BY_SUBSCRIPTION_FALSE = 
 +  Boolean.getBoolean("gemfire.cache-server.enable-notify-by-subscription-false");
 +  
 + 
 +  // ////////////////////// Constructors //////////////////////
 +
 +  /**
 +   * Creates a new <code>BridgeServerImpl</code> that serves the contents of
 +   * the give <code>Cache</code>. It has the default configuration.
 +   */
 +  public CacheServerImpl(GemFireCacheImpl cache, boolean isGatewayReceiver) {
 +    super(cache);
 +    this.isGatewayReceiver = isGatewayReceiver;
 +  }
 +
 +  // //////////////////// Instance Methods ///////////////////
 +  
 +  public CancelCriterion getCancelCriterion() {
 +    return cache.getCancelCriterion();    
 +  }
 +
 +  /**
 +   * Checks to see whether or not this bridge server is running. If so, an
 +   * {@link IllegalStateException} is thrown.
 +   */
 +  private void checkRunning() {
 +    if (this.isRunning()) {
 +      throw new IllegalStateException(LocalizedStrings.CacheServerImpl_A_CACHE_SERVERS_CONFIGURATION_CANNOT_BE_CHANGED_ONCE_IT_IS_RUNNING.toLocalizedString());
 +    }
 +  }
 +
 +  public boolean isGatewayReceiver() {
 +    return this.isGatewayReceiver;
 +  }
 +  
 +  @Override
 +  public int getPort() {
 +    if (this.acceptor != null) {
 +      return this.acceptor.getPort();
 +    }
 +    else {
 +      return super.getPort();
 +    }
 +  }
 +
 +  @Override
 +  public void setPort(int port) {
 +    checkRunning();
 +    super.setPort(port);
 +  }
 +
 +  @Override
 +  public void setBindAddress(String address) {
 +    checkRunning();
 +    super.setBindAddress(address);
 +  }
 +  @Override
 +  public void setHostnameForClients(String name) {
 +    checkRunning();
 +    super.setHostnameForClients(name);
 +  }
 +
 +  @Override
 +  public void setMaxConnections(int maxCon) {
 +    checkRunning();
 +    super.setMaxConnections(maxCon);
 +  }
 +
 +  @Override
 +  public void setMaxThreads(int maxThreads) {
 +    checkRunning();
 +    super.setMaxThreads(maxThreads);
 +  }
 +
 +  @Override
 +  public void setNotifyBySubscription(boolean b) {
 +    checkRunning();
 +    if (CacheServerImpl.ENABLE_NOTIFY_BY_SUBSCRIPTION_FALSE) {
 +      this.notifyBySubscription = b;
 +    }
 +  }
 +
 +  @Override
 +  public void setMaximumMessageCount(int maximumMessageCount) {
 +    checkRunning();
 +    super.setMaximumMessageCount(maximumMessageCount);
 +  }
 +
 +  @Override
 +  public void setSocketBufferSize(int socketBufferSize) {
 +    this.socketBufferSize = socketBufferSize;
 +  }
 +
 +  @Override
 +  public int getSocketBufferSize() {
 +    return this.socketBufferSize;
 +  }
 +  
 +  @Override
 +  public void setMaximumTimeBetweenPings(int maximumTimeBetweenPings) {
 +    this.maximumTimeBetweenPings = maximumTimeBetweenPings;
 +  }
 +
 +  @Override
 +  public int getMaximumTimeBetweenPings() {
 +    return this.maximumTimeBetweenPings;
 +  }
 +
 +
 +  @Override
 +  public void setLoadPollInterval(long loadPollInterval) {
 +    checkRunning();
 +    super.setLoadPollInterval(loadPollInterval);
 +  }
 +
 +  @Override
 +  public int getMaximumMessageCount() {
 +    return this.maximumMessageCount;
 +  }
 +
 +  @Override
 +  public void setLoadProbe(ServerLoadProbe loadProbe) {
 +    checkRunning();
 +    super.setLoadProbe(loadProbe);
 +  }
 +
 +  public void setGatewayTransportFilter(
 +      List<GatewayTransportFilter> transportFilters) {
 +    this.gatewayTransportFilters = transportFilters;
 +  }
 +  
 +  @Override
 +  public int getMessageTimeToLive() {
 +    return this.messageTimeToLive;
 +  }
 +  
 +
 +  public ClientSubscriptionConfig getClientSubscriptionConfig(){
 +    return this.clientSubscriptionConfig;
 +  }
 +
++  public boolean isDefaultServer() {
++    return isDefaultServer;
++  }
++
++  public void setIsDefaultServer() {
++    this.isDefaultServer = true;
++  }
++
 +  /**
 +   * Sets the configuration of <b>this</b> <code>CacheServer</code> based on
 +   * the configuration of <b>another</b> <code>CacheServer</code>.
 +   */
 +  public void configureFrom(CacheServer other) {
 +    setPort(other.getPort());
 +    setBindAddress(other.getBindAddress());
 +    setHostnameForClients(other.getHostnameForClients());
 +    setMaxConnections(other.getMaxConnections());
 +    setMaxThreads(other.getMaxThreads());
 +    setNotifyBySubscription(other.getNotifyBySubscription());
 +    setSocketBufferSize(other.getSocketBufferSize());
 +    setTcpNoDelay(other.getTcpNoDelay());
 +    setMaximumTimeBetweenPings(other.getMaximumTimeBetweenPings());
 +    setMaximumMessageCount(other.getMaximumMessageCount());
 +    setMessageTimeToLive(other.getMessageTimeToLive());
 +//    setTransactionTimeToLive(other.getTransactionTimeToLive());  not implemented in CacheServer for v6.6
 +    setGroups(other.getGroups());
 +    setLoadProbe(other.getLoadProbe());
 +    setLoadPollInterval(other.getLoadPollInterval());
 +    ClientSubscriptionConfig cscOther = other.getClientSubscriptionConfig();
 +    ClientSubscriptionConfig cscThis = this.getClientSubscriptionConfig();
 +    // added for configuration of ha overflow
 +    cscThis.setEvictionPolicy(cscOther.getEvictionPolicy());
 +    cscThis.setCapacity(cscOther.getCapacity());
 +    String diskStoreName = cscOther.getDiskStoreName();
 +    if (diskStoreName != null) {
 +      cscThis.setDiskStoreName(diskStoreName);
 +    } else {
 +      cscThis.setOverflowDirectory(cscOther.getOverflowDirectory());
 +    }
 +  }
 +
 +  @Override
 +  public synchronized void start() throws IOException {
 +    Assert.assertTrue(this.cache != null);
 +    boolean isSqlFabricSystem = ((GemFireCacheImpl)this.cache).isSqlfSystem();
 +    
 +    this.serialNumber = createSerialNumber();
 +    if (DynamicRegionFactory.get().isOpen()) {
 +      // force notifyBySubscription to be true so that meta info is pushed
 +      // from servers to clients instead of invalidates.
 +      if (!this.notifyBySubscription) {
 +        logger.info(LocalizedMessage.create(LocalizedStrings.CacheServerImpl_FORCING_NOTIFYBYSUBSCRIPTION_TO_SUPPORT_DYNAMIC_REGIONS));
 +        this.notifyBySubscription = true;
 +      }
 +    }
 +    this.advisor = CacheServerAdvisor.createCacheServerAdvisor(this);
 +    this.loadMonitor = new LoadMonitor(loadProbe, maxConnections,
 +        loadPollInterval, FORCE_LOAD_UPDATE_FREQUENCY, 
 +        advisor);
 +    List overflowAttributesList = new LinkedList();
 +    ClientSubscriptionConfig csc = this.getClientSubscriptionConfig();
 +    overflowAttributesList.add(0, csc.getEvictionPolicy());
 +    overflowAttributesList.add(1, Integer.valueOf(csc.getCapacity()));
 +    overflowAttributesList.add(2, Integer.valueOf(this.port));
 +    String diskStoreName = csc.getDiskStoreName();
 +    if (diskStoreName != null) {
 +      overflowAttributesList.add(3, diskStoreName);
 +      overflowAttributesList.add(4, true); // indicator to use diskstore
 +    } else {
 +      overflowAttributesList.add(3, csc.getOverflowDirectory());
 +      overflowAttributesList.add(4, false);
 +    }
 +
 +    this.acceptor = new AcceptorImpl(getPort(), 
 +                                     getBindAddress(),
 +                                     getNotifyBySubscription(),
 +                                     getSocketBufferSize(), 
 +                                     getMaximumTimeBetweenPings(), 
 +                                     this.cache,
 +                                     getMaxConnections(), 
 +                                     getMaxThreads(), 
 +                                     getMaximumMessageCount(),
 +                                     getMessageTimeToLive(),
 +                                     getTransactionTimeToLive(),
 +                                     this.loadMonitor,
 +                                     overflowAttributesList, 
 +                                     isSqlFabricSystem,
 +                                     this.isGatewayReceiver,
 +                                     this.gatewayTransportFilters, this.tcpNoDelay);
 +
 +    this.acceptor.start();
 +    this.advisor.handshake();
 +    this.loadMonitor.start(new ServerLocation(getExternalAddress(),
 +        getPort()), acceptor.getStats());
 +    
 +    // TODO : Need to provide facility to enable/disable client health monitoring.
 +    //Creating ClientHealthMonitoring region.
 +    // Force initialization on current cache
 +    if(cache instanceof GemFireCacheImpl) {
 +      ClientHealthMonitoringRegion.getInstance((GemFireCacheImpl)cache);
 +    }
 +    this.cache.getLoggerI18n().config(LocalizedStrings.CacheServerImpl_CACHESERVER_CONFIGURATION___0, getConfig());
 +    
 +    /* 
 +     * If the stopped bridge server is restarted, we'll need to re-register the 
 +     * client membership listener. If the listener is already registered it 
 +     * won't be registered as would the case when start() is invoked for the 
 +     * first time.  
 +     */
 +    ClientMembershipListener[] membershipListeners = 
 +                                ClientMembership.getClientMembershipListeners();
 +    
 +    boolean membershipListenerRegistered = false;
 +    for (ClientMembershipListener membershipListener : membershipListeners) {
 +      //just checking by reference as the listener instance is final
 +      if (listener == membershipListener) {
 +        membershipListenerRegistered = true;
 +        break;
 +      }
 +    }
 +    
 +    if (!membershipListenerRegistered) {
 +      ClientMembership.registerClientMembershipListener(listener);
 +    }
 +    
 +    if (!isGatewayReceiver) {
 +      InternalDistributedSystem system = ((GemFireCacheImpl) this.cache)
 +          .getDistributedSystem();
 +      system.handleResourceEvent(ResourceEvent.CACHE_SERVER_START, this);
 +    }
 +    
 +  }
 +
 +  
 +  /**
 +   * Gets the address that this bridge server can be contacted on from external
 +   * processes.
 +   * @since 5.7
 +   */
 +  public String getExternalAddress() {
 +    return getExternalAddress(true);
 +  }
 +  
 +  public String getExternalAddress(boolean checkServerRunning) {
 +    if (checkServerRunning) {
 +      if (!this.isRunning()) {
 +        String s = "A bridge server's bind address is only available if it has been started";
 +        this.cache.getCancelCriterion().checkCancelInProgress(null);
 +        throw new IllegalStateException(s);
 +      }
 +    }
 +    if (this.hostnameForClients == null || this.hostnameForClients.equals("")) {
 +      if (this.acceptor != null) {
 +        return this.acceptor.getExternalAddress();
 +      }
 +      else {
 +        return null;
 +      }
 +    }
 +    else {
 +      return this.hostnameForClients;
 +    }
 +  }
 +
 +  public boolean isRunning() {
 +    return this.acceptor != null && this.acceptor.isRunning();
 +  }
 +
 +  public synchronized void stop() {
 +    if (!isRunning()) {
 +      return;
 +    }
 +    
 +    RuntimeException firstException = null;
 +    
 +    try {
 +      if(this.loadMonitor != null) {
 +        this.loadMonitor.stop();
 +      }
 +    } catch(RuntimeException e) {
 +      cache.getLoggerI18n().warning(LocalizedStrings.CacheServerImpl_CACHESERVER_ERROR_CLOSING_LOAD_MONITOR, e);
 +      firstException = e;
 +    }
 +    
 +    try {
 +      if (this.advisor != null) {
 +        this.advisor.close();
 +      }
 +    } catch(RuntimeException e) {
 +      cache.getLoggerI18n().warning(LocalizedStrings.CacheServerImpl_CACHESERVER_ERROR_CLOSING_ADVISOR, e);
 +      firstException = e;
 +    } 
 +    
 +    try {
 +      if (this.acceptor != null) {
 +        this.acceptor.close();
 +      }
 +    } catch(RuntimeException e) {
 +      logger.warn(LocalizedMessage.create(LocalizedStrings.CacheServerImpl_CACHESERVER_ERROR_CLOSING_ACCEPTOR_MONITOR), e);
 +      if (firstException != null) {
 +        firstException = e;
 +      }
 +    }
 +    
 +    if(firstException != null) {
 +      throw firstException;
 +    }
 +    
 +    //TODO : We need to clean up the admin region created for client
 +    //monitoring.
 +    
 +    // BridgeServer is still available, just not running, so we don't take
 +    // it out of the cache's list...
 +    // cache.removeBridgeServer(this);
 +
 +    /* Assuming start won't be called after stop */
 +    ClientMembership.unregisterClientMembershipListener(listener);
 +    
 +    TXManagerImpl txMgr = (TXManagerImpl) cache.getCacheTransactionManager();
 +    txMgr.removeHostedTXStatesForClients();
 +    
 +    if (!isGatewayReceiver) {
 +      InternalDistributedSystem system = ((GemFireCacheImpl) this.cache)
 +          .getDistributedSystem();
 +      system.handleResourceEvent(ResourceEvent.CACHE_SERVER_STOP, this);
 +    }
 +
 +  }
 +
 +  private String getConfig() {
 +    ClientSubscriptionConfig csc = this.getClientSubscriptionConfig();
 +    String str =
 +    "port=" + getPort() + " max-connections=" + getMaxConnections()
 +        + " max-threads=" + getMaxThreads() + " notify-by-subscription="
 +        + getNotifyBySubscription() + " socket-buffer-size="
 +        + getSocketBufferSize() + " maximum-time-between-pings="
 +        + getMaximumTimeBetweenPings() + " maximum-message-count="
 +        + getMaximumMessageCount() + " message-time-to-live="
 +        + getMessageTimeToLive() + " eviction-policy=" + csc.getEvictionPolicy()
 +        + " capacity=" + csc.getCapacity() + " overflow directory=";
 +    if (csc.getDiskStoreName() != null) {
 +      str += csc.getDiskStoreName();
 +    } else {
 +      str += csc.getOverflowDirectory(); 
 +    }
 +    str += 
 +        " groups=" + Arrays.asList(getGroups())
 +        + " loadProbe=" + loadProbe
 +        + " loadPollInterval=" + loadPollInterval
 +        + " tcpNoDelay=" + tcpNoDelay;
 +    return str;
 +  }
 +
 +  @Override
 +  public String toString() {
 +    ClientSubscriptionConfig csc = this.getClientSubscriptionConfig();
 +    String str = 
 +    "CacheServer on port=" + getPort() + " client subscription config policy="
 +        + csc.getEvictionPolicy() + " client subscription config capacity="
 +        + csc.getCapacity();
 +    if (csc.getDiskStoreName() != null) {
 +      str += " client subscription config overflow disk store="
 +        + csc.getDiskStoreName();
 +    } else {
 +      str += " client subscription config overflow directory="
 +        + csc.getOverflowDirectory();
 +    }
 +    return str;
 +  }
 +
 +  /**
 +   * Test method used to access the internal acceptor
 +   * 
 +   * @return the internal acceptor
 +   */
 +  public AcceptorImpl getAcceptor() {
 +    return this.acceptor;
 +  }
 +
 +  // DistributionAdvisee methods
 +
 +  public DM getDistributionManager() {
 +    return getSystem().getDistributionManager();
 +  }
 +  
 +  public ClientSession getClientSession(String durableClientId) {
 +    return getCacheClientNotifier().getClientProxy(durableClientId);
 +  }
 +
 +  public ClientSession getClientSession(DistributedMember member) {
 +    return getCacheClientNotifier().getClientProxy(
 +        ClientProxyMembershipID.getClientId(member));
 +  }
 +  
 +  public Set getAllClientSessions() {
 +    return new HashSet(getCacheClientNotifier().getClientProxies());
 +  }
 +
 +  /**
 +   * create client subscription
 +   * 
 +   * @param cache
 +   * @param ePolicy
 +   * @param capacity
 +   * @param port
 +   * @param overFlowDir
 +   * @param isDiskStore
 +   * @return client subscription name
 +   * @since 5.7
 +   */
 +  public static String clientMessagesRegion(GemFireCacheImpl cache, String ePolicy,
 +      int capacity, int port, String overFlowDir, boolean isDiskStore) {
 +    AttributesFactory factory = getAttribFactoryForClientMessagesRegion(cache, 
 +        ePolicy, capacity, overFlowDir, isDiskStore);
 +    RegionAttributes attr = factory.create();
 +
 +    return createClientMessagesRegion(attr, cache, capacity, port);
 +  }
 +
 +  public static AttributesFactory getAttribFactoryForClientMessagesRegion(
 +      GemFireCacheImpl cache,
 +      String ePolicy, int capacity, String overflowDir, boolean isDiskStore)
 +      throws InvalidValueException, GemFireIOException {
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.LOCAL);
 +
 +    if (isDiskStore) {
 +      // overflowDir parameter is actually diskstore name
 +      factory.setDiskStoreName(overflowDir);
 +      // client subscription queue is always overflow to disk, so do async
 +      // see feature request #41479
 +      factory.setDiskSynchronous(true);
 +    } else if  (overflowDir == null || overflowDir.equals(ClientSubscriptionConfig.DEFAULT_OVERFLOW_DIRECTORY)) {
 +      factory.setDiskStoreName(null);
 +      // client subscription queue is always overflow to disk, so do async
 +      // see feature request #41479
 +      factory.setDiskSynchronous(true);
 +    } else {
 +      File dir = new File(overflowDir + File.separatorChar
 +          + generateNameForClientMsgsRegion(OSProcess.getId()));
 +      // This will delete the overflow directory when virtual machine terminates.
 +      dir.deleteOnExit();
 +      if (!dir.mkdirs() && !dir.isDirectory()) {
 +        throw new GemFireIOException("Could not create client subscription overflow directory: "
 +            + dir.getAbsolutePath());
 +      }
 +      File[] dirs = { dir };
 +      DiskStoreFactory dsf = cache.createDiskStoreFactory();
 +      DiskStore bsi = dsf.setAutoCompact(true)
 +      .setDiskDirsAndSizes(dirs, new int[] { Integer.MAX_VALUE })
 +      .create("bsi");
 +      factory.setDiskStoreName("bsi");
 +      // backward compatibility, it was sync
 +      factory.setDiskSynchronous(true);
 +    }
 +    factory.setDataPolicy(DataPolicy.NORMAL);
 +    // enable statistics
 +    factory.setStatisticsEnabled(true);
 +    /* setting LIFO related eviction attributes */
 +    if (HARegionQueue.HA_EVICTION_POLICY_ENTRY.equals(ePolicy)) {
 +      factory
 +          .setEvictionAttributes(EvictionAttributesImpl.createLIFOEntryAttributes(
 +              capacity, EvictionAction.OVERFLOW_TO_DISK));
 +    }
 +    else if (HARegionQueue.HA_EVICTION_POLICY_MEMORY.equals(ePolicy)) { // condition refinement
 +      factory
 +          .setEvictionAttributes(EvictionAttributesImpl.createLIFOMemoryAttributes(
 +              capacity, EvictionAction.OVERFLOW_TO_DISK));
 +    }
 +    else {
 +      // throw invalid eviction policy exception
 +      throw new InvalidValueException(
 +        LocalizedStrings.CacheServerImpl__0_INVALID_EVICTION_POLICY.toLocalizedString(ePolicy));
 +    }
 +    return factory;
 +  }
 +
 +  public static String createClientMessagesRegion(RegionAttributes attr,
 +      GemFireCacheImpl cache, int capacity, int port) {
 +    // generating unique name in VM for ClientMessagesRegion
 +    String regionName = generateNameForClientMsgsRegion(port);
 +    try {
 +      cache.createVMRegion(regionName, attr,
 +          new InternalRegionArguments().setDestroyLockFlag(true)
 +              .setRecreateFlag(false).setSnapshotInputStream(null)
 +              .setImageTarget(null).setIsUsedForMetaRegion(true));
 +    }
 +    catch (RegionExistsException ree) {
 +      InternalGemFireError assErr = new InternalGemFireError(
 +          "unexpected exception");
 +      assErr.initCause(ree);
 +      throw assErr;
 +    }
 +    catch (IOException e) {
 +      // only if loading snapshot, not here
 +      InternalGemFireError assErr = new InternalGemFireError(
 +          "unexpected exception");
 +      assErr.initCause(e);
 +      throw assErr;
 +    }
 +    catch (ClassNotFoundException e) {
 +      // only if loading snapshot, not here
 +      InternalGemFireError assErr = new InternalGemFireError(
 +          "unexpected exception");
 +      assErr.initCause(e);
 +      throw assErr;
 +    }
 +    return regionName;
 +  }
 +
 +  public static String createClientMessagesRegionForTesting(GemFireCacheImpl cache,
 +      String ePolicy, int capacity, int port, int expiryTime, String overFlowDir, boolean isDiskStore) {
 +    AttributesFactory factory = getAttribFactoryForClientMessagesRegion(cache, 
 +        ePolicy, capacity, overFlowDir, isDiskStore);
 +    ExpirationAttributes ea = new ExpirationAttributes(expiryTime,
 +        ExpirationAction.LOCAL_INVALIDATE);
 +    factory.setEntryTimeToLive(ea);
 +    RegionAttributes attr = factory.create();
 +
 +    return createClientMessagesRegion(attr, cache, capacity, port);
 +  }
 +
 +  /**
 +   * Generates the name for the client subscription using the given id.
 +   * 
 +   * @param id
 +   * @return String
 +   * @since 5.7 
 +   */
 +  public static String generateNameForClientMsgsRegion(int id) {
 +    return ClientSubscriptionConfigImpl.CLIENT_SUBSCRIPTION + "_" + id;
 +  }
 +
 +  /*
 +   * Marker class name to identify the lock more easily in thread dumps private
 +   * static class ClientMessagesRegionLock extends Object { }
 +   */
 +  public DistributionAdvisor getDistributionAdvisor() {
 +    return this.advisor;
 +  }
 +  
 +  /**
 +   * Returns the BridgeServerAdvisor for this server
 +   */
 +  public CacheServerAdvisor getCacheServerAdvisor() {
 +    return this.advisor;
 +  }
 +  
 +  public Profile getProfile() {
 +    return getDistributionAdvisor().createProfile();
 +  }
 +  
 +  public DistributionAdvisee getParentAdvisee() {
 +    return null;
 +  }
 +  
 +  /**
 +   * Returns the underlying <code>InternalDistributedSystem</code> connection.
 +   * @return the underlying <code>InternalDistributedSystem</code>
 +   */
 +  public InternalDistributedSystem getSystem() {
 +    return (InternalDistributedSystem)this.cache.getDistributedSystem();
 +  }
 +  
 +  public String getName() {
 +    return "CacheServer";
 +  }
 +  
 +  public String getFullPath() {
 +    return getName();
 +  }
 +
 +  private final static AtomicInteger profileSN = new AtomicInteger();
 +  
 +  private static int createSerialNumber() {
 +    return profileSN.incrementAndGet();
 +  }
 +
 +  /**
 +   * Returns an array of all the groups of this bridge server.
 +   * This includes those from the groups gemfire property
 +   * and those explicitly added to this server.
 +   */
 +  public String[] getCombinedGroups() {
 +    ArrayList<String> groupList = new ArrayList<String>();
 +    for (String g: MemberAttributes.parseGroups(null, getSystem().getConfig().getGroups())) {
 +      if (!groupList.contains(g)) {
 +        groupList.add(g);
 +      }
 +    }
 +    for (String g: getGroups()) {
 +      if (!groupList.contains(g)) {
 +        groupList.add(g);
 +      }
 +    }
 +    String[] groups = new String[groupList.size()];
 +    return groupList.toArray(groups);
 +  }
 +  
 +  public /*synchronized causes deadlock*/ void fillInProfile(Profile profile) {
 +    assert profile instanceof CacheServerProfile;
 +    CacheServerProfile bp = (CacheServerProfile)profile;
 +    bp.setHost(getExternalAddress(false));
 +    bp.setPort(getPort());
 +    bp.setGroups(getCombinedGroups());
 +    bp.setMaxConnections(maxConnections);
 +    bp.setInitialLoad(loadMonitor.getLastLoad());
 +    bp.setLoadPollInterval(getLoadPollInterval());
 +    bp.serialNumber = getSerialNumber();
 +    bp.finishInit();
 +  }
 +
 +  public int getSerialNumber() {
 +    return this.serialNumber;
 +  }
 +
 +  
 +   protected CacheClientNotifier getCacheClientNotifier() {
 +    return getAcceptor().getCacheClientNotifier();
 +  } 
 +   
 +  /**
 +   * Registers a new <code>InterestRegistrationListener</code> with the set of
 +   * <code>InterestRegistrationListener</code>s.
 +   * 
 +   * @param listener
 +   *                The <code>InterestRegistrationListener</code> to register
 +   * @throws IllegalStateException if the BridgeServer has not been started
 +   * @since 5.8Beta
 +   */
 +  public void registerInterestRegistrationListener(
 +      InterestRegistrationListener listener) {
 +    if (!this.isRunning()) {
 +      throw new IllegalStateException(LocalizedStrings.CacheServerImpl_MUST_BE_RUNNING.toLocalizedString());
 +    }
 +    getCacheClientNotifier().registerInterestRegistrationListener(listener); 
 +  }
 +
 +  /**
 +   * Unregisters an existing <code>InterestRegistrationListener</code> from
 +   * the set of <code>InterestRegistrationListener</code>s.
 +   * 
 +   * @param listener
 +   *                The <code>InterestRegistrationListener</code> to
 +   *                unregister
 +   * 
 +   * @since 5.8Beta
 +   */
 +  public void unregisterInterestRegistrationListener(
 +      InterestRegistrationListener listener) {
 +    getCacheClientNotifier().unregisterInterestRegistrationListener(listener);     
 +  }
 +
 +  /**
 +   * Returns a read-only set of <code>InterestRegistrationListener</code>s
 +   * registered with this notifier.
 +   * 
 +   * @return a read-only set of <code>InterestRegistrationListener</code>s
 +   *         registered with this notifier
 +   * 
 +   * @since 5.8Beta
 +   */
 +  public Set getInterestRegistrationListeners() {
 +    return getCacheClientNotifier().getInterestRegistrationListeners(); 
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerLauncher.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerLauncher.java
index ac198e9,0000000..c5de84b
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerLauncher.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheServerLauncher.java
@@@ -1,1391 -1,0 +1,1393 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache;
 +
 +import java.io.File;
 +import java.io.FileInputStream;
 +import java.io.FileNotFoundException;
 +import java.io.FileOutputStream;
 +import java.io.IOException;
 +import java.io.ObjectInputStream;
 +import java.io.ObjectOutputStream;
 +import java.io.PrintStream;
 +import java.io.Serializable;
 +import java.net.URL;
 +import java.util.AbstractList;
 +import java.util.ArrayList;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.concurrent.TimeUnit;
 +
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.i18n.LogWriterI18n;
 +import com.gemstone.gemfire.internal.OSProcess;
 +import com.gemstone.gemfire.internal.PureJavaMode;
 +import com.gemstone.gemfire.internal.SocketCreator;
++import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerHelper;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
- import com.gemstone.gemfire.internal.logging.PureLogWriter;
 +import com.gemstone.gemfire.internal.process.StartupStatus;
 +import com.gemstone.gemfire.internal.process.StartupStatusListener;
 +import com.gemstone.gemfire.internal.util.IOUtils;
 +import com.gemstone.gemfire.internal.util.JavaCommandBuilder;
 +
 +/**
 + * Launcher program to start a cache server.
 + *
 + * @author Sudhir Menon
 + * @author Barry Oglesby
 + * @author David Whitlock
 + * @author John Blum
 + *
 + * @since 2.0.2
 + */
 +public class CacheServerLauncher  {
 +
 +  /** Is this VM a dedicated Cache Server?  This value is used mainly by the admin API. */
 +  public static boolean isDedicatedCacheServer = Boolean.getBoolean("gemfire.isDedicatedServer");
 +
 +  public static boolean ASSIGN_BUCKETS = Boolean.getBoolean("gemfire.CacheServerLauncher.assignBucketsToPartitions");
 +
 +  //default is to exit if property not defined
 +  public static boolean DONT_EXIT_AFTER_LAUNCH = Boolean.getBoolean("gemfire.CacheServerLauncher.dontExitAfterLaunch");
 +
 +  /** Should the launch command be printed? */
 +  public static final boolean PRINT_LAUNCH_COMMAND = Boolean.getBoolean(
 +    CacheServerLauncher.class.getSimpleName() + ".PRINT_LAUNCH_COMMAND");
 +  
 +  private static final long STATUS_WAIT_TIME 
 +    = Long.getLong("gemfire.CacheServerLauncher.STATUS_WAIT_TIME_MS", 15000);
 +  
 +  /** How long to wait for a cache server to stop */
 +  private static final long SHUTDOWN_WAIT_TIME 
 +    = Long.getLong("gemfire.CacheServerLauncher.SHUTDOWN_WAIT_TIME_MS", 20000);
 +
 +  protected final String baseName;
 +  protected final String defaultLogFileName;
 +  protected final String startLogFileName;
 +  protected final String statusName;
 +  protected Status status = null;
 +  protected File workingDir = null;
 +  protected PrintStream oldOut = System.out;
 +  protected PrintStream oldErr = System.err;
 +  protected LogWriterI18n logger = null;
 +  protected String maxHeapSize;
 +  protected String initialHeapSize;
 +  protected String offHeapSize;
 +
 +
 +  public static final int SHUTDOWN = 0;
 +  public static final int STARTING = 1;
 +  public static final int RUNNING = 2;
 +  public static final int SHUTDOWN_PENDING = 3;
 +
 +  private static final int FORCE_STATUS_FILE_READ_ITERATION_COUNT = 10;
 +
 +  public CacheServerLauncher(final String baseName) {
 +    assert baseName != null : "The base name used for the cache server launcher files cannot be null!";
 +    this.baseName = baseName;
 +    final String baseNameLowerCase = baseName.toLowerCase().replace(" ", "");
 +    this.startLogFileName = "start_" + baseNameLowerCase + ".log";
 +    this.defaultLogFileName = baseNameLowerCase + ".log";
 +    this.statusName = "." + baseNameLowerCase + ".ser";
 +  }
 +
 +  protected static Status createStatus(final String baseName, final int state, final int pid) {
 +    return createStatus(baseName, state, pid, null, null);
 +  }
 +
 +  protected static Status createStatus(final String baseName, final int state, final int pid, final String msg, final Throwable t) {
 +    final Status status = new Status(baseName);
 +    status.state = state;
 +    status.pid = pid;
 +    status.msg = msg;
 +    status.exception = t;
 +    return status;
 +  }
 +
 +  /**
 +   * Prints usage information about this program.
 +   */
 +  protected void usage() {
 +    PrintStream out = System.out;
 +    out.println("cacheserver start [-J<vmarg>]* [<attName>=<attValue>]* [-dir=<workingdir>] [-classpath=<classpath>] [-disable-default-server] [-rebalance] [-lock-memory] [-server-port=<server-port>] [-server-bind-address=<server-bind-address>] [-critical-heap-percentage=<critical-heap-percentage>] [-eviction-heap-percentage=<eviction-heap-percentage>] [-critical-off-heap-percentage=<critical-off-heap-percentage>] [-eviction-off-heap-percentage=<eviction-off-heap-percentage>]\n" );
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_STARTS_A_GEMFIRE_CACHESERVER_VM.toLocalizedString() );
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_VMARG.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_DIR.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_CLASSPATH.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_ATTNAME.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_REBALANCE.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_DISABLE_DEFAULT_SERVER.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_SERVER_PORT.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_SERVER_BIND_ADDRESS.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_CRITICAL_HEAP_PERCENTAGE.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_EVICTION_HEAP_PERCENTAGE.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_CRITICAL_OFF_HEAP_PERCENTAGE.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_EVICTION_OFF_HEAP_PERCENTAGE.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_LOCK_MEMORY.toLocalizedString());
 +
 +    out.println();
 +    out.println( "cacheserver stop [-dir=<workingdir>]" );
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_STOPS_A_GEMFIRE_CACHESERVER_VM.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_DIR.toLocalizedString());
 +    out.println();
 +    out.println( "cacheserver status [-dir=<workingdir>]" );
 +    out.println( "\t" + LocalizedStrings.CacheServerLauncher_STATUS.toLocalizedString());
 +    out.println("\t" + LocalizedStrings.CacheServerLauncher_DIR.toLocalizedString());
 +  }
 +
 +  /**
 +   * Prints the status of the cache server running the configured
 +   * working directory.
 +   */
 +  protected void status(final String[] args) throws Exception {
 +    workingDir = (File) getStopOptions(args).get(DIR);
 +    System.out.println(getStatus());
 +    System.exit(0);
 +  }
 +
 +  /**
 +   * Returns the <code>Status</code> of the cache server in the
 +   * <code>workingDir</code>.
 +   */
 +  protected Status getStatus() throws Exception {
 +    Status status;
 +
 +    if (new File(workingDir, statusName).exists()) {
 +      status = spinReadStatus(); // See bug 32456
 +    }
 +    else {
 +      // no pid since the cache server is not running
 +      status = createStatus(this.baseName, SHUTDOWN, 0);
 +    }
 +
 +    return status;
 +  }
 +
 +  /**
 +   * Main method that parses the command line and performs an
 +   * will start, stop, or get the status of a cache server.  This main
 +   * method is also the main method of the launched cacher server VM
 +   * ("server" mode).
 +   */
 +  public static void main(final String[] args) {
 +    final CacheServerLauncher launcher = new CacheServerLauncher("CacheServer");
 +    boolean inServer = false;
 +
 +    try {
 +      if (args.length > 0) {
 +        if (args[0].equalsIgnoreCase("start")) {
 +          launcher.start(args);
 +        }
 +        else if (args[0].equalsIgnoreCase("server")) {
 +          inServer = true;
 +          launcher.server(args);
 +        }
 +        else if (args[0].equalsIgnoreCase("stop")) {
 +          launcher.stop(args);
 +        }
 +        else if (args[0].equalsIgnoreCase("status")) {
 +          launcher.status(args);
 +        }
 +        else {
 +          launcher.usage();
 +          System.exit(1);
 +        }
 +      }
 +      else {
 +        launcher.usage();
 +        System.exit(1);
 +      }
 +
 +      throw new Exception(LocalizedStrings.CacheServerLauncher_INTERNAL_ERROR_SHOULDNT_REACH_HERE.toLocalizedString());
 +    }
 +    catch (VirtualMachineError err) {
 +      SystemFailure.initiateFailure(err);
 +      // If this ever returns, rethrow the error.  We're poisoned
 +      // now, so don't let this thread continue.
 +      throw err;
 +    }
 +    catch (Throwable t) {
 +      // Whenever you catch Error or Throwable, you must also
 +      // catch VirtualMachineError (see above).  However, there is
 +      // _still_ a possibility that you are dealing with a cascading
 +      // error condition, so you also need to check to see if the JVM
 +      // is still usable:
 +      SystemFailure.checkFailure();
 +      t.printStackTrace();
 +      if (inServer) {
 +        launcher.setServerError(LocalizedStrings.CacheServerLauncher_ERROR_STARTING_SERVER_PROCESS
 +          .toLocalizedString(), t);
 +      }
 +      launcher.restoreStdOut();
 +      if (launcher.logger != null) {
 +        launcher.logger.severe(LocalizedStrings.CacheServerLauncher_CACHE_SERVER_ERROR, t);
 +
 +      }
 +      else {
 +        System.out.println(LocalizedStrings.CacheServerLauncher_ERROR_0.toLocalizedString(t.getMessage()));
 +      }
 +      System.exit(1);
 +    }
 +  }
 +
 +  protected void restoreStdOut( ) {
 +    System.setErr( oldErr );
 +    System.setOut( oldOut );
 +  }
 +
 +  protected static final String DIR     = "dir";
 +  protected static final String VMARGS  = "vmargs";
 +  protected static final String PROPERTIES = "properties";
 +  protected static final String CLASSPATH = "classpath";
 +  protected static final String REBALANCE = "rebalance";
 +  protected static final String SERVER_PORT = "server-port";
 +  protected static final String SERVER_BIND_ADDRESS = "server-bind-address";
 +  protected static final String DISABLE_DEFAULT_SERVER = "disable-default-server";
 +  public static final String CRITICAL_HEAP_PERCENTAGE =
 +    "critical-heap-percentage";
 +  public static final String EVICTION_HEAP_PERCENTAGE =
 +      "eviction-heap-percentage";
 +  public static final String CRITICAL_OFF_HEAP_PERCENTAGE =
 +      "critical-off-heap-percentage";
 +  public static final String EVICTION_OFF_HEAP_PERCENTAGE =
 +      "eviction-off-heap-percentage";
 +  protected static final String LOCK_MEMORY = "lock-memory";
 +
 +  protected final File processDirOption(final Map<String, Object> options, final String dirValue) throws FileNotFoundException {
 +    final File inputWorkingDirectory = new File(dirValue);
 +
 +    if (!inputWorkingDirectory.exists()) {
 +      throw new FileNotFoundException(LocalizedStrings.CacheServerLauncher_THE_INPUT_WORKING_DIRECTORY_DOES_NOT_EXIST_0
 +        .toLocalizedString(dirValue));
 +    }
 +
 +    options.put(DIR, inputWorkingDirectory);
 +
 +    return inputWorkingDirectory;
 +  }
 +
 +  /**
 +   * Populates a map that maps the name of the start options such as {@link #DIR} to its value on the command line.
 +   * If no value is specified on the command line, a default one is provided.
 +   */
 +  protected Map<String, Object> getStartOptions(String[] args) throws Exception {
 +    final Map<String, Object> options = new HashMap<String, Object>();
 +    options.put(DIR, new File(System.getProperty("user.dir")));
 +
 +    final List<String> vmArgs = new ArrayList<String>();
 +    options.put(VMARGS, vmArgs);
 +
 +    final Properties props = new Properties();
 +    options.put(PROPERTIES, props);
 +
 +    for (final String arg : args) {
 +      if (arg.equals("start")) {
 +        // expected
 +      }
 +      else if (arg.startsWith("-classpath=")) {
 +        options.put(CLASSPATH, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-dir=")) {
 +        processDirOption(options, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-disable-default-server")) {
 +        options.put(DISABLE_DEFAULT_SERVER, arg);
 +      }
 +      else if (arg.startsWith("-lock-memory")) {
 +        if (System.getProperty("os.name").indexOf("Windows") >= 0) {
 +          throw new IllegalArgumentException("Unable to lock memory on this operating system");
 +        }
 +        props.put(DistributionConfig.LOCK_MEMORY_NAME, "true");
 +      }
 +      else if (arg.startsWith("-rebalance")) {
 +        options.put(REBALANCE, Boolean.TRUE);
 +      }
 +      else if (arg.startsWith("-server-port")) {
 +        options.put(SERVER_PORT, arg);
 +      }
 +      else if (arg.startsWith("-" + CRITICAL_HEAP_PERCENTAGE) ) {
 +        options.put(CRITICAL_HEAP_PERCENTAGE, arg);
 +      }
 +      else if (arg.startsWith("-" + EVICTION_HEAP_PERCENTAGE) ) {
 +        options.put(EVICTION_HEAP_PERCENTAGE, arg);
 +      }
 +      else if (arg.startsWith("-" + CRITICAL_OFF_HEAP_PERCENTAGE) ) {
 +        options.put(CRITICAL_OFF_HEAP_PERCENTAGE, arg);
 +      }
 +      else if (arg.startsWith("-" + EVICTION_OFF_HEAP_PERCENTAGE) ) {
 +        options.put(EVICTION_OFF_HEAP_PERCENTAGE, arg);
 +      }
 +      else if (arg.startsWith("-server-bind-address")) {
 +        options.put(SERVER_BIND_ADDRESS, arg);
 +      }
 +      else if (arg.startsWith("-J")) {
 +        String vmArg = arg.substring(2);
 +        if (vmArg.startsWith("-Xmx")) {
 +          this.maxHeapSize = vmArg.substring(4);
 +        } else if (vmArg.startsWith("-Xms")) {
 +          this.initialHeapSize = vmArg.substring(4);
 +        }
 +        vmArgs.add(vmArg);
 +      }
 +      // moved this default block down so that "-J" like options can have '=' in them.
 +      // an 'indexOf' the assignment operator with greater than 0 ensures a non-empty String key value
 +      else if (arg.indexOf("=") > 0) {
 +        final int assignmentIndex = arg.indexOf("=");
 +        final String key = arg.substring(0, assignmentIndex);
 +        final String value = arg.substring(assignmentIndex + 1);
 +
 +        if (key.startsWith("-")) {
 +          processStartOption(key.substring(1), value, options, vmArgs, props);
 +        }
 +        else {
 +          processStartArg(key, value, options, vmArgs, props);
 +        }
 +      }
 +      else {
 +        throw new IllegalArgumentException(LocalizedStrings.CacheServerLauncher_UNKNOWN_ARGUMENT_0
 +          .toLocalizedString(arg));
 +      }
 +    }
 +
 +    // -J-Djava.awt.headless=true has been added for Mac platform where it
 +    // causes an icon to appear for sqlf launched procs
 +    // TODO: check which library/GemFire code causes awt to be touched
 +    vmArgs.add("-Djava.awt.headless=true");
 +
 +    // configure commons-logging to use JDK logging 
 +    vmArgs.add("-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger");
 +    
 +    options.put(VMARGS, vmArgs);
 +    return options;
 +  }
 +
 +  /**
 +   * Process a command-line options of the form "key=value".
 +   */
 +  protected void processStartArg(final String key,
 +                                 final String value,
 +                                 final Map<String, Object> options,
 +                                 final List<String> vmArgs,
 +                                 final Properties props)
 +    throws Exception
 +  {
 +    props.setProperty(key, value);
 +  }
 +
 +  /**
 +   * Process a command-line option of the form "-key=value".
 +   */
 +  protected void processStartOption(final String key,
 +                                    final String value,
 +                                    final Map<String, Object> options,
 +                                    final List<String> vmArgs,
 +                                    final Properties props)
 +    throws Exception
 +  {
 +    processUnknownStartOption(key, value, options, vmArgs, props);
 +  }
 +
 +  /**
 +   * Process a command-line option of the form "-key=value" unknown to the base class.
 +   */
 +  protected void processUnknownStartOption(final String key,
 +                                           final String value,
 +                                           final Map<String, Object> options,
 +                                           final List<String> vmArgs,
 +                                           final Properties props) {
 +    throw new IllegalArgumentException(LocalizedStrings.CacheServerLauncher_UNKNOWN_ARGUMENT_0.toLocalizedString(key));
 +  }
 +
 +  /**
 +   * Extracts configuration information used when launching the cache server VM.
 +   */
 +  protected Map<String, Object> getServerOptions(final String[] args) throws Exception {
 +    final Map<String, Object> options = new HashMap<String, Object>();
 +    options.put(DIR, new File("."));
 +    workingDir = (File) options.get(DIR);
 +
 +    final Properties props = new Properties();
 +    options.put(PROPERTIES, props);
 +
 +    for (final String arg : args) {
 +      if (arg.equals("server")) {
 +        // expected
 +      }
 +      else if (arg.startsWith("-dir=")) {
 +        this.workingDir = processDirOption(options, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-rebalance")) {
 +        options.put(REBALANCE, Boolean.TRUE);
 +      }
 +      else if (arg.startsWith("-disable-default-server")) {
 +        options.put(DISABLE_DEFAULT_SERVER, Boolean.TRUE);
 +      }
 +      else if (arg.startsWith("-lock-memory")) {
 +        props.put(DistributionConfig.LOCK_MEMORY_NAME, "true");
 +      }
 +      else if (arg.startsWith("-server-port")) {
 +        options.put(SERVER_PORT, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-server-bind-address")) {
 +        options.put(SERVER_BIND_ADDRESS, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-" + CRITICAL_HEAP_PERCENTAGE)) {
 +        options.put(CRITICAL_HEAP_PERCENTAGE, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-" + EVICTION_HEAP_PERCENTAGE)) {
 +        options.put(EVICTION_HEAP_PERCENTAGE, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-" + CRITICAL_OFF_HEAP_PERCENTAGE)) {
 +        options.put(CRITICAL_OFF_HEAP_PERCENTAGE, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.startsWith("-" + EVICTION_OFF_HEAP_PERCENTAGE)) {
 +        options.put(EVICTION_OFF_HEAP_PERCENTAGE, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else if (arg.indexOf("=") > 1) {
 +        final int assignmentIndex = arg.indexOf("=");
 +        final String key = arg.substring(0, assignmentIndex);
 +        final String value = arg.substring(assignmentIndex + 1);
 +
 +        if (key.startsWith("-")) {
 +          options.put(key.substring(1), value);
 +        }
 +        else {
 +          props.setProperty(key, value);
 +        }
 +      }
 +      else {
 +        throw new IllegalArgumentException(LocalizedStrings.CacheServerLauncher_UNKNOWN_ARGUMENT_0.toLocalizedString(arg));
 +      }
 +    }
 +
 +    return options;
 +  }
 +
 +  /**
 +   * Extracts configuration information for stopping a cache server based on the contents of the command-line.
 +   * This method can also be used with getting the status of a cache server.
 +   */
 +  protected Map<String, Object> getStopOptions(final String[] args) throws Exception {
 +    final Map<String, Object> options = new HashMap<String, Object>();
 +    options.put(DIR, new File("."));
 +
 +    for (final String arg : args) {
 +      if (arg.equals("stop") || arg.equals("status")) {
 +        // expected
 +      }
 +      else if (arg.startsWith("-dir=")) {
 +        processDirOption(options, arg.substring(arg.indexOf("=") + 1));
 +      }
 +      else {
 +        throw new IllegalArgumentException(LocalizedStrings.CacheServerLauncher_UNKNOWN_ARGUMENT_0
 +          .toLocalizedString(arg));
 +      }
 +    }
 +
 +    return options;
 +  }
 +
 +  /**
 +   * Configures and spawns a VM that hosts a cache server.  Any output
 +   * generated while starting the VM will be placed in a special
 +   * {@linkplain #startLogFileName log file}.
 +   *
 +   * See #getStartOptions
 +   * @see OSProcess#bgexec(String[], File, File, boolean, Map)
 +   */
 +  public void start(final String[] args) throws Exception {
 +    final Map<String, Object> options = getStartOptions(args);
 +
 +    workingDir = (File) options.get(DIR);
 +
 +    // Complain if a cache server is already running in the specified working directory.
 +    // See bug 32574.
 +    verifyAndClearStatus();
 +
 +    // start the GemFire Cache Server proces...
 +    runCommandLine(options, buildCommandLine(options));
 +
 +    // wait for status.state == RUNNING
 +    waitForRunning();
 +
 +    if (DONT_EXIT_AFTER_LAUNCH) {
 +      return;
 +    }
 +
 +    System.exit(0);
 +  }
 +
 +  private void verifyAndClearStatus() throws Exception {
 +    final Status status = getStatus();
 +
 +    if (status != null && status.state != SHUTDOWN) {
 +      throw new IllegalStateException(LocalizedStrings.CacheServerLauncher_A_0_IS_ALREADY_RUNNING_IN_DIRECTORY_1_2
 +        .toLocalizedString(this.baseName, workingDir, status));
 +    }
 +
 +    deleteStatus();
 +  }
 +
 +  private String[] buildCommandLine(final Map<String, Object> options) {
 +    final List<String> commandLine = JavaCommandBuilder.buildCommand(this.getClass().getName(),
 +      (String) options.get(CLASSPATH), null, (List<String>) options.get(VMARGS));
 +
 +    commandLine.add("server");
 +    addToServerCommand(commandLine, options);
 +
 +    return commandLine.toArray(new String[commandLine.size()]);
 +  }
 +
 +  private void printCommandLine(final String[] commandLine) {
 +    if (PRINT_LAUNCH_COMMAND) {
 +      System.out.println("Starting " + this.baseName + " with command:");
 +      for (final String command : commandLine) {
 +        System.out.print(command);
 +        System.out.print(" ");
 +      }
 +      System.out.println();
 +    }
 +  }
 +
 +  private int runCommandLine(final Map<String, Object> options, final String[] commandLine) throws Exception {
 +    final File startLogFile = new File(workingDir, startLogFileName).getAbsoluteFile(); // see bug 32548
 +
 +    if (startLogFile.exists() && !startLogFile.delete()) {
 +      throw new IOException("Unable to delete start log file (" + startLogFile.getAbsolutePath() + ")!");
 +    }
 +
 +    Map<String, String> env = new HashMap<String, String>();
 +    // read the passwords from command line
 +    SocketCreator.readSSLProperties(env);
 +    
 +    printCommandLine(commandLine);
 +
 +    final int pid = OSProcess.bgexec(commandLine, workingDir, startLogFile, false, env);
 +
 +    printStartMessage(options, pid);
 +
 +    return pid;
 +  }
 +
 +  protected void printStartMessage(final Map<String, Object> options, final int pid) throws Exception {
 +    System.out.println(LocalizedStrings.CacheServerLauncher_STARTING_0_WITH_PID_1.toLocalizedString(this.baseName, pid));
 +  }
 +
 +  /**
 +   * Sets the status of the cache server to be {@link #RUNNING}.
 +   */
 +  public void running() {
 +    try {
 +      writeStatus(createStatus(this.baseName, RUNNING, OSProcess.getId()));
 +    }
 +    catch (Exception e) {
 +      e.printStackTrace();
 +    }
 +  }
 +
 +  public static ThreadLocal<Integer> serverPort = new ThreadLocal<Integer>();
 +
 +  public static ThreadLocal<String> serverBindAddress = new ThreadLocal<String>();
 +
 +  public static Integer getServerPort() {
 +    return serverPort.get();
 +  }
 +
 +  public static String getServerBindAddress() {
 +    return serverBindAddress.get();
 +  }
 +
 +  public static ThreadLocal<Boolean> disableDefaultServer = new ThreadLocal<Boolean>();
 +
 +  public static Boolean getDisableDefaultServer() {
 +    return disableDefaultServer.get();
 +  }
 +
 +  /**
 +   * The method that does the work of being a cache server.  It is
 +   * invoked in the VM spawned by the {@link #start} method.
 +   * Basically, it creates a GemFire {@link Cache} based on
 +   * configuration passed in from the command line.  (It will also
 +   * take <code>gemfire.properties</code>, etc. into account, just
 +   * like an application cache.)
 +   *
 +   * <P>
 +   *
 +   * After creating the cache and setting the server's status to {@link
 +   * #RUNNING}, it periodically monitors the status, waiting for it to
 +   * change to {@link #SHUTDOWN_PENDING} (see {@link #stop}).  When
 +   * the status does change, it closes the <code>Cache</code> and sets
 +   * the status to be {@link #SHUTDOWN}.
 +   *
 +   * @param args Configuration options passed in from the command line
 +   */
 +  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
 +  public void server(final String[] args) throws Exception {
 +    isDedicatedCacheServer = true;
 +    SystemFailure.setExitOK(true);
 +
 +    final Map<String, Object> options = getServerOptions(args);
 +
 +    final String serverPortString = (String) options.get(SERVER_PORT);
 +
 +    if (serverPortString != null) {
 +      serverPort.set(Integer.parseInt(serverPortString));
 +    }
 +
 +    serverBindAddress.set((String) options.get(SERVER_BIND_ADDRESS));
 +    disableDefaultServer.set((Boolean) options.get(DISABLE_DEFAULT_SERVER));
 +    workingDir = new File(System.getProperty("user.dir"));
 +
 +    // Say that we're starting...
 +    Status originalStatus = createStatus(this.baseName, STARTING, OSProcess.getId());
 +    status = originalStatus;
 +    writeStatus(status);
 +
 +    // Connect to the distributed system.  The properties will
 +    // properly configure logging, the declarative caching file, etc.
 +    final Properties props = (Properties) options.get(PROPERTIES);
 +
 +    if (props.getProperty(DistributionConfig.LOG_FILE_NAME) == null && CacheServerLauncher.isLoggingToStdOut()) {
 +      // Check First if the gemfire.properties set the log-file. If they do, we shouldn't override that default
 +      final Properties gemfireProperties = new Properties();
 +
 +      DistributionConfigImpl.loadGemFireProperties(gemfireProperties);
 +
 +      if (gemfireProperties.get(DistributionConfig.LOG_FILE_NAME) == null) {
 +        // Do not allow the cache server to log to stdout, override the logger with #defaultLogFileName
 +        props.setProperty(DistributionConfig.LOG_FILE_NAME, defaultLogFileName);
 +      }
 +    }
 +
 +    InternalDistributedSystem system = this.connect(props);
 +
 +    installLogListener();
 +    
 +    logger = system.getLogWriter().convertToLogWriterI18n();
 +    // redirect output to the log file
 +    OSProcess.redirectOutput(system.getConfig().getLogFile());
 +
 +    Cache cache = this.createCache(system, options);
 +    cache.setIsServer(true);
 +    startAdditionalServices(cache, options);
 +
 +    this.running();
 +    
 +    clearLogListener();
 +
 +    if (ASSIGN_BUCKETS) {
 +      for (PartitionedRegion region : ((GemFireCacheImpl) cache).getPartitionedRegions()) {
 +        PartitionRegionHelper.assignBucketsToPartitions(region);
 +      }
 +    }
 +
 +    if (Boolean.TRUE.equals(options.get(REBALANCE))) {
 +      cache.getResourceManager().createRebalanceFactory().start();
 +    }
 +
 +    File statusFile = new File( workingDir, statusName );
 +    long lastModified=0, oldModified = statusFile.lastModified();
 +    // Every FORCE_STATUS_FILE_READ_ITERATION_COUNT iterations, read the status file despite the modification time
 +    // to catch situations where the file is modified quicker than the file timestamp's resolution.
 +    short count = 0;
 +    boolean loggedWarning = false;
 +    while(true) {
 +      lastModified = statusFile.lastModified();
 +      if (lastModified > oldModified || count++ == FORCE_STATUS_FILE_READ_ITERATION_COUNT) {
 +        count = 0;
 +        Thread.sleep( 500 ); // allow for it to be finished writing.
 +        //Sometimes the status file is partially written causing readObject to
 +        //fail, sleep and retry.
 +        try {
 +          status = readStatus( );
 +        } catch(IOException ioeSecondChance) {
 +          Thread.sleep(1000);
 +          try {
 +            status = readStatus( );
 +          } catch(IOException ioeThirdChance) {
 +            Thread.sleep(5000);
 +            try {
 +              status = readStatus( );
 +            } catch (FileNotFoundException fnfe) {
 +              // See bug 44627.
 +              // The cache server used to just shutdown at this point. Instead,
 +              // recreate the status file if possible and continue.
 +              status = createStatus(this.baseName, RUNNING, originalStatus.pid);
 +              try {
 +                writeStatus(status);
 +              } catch (FileNotFoundException e) {
 +                if (!loggedWarning) {
 +                  logger.warning(LocalizedStrings.CacheServerLauncher_CREATE_STATUS_EXCEPTION_0, e.toString());
 +                  loggedWarning = true;
 +                }
 +              }
 +            }
 +          }
 +        }
 +        oldModified = lastModified;
 +        if (status.state == SHUTDOWN_PENDING) {
 +            stopAdditionalServices();
 +            this.disconnect(cache);
 +            status.state = SHUTDOWN;
 +            writeStatus(status);
 +        } else {
 +          Thread.sleep( 250 );
 +        }
 +
 +      } else {
 +        Thread.sleep(1000);
 +      }
 +      if (!system.isConnected()) {
 +//        System.out.println("System is disconnected.  isReconnecting = " + system.isReconnecting());
 +        boolean reconnected = false;
 +        if (system.isReconnecting()) {
 +          reconnected = system.waitUntilReconnected(-1, TimeUnit.SECONDS);
 +          if (reconnected) {
 +            system = (InternalDistributedSystem)system.getReconnectedSystem();
 +            cache = GemFireCacheImpl.getInstance();
 +          }
 +        }
 +        if (!reconnected) {
 +          // shutdown-all disconnected the DS
 +          System.exit(0);
 +        }
 +      }
 +    }
 +  }
 +
 +  private void installLogListener() {
 +    MainLogReporter reporter = new MainLogReporter(this.status);
 +    StartupStatus.setListener(reporter);
 +    reporter.setDaemon(true);
 +    reporter.start();
 +  }
 +  
 +  private void clearLogListener() {
 +    MainLogReporter mainLogListener = (MainLogReporter) StartupStatus.getStartupListener();
 +    if(mainLogListener != null) {
 +      mainLogListener.shutdown();
 +      StartupStatus.clearListener();
 +    }
 +  }
 +  
 +  protected InternalDistributedSystem connect(Properties props) {
 +    return (InternalDistributedSystem)DistributedSystem.connect(props);
 +  }
 +
 +  protected static float getCriticalHeapPercent(Map<String, Object> options) {
 +    if (options != null) {
 +      String criticalHeapThreshold = (String)options
 +          .get(CRITICAL_HEAP_PERCENTAGE);
 +      if (criticalHeapThreshold != null) {
 +        return Float.parseFloat(criticalHeapThreshold
 +            .substring(criticalHeapThreshold.indexOf("=") + 1));
 +      }
 +    }
 +    return -1.0f;
 +  }
 +  
 +  protected static float getEvictionHeapPercent(Map<String, Object> options) {
 +    if (options != null) {
 +      String evictionHeapThreshold = (String)options
 +          .get(EVICTION_HEAP_PERCENTAGE);
 +      if (evictionHeapThreshold != null) {
 +        return Float.parseFloat(evictionHeapThreshold
 +            .substring(evictionHeapThreshold.indexOf("=") + 1));
 +      }
 +    }
 +    return -1.0f;
 +  }
 +  
 +  protected static float getCriticalOffHeapPercent(Map<String, Object> options) {
 +    if (options != null) {
 +      String criticalOffHeapThreshold = (String)options
 +          .get(CRITICAL_OFF_HEAP_PERCENTAGE);
 +      if (criticalOffHeapThreshold != null) {
 +        return Float.parseFloat(criticalOffHeapThreshold
 +            .substring(criticalOffHeapThreshold.indexOf("=") + 1));
 +      }
 +    }
 +    return -1.0f;
 +  }
 +  
 +  protected static float getEvictionOffHeapPercent(Map<String, Object> options) {
 +    if (options != null) {
 +      String evictionOffHeapThreshold = (String)options
 +          .get(EVICTION_OFF_HEAP_PERCENTAGE);
 +      if (evictionOffHeapThreshold != null) {
 +        return Float.parseFloat(evictionOffHeapThreshold
 +            .substring(evictionOffHeapThreshold.indexOf("=") + 1));
 +      }
 +    }
 +    return -1.0f;
 +  }
 +  
 +  protected Cache createCache(InternalDistributedSystem system, Map<String, Object> options) throws IOException {
 +    Cache cache = CacheFactory.create(system);
 +
 +    float threshold = getCriticalHeapPercent(options);
 +    if (threshold > 0.0f) {
 +      cache.getResourceManager().setCriticalHeapPercentage(threshold);
 +    }
 +    threshold = getEvictionHeapPercent(options);
 +    if (threshold > 0.0f) {
 +      cache.getResourceManager().setEvictionHeapPercentage(threshold);
 +    }
 +    
 +    threshold = getCriticalOffHeapPercent(options);
 +    getCriticalOffHeapPercent(options);
 +    if (threshold > 0.0f) {
 +      cache.getResourceManager().setCriticalOffHeapPercentage(threshold);
 +    }
 +    threshold = getEvictionOffHeapPercent(options);
 +    if (threshold > 0.0f) {
 +      cache.getResourceManager().setEvictionOffHeapPercentage(threshold);
 +    }
 +
 +
 +    // Create and start a default cache server
 +    // If (disableDefaultServer is not set or it is set but false) AND (the number of cacheservers is 0)
 +    Boolean disable = disableDefaultServer.get();
 +    if ((disable == null || !disable) && cache.getCacheServers().size() == 0) {
 +      // Create and add a cache server
 +      CacheServer server = cache.addCacheServer();
++      
++      CacheServerHelper.setIsDefaultServer(server);
 +
 +      // Set its port if necessary
 +      Integer serverPort = CacheServerLauncher.getServerPort();
 +      if (serverPort != null) {
 +        server.setPort(serverPort);
 +      }
 +
 +      // Set its bind address if necessary
 +      String serverBindAddress = getServerBindAddress();
 +      if (serverBindAddress != null) {
 +        server.setBindAddress(serverBindAddress.trim());
 +      }
 +
 +      // Start it
 +      server.start();
 +    }
 +
 +    return cache;
 +  }
 +
 +  protected void disconnect(Cache cache) {
 +    DistributedSystem dsys = cache.getDistributedSystem();
 +    cache.close();
 +    dsys.disconnect();
 +  }
 +
 +  /**
 +   * Stops a cache server (which is running in a different VM) by setting its status to {@link #SHUTDOWN_PENDING}.
 +   * Waits for the cache server to actually shut down.
 +   */
 +  public void stop(final String[] args) throws Exception {
 +    this.workingDir = (File) getStopOptions(args).get(DIR);
 +
 +    // determine the current state of the Cache Server process...
 +    final File statusFile = new File(this.workingDir, this.statusName);
 +    int exitStatus = 1;
 +
 +    if (statusFile.exists()) {
 +      this.status = spinReadStatus();
 +
 +      // upon reading the status file, request the Cache Server to shutdown if it has not already...
 +      if (this.status.state != SHUTDOWN) {
 +        // copy server PID and not use own PID; see bug #39707
 +        this.status = createStatus(this.baseName, SHUTDOWN_PENDING, this.status.pid);
 +        writeStatus(this.status);
 +      }
 +
 +      // poll the Cache Server for a response to our shutdown request (passes through if the Cache Server
 +      // has already shutdown)...
 +      pollCacheServerForShutdown();
 +
 +      // after polling, determine the status of the Cache Server one last time and determine how to exit...
 +      if (this.status.state == SHUTDOWN) {
 +        System.out.println(LocalizedStrings.CacheServerLauncher_0_STOPPED.toLocalizedString(this.baseName));
 +        deleteStatus();
 +        exitStatus = 0;
 +      }
 +      else {
 +        System.out.println(LocalizedStrings.CacheServerLauncher_TIMEOUT_WAITING_FOR_0_TO_SHUTDOWN_STATUS_IS_1
 +          .toLocalizedString(this.baseName, this.status));
 +      }
 +    }
 +    else {
 +      System.out.println(LocalizedStrings.CacheServerLauncher_THE_SPECIFIED_WORKING_DIRECTORY_0_CONTAINS_NO_STATUS_FILE
 +        .toLocalizedString(this.workingDir));
 +    }
 +
 +    if (DONT_EXIT_AFTER_LAUNCH) {
 +      return;
 +    }
 +
 +    System.exit(exitStatus);
 +  }
 +
 +  private void pollCacheServerForShutdown() throws InterruptedException {
 +    final int increment = 250; // unit is in milliseconds
 +    int clock = 0;
 +
 +    // wait for a total of 20000 milliseconds (or 20 seconds)
 +    while (clock < SHUTDOWN_WAIT_TIME && status.state != SHUTDOWN) {
 +      try {
 +        status = readStatus();
 +      }
 +      catch (IOException ignore) {
 +      }
 +
 +      try {
 +        Thread.sleep(increment);
 +      }
 +      catch (InterruptedException ie) {
 +        break;
 +      }
 +
 +      clock += increment;
 +    }
 +  }
 +
 +  /**
 +   * A class that represents the status of a cache server.  Instances
 +   * of this class are serialized to a {@linkplain #statusName file}
 +   * on disk.
 +   *
 +   * @see #SHUTDOWN
 +   * @see #STARTING
 +   * @see #RUNNING
 +   * @see #SHUTDOWN_PENDING
 +   */
 +  static class Status implements Serializable {
 +
 +    private static final long serialVersionUID = 190943081363646485L;
 +    public int state = 0;
 +    public int pid = 0;
 +
 +    private final String baseName;
 +    public Throwable exception;
 +    public String msg;
 +    public String dsMsg;
 +
 +    public Status(String baseName) {
 +      this.baseName = baseName;
 +    }
 +
 +    @Override
 +    public String toString() {
 +      final StringBuilder buffer = new StringBuilder();
 +      buffer.append(this.baseName).append(" pid: ").append(pid).append(" status: ");
 +      switch (state) {
 +        case SHUTDOWN:
 +          buffer.append("stopped");
 +          break;
 +        case STARTING:
 +          buffer.append("starting");
 +          break;
 +        case RUNNING:
 +          buffer.append("running");
 +          break;
 +        case SHUTDOWN_PENDING:
 +          buffer.append("stopping");
 +          break;
 +        default:
 +          buffer.append("unknown");
 +          break;
 +      }
 +      if (exception != null) {
 +        if (msg != null) {
 +          buffer.append("\n").append(msg).append(" - ");
 +        }
 +        else {
 +          buffer.append("\nException in ").append(this.baseName).append(" - ");
 +        }
 +        buffer.append(LocalizedStrings
 +            .CacheServerLauncher_SEE_LOG_FILE_FOR_DETAILS.toLocalizedString());
 +      }
 +      else if (this.dsMsg != null) {
 +        buffer.append('\n').append(this.dsMsg);
 +      }
 +      return buffer.toString();
 +    }
 +  }
 +
 +  /**
 +   * Notes that an error has occurred in the cache server and that it
 +   * has shut down because of it.
 +   */
 +  protected void setServerError(final String msg, final Throwable t) {
 +    try {
 +      writeStatus(createStatus(this.baseName, SHUTDOWN, OSProcess.getId(), msg, t));
 +    }
 +    catch (Exception e) {
 +      if (logger != null) {
 +        logger.severe(e);
 +      }
 +      else {
 +        e.printStackTrace();
 +      }
 +      System.exit(1);
 +    }
 +  }
 +
 +  /**
 +   * Sets the status of a cache server by serializing a <code>Status</code>
 +   * instance to a file in the server's working directory.
 +   */
 +  public void writeStatus(final Status s) throws IOException {
 +    FileOutputStream fileOutput = null;
 +    ObjectOutputStream objectOutput = null;
 +
 +    try {
 +      fileOutput = new FileOutputStream(new File(workingDir, statusName));
 +      objectOutput = new ObjectOutputStream(fileOutput);
 +      objectOutput.writeObject(s);
 +      objectOutput.flush();
 +    }
 +    finally {
 +      IOUtils.close(objectOutput);
 +      IOUtils.close(fileOutput);
 +    }
 +  }
 +
 +  /**
 +   * Reads a cache server's status.  If the status file cannot be read because of I/O problems, it will try again.
 +   */
 +  protected Status spinReadStatus() {
 +    final long timeout = (System.currentTimeMillis() + 60000);
 +    Status status = null;
 +
 +    while (status == null && System.currentTimeMillis() < timeout) {
 +      try {
 +        status = readStatus();
 +      }
 +      catch (Exception e) {
 +        // try again - the status might have been read in the middle of it being written by the server resulting in
 +        // an EOFException here
 +        try {
 +          Thread.sleep(500);
 +        }
 +        catch (InterruptedException ie) {
 +          Thread.currentThread().interrupt();
 +          status = null;
 +          break;
 +        }
 +      }
 +    }
 +
 +    return status;
 +  }
 +
 +  /**
 +   * Reads a cache server's status from a file in its working directory.
 +   */
 +  protected Status readStatus() throws InterruptedException, IOException {
 +    final File statusFile = new File(workingDir, statusName);
 +
 +    FileInputStream fileInput = null;
 +    ObjectInputStream objectInput = null;
 +
 +    try {
 +      fileInput = new FileInputStream(statusFile);
 +      objectInput = new ObjectInputStream(fileInput);
 +
 +      Status status = (Status) objectInput.readObject();
 +
 +      // See bug 32760
 +      // Note, only execute the conditional createStatus statement if we are in native mode; if we are in pure Java mode
 +      // the the process ID identified in the Status object is assumed to exist!
 +      if (!isExistingProcess(status.pid)) {
 +        status = createStatus(this.baseName, SHUTDOWN, status.pid);
 +      }
 +
 +      return status;
 +    }
 +    catch (ClassNotFoundException e) {
 +      throw new RuntimeException(e);
 +    }
 +    catch (FileNotFoundException e) {
 +      Thread.sleep(500);
 +
 +      if (statusFile.exists()) {
 +        return readStatus();
 +      }
 +      else {
 +        throw e;
 +      }
 +    }
 +    finally {
 +      IOUtils.close(objectInput);
 +      IOUtils.close(fileInput);
 +    }
 +  }
 +
 +  /**
 +   * Removes a cache server's status file
 +   */
 +  private void deleteStatus() throws IOException {
 +    final File statusFile = new File(workingDir, statusName);
 +
 +    if (statusFile.exists() && !statusFile.delete()) {
 +      throw new IOException("Could not delete status file (" + statusFile.getAbsolutePath() + ")!");
 +    }
 +  }
 +
 +  protected boolean isExistingProcess(final int pid) {
 +    return (PureJavaMode.isPure() || (pid != 0 && OSProcess.exists(pid)));
 +  }
 +
 +  protected void waitForRunning() throws Exception {
 +    Status status = spinReadStatus();
 +    String lastReadMessage = null;
 +    String lastReportedMessage = null;
 +    long lastReadTime = System.nanoTime();
 +    if ( status == null ) {
 +      throw new Exception(LocalizedStrings.CacheServerLauncher_NO_AVAILABLE_STATUS.toLocalizedString());
 +    } else {
 +      switch ( status.state  ) {
 +        case STARTING:
 +          // re-read status for a while...
 +          while( status.state == STARTING ) {
 +            Thread.sleep( 500 ); // fix for bug 36998
 +            status = spinReadStatus();
 +            
 +            //check to see if the status message has changed
 +            if(status.dsMsg != null && !status.dsMsg.equals(lastReadMessage)) {
 +              lastReadMessage = status.dsMsg;
 +              lastReadTime = System.nanoTime();
 +            }
 +            
 +            //if the status message has not changed for 15 seconds, print
 +            //out the message.
 +            long elapsed = System.nanoTime() - lastReadTime;
 +            if(TimeUnit.NANOSECONDS.toMillis(elapsed) > STATUS_WAIT_TIME
 +                && lastReadMessage != null &&
 +                !lastReadMessage.equals(lastReportedMessage)) {
 +              long elapsedSec = TimeUnit.NANOSECONDS.toSeconds(elapsed);
 +              System.out.println(LocalizedStrings.CacheServerLauncher_LAUNCH_IN_PROGRESS_0
 +                  .toLocalizedString(elapsedSec, status.dsMsg));
 +              lastReportedMessage = lastReadMessage;
 +            }
 +          }
 +          if (status.state == SHUTDOWN) {
 +            System.out.println(status);
 +            System.exit(1);
 +          }
 +          break;
 +        default:
 +          break;
 +      }
 +      System.out.println( status );
 +    }
 +  }
 +
 +  /**
 +   * Reads {@link DistributedSystem#PROPERTY_FILE} and determines if the
 +   * {@link DistributionConfig#LOG_FILE_NAME} property is set to stdout
 +   * @return true if the logging would go to stdout
 +   */
 +  private static boolean isLoggingToStdOut() {
 +    Properties gfprops = new Properties();
 +    URL url = DistributedSystem.getPropertyFileURL();
 +    if (url != null) {
 +      try {
 +        gfprops.load(url.openStream());
 +      } catch (IOException io) {
 +        //throw new GemFireIOException("Failed reading " + url, io);
 +        System.out.println("Failed reading " + url);
 +        System.exit( 1 );
 +      }
 +      final String logFile = gfprops.getProperty(DistributionConfig.LOG_FILE_NAME);
 +      if ( logFile == null || logFile.length() == 0 ) {
 +        return true;
 +      }
 +    } else {
 +      //Didnt find a property file, assuming the default is to log to stdout
 +      return true;
 +    }
 +    return false;
 +  }
 +
 +  /**
 +   * Process information contained in the options map and add to the command
 +   * line of the subprocess as needed.
 +   */
 +  protected void addToServerCommand(final List<String> commandLine, final Map<String, Object> options) {
 +    final ListWrapper<String> commandLineWrapper = new ListWrapper<String>(commandLine);
 +
 +    if (Boolean.TRUE.equals(options.get(REBALANCE))) {
 +      commandLineWrapper.add("-rebalance");
 +    }
 +
 +    commandLineWrapper.add((String) options.get(DISABLE_DEFAULT_SERVER));
 +    commandLineWrapper.add((String) options.get(SERVER_PORT));
 +    commandLineWrapper.add((String) options.get(SERVER_BIND_ADDRESS));
 +
 +    String criticalHeapThreshold = (String)options.get(CRITICAL_HEAP_PERCENTAGE);
 +    if (criticalHeapThreshold != null) {
 +      commandLineWrapper.add(criticalHeapThreshold);
 +    }
 +    String evictionHeapThreshold = (String)options
 +        .get(EVICTION_HEAP_PERCENTAGE);
 +    if (evictionHeapThreshold != null) {
 +      commandLineWrapper.add(evictionHeapThreshold);
 +    }
 +    
 +    String criticalOffHeapThreshold = (String)options.get(CRITICAL_OFF_HEAP_PERCENTAGE);
 +    if (criticalOffHeapThreshold != null) {
 +      commandLineWrapper.add(criticalOffHeapThreshold);
 +    }
 +    String evictionOffHeapThreshold = (String)options
 +        .get(EVICTION_OFF_HEAP_PERCENTAGE);
 +    if (evictionOffHeapThreshold != null) {
 +      commandLineWrapper.add(evictionOffHeapThreshold);
 +    }
 +
 +    final Properties props = (Properties) options.get(PROPERTIES);
 +
 +    for (final Object key : props.keySet()) {
 +      commandLineWrapper.add(key + "=" + props.getProperty(key.toString()));
 +    }
 +
 +    if (props.getProperty(DistributionConfig.LOG_FILE_NAME) == null && CacheServerLauncher.isLoggingToStdOut()) {
 +      // Do not allow the cache server to log to stdout; override the logger with #defaultLogFileName
 +      commandLineWrapper.add(DistributionConfig.LOG_FILE_NAME + "=" + defaultLogFileName);
 +    }
 +  }
 +
 +  /**
 +   * This method is called immediately following cache creation in the spawned
 +   * process, but prior to setting the RUNNING flag in the status file. So the
 +   * spawning process will block until this method completes.
 +   */
 +  protected void startAdditionalServices(final Cache cache, final Map<String, Object> options) throws Exception {
 +  }
 +
 +  /**
 +   * This method is called prior to DistributedSytstem.disconnect(). Care should
 +   * be taken not to take too long in this method or else
 +   * #CacheServerLauncher.stop may timeout.
 +   */
 +  protected void stopAdditionalServices() throws Exception {
 +  }
 +
 +  /**
 +   * A List implementation that disallows null values.
 +   * @param <E> the Class type for the List elements.
 +   */
 +  protected static class ListWrapper<E> extends AbstractList<E>  {
 +
 +    private static final ThreadLocal<Boolean> addResult = new ThreadLocal<Boolean>();
 +
 +    private final List<E> list;
 +
 +    public ListWrapper(final List<E> list) {
 +      assert list != null : "The List cannot be null!";
 +      this.list = list;
 +    }
 +
 +    @Override
 +    public boolean add(final E e) {
 +      final boolean localAddResult = super.add(e);
 +      return (localAddResult && addResult.get());
 +    }
 +
 +    @Override
 +    public void add(final int index, final E element) {
 +      if (element != null) {
 +        list.add(index, element);
 +      }
 +      addResult.set(element != null);
 +    }
 +
 +    @Override
 +    public E get(final int index) {
 +      return this.list.get(index);
 +    }
 +
 +    @Override
 +    public E remove(final int index) {
 +      return list.remove(index);
 +    }
 +
 +    @Override
 +    public E set(final int index, final E element) {
 +      return (element != null ? list.set(index, element) : list.get(index));
 +    }
 +
 +    @Override
 +    public int size() {
 +      return list.size();
 +    }
 +  }
 +  
 +  private class MainLogReporter extends Thread implements StartupStatusListener {
 +    private String lastLogMessage;
 +    private final Status status;
 +    boolean running = true;
 +
 +    public MainLogReporter(Status status) {
 +      this.status = status;
 +    }
 +
 +    public synchronized void shutdown() {
 +      this.running = false;
 +      this.status.dsMsg = null;
 +      this.notifyAll();
 +    }
 +
 +    
 +    @Override
 +    public void setStatus(String status) {
 +      lastLogMessage = status;      
 +    }
 +
 +    public synchronized void run() {
 +      while(running) {
 +        try {
 +          wait(1000);
 +        } catch (InterruptedException e) {
 +          //this should not happen.
 +          break;
 +        }
 +        if(running && lastLogMessage != status.dsMsg) {
 +          status.dsMsg = lastLogMessage;
 +          try {
 +            writeStatus(status);
 +          } catch (IOException e) {
 +            //this could happen if there was a concurrent write to the file
 +            //eg a stop.
 +            continue;
 +          }
 +        }
 +      }
 +    }
 +  }
 +}


[011/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexUseJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexUseJUnitTest.java
index c3223d8,0000000..b171ac1
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexUseJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexUseJUnitTest.java
@@@ -1,1890 -1,0 +1,1654 @@@
 +/*
 + * 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.
 + */
- /*
-  * IndexTest.java
-  *
-  * Created on February 23, 2005, 3:17 PM
-  */
 +package com.gemstone.gemfire.cache.query.internal.index;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
 +
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.HashMap;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +
 +import org.junit.After;
 +import org.junit.Before;
 +import org.junit.Test;
 +import org.junit.experimental.categories.Category;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
++import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.PartitionAttributesFactory;
 +import com.gemstone.gemfire.cache.Region;
++import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.query.CacheUtils;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.IndexType;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryInvalidException;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.SelectResults;
 +import com.gemstone.gemfire.cache.query.Struct;
 +import com.gemstone.gemfire.cache.query.data.Portfolio;
 +import com.gemstone.gemfire.cache.query.functional.StructSetOrResultsSet;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverAdapter;
 +import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexManager.TestHook;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
 +
 +/**
 + * 
 + * @author vaibhav
 + */
 +@Category(IntegrationTest.class)
 +public class IndexUseJUnitTest
 +{
 +
 +  Region region;
 +
 +  QueryService qs;
 +
 +  @Before
 +  public void setUp() throws Exception {
 +    CacheUtils.startCache();
 +    region = CacheUtils.createRegion("pos", Portfolio.class);
 +    region.put("0", new Portfolio(0));
 +    region.put("1", new Portfolio(1));
 +    region.put("2", new Portfolio(2));
 +    region.put("3", new Portfolio(3));
 +
 +    qs = CacheUtils.getQueryService();
 +    qs.createIndex("statusIndex", IndexType.FUNCTIONAL, "status", "/pos");
 +    qs.createIndex("idIndex", IndexType.FUNCTIONAL, "ID", "/pos");
 +    qs.createIndex("secIdIndex", IndexType.FUNCTIONAL, "P1.secId", "/pos");
 +    qs.createIndex("secIdIndex2", IndexType.FUNCTIONAL, "P2.secId", "/pos");
 +    qs.createIndex("p1secindex", "p.position1.secId", " /pos p ");
 +  }
 +
 +  @After
 +  public void tearDown() throws Exception {
 +    CacheUtils.closeCache();
 +    IndexManager indexManager = ((LocalRegion)region).getIndexManager();
 +    if (indexManager != null)
 +      indexManager.destroy();
 +    IndexManager.TEST_RANGEINDEX_ONLY = false;
 +    
 +  }
 +
 +  @Test
 +  public void testIndexUseSingleCondition() throws Exception {
 +    String testData[][] = { { "status", "'active'" }, { "ID", "2" },
 +        { "P1.secId", "'IBM'" }, };
 +    String operators[] = { "=", "<>", "!=", "<", "<=", ">", ">=" };
 +    for (int i = 0; i < operators.length; i++) {
 +      String operator = operators[i];
 +      for (int j = 0; j < testData.length; j++) {
 +        Query q = qs.newQuery("SELECT DISTINCT * FROM /pos where "
 +            + testData[j][0] + " " + operator + " " + testData[j][1]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        q.execute();
 +        if (!observer.isIndexesUsed) {
-           fail("Index not uesd for operator '" + operator + "'");
++          fail("Index not used for operator '" + operator + "'");
 +        }
 +      }
 +    }
 +  }
 +
 +  @Test
 +  public void testIndexUseMultipleConditions() throws Exception {
 +    String testData[][] = { { "P1.secType = 'a'", "0" },
 +        { "status = 'active' AND ID = 2", "1" },
 +        { "status = 'active' AND ID = 2 AND P1.secId  = 'IBM'", "1" },
 +        { "status = 'active' OR ID = 2", "2" },
 +        { "status = 'active' OR ID = 2 OR P1.secId  = 'IBM'", "3" },
 +        { "status = 'active' AND ID = 2 OR P1.secId  = 'IBM'", "2" },
 +        { "status = 'active' AND ( ID = 2 OR P1.secId  = 'IBM')", "1" },
 +        { "status = 'active' OR ID = 2 AND P1.secId  = 'IBM'", "2" },
 +        { "(status = 'active' OR ID = 2) AND P1.secId  = 'IBM'", "1" },
 +        { "NOT (status = 'active') AND ID = 2", "1" },
 +        { "status = 'active' AND NOT( ID = 2 )", "1" },
 +        { "NOT (status = 'active') OR ID = 2", "2" },
 +        { "status = 'active' OR NOT( ID = 2 )", "2" },
 +        { "status = 'active' AND P1.secType = 'a'", "1" },
 +        { "status = 'active' OR P1.secType = 'a'", "0" },
 +        { "status = 'active' AND ID =1 AND P1.secType = 'a'", "1" },
 +        { "status = 'active' AND ID = 1 OR P1.secType = 'a'", "0" },
 +        { "status = 'active' OR ID = 1 AND P1.secType = 'a'", "2" },
 +        { "P2.secId = null", "1" }, { "IS_UNDEFINED(P2.secId)", "1" },
 +        { "IS_DEFINED(P2.secId)", "1" }, { "P2.secId = UNDEFINED", "0" }, };
 +    for (int j = 0; j < testData.length; j++) {
 +      Query q = qs.newQuery("SELECT DISTINCT * FROM /pos where "
 +          + testData[j][0]);
 +      QueryObserverImpl observer = new QueryObserverImpl();
 +      QueryObserverHolder.setInstance(observer);
 +      q.execute();
 +      if (observer.indexesUsed.size() != Integer.parseInt(testData[j][1])) {
 +        fail("Wrong Index use for " + testData[j][0] + "\n Indexes used "
 +            + observer.indexesUsed);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Test to check if Region object is passed as bind argument, the index
 +   * utilization occurs or not
 +   * @author ashahid
 +   */
 +  @Test
 +  public void testBug36421_part1() {
 +    try {
 +      String testData[][] = { { "status", "'active'" }, };
 +      String operators[] = { "=" };
 +      for (int i = 0; i < operators.length; i++) {
 +        String operator = operators[i];
 +        for (int j = 0; j < testData.length; j++) {
 +          Query q = qs.newQuery("SELECT DISTINCT * FROM $1 where "
 +              + testData[j][0] + " " + operator + " " + testData[j][1]);
 +          QueryObserverImpl observer = new QueryObserverImpl();
 +          QueryObserverHolder.setInstance(observer);
 +          q.execute(new Object[] { CacheUtils.getRegion("/pos") });
 +          if (!observer.isIndexesUsed) {
-             fail("Index not uesd for operator '" + operator + "'");
++            fail("Index not used for operator '" + operator + "'");
 +          }
 +        }
 +      }
 +    }
 +    catch (Exception e) {
 +      CacheUtils.getLogger().error(e);
-       fail("Test faield due to exception =" + e);
++      fail("Test failed due to exception =" + e);
 +    }
 +  }
 +
 +  /**
 +   * Test to check if Region short cut method is used for querying, the index
 +   * utilization occurs or not
 +   * @author ashahid
 +   */
 +  @Test
 +  public void testBug36421_part2() {
 +    try {
 +      String testData[][] = { { "status", "'active'" }, };
 +      String operators[] = { "=" };
 +      for (int i = 0; i < operators.length; i++) {
 +        String operator = operators[i];
 +        for (int j = 0; j < testData.length; j++) {
 +
 +          QueryObserverImpl observer = new QueryObserverImpl();
 +          QueryObserverHolder.setInstance(observer);
 +          CacheUtils.getRegion("/pos").query(
 +              testData[j][0] + " " + operator + " " + testData[j][1]);
 +          if (!observer.isIndexesUsed) {
-             fail("Index not uesd for operator '" + operator + "'");
++            fail("Index not used for operator '" + operator + "'");
 +          }
 +        }
 +      }
 +    }
 +    catch (Exception e) {
 +      CacheUtils.getLogger().error(e);
 +      fail("Test failed due to exception =" + e);
 +    }
 +  }
 +
 +  /**
 +   * Test to check if a parametrized query when using different bind arguments
 +   * of Region uses the index correctly
 +   * @author ashahid
 +   */
 +  @Test
 +  public void testBug36421_part3() {
 +
 +    Query q = null;
 +    try {
 +      q = qs.newQuery("SELECT DISTINCT * FROM $1 z where z.status = 'active'");
 +      QueryObserverImpl observer = new QueryObserverImpl();
 +      QueryObserverHolder.setInstance(observer);
 +      q.execute(new Object[] { CacheUtils.getRegion("/pos") });
 +      if (!observer.isIndexesUsed) {
 +        fail("Index not uesd for operator '='");
 +      }
 +      assertTrue(observer.indexesUsed.get(0).equals("statusIndex"));
 +      region = CacheUtils.createRegion("pos1", Portfolio.class);
 +      region.put("0", new Portfolio(0));
 +      region.put("1", new Portfolio(1));
 +      region.put("2", new Portfolio(2));
 +      region.put("3", new Portfolio(3));
 +      qs.createIndex("statusIndex1", IndexType.FUNCTIONAL, "pf1.status",
 +          "/pos1 pf1");
 +      region.put("4", new Portfolio(4));
 +      observer = new QueryObserverImpl();
 +      QueryObserverHolder.setInstance(observer);
 +      q.execute(new Object[] { CacheUtils.getRegion("/pos1") });
 +      if (!observer.isIndexesUsed) {
-         fail("Index not uesd for operator'='");
++        fail("Index not used for operator'='");
 +      }
 +      assertTrue(observer.indexesUsed.get(0).equals("statusIndex1"));
 +
 +    }
 +    catch (Exception e) {
 +      CacheUtils.getLogger().error(e);
 +      fail("Test failed due to exception =" + e);
 +    }
 +  }
 +
 +  /**
 +   * Test to check if Region short cut method is used for querying, the Primary
 +   * key index utilization occurs or not 
 +   * @author ashahid
 +   */
 +  @Test
 +  public void testBug36421_part4() {
 +//    Query q = null;
 +    try {
 +      qs.createIndex("pkIndex", IndexType.PRIMARY_KEY, "pk", "/pos");
 +      QueryObserverImpl observer = new QueryObserverImpl();
 +      QueryObserverHolder.setInstance(observer);
 +      SelectResults rs = CacheUtils.getRegion("/pos").query("pk = '2'");
 +      if (!observer.isIndexesUsed) {
 +        fail("Index not uesd for operator '='");
 +      }
 +      assertTrue(rs.size() == 1);
 +      assertTrue(((Portfolio)rs.iterator().next()).pkid.equals("2"));
 +      assertTrue(observer.indexesUsed.get(0).equals("pkIndex"));
 +      CacheUtils.getRegion("/pos").put("7", new Portfolio(7));
 +      observer = new QueryObserverImpl();
 +      QueryObserverHolder.setInstance(observer);
 +      rs = CacheUtils.getRegion("/pos").query("pk = '7'");
 +      if (!observer.isIndexesUsed) {
-         fail("Index not uesd for operator '='");
++        fail("Index not used for operator '='");
 +      }
 +      assertTrue(rs.size() == 1);
 +      assertTrue(((Portfolio)rs.iterator().next()).pkid.equals("7"));
 +      assertTrue(observer.indexesUsed.get(0).equals("pkIndex"));
 +    }
 +    catch (Exception e) {
 +      CacheUtils.getLogger().error(e);
 +      fail("Test failed due to exception =" + e);
 +    }
 +  }
 +  
 +  @Test
 +  public void testMapIndexUsageAllKeys() throws Exception {
++    try {
++      IndexManager.TEST_RANGEINDEX_ONLY = true;
++      evaluateMapTypeIndexUsageAllKeys();
++    }
++    finally {
++      IndexManager.TEST_RANGEINDEX_ONLY = false;
++    }
++  }
++  
++  private void evaluateMapTypeIndexUsageAllKeys() throws Exception {
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    int ID =1;
 +    //Add some test data now
 +    //Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for(; ID <=30; ++ID) {
 +      MapKeyIndexData mkid = new MapKeyIndexData(ID);
 +      for(int j =1; j<= ID;++j) {
 +        mkid.maap.put("key1", j*1);
 +        mkid.maap.put("key2", j*2);
 +        mkid.maap.put("key3", j*3);
 +      }
 +      testRgn.put(ID, mkid);
 +    }
 +    String queries[] = {
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 16"
 +       /* "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 16" ,*/        
 +    };
 +    String queriesIndexNotUsed[] = {        
 +         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 16"         
 +     };
 +    Object r[][]= new Object[queries.length][2];
 +    
 +    qs = CacheUtils.getQueryService();
 +    
 +  //Execute Queries without Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +        Query q = null;
 +        try {
 +            q = CacheUtils.getQueryService().newQuery(queries[i]);
 +            CacheUtils.getLogger().info("Executing query: " + queries[i]);              
 +            r[i][0] = q.execute();         
 +          CacheUtils.log("Executed query: " + queries[i] );
 +        } catch (Exception e) {
 +            e.printStackTrace();
 +            fail(q.getQueryString());
 +        }
 +    }  
 +    
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "objs.maap[*]",
 +        "/testRgn objs");
 +    
 +          //Execute Queries with Indexes
 +      for (int i = 0; i < queries.length; i++) {
 +          Query q = null;
 +          try {
 +              q = CacheUtils.getQueryService().newQuery(queries[i]);
 +              CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +              QueryObserverImpl observer = new QueryObserverImpl();
 +              QueryObserverHolder.setInstance(observer);
 +              r[i][1] = q.execute();
 +              CacheUtils.log("Executing query: " + queries[i] + " with index created");
 +              if(!observer.isIndexesUsed){
-                   fail("Index is NOT uesd");
++                  fail("Index is NOT used");
 +              }              
 +              Iterator itr = observer.indexesUsed.iterator();
 +              assertTrue(itr.hasNext());
 +              String temp = itr.next().toString();
 +              assertEquals(temp,"Index1");       
 +              
 +          } catch (Exception e) {
 +              e.printStackTrace();
 +              fail(q.getQueryString());
 +          }
 +      }
 +      StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +      ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r,queries.length,queries);
 +      
 +      //Test queries index not used
 +      for (int i = 0; i < queriesIndexNotUsed.length; i++) {
 +        Query q = null;
 +        try {
 +            q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
 +            CacheUtils.getLogger().info("Executing query: " + queriesIndexNotUsed[i]);
 +            QueryObserverImpl observer = new QueryObserverImpl();
 +            QueryObserverHolder.setInstance(observer);            
 +            CacheUtils.log("Executing query: " + queriesIndexNotUsed[i] + " with index created");
 +            q.execute();
 +            assertFalse(observer.isIndexesUsed);                          
 +            Iterator itr = observer.indexesUsed.iterator();
 +            assertFalse(itr.hasNext());                   
 +            
 +        } catch (Exception e) {
 +            e.printStackTrace();
 +            fail(q.getQueryString());
 +        }
 +    }
 +      
 +  }
 +  
 +  @Test
 +  public void testCompactMapIndexUsageWithIndexOnSingleKey() throws Exception
 +  {
-     QueryService qs;
-     qs = CacheUtils.getQueryService();
++    String queries[] = {
++        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3"};
++    String queriesIndexNotUsed[] = {
++        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 3"};
++
++    
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    int ID = 1;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (; ID <= 30; ++ID) {
 +      MapKeyIndexData mkid = new MapKeyIndexData(ID);
 +      for (int j = 1; j <= ID; ++j) {
 +        mkid.addKeyValue("key1", j * 1);
 +        mkid.addKeyValue("key2", j * 2);
 +        mkid.addKeyValue("key3", j * 3);
 +      }
 +      testRgn.put(ID, mkid);
 +    }
- 
-     qs = CacheUtils.getQueryService();
-     String queries[] = { "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3" };
- 
-     String queriesIndexNotUsed[] = {
-         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 3",
-         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key3'] >= 3", };
- 
-     Object r[][] = new Object[queries.length][2];
- 
-     // Execute Queries without Indexes
-     for (int i = 0; i < queries.length; i++) {
-       Query q = null;
-       try {
-         q = CacheUtils.getQueryService().newQuery(queries[i]);
-         CacheUtils.getLogger().info("Executing query: " + queries[i]);
-         r[i][0] = q.execute();
-         CacheUtils.log("Executed query: " + queries[i]);
-       }
-       catch (Exception e) {
-         e.printStackTrace();
-         fail(q.getQueryString());
-       }
-     }
- 
-     Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
-         "objs.maap['key2']", "/testRgn objs");
-     assertTrue(i1 instanceof CompactRangeIndex);
-     // Execute Queries with Indexes
-     for (int i = 0; i < queries.length; i++) {
-       Query q = null;
-       try {
-         q = CacheUtils.getQueryService().newQuery(queries[i]);
-         CacheUtils.getLogger().info("Executing query: " + queries[i]);
-         QueryObserverImpl observer = new QueryObserverImpl();
-         QueryObserverHolder.setInstance(observer);
-         r[i][1] = q.execute();
-         CacheUtils.log("Executing query: " + queries[i]
-             + " with index created");
-         if (!observer.isIndexesUsed) {
-           fail("Index is NOT uesd");
-         }
-         Iterator itr = observer.indexesUsed.iterator();
-         assertTrue(itr.hasNext());
-         String temp = itr.next().toString();
-         assertEquals(temp, "Index1");
- 
-       }
-       catch (Exception e) {
-         e.printStackTrace();
-         fail(q.getQueryString());
-       }
-     }
-     StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
-     ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
- 
-     // Test queries index not used
-     for (int i = 0; i < queriesIndexNotUsed.length; i++) {
-       Query q = null;
-       try {
-         q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
-         CacheUtils.getLogger().info(
-             "Executing query: " + queriesIndexNotUsed[i]);
-         QueryObserverImpl observer = new QueryObserverImpl();
-         QueryObserverHolder.setInstance(observer);
-         CacheUtils.log("Executing query: " + queriesIndexNotUsed[i]
-             + " with index created");
-         q.execute();
-         assertFalse(observer.isIndexesUsed);
-         Iterator itr = observer.indexesUsed.iterator();
-         assertFalse(itr.hasNext());
- 
-       }
-       catch (Exception e) {
-         e.printStackTrace();
-         fail(q.getQueryString());
-       }
-     }
++    
++    evaluateMapTypeIndexUsage("objs.maap['key2']", "/testRgn objs", queries, queriesIndexNotUsed, CompactRangeIndex.class);
 +
 +    String query = "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.liist[0] >= 2";
 +    SelectResults withoutIndex, withIndex;
 +    Query q = CacheUtils.getQueryService().newQuery(query);
 +    CacheUtils.getLogger().info("Executing query: " + query);
 +    withoutIndex = (SelectResults)q.execute();
 +    CacheUtils.log("Executed query: " + query);
 +
 +    Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL, "objs.liist[0]",
 +        "/testRgn objs");
 +    assertTrue(i2 instanceof CompactRangeIndex);
 +    CacheUtils.getLogger().info("Executing query: " + query);
 +    QueryObserverImpl observer = new QueryObserverImpl();
 +    QueryObserverHolder.setInstance(observer);
 +    withIndex = (SelectResults)q.execute();
 +    CacheUtils.log("Executing query: " + query + " with index created");
 +    if (!observer.isIndexesUsed) {
 +      fail("Index is NOT uesd");
 +    }
 +    Iterator itr = observer.indexesUsed.iterator();
 +    assertTrue(itr.hasNext());
 +    String temp = itr.next().toString();
 +    assertEquals(temp, "Index2");
 +
-     ssOrrs = new StructSetOrResultsSet();
++    StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +    ssOrrs.CompareQueryResultsWithoutAndWithIndexes(new Object[][] { {
 +        withoutIndex, withIndex } }, 1,queries);
 +
 +  }
 +  @Test
 +  public void testCompactMapIndexUsageWithIndexOnMultipleKeys() throws Exception
 +  {
-     QueryService qs;
-     qs = CacheUtils.getQueryService();
-     LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
-     int ID = 1;
-     // Add some test data now
-     // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
-     // and so on
-     for (; ID <= 30; ++ID) {
-       MapKeyIndexData mkid = new MapKeyIndexData(ID);
-       for (int j = 1; j <= ID; ++j) {
-         mkid.addKeyValue("key1", j * 1);
-         mkid.addKeyValue("key2", j * 2);
-         mkid.addKeyValue("key3", j * 3);
-       }
-       testRgn.put(ID, mkid);
-     }
- 
-     qs = CacheUtils.getQueryService();
 +    String queries[] = {
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key3'] >= 3" };
- 
 +    String queriesIndexNotUsed[] = {
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 16",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key4'] >= 16", };
 +
-     Object r[][] = new Object[queries.length][2];
- 
-     // Execute Queries without Indexes
-     for (int i = 0; i < queries.length; i++) {
-       Query q = null;
-       try {
-         q = CacheUtils.getQueryService().newQuery(queries[i]);
-         CacheUtils.getLogger().info("Executing query: " + queries[i]);
-         r[i][0] = q.execute();
-         CacheUtils.log("Executed query: " + queries[i]);
-       }
-       catch (Exception e) {
-         e.printStackTrace();
-         fail(q.getQueryString());
-       }
-     }
- 
-     Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
-         "objs.maap['key2','key3']", "/testRgn objs");
-     assertTrue(i1 instanceof CompactMapRangeIndex);
-     // Execute Queries with Indexes
-     for (int i = 0; i < queries.length; i++) {
-       Query q = null;
-       try {
-         q = CacheUtils.getQueryService().newQuery(queries[i]);
-         CacheUtils.getLogger().info("Executing query: " + queries[i]);
-         QueryObserverImpl observer = new QueryObserverImpl();
-         QueryObserverHolder.setInstance(observer);
-         r[i][1] = q.execute();
-         CacheUtils.log("Executing query: " + queries[i]
-             + " with index created");
-         if (!observer.isIndexesUsed) {
-           fail("Index is NOT uesd");
-         }
-         Iterator itr = observer.indexesUsed.iterator();
-         assertTrue(itr.hasNext());
-         String temp = itr.next().toString();
-         assertEquals(temp, "Index1");
- 
-       }
-       catch (Exception e) {
-         e.printStackTrace();
-         fail(q.getQueryString());
-       }
-     }
-     StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
-     ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
- 
-     // Test queries index not used
-     for (int i = 0; i < queriesIndexNotUsed.length; i++) {
-       Query q = null;
-       try {
-         q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
-         CacheUtils.getLogger().info(
-             "Executing query: " + queriesIndexNotUsed[i]);
-         QueryObserverImpl observer = new QueryObserverImpl();
-         QueryObserverHolder.setInstance(observer);
-         CacheUtils.log("Executing query: " + queriesIndexNotUsed[i]
-             + " with index created");
-         q.execute();
-         assertFalse(observer.isIndexesUsed);
-         Iterator itr = observer.indexesUsed.iterator();
-         assertFalse(itr.hasNext());
- 
-       }
-       catch (Exception e) {
-         e.printStackTrace();
-         fail(q.getQueryString());
-       }
-     }
- 
-   }
-       
-   @Test
-   public void testMapIndexUsageWithIndexOnMultipleKeys() throws Exception
-   {
-     IndexManager.TEST_RANGEINDEX_ONLY = true;
-     QueryService qs;
-     qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    int ID = 1;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (; ID <= 30; ++ID) {
 +      MapKeyIndexData mkid = new MapKeyIndexData(ID);
 +      for (int j = 1; j <= ID; ++j) {
 +        mkid.addKeyValue("key1", j * 1);
 +        mkid.addKeyValue("key2", j * 2);
 +        mkid.addKeyValue("key3", j * 3);
 +      }
 +      testRgn.put(ID, mkid);
 +    }
++    evaluateMapTypeIndexUsage("objs.maap['key2','key3']", "/testRgn objs", queries, queriesIndexNotUsed, CompactMapRangeIndex.class);
++  }
++      
++  @Test
++  public void testMapIndexUsageWithIndexOnMultipleKeys() throws Exception
++  {
++    try {
++      IndexManager.TEST_RANGEINDEX_ONLY = true;
++      String queries[] = {
++          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3",
++          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key3'] >= 3" };
++      String queriesIndexNotUsed[] = {
++          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 16",
++          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key4'] >= 16", };
 +
-     qs = CacheUtils.getQueryService();
-     String queries[] = {
-         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3",
-         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key3'] >= 3" };
- 
-     String queriesIndexNotUsed[] = {
-         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap.get('key2') >= 16",
-         "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key4'] >= 16", };
- 
++      
++      LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
++      int ID = 1;
++      // Add some test data now
++      // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
++      // and so on
++      for (; ID <= 30; ++ID) {
++        MapKeyIndexData mkid = new MapKeyIndexData(ID);
++        for (int j = 1; j <= ID; ++j) {
++          mkid.addKeyValue("key1", j * 1);
++          mkid.addKeyValue("key2", j * 2);
++          mkid.addKeyValue("key3", j * 3);
++        }
++        testRgn.put(ID, mkid);
++      }
++      
++      evaluateMapTypeIndexUsage("objs.maap['key2','key3']", "/testRgn objs", queries, queriesIndexNotUsed, MapRangeIndex.class);
++    }
++    finally {
++      IndexManager.TEST_RANGEINDEX_ONLY = false;
++    }
++  }
++  
++  private void evaluateMapTypeIndexUsage(String indexExpression, String fromClause, String[] queries, String[] queriesIndexNotUsed, Class expectedIndexClass) throws Exception {
++    QueryService qs = CacheUtils.getQueryService();
++   
 +    Object r[][] = new Object[queries.length][2];
 +
 +    // Execute Queries without Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        r[i][0] = q.execute();
 +        CacheUtils.log("Executed query: " + queries[i]);
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
-         "objs.maap['key2','key3']", "/testRgn objs");
-     assertTrue(i1 instanceof MapRangeIndex);
++        indexExpression, fromClause);
++    assertTrue(i1.getClass().equals(expectedIndexClass));
++    
 +    // Execute Queries with Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        r[i][1] = q.execute();
 +        CacheUtils.log("Executing query: " + queries[i]
 +            + " with index created");
 +        if (!observer.isIndexesUsed) {
-           fail("Index is NOT uesd");
++          fail("Index is NOT used");
 +        }
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertTrue(itr.hasNext());
 +        String temp = itr.next().toString();
 +        assertEquals(temp, "Index1");
 +
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +    StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +    ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
 +
 +    // Test queries index not used
 +    for (int i = 0; i < queriesIndexNotUsed.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
 +        CacheUtils.getLogger().info(
 +            "Executing query: " + queriesIndexNotUsed[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        CacheUtils.log("Executing query: " + queriesIndexNotUsed[i]
 +            + " with index created");
 +        q.execute();
 +        assertFalse(observer.isIndexesUsed);
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertFalse(itr.hasNext());
 +
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
- 
 +  }
 +
 +  @Test
 +  public void testIndexUsageWithOrderBy() throws Exception
 +  {
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    
 +    int numObjects = 30;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (int i=0; i < numObjects; i++) {
 +      Portfolio p = new Portfolio(i);
 +      p.pkid = ("" +(numObjects - i));
 +      testRgn.put("" + i, p);
 +    }
 +
 +    qs = CacheUtils.getQueryService();
 +    String queries[] = {
 +        "SELECT DISTINCT * FROM /testRgn p  WHERE p.ID <= 10 order by p.pkid asc limit 1",
 +        "SELECT DISTINCT * FROM /testRgn p  WHERE p.ID <= 10 order by p.pkid desc limit 1",
 +    };
 +
 +    Object r[][] = new Object[queries.length][2];
 +
 +    // Execute Queries without Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        // verify individual result
 +        SelectResults sr = (SelectResults)q.execute();
 +        List results = sr.asList();
 +        for (int rows=0; rows < results.size(); rows++) {
 +          Portfolio p = (Portfolio)results.get(0);
 +          CacheUtils.getLogger().info("p: " + p);
 +          if (i == 0) {
 +            assertEquals(p.getID(), 10);
 +            assertEquals(p.pkid, "" + (numObjects - 10));
 +          } else if (i == 1) {
 +            assertEquals(p.getID(), 0);
 +            assertEquals(p.pkid, "" + numObjects);
 +          }
 +        }
 +        r[i][0] = sr;
 +        CacheUtils.log("Executed query: " + queries[i]);
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "p.ID", "/testRgn p");
 + 
 +    // Execute Queries with Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        SelectResults sr = (SelectResults)q.execute();
 +        List results = sr.asList();
 +        for (int rows=0; rows < results.size(); rows++) {
 +          Portfolio p = (Portfolio)results.get(0);
 +          CacheUtils.getLogger().info("index p: " + p);
 +          if (i == 0) {
 +            assertEquals(p.getID(), 10);
 +            assertEquals(p.pkid, "" + (numObjects - 10));
 +          } else if (i == 1) {
 +            assertEquals(p.getID(), 0);
 +            assertEquals(p.pkid, "" + numObjects);
 +          }
 +        }
 +        r[i][1] = sr;
 +        //r[i][1] = q.execute();
 +        CacheUtils.log("Executing query: " + queries[i]
 +            + " with index created");
 +        if (!observer.isIndexesUsed) {
 +          fail("Index is NOT uesd");
 +        }
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertTrue(itr.hasNext());
 +        String temp = itr.next().toString();
 +        assertEquals(temp, "Index1");
 +      }
 +      
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +    StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +    ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
 +  }
 +  
 +  @Test
 +  public void testIndexUsageWithOrderBy3() throws Exception
 +  {
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    
 +    int numObjects = 30;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (int i=0; i < numObjects; i++) {
 +      Portfolio p = new Portfolio(i);
 +      p.pkid = ("" +(numObjects - i));
 +      testRgn.put("" + i, p);
 +    }
 +
 +    qs = CacheUtils.getQueryService();
 +    String queries[] = {
 +        "SELECT DISTINCT * FROM /testRgn p  WHERE p.ID <= 10 order by ID asc limit 1",
 +        "SELECT DISTINCT * FROM /testRgn p  WHERE p.ID <= 10 order by p.ID desc limit 1",
 +    };
 +
 +    Object r[][] = new Object[queries.length][2];
 +
 +    
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "p.ID", "/testRgn p");
 + 
 +    // Execute Queries with Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        SelectResults sr = (SelectResults)q.execute();
 +        List results = sr.asList();
 +        for (int rows=0; rows < results.size(); rows++) {
 +          Portfolio p = (Portfolio)results.get(0);
 +          CacheUtils.getLogger().info("index p: " + p);
 +          if (i == 0) {
 +            assertEquals(p.getID(), 0);
 +            
 +          } else if (i == 1) {
 +            assertEquals(p.getID(), 10);
 +            
 +          }
 +        }
 +        r[i][1] = sr;
 +        //r[i][1] = q.execute();
 +        CacheUtils.log("Executing query: " + queries[i]
 +            + " with index created");
 +        if (!observer.isIndexesUsed) {
 +          fail("Index is NOT uesd");
 +        }
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertTrue(itr.hasNext());
 +        String temp = itr.next().toString();
 +        assertEquals(temp, "Index1");
 +      }
 +      
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +   
 +  }
 +
 +  @Test
 +  public void testIndexUsageWithOrderBy2() throws Exception
 +  {
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    
 +    int numObjects = 30;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (int i=0; i < numObjects; i++) {
 +      Portfolio p = new Portfolio(i % 2);
 +      p.createTime = (numObjects - i);
 +      testRgn.put("" + i, p);
 +    }
 +
 +    qs = CacheUtils.getQueryService();
 +    String queries[] = {
 +        "SELECT DISTINCT p.key, p.value FROM /testRgn.entrySet p  WHERE p.value.ID <= 10 order by p.value.createTime asc limit 1",
 +        "SELECT DISTINCT p.key, p.value FROM /testRgn.entrySet p  WHERE p.value.ID <= 10 order by p.value.createTime desc limit 1",
 +    };
 +
 +    Object r[][] = new Object[queries.length][2];
 +
 +    // Execute Queries without Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        // verify individual result
 +        SelectResults sr = (SelectResults)q.execute();
 +        List results = sr.asList();
 +        for (int rows=0; rows < results.size(); rows++) {
 +          Struct s = (Struct)results.get(0);
 +          Portfolio p = (Portfolio)s.get("value");
 +          CacheUtils.getLogger().info("p: " + p);
 +          if (i == 0) {
 +            assertEquals(p.createTime, 1);
 +          } else if (i == 1) {
 +            assertEquals(p.createTime, numObjects);
 +          }
 +        }
 +        r[i][0] = sr;
 +        CacheUtils.log("Executed query: " + queries[i]);
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "p.value.ID", "/testRgn.entrySet p");
 + 
 +    // Execute Queries with Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        SelectResults sr = (SelectResults)q.execute();
 +        List results = sr.asList();
 +        for (int rows=0; rows < results.size(); rows++) {
 +          Struct s = (Struct)results.get(0);
 +          Portfolio p = (Portfolio)s.get("value");
 +          CacheUtils.getLogger().info("index p: " + p);
 +          if (i == 0) {
 +            assertEquals(p.createTime, 1);
 +          } else if (i == 1) {
 +            assertEquals(p.createTime, numObjects);
 +          }
 +        }
 +        r[i][1] = sr;
 +        //r[i][1] = q.execute();
 +        CacheUtils.log("Executing query: " + queries[i]
 +            + " with index created");
 +        if (!observer.isIndexesUsed) {
 +          fail("Index is NOT uesd");
 +        }
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertTrue(itr.hasNext());
 +        String temp = itr.next().toString();
 +        assertEquals(temp, "Index1");
 +      }
 +      
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +    StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +    ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
 +  }
 +
 +  @Test
 +  public void testIncorrectIndexOperatorSyntax() {
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    int ID =1;
 +    //Add some test data now
 +    //Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for(; ID <=30; ++ID) {
 +      MapKeyIndexData mkid = new MapKeyIndexData(ID);
 +      for(int j =1; j<= ID;++j) {
 +        mkid.maap.put("key1", j*1);
 +        mkid.maap.put("key2", j*2);
 +        mkid.maap.put("key3", j*3);
 +      }
 +      testRgn.put(ID, mkid);
 +    }
 +    
 +    
 +    qs = CacheUtils.getQueryService();
 +    try { 
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap[*] >= 3");
 +    fail("Should have thrown exception");
 +    }catch(QueryInvalidException qe) {
 +      //ok      
 +    }           
 +    
 +    try { 
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key1','key2'] >= 3");
 +    fail("Should have thrown exception");
 +    }catch(QueryInvalidException qe) {
 +      //ok      
 +    }   
 +      
 +  }
 +  
 +  @Test
 +  public void testRangeGroupingBehaviourOfCompactMapIndex() throws Exception {
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    int ID = 1;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (; ID <= 30; ++ID) {
 +      MapKeyIndexData mkid = new MapKeyIndexData(ID);
 +      for (int j = 1; j <= ID; ++j) {
 +        mkid.addKeyValue("key1", j * 1);
 +        mkid.addKeyValue("key2", j * 2);
 +        mkid.addKeyValue("key3", j * 3);
 +      }
 +      testRgn.put(ID, mkid);
 +    }
 +
 +    qs = CacheUtils.getQueryService();
 +    String queries[] = {
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3 and itr1.maap['key2'] <=18",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key3'] >= 3  and  itr1.maap['key3'] >= 13 ",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3  and  itr1.maap['key3'] >= 13 ",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3  and  itr1.maap['key3'] < 18 "
 +        
 +    };
 +
 +
 +    Object r[][] = new Object[queries.length][2];
 +
 +    // Execute Queries without Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        r[i][0] = q.execute();
 +        CacheUtils.log("Executed query: " + queries[i]);
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "objs.maap['key2','key3']", "/testRgn objs");
 +    assertTrue(i1 instanceof CompactMapRangeIndex);
 +    // Execute Queries with Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        r[i][1] = q.execute();
 +        CacheUtils.log("Executing query: " + queries[i]
 +            + " with index created");
 +        if (!observer.isIndexesUsed) {
 +          fail("Index is NOT uesd");
 +        }
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertTrue(itr.hasNext());
 +        String temp = itr.next().toString();
 +        assertEquals(temp, "Index1");
 +
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +    StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +    ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
 +    
 +  }
 +  
 +  @Test
 +  public void testRangeGroupingBehaviourOfMapIndex() throws Exception {
 +    IndexManager.TEST_RANGEINDEX_ONLY = true;
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    int ID = 1;
 +    // Add some test data now
 +    // Add 5 main objects. 1 will contain key1, 2 will contain key1 & key2
 +    // and so on
 +    for (; ID <= 30; ++ID) {
 +      MapKeyIndexData mkid = new MapKeyIndexData(ID);
 +      for (int j = 1; j <= ID; ++j) {
 +        mkid.addKeyValue("key1", j * 1);
 +        mkid.addKeyValue("key2", j * 2);
 +        mkid.addKeyValue("key3", j * 3);
 +      }
 +      testRgn.put(ID, mkid);
 +    }
 +
 +    qs = CacheUtils.getQueryService();
 +    String queries[] = {
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3 and itr1.maap['key2'] <=18",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key3'] >= 3  and  itr1.maap['key3'] >= 13 ",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3  and  itr1.maap['key3'] >= 13 ",
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3  and  itr1.maap['key3'] < 18 "
 +        
 +    };
 +
 +
 +    Object r[][] = new Object[queries.length][2];
 +
 +    // Execute Queries without Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        r[i][0] = q.execute();
 +        CacheUtils.log("Executed query: " + queries[i]);
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "objs.maap['key2','key3']", "/testRgn objs");
 +    assertTrue(i1 instanceof MapRangeIndex);
 +    // Execute Queries with Indexes
 +    for (int i = 0; i < queries.length; i++) {
 +      Query q = null;
 +      try {
 +        q = CacheUtils.getQueryService().newQuery(queries[i]);
 +        CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        r[i][1] = q.execute();
 +        CacheUtils.log("Executing query: " + queries[i]
 +            + " with index created");
 +        if (!observer.isIndexesUsed) {
 +          fail("Index is NOT uesd");
 +        }
 +        Iterator itr = observer.indexesUsed.iterator();
 +        assertTrue(itr.hasNext());
 +        String temp = itr.next().toString();
 +        assertEquals(temp, "Index1");
 +
 +      }
 +      catch (Exception e) {
 +        e.printStackTrace();
 +        fail(q.getQueryString());
 +      }
 +    }
 +    StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +    ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length,queries);
 +    
 +  }
 +  
 +  @Test
 +  public void testMapIndexUsableQueryOnEmptyRegion() throws Exception
 +  {
- 
++    IndexManager.TEST_RANGEINDEX_ONLY = true;
 +    QueryService qs;
 +    qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "objs.maap['key2','key3']", "/testRgn objs");
 +    qs = CacheUtils.getQueryService();
 +    // Execute Queries without Indexes
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.maap['key2'] >= 3 ");
 +    SelectResults sr = (SelectResults)q.execute();
 +    assertTrue(sr.isEmpty());
 +
 +  }
 +
 +  @Test
 +  public void testSizeEstimateLTInRangeIndexForNullMap() throws Exception {
 +    QueryService qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    //Create indexes
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "p.status", "/testRgn p, p.positions");
 +    Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL,
 +        "p.ID", "/testRgn p, p.positions");
 +    
 +    //put values
 +    testRgn.put(0, new Portfolio(0));
 +    testRgn.put(1, new Portfolio(1));
 +
 +    //Set TestHook in RangeIndex
 +    TestHook hook = new RangeIndexTestHook();
 +    RangeIndex.setTestHook(hook);
 +    // Execute Queries without Indexes
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "<trace> SELECT * FROM /testRgn p, p.positions where p.status = 'active' AND p.ID > 0 ");
 +    
 +    //Following should throw NullPointerException.
 +    SelectResults sr = (SelectResults)q.execute();
 +    
 +    assertTrue("RangeIndexTestHook was not hooked for spot 2", ((RangeIndexTestHook)hook).isHooked(2));
 +    RangeIndex.setTestHook(null);
 +  }
 +
 +  @Test
 +  public void testSizeEstimateGTInRangeIndexForNullMap() throws Exception {
 +    QueryService qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    //Create indexes
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "p.status", "/testRgn p, p.positions");
 +    Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL,
 +        "p.ID", "/testRgn p, p.positions");
 +    
 +    //put values
 +    testRgn.put(0, new Portfolio(0));
 +    testRgn.put(1, new Portfolio(1));
 +
 +    //Set TestHook in RangeIndex
 +    TestHook hook = new RangeIndexTestHook();
 +    RangeIndex.setTestHook(hook);
 +    // Execute Queries without Indexes
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "<trace> SELECT * FROM /testRgn p, p.positions where p.status = 'active' AND p.ID < 0 ");
 +    
 +    //Following should throw NullPointerException.
 +    SelectResults sr = (SelectResults)q.execute();
 +    
 +    assertTrue("RangeIndexTestHook was not hooked for spot 1", ((RangeIndexTestHook)hook).isHooked(1));
 +    RangeIndex.setTestHook(null);
 +  }
 +
 +  @Test
 +  public void testSizeEstimateLTInCompactRangeIndexForNullMap() throws Exception {
 +    QueryService qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    //Create indexes
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "p.status", "/testRgn p");
 +    Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL,
 +        "p.ID", "/testRgn p");
 +    
 +    //put values
 +    testRgn.put(0, new Portfolio(0));
 +    testRgn.put(1, new Portfolio(1));
 +
 +    //Set TestHook in RangeIndex
 +    TestHook hook = new RangeIndexTestHook();
 +    CompactRangeIndex.setTestHook(hook);
 +    // Execute Queries without Indexes
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "<trace> SELECT * FROM /testRgn p where p.status = 'active' AND p.ID > 0 ");
 +    
 +    //Following should throw NullPointerException.
 +    SelectResults sr = (SelectResults)q.execute();
 +    
 +    assertTrue("RangeIndexTestHook was not hooked for spot 2", ((RangeIndexTestHook)hook).isHooked(2));
 +    CompactRangeIndex.setTestHook(null);
 +  }
 +
 +  @Test
 +  public void testSizeEstimateGTInCompactRangeIndexForNullMap() throws Exception {
 +    QueryService qs = CacheUtils.getQueryService();
 +    LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +    //Create indexes
 +    Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL,
 +        "p.status", "/testRgn p");
 +    Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL,
 +        "p.ID", "/testRgn p");
 +    
 +    //put values
 +    testRgn.put(0, new Portfolio(0));
 +    testRgn.put(1, new Portfolio(1));
 +
 +    //Set TestHook in RangeIndex
 +    TestHook hook = new RangeIndexTestHook();
 +    CompactRangeIndex.setTestHook(hook);
 +    // Execute Queries without Indexes
 +    Query q = CacheUtils.getQueryService().newQuery(
 +        "<trace> SELECT * FROM /testRgn p where p.status = 'active' AND p.ID < 0 ");
 +    
 +    //Following should throw NullPointerException.
 +    SelectResults sr = (SelectResults)q.execute();
 +    
 +    assertTrue("RangeIndexTestHook was not hooked for spot 1", ((RangeIndexTestHook)hook).isHooked(1));
 +    CompactRangeIndex.setTestHook(null);
 +  }
 +  
 +  @Test
 +  public void testCompactMapIndexUsageAllKeysWithVariousValueTypes() throws Exception {
 +      QueryService qs;
 +      qs = CacheUtils.getQueryService();
 +      LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +      int ID =1;
 +      for(; ID <=30; ++ID) {
 +        TestObject object = new TestObject(ID);
 +        testRgn.put(ID, object);
 +      }
 +      String queries[] = {
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['string'] = '1'",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['double'] > 1D",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['integer'] > 1",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['long'] > 1L"
 +      };
 +      String queriesIndexNotUsed[] = {        
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('string') = '1'",       
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('double') > 1D",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('integer') > 1",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('long') > 1L"         
 +       };
-       Object r[][]= new Object[queries.length][2];
-       
-       qs = CacheUtils.getQueryService();
-       
-     //Execute Queries without Indexes
-       for (int i = 0; i < queries.length; i++) {
-           Query q = null;
-           try {
-               q = CacheUtils.getQueryService().newQuery(queries[i]);
-               CacheUtils.getLogger().info("Executing query: " + queries[i]);              
-               r[i][0] = q.execute();         
-             CacheUtils.log("Executed query: " + queries[i] );
-           } catch (Exception e) {
-               e.printStackTrace();
-               fail(q.getQueryString());
-           }
-       }  
-       
-       Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "itr1.testFields[*]",
-           "/testRgn itr1");
-       
-       assertTrue(i1 instanceof CompactMapRangeIndex);
-       
-             //Execute Queries with Indexes
-         for (int i = 0; i < queries.length; i++) {
-             Query q = null;
-             try {
-                 q = CacheUtils.getQueryService().newQuery(queries[i]);
-                 CacheUtils.getLogger().info("Executing query: " + queries[i]);
-                 QueryObserverImpl observer = new QueryObserverImpl();
-                 QueryObserverHolder.setInstance(observer);
-                 r[i][1] = q.execute();
-                 CacheUtils.log("Executing query: " + queries[i] + " with index created");
-                 if(!observer.isIndexesUsed){
-                     fail("Index is NOT uesd");
-                 }              
-                 Iterator itr = observer.indexesUsed.iterator();
-                 assertTrue(itr.hasNext());
-                 String temp = itr.next().toString();
-                 assertEquals(temp,"Index1");       
-                 
-             } catch (Exception e) {
-                 e.printStackTrace();
-                 fail(q.getQueryString());
-             }
-         }
-         StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
-         ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r,queries.length,queries);
-         
-         //Test queries index not used
-         for (int i = 0; i < queriesIndexNotUsed.length; i++) {
-           Query q = null;
-           try {
-               q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
-               CacheUtils.getLogger().info("Executing query: " + queriesIndexNotUsed[i]);
-               QueryObserverImpl observer = new QueryObserverImpl();
-               QueryObserverHolder.setInstance(observer);            
-               CacheUtils.log("Executing query: " + queriesIndexNotUsed[i] + " with index created");
-               q.execute();
-               assertFalse(observer.isIndexesUsed);                          
-               Iterator itr = observer.indexesUsed.iterator();
-               assertFalse(itr.hasNext());                   
-               
-           } catch (Exception e) {
-               e.printStackTrace();
-               fail(q.getQueryString());
-           }
-       }
++      this.evaluateMapTypeIndexUsage("itr1.testFields[*]", "/testRgn itr1", queries, queriesIndexNotUsed, CompactMapRangeIndex.class);
 +    }
 +    
 +    @Test
 +  public void testCompactMapIndexUsageAllKeysOneIndex() throws Exception {
 +      QueryService qs;
 +      qs = CacheUtils.getQueryService();
 +      LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +      int ID =1;
 +      for(; ID <=30; ++ID) {
 +        TestObject object = new TestObject(ID);
 +        testRgn.put(ID, object);
 +      }
 +      String queries[] = {
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['string'] = '1'",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['double'] > 1D",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['integer'] > 1",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['long'] > 1L"
 +      };
 +      String queriesIndexNotUsed[] = {        
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('string') = '1'",       
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('double') > 1D",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('integer') > 1",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('long') > 1L"         
 +       };
-       Object r[][]= new Object[queries.length][2];
-       
-       qs = CacheUtils.getQueryService();
-       
-     //Execute Queries without Indexes
-       for (int i = 0; i < queries.length; i++) {
-           Query q = null;
-           try {
-               q = CacheUtils.getQueryService().newQuery(queries[i]);
-               CacheUtils.getLogger().info("Executing query: " + queries[i]);              
-               r[i][0] = q.execute();         
-             CacheUtils.log("Executed query: " + queries[i] );
-           } catch (Exception e) {
-               e.printStackTrace();
-               fail(q.getQueryString());
-           }
-       }  
-       
-       Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "itr1.testFields['string','double','integer','long']",
-           "/testRgn itr1");
-       
-       assertTrue(i1 instanceof CompactMapRangeIndex);
-       
-             //Execute Queries with Indexes
-         for (int i = 0; i < queries.length; i++) {
-             Query q = null;
-             try {
-                 q = CacheUtils.getQueryService().newQuery(queries[i]);
-                 CacheUtils.getLogger().info("Executing query: " + queries[i]);
-                 QueryObserverImpl observer = new QueryObserverImpl();
-                 QueryObserverHolder.setInstance(observer);
-                 r[i][1] = q.execute();
-                 CacheUtils.log("Executing query: " + queries[i] + " with index created");
-                 if(!observer.isIndexesUsed){
-                     fail("Index is NOT uesd");
-                 }              
-                 Iterator itr = observer.indexesUsed.iterator();
-                 assertTrue(itr.hasNext());
-                 String temp = itr.next().toString();
-                 assertEquals(temp,"Index1");       
-                 
-             } catch (Exception e) {
-                 e.printStackTrace();
-                 fail(q.getQueryString());
-             }
-         }
-         StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
-         ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r,queries.length,queries);
-         
-         //Test queries index not used
-         for (int i = 0; i < queriesIndexNotUsed.length; i++) {
-           Query q = null;
-           try {
-               q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
-               CacheUtils.getLogger().info("Executing query: " + queriesIndexNotUsed[i]);
-               QueryObserverImpl observer = new QueryObserverImpl();
-               QueryObserverHolder.setInstance(observer);            
-               CacheUtils.log("Executing query: " + queriesIndexNotUsed[i] + " with index created");
-               q.execute();
-               assertFalse(observer.isIndexesUsed);                          
-               Iterator itr = observer.indexesUsed.iterator();
-               assertFalse(itr.hasNext());                   
-               
-           } catch (Exception e) {
-               e.printStackTrace();
-               fail(q.getQueryString());
-           }
-       }
++     evaluateMapTypeIndexUsage("itr1.testFields['string','double','integer','long']", "/testRgn itr1", queries, queriesIndexNotUsed, CompactMapRangeIndex.class);
 +    }
 +    
 +    @Test
 +  public void testCompactMapIndexUsageManyGetKeysWithVariousValueTypes() throws Exception {
 +      QueryService qs;
 +      qs = CacheUtils.getQueryService();
 +      LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +      int ID =1;
 +      for(; ID <=30; ++ID) {
 +        TestObject object = new TestObject(ID);
 +        testRgn.put(ID, object);
 +      }
 +      String queries[] = {
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('string') = '1'",       
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('double') > 1D",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('integer') > 1",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('long') > 1L" 
 +      };
 +      String queriesIndexNotUsed[] = {        
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['string'] = '1'",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['double'] > 1D",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['integer'] > 1",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['long'] > 1L"
 +       };
 +      Object r[][]= new Object[queries.length][2];
 +      
 +      qs = CacheUtils.getQueryService();
 +      
 +      //Execute Queries without Indexes
 +      for (int i = 0; i < queries.length; i++) {
 +          Query q = null;
 +          try {
 +              q = CacheUtils.getQueryService().newQuery(queries[i]);
 +              CacheUtils.getLogger().info("Executing query: " + queries[i]);              
 +              r[i][0] = q.execute();         
 +            CacheUtils.log("Executed query: " + queries[i] );
 +          } catch (Exception e) {
 +              e.printStackTrace();
 +              fail(q.getQueryString());
 +          }
 +      }  
 +      
 +      Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "itr1.testFields.get('string')",
 +          "/testRgn itr1");
 +      Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL, "itr1.testFields.get('double')",
 +          "/testRgn itr1");
 +      Index i3 = qs.createIndex("Index3", IndexType.FUNCTIONAL, "itr1.testFields.get('integer')",
 +          "/testRgn itr1");
 +      Index i4 = qs.createIndex("Index4", IndexType.FUNCTIONAL, "itr1.testFields.get('long')",
 +          "/testRgn itr1");  
 +      Index i5 = qs.createIndex("Index5", IndexType.FUNCTIONAL, "itr1.testFields.get('complex')",
 +          "/testRgn itr1");
 +      
 +      assertTrue(i1 instanceof CompactRangeIndex);
 +      
 +            //Execute Queries with Indexes
 +        for (int i = 0; i < queries.length; i++) {
 +            Query q = null;
 +            try {
 +                q = CacheUtils.getQueryService().newQuery(queries[i]);
 +                CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +                QueryObserverImpl observer = new QueryObserverImpl();
 +                QueryObserverHolder.setInstance(observer);
 +                r[i][1] = q.execute();
 +                CacheUtils.log("Executing query: " + queries[i] + " with index created");
 +                if(!observer.isIndexesUsed){
 +                    fail("Index is NOT uesd");
 +                }              
 +                Iterator itr = observer.indexesUsed.iterator();
 +                assertTrue(itr.hasNext());
 +                String temp = itr.next().toString();
 +                assertEquals(temp,"Index" + (i + 1));       
 +                
 +            } catch (Exception e) {
 +                e.printStackTrace();
 +                fail(q.getQueryString());
 +            }
 +        }
 +        StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +        ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r,queries.length,queries);
 +        
 +        //Test queries index not used
 +        for (int i = 0; i < queriesIndexNotUsed.length; i++) {
 +          Query q = null;
 +          try {
 +              q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
 +              CacheUtils.getLogger().info("Executing query: " + queriesIndexNotUsed[i]);
 +              QueryObserverImpl observer = new QueryObserverImpl();
 +              QueryObserverHolder.setInstance(observer);            
 +              CacheUtils.log("Executing query: " + queriesIndexNotUsed[i] + " with index created");
 +              q.execute();
 +              assertFalse(observer.isIndexesUsed);                          
 +              Iterator itr = observer.indexesUsed.iterator();
 +              assertFalse(itr.hasNext());                   
 +              
 +          } catch (Exception e) {
 +              e.printStackTrace();
 +              fail(q.getQueryString());
 +          }
 +      }
 +    }
 +    
 +    @Test
 +  public void testCompactMapIndexUsageManyKeysWithVariousValueTypes() throws Exception {
 +      QueryService qs;
 +      qs = CacheUtils.getQueryService();
 +      LocalRegion testRgn = (LocalRegion)CacheUtils.createRegion("testRgn", null);
 +      int ID =1;
 +      for(; ID <=30; ++ID) {
 +        TestObject object = new TestObject(ID);
 +        testRgn.put(ID, object);
 +      }
 +      String queries[] = {
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['string'] = '1'",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['double'] > 1D",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['integer'] > 1",
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields['long'] > 1L"
 +      };
 +      String queriesIndexNotUsed[] = {        
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('string') = '1'",       
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('double') > 1D",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('integer') > 1",         
 +          "SELECT DISTINCT * FROM /testRgn itr1  WHERE itr1.testFields.get('long') > 1L"         
 +       };
 +      Object r[][]= new Object[queries.length][2];
 +      
 +      qs = CacheUtils.getQueryService();
 +      
 +    //Execute Queries without Indexes
 +      for (int i = 0; i < queries.length; i++) {
 +          Query q = null;
 +          try {
 +              q = CacheUtils.getQueryService().newQuery(queries[i]);
 +              CacheUtils.getLogger().info("Executing query: " + queries[i]);              
 +              r[i][0] = q.execute();         
 +            CacheUtils.log("Executed query: " + queries[i] );
 +          } catch (Exception e) {
 +              e.printStackTrace();
 +              fail(q.getQueryString());
 +          }
 +      }  
 +      
 +      Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "itr1.testFields['string']",
 +          "/testRgn itr1");
 +      Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL, "itr1.testFields['double']",
 +          "/testRgn itr1");
 +      Index i3 = qs.createIndex("Index3", IndexType.FUNCTIONAL, "itr1.testFields['integer']",
 +          "/testRgn itr1");
 +      Index i4 = qs.createIndex("Index4", IndexType.FUNCTIONAL, "itr1.testFields['long']",
 +          "/testRgn itr1");
 +      Index i5 = qs.createIndex("Index5", IndexType.FUNCTIONAL, "itr1.testFields['complex']",
 +          "/testRgn itr1");
 +      
 +      assertTrue(i1 instanceof CompactRangeIndex);
 +      
 +            //Execute Queries with Indexes
 +        for (int i = 0; i < queries.length; i++) {
 +            Query q = null;
 +            try {
 +                q = CacheUtils.getQueryService().newQuery(queries[i]);
 +                CacheUtils.getLogger().info("Executing query: " + queries[i]);
 +                QueryObserverImpl observer = new QueryObserverImpl();
 +                QueryObserverHolder.setInstance(observer);
 +                r[i][1] = q.execute();
 +                CacheUtils.log("Executing query: " + queries[i] + " with index created");
 +                if(!observer.isIndexesUsed){
 +                    fail("Index is NOT uesd");
 +                }              
 +                Iterator itr = observer.indexesUsed.iterator();
 +                assertTrue(itr.hasNext());
 +                String temp = itr.next().toString();
 +                assertEquals(temp,"Index" + (i+1));       
 +                
 +            } catch (Exception e) {
 +                e.printStackTrace();
 +                fail(q.getQueryString());
 +            }
 +        }
 +        StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
 +        ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r,queries.length,queries);
 +        
 +        //Test queries index not used
 +        for (int i = 0; i < queriesIndexNotUsed.length; i++) {
 +          Query q = null;
 +          try {
 +              q = CacheUtils.getQueryService().newQuery(queriesIndexNotUsed[i]);
 +              CacheUtils.getLogger().info("Executing query: " + queriesIndexNotUsed[i]);
 +              QueryObserverImpl observer = new QueryObserverImpl();
 +              QueryObserverHolder.setInstance(observer);            
 +              CacheUtils.log("Executing query: " + queriesIndexNotUsed[i] + " with index created");
 +              q.execute();
 +              assertFalse(observer.isIndexesUsed);                          
 +              Iterator itr = observer.indexesUsed.iterator();
 +              assertFalse(itr.hasNext());                   
 +              
 +          } catch (Exception e) {
 +              e.printStackTrace();
 +              fail(q.getQueryString());
 +          }
 +      }
 +    }
 +
 +    @Test
 +  public void testIndexUseSelfJoin() throws Exception {
 +      String[] queries = {"SELECT DISTINCT * FROM /pos p1, /pos p2 where p1.status = p2.status",
 +          "SELECT DISTINCT * FROM /pos p1, /pos p2 where p1.ID = p2.ID",
 +          "SELECT DISTINCT * FROM /pos p1, /pos p2 where p1.P1.secId = p2.P1.secId",
 +          "SELECT DISTINCT * FROM /pos p1, /pos p2 where p1.status = p2.status and p1.status = 'active'",
 +          "SELECT DISTINCT * FROM /pos p1, /pos p2 where p1.ID = p2.ID and p1.ID < 2",
 +          "SELECT * FROM /pos p1, /pos p2 where p1.ID = p2.ID",
 +          "SELECT * FROM /pos p1, /pos p2 where p1.P1.secId = p2.P1.secId",
 +          "SELECT * FROM /pos p1, /pos p2 where p1.status = p2.status and p1.status = 'active'",
 +          "SELECT * FROM /pos p1, /pos p2 where p1.ID = p2.ID and p1.ID < 2"};
 +
 +      SelectResults[][] sr = new SelectResults[queries.length][2];
 +        for (int j = 0; j < queries.length; j++) {
 +          Query q = qs.newQuery(queries[j]);
 +          QueryObserverImpl observer = new QueryObserverImpl();
 +          QueryObserverHolder.setInstance(observer);
 +          sr[j][0] = (SelectResults) q.execute();
 +          if(sr[j][0].size() == 0) {
 +            fail("Query " + q.getQueryString() + " should have returned results");
 +          }
 +          if (!observer.isIndexesUsed) {
 +            fail("Index should have been used for query '" + q.getQueryString() + "'");
 +          }
 +        }
 +        qs.removeIndexes();
 +        for (int j = 0; j < queries.length; j++) {
 +          Query q = qs.newQuery(queries[j]);
 +          QueryObserverImpl observer = new QueryObserverImpl();
 +          QueryObserverHolder.setInstance(observer);
 +          sr[j][1] = (SelectResults) q.execute();
 +          if(sr[j][1].size() == 0) {
 +            fail("Query " + q.getQueryString() + " should have returned results");
 +          }
 +          if (observer.isIndexesUsed) {
 +            fail("Index should not be used for query '" + q.getQueryString() + "'");
 +          }
 +        }
 +        CacheUtils.compareResultsOfWithAndWithoutIndex(sr);
 +    }
 +
 +    @Test
-   public void testUndefinedInResults() throws Exception {
++  public void testUndefinedResultsAreReturnedWhenANotEqualsQueryIsExecuted() throws Exception {
 +      Portfolio p1 = new Portfolio(0);
 +      p1.position1 = null;
 +      region.put("0", p1);
 +      Portfolio p2 = new Portfolio(2);
 +      p2.position1 = null;
 +      region.put("2", p2);
 +
 +      String query = "SELECT p.position1.secId FROM /pos p where p.position1.secId != 'MSFT' ";
 +      SelectResults[][] sr = new SelectResults[1][2];
 +      sr[0][0] = (SelectResults) qs.newQuery(query).execute();
 +      qs.removeIndexes();
 +      sr[0][1] = (SelectResults) qs.newQuery(query).execute();
 +      if(!CacheUtils.compareResultsOfWithAndWithoutIndex(sr)) {
 +        fail("Query results not same with and without index");
 +      }
 +    }
 +
 +    @Test
-     public void testBug52444() throws Exception {
++    public void testIndexesRemainInUseAfterARebalance() throws Exception {
 +        // Create partitioned region
 +        PartitionAttributesFactory paf = new PartitionAttributesFactory();
 +        AttributesFactory af = new AttributesFactory();
 +        af.setPartitionAttributes(paf.create());
-         Region region = CacheUtils.createRegion("testBug52444", af.create(), false);
++        Region region = CacheUtils.createRegion("testIndexesRemainInUseAfterARebalance", af.create(), false);
 +
 +        // Add index
 +        PartitionedIndex index = (PartitionedIndex) qs.createIndex("statusIndex", "status", region.getFullPath());
 +
 +        // Do puts
 +        for (int i=0; i<200; i++) {
 +          region.put(i, new Portfolio(i));
 +        }
 +        
 +        // Initialize query observer
 +        QueryObserverImpl observer = new QueryObserverImpl();
 +        QueryObserverHolder.setInstance(observer);
 +        
 +        // Create and run query
 +        Query query = qs.newQuery("SELECT * FROM " + region.getFullPath() + " where status = 'active'");
 +        query.execute();
 +
 +        // Verify index was used
 +        assertTrue(observer.isIndexesUsed);
 +
 +        // Get the first index entry in the PartitionedIndex bucketIndexes and delete the index from it (to simulate what happens when a bucket is moved)
 +        Map.Entry<Region,List<Index>> firstIndexEntry = index.getFirstBucketIndex();
 +        assertTrue(!firstIndexEntry.getValue().isEmpty());
 +        index.removeFromBucketIndexes(firstIndexEntry.getKey(), firstIndexEntry.getValue().iterator().next());
 +        
 +        // Verify the index was removed from the entry and the entry was removed from the bucket indexes
 +        assertTrue(firstIndexEntry.getValue().isEmpty());      
 +        Map.Entry<Region,List<Index>> nextFirstIndexEntry = index.getFirstBucketIndex();
 +        assertTrue(!nextFirstIndexEntry.getValue().isEmpty());
 +        
 +        // Run query again
 +        observer.reset();
 +        query.execute();
 +        
 +        // Verify index was still used
 +        assertTrue(observer.isIndexesUsed);
 +      }
++    
++  @Test
++  public void testPKIndexUseWithPR() throws Exception {
++    evaluatePKIndexUsetest(RegionShortcut.PARTITION, "pkTest");
++  }
++
++  @Test
++  public void testPKIndexUseWithReplicate() throws Exception {
++    evaluatePKIndexUsetest(RegionShortcut.REPLICATE, "pkTest");
++  }
++    
++  private void evaluatePKIndexUsetest(RegionShortcut regionShortcut, String regionName) throws Exception {
++    Cache cache = CacheUtils.getCache();
++    Region r = cache.createRegionFactory(regionShortcut).create(regionName);
++    Map map0 = new HashMap();
++    Map map1 = new HashMap();
++    Map map2 = new HashMap();
++    r.put("A0", map0);
++    r.put("A1", map1);
++    r.put("A2", map2);
++    qs.createIndex("pkIndex", IndexType.PRIMARY_KEY, "p.pk", "/" + regionName + " p");
++    QueryObserverImpl observer = new QueryObserverImpl();
++    QueryObserverHolder.setInstance(observer);
++    SelectResults sr = (SelectResults) qs.newQuery("select * from /" + regionName + " p where p.pk = 'A1'").execute();
++    assertEquals(1, sr.size());
++
++    if (!observer.isIndexesUsed) {
++      fail("Index not used for operator '='");
++    }
++  }
 +
 +  class QueryObserverImpl extends QueryObserverAdapter
 +  {
 +    boolean isIndexesUsed = false;
 +
 +    ArrayList indexesUsed = new ArrayList();
 +
 +    public void beforeIndexLookup(Index index, int oper, Object key) {
 +      indexesUsed.add(index.getName());
 +    }
 +
 +    public void afterIndexLookup(Collection results) {
 +      if (results != null) {
 +        isIndexesUsed = true;
 +      }
 +    }
 +    
 +    public void reset() {
 +      this.isIndexesUsed = false;
 +      this.indexesUsed.clear();
 +    }
 +  }
 +  
 +  public class RangeIndexTestHook implements TestHook {
 +
 +    int lastHook = -1;
 +    @Override
 +    public void hook(int spot) throws RuntimeException {
 +      lastHook = spot;
 +      CacheUtils.getCache().getLogger().fine("Inside RangeIndexTestHook for spot "+ spot);
 +      if (spot == 1) { //LT size estimate
 +        CacheUtils.getCache().getRegion("testRgn").clear();
 +      } else if (spot == 2) { //GT size estimate
 +        CacheUtils.getCache().getRegion("testRgn").clear();
 +      }
 +    }
 +
 +    public boolean isHooked(int spot) {
 +      return spot==lastHook;
 +    }
 +  }
 +  static  class MapKeyIndexData {
 +    int id;
 +    public Map maap = new HashMap();
 +    public List liist = new ArrayList();
 +    public MapKeyIndexData(int id) {
 +      this.id = id;
 +    }
 +    public void addKeyValue(Object key, Object value) {
 +      this.maap.put(key,value);
 +      this.liist.add(value);
 +    }
 +  }
 +  private class TestObject {
 +      public Map testFields = new HashMap();
 +      TestObject(int i) {
 +        testFields.put("string", "String Value" + i);
 +        testFields.put("double", (double) i);
 +        testFields.put("integer", i);
 +        testFields.put("long", (long) i);
 +        testFields.put("complex", new CompObject(i));
 +      }
 +      public Map getTestFields() {
 +        return testFields;
 +      }
 +    }
 +    
 +    private class CompObject implements Comparable {
 +      int value;
 +      CompObject(int i) {
 +        value = i;
 +      }
 +      
 +      
 +      public int compareTo(Object o) {
 +        if (o instanceof CompObject) {
 +          CompObject other = (CompObject) o;
 +          if (value > other.value) {
 +            return 1;
 +          }
 +          else if (value == other.value){
 +            return 0;
 +          }
 +          else {
 +            return -1;
 +          }
 +        }
 +        throw new ClassCastException("Could not cast " + o.getClass().getName() + " to compObject");
 +      }
 +      
 +    }
 +
 +}


[100/100] [abbrv] incubator-geode git commit: GEODE-870: Adding GMSJoinLeaveTestHelper back after gemfire/geode merge

Posted by ud...@apache.org.
GEODE-870: Adding GMSJoinLeaveTestHelper back after gemfire/geode merge


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/0ff94225
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/0ff94225
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/0ff94225

Branch: refs/heads/feature/GEODE-870
Commit: 0ff9422520ba97a68d05d0b86285343eff712f79
Parents: bd6749c
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Tue Feb 23 08:20:45 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 08:20:45 2016 +1100

----------------------------------------------------------------------
 .../gms/membership/GMSJoinLeaveTestHelper.java  | 67 --------------------
 .../gms/membership/GMSJoinLeaveTestHelper.java  | 67 ++++++++++++++++++++
 2 files changed, 67 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0ff94225/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
deleted file mode 100644
index 493c625..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
+++ /dev/null
@@ -1,67 +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 com.gemstone.gemfire.distributed.internal.membership.gms.membership;
-
-import com.gemstone.gemfire.distributed.Locator;
-import com.gemstone.gemfire.distributed.internal.DM;
-import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
-import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
-import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
-
-public class GMSJoinLeaveTestHelper {
-
-  public static void becomeCoordinatorForTest(GMSJoinLeave gmsJoinLeave) {
-    synchronized (gmsJoinLeave.getViewInstallationLock()) {
-      gmsJoinLeave.becomeCoordinator();
-    }
-  }
-
-  public static boolean isViewCreator() {
-    GMSJoinLeave gmsJoinLeave = getGmsJoinLeave();
-    if (gmsJoinLeave != null) {
-      GMSJoinLeave.ViewCreator viewCreator = gmsJoinLeave.getViewCreator();
-      if (viewCreator != null && !viewCreator.isShutdown()) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-    throw new RuntimeException("This should not have happened. There should be a JoinLeave for every DS");
-  }
-
-  private static GMSJoinLeave getGmsJoinLeave() {
-    InternalDistributedSystem distributedSystem = getInternalDistributedSystem();
-    DM dm = distributedSystem.getDM();
-    GMSMembershipManager membershipManager = (GMSMembershipManager) dm.getMembershipManager();
-    Services services = membershipManager.getServices();
-    return (GMSJoinLeave) services.getJoinLeave();
-  }
-
-  public static Integer getViewId() {
-    return getGmsJoinLeave().getView().getViewId();
-  }
-
-  private static InternalDistributedSystem getInternalDistributedSystem() {
-    InternalDistributedSystem distributedSystem = InternalDistributedSystem.getAnyInstance();
-    if (distributedSystem == null) {
-      Locator locator = Locator.getLocator();
-      return (InternalDistributedSystem) locator.getDistributedSystem();
-    } else {
-      return distributedSystem;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0ff94225/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
new file mode 100644
index 0000000..493c625
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveTestHelper.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.distributed.internal.membership.gms.membership;
+
+import com.gemstone.gemfire.distributed.Locator;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
+import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
+
+public class GMSJoinLeaveTestHelper {
+
+  public static void becomeCoordinatorForTest(GMSJoinLeave gmsJoinLeave) {
+    synchronized (gmsJoinLeave.getViewInstallationLock()) {
+      gmsJoinLeave.becomeCoordinator();
+    }
+  }
+
+  public static boolean isViewCreator() {
+    GMSJoinLeave gmsJoinLeave = getGmsJoinLeave();
+    if (gmsJoinLeave != null) {
+      GMSJoinLeave.ViewCreator viewCreator = gmsJoinLeave.getViewCreator();
+      if (viewCreator != null && !viewCreator.isShutdown()) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    throw new RuntimeException("This should not have happened. There should be a JoinLeave for every DS");
+  }
+
+  private static GMSJoinLeave getGmsJoinLeave() {
+    InternalDistributedSystem distributedSystem = getInternalDistributedSystem();
+    DM dm = distributedSystem.getDM();
+    GMSMembershipManager membershipManager = (GMSMembershipManager) dm.getMembershipManager();
+    Services services = membershipManager.getServices();
+    return (GMSJoinLeave) services.getJoinLeave();
+  }
+
+  public static Integer getViewId() {
+    return getGmsJoinLeave().getView().getViewId();
+  }
+
+  private static InternalDistributedSystem getInternalDistributedSystem() {
+    InternalDistributedSystem distributedSystem = InternalDistributedSystem.getAnyInstance();
+    if (distributedSystem == null) {
+      Locator locator = Locator.getLocator();
+      return (InternalDistributedSystem) locator.getDistributedSystem();
+    } else {
+      return distributedSystem;
+    }
+  }
+}


[094/100] [abbrv] incubator-geode git commit: GEODE-870: Rejecting of old view

Posted by ud...@apache.org.
GEODE-870: Rejecting of old view


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/80cbc3f5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/80cbc3f5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/80cbc3f5

Branch: refs/heads/feature/GEODE-870
Commit: 80cbc3f59c2ed6cb999707851ccc14272fcd8397
Parents: c741a68
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Mon Feb 1 14:08:32 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 07:25:44 2016 +1100

----------------------------------------------------------------------
 .../gms/messages/ViewRejectMessage.java         |  96 +++
 .../membership/gms/membership/GMSJoinLeave.java |  92 +--
 .../internal/DataSerializableFixedID.java       |   3 +-
 .../gemfire/distributed/LocatorDUnitTest.java   | 818 +++++++++++--------
 .../test/dunit/SerializableRunnable.java        |  12 +-
 5 files changed, 609 insertions(+), 412 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/80cbc3f5/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java
new file mode 100755
index 0000000..e5bf9e2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java
@@ -0,0 +1,96 @@
+/*
+ * 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 com.gemstone.gemfire.distributed.internal.membership.gms.messages;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.HighPriorityDistributionMessage;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.distributed.internal.membership.NetView;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class ViewRejectMessage extends HighPriorityDistributionMessage {
+
+  private int viewId;
+  private NetView rejectedView;
+  private String reason;
+
+  public ViewRejectMessage(InternalDistributedMember recipient, int viewId, NetView rejectedView, String reason) {
+    super();
+    setRecipient(recipient);
+    this.viewId = viewId;
+    this.rejectedView = rejectedView;
+    this.reason = reason;
+  }
+
+  public ViewRejectMessage() {
+    // no-arg constructor for serialization
+  }
+  
+  public int getViewId() {
+    return viewId;
+  }
+  
+  public NetView getRejectedView() {
+    return this.rejectedView;
+  }
+  
+
+  @Override
+  public int getDSFID() {
+    // TODO Auto-generated method stub
+    return VIEW_REJECT_MESSAGE;
+  }
+
+  public String getReason() {
+    return reason;
+  }
+
+  @Override
+  public int getProcessorType() {
+    return 0;
+  }
+
+  @Override
+  public void process(DistributionManager dm) {
+    throw new IllegalStateException("this message is not intended to execute in a thread pool");
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    out.writeInt(this.viewId);
+    DataSerializer.writeObject(this.rejectedView, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    this.viewId = in.readInt();
+    this.rejectedView = DataSerializer.readObject(in);
+  }
+  
+  @Override
+  public String toString() {
+    String s = getSender() == null? getRecipientsDescription() : ""+getSender();
+    return "ViewRejectMessage("+s+"; "+this.viewId+";  rejectedView="+this.rejectedView +")";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/80cbc3f5/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index 5d34041..c7eacfa 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -16,41 +16,6 @@
  */
 package com.gemstone.gemfire.distributed.internal.membership.gms.membership;
 
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.FIND_COORDINATOR_REQ;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.FIND_COORDINATOR_RESP;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.INSTALL_VIEW_MESSAGE;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.JOIN_REQUEST;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.JOIN_RESPONSE;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.LEAVE_REQUEST_MESSAGE;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.NETWORK_PARTITION_MESSAGE;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.REMOVE_MEMBER_REQUEST;
-import static com.gemstone.gemfire.internal.DataSerializableFixedID.VIEW_ACK_MESSAGE;
-import static com.gemstone.gemfire.distributed.internal.membership.gms.ServiceConfig.MEMBER_REQUEST_COLLECTION_INTERVAL;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimerTask;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.logging.log4j.Logger;
-
 import com.gemstone.gemfire.GemFireConfigException;
 import com.gemstone.gemfire.SystemConnectException;
 import com.gemstone.gemfire.distributed.DistributedMember;
@@ -68,24 +33,26 @@ import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.JoinL
 import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.MessageHandler;
 import com.gemstone.gemfire.distributed.internal.membership.gms.locator.FindCoordinatorRequest;
 import com.gemstone.gemfire.distributed.internal.membership.gms.locator.FindCoordinatorResponse;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.HasMemberID;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.InstallViewMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.JoinRequestMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.JoinResponseMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.LeaveRequestMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.NetworkPartitionMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.RemoveMemberMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.ViewAckMessage;
+import com.gemstone.gemfire.distributed.internal.membership.gms.messages.*;
 import com.gemstone.gemfire.distributed.internal.tcpserver.TcpClient;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.security.AuthenticationFailedException;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static com.gemstone.gemfire.distributed.internal.membership.gms.ServiceConfig.MEMBER_REQUEST_COLLECTION_INTERVAL;
+import static com.gemstone.gemfire.internal.DataSerializableFixedID.*;
 
 /**
  * GMSJoinLeave handles membership communication with other processes in the
  * distributed system.  It replaces the JGroups channel membership services
  * that Geode formerly used for this purpose.
- * 
  */
 public class GMSJoinLeave implements JoinLeave, MessageHandler {
   
@@ -221,7 +188,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
     try {
       if (Boolean.getBoolean(BYPASS_DISCOVERY_PROPERTY)) {
-        synchronized(viewInstallationLock) {
+        synchronized (viewInstallationLock) {
           becomeCoordinator();
         }
         return true;
@@ -391,7 +358,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     }
     return response;
   }
-  
+
   @Override
   public boolean isMemberLeaving(DistributedMember mbr) {
     if (getPendingRequestIDs(LEAVE_REQUEST_MESSAGE).contains(mbr)
@@ -471,8 +438,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       recordViewRequest(incomingRequest);
       return;
     }
-    
-    
+
     InternalDistributedMember mbr = incomingRequest.getMemberID();
 
     if (logger.isDebugEnabled()) {
@@ -543,7 +509,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
     if (!fromMe) {
       logger.info("Membership received a request to remove " + mbr
-        + " from " + incomingRequest.getSender() 
+        + " from " + incomingRequest.getSender()
         + " reason="+incomingRequest.getReason());
     }
 
@@ -630,7 +596,6 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   public void delayViewCreationForTest(int millis) {
     requestCollectionInterval = millis;
   }
-  
 
   /**
    * Transitions this member into the coordinator role.  This must
@@ -872,6 +837,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   void setTcpClientWrapper(TcpClientWrapper tcpClientWrapper) {
     this.tcpClientWrapper = tcpClientWrapper;
   }
+
   /**
    * This contacts the locators to find out who the current coordinator is.
    * All locators are contacted. If they don't agree then we choose the oldest
@@ -940,8 +906,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         }
       }
     } while (!anyResponses && System.currentTimeMillis() < giveUpTime);
-    
-    
+
     if (coordinators.isEmpty()) {
       return false;
     }
@@ -1523,6 +1488,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
   /***
    * test method
+   *
    * @return ViewReplyProcessor
    */
   protected ViewReplyProcessor getPrepareViewReplyProcessor() {
@@ -1558,6 +1524,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     boolean isWaiting(){
       return waiting;
     }
+
     synchronized void processPendingRequests(Set<InternalDistributedMember> pendingLeaves, Set<InternalDistributedMember> pendingRemovals) {
       // there's no point in waiting for members who have already
       // requested to leave or who have been declared crashed.
@@ -1711,7 +1678,6 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         services.getMessenger().sendUnreliably(msg);
       }
     }
-    
   }
 
   class ViewCreator extends Thread {
@@ -2094,7 +2060,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         }
 
         logger.debug("unresponsive members that could not be reached: {}", unresponsive);
-        
+
         List<InternalDistributedMember> failures = new ArrayList<>(currentView.getCrashedMembers().size() + unresponsive.size());
 
         if (conflictingView != null && !conflictingView.getCreator().equals(localAddress) && conflictingView.getViewId() > newView.getViewId()
@@ -2188,10 +2154,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
       filterMembers(suspects, newRemovals, REMOVE_MEMBER_REQUEST);
       filterMembers(suspects, newLeaves, LEAVE_REQUEST_MESSAGE);
-      newRemovals.removeAll(newLeaves);  // if we received a Leave req the member is "healthy" 
-      
+      newRemovals.removeAll(newLeaves);  // if we received a Leave req the member is "healthy"
+
       suspects.removeAll(newLeaves);
-      
+
       for (InternalDistributedMember mbr : suspects) {
         if (newRemovals.contains(mbr) || newLeaves.contains(mbr)) {
           continue; // no need to check this member - it's already been checked or is leaving
@@ -2215,7 +2181,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           }
         });
       }
-      
+
       if (checkers.isEmpty()) {
         logger.debug("all unresponsive members are already scheduled to be removed");
         return;
@@ -2236,19 +2202,19 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         long giveUpTime = System.currentTimeMillis() + viewAckTimeout;
         // submit the tasks that will remove dead members from the suspects collection
         submitAll(svc, checkers);
-        
+
         // now wait for the tasks to do their work
         long waitTime = giveUpTime - System.currentTimeMillis();
         synchronized (viewRequests) {
           while ( waitTime > 0 ) {
             logger.debug("removeHealthyMembers: mbrs" + suspects.size());
-            
+
             filterMembers(suspects, newRemovals, REMOVE_MEMBER_REQUEST);
             filterMembers(suspects, newLeaves, LEAVE_REQUEST_MESSAGE);
             newRemovals.removeAll(newLeaves);
-            
+
             suspects.removeAll(newLeaves);
-            
+
             if(suspects.isEmpty() || newRemovals.containsAll(suspects)) {
               break;
             }
@@ -2270,7 +2236,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
      */
     protected void filterMembers(Collection<InternalDistributedMember> mbrs, Set<InternalDistributedMember> matchingMembers, short requestType) {
       Set<InternalDistributedMember> requests = getPendingRequestIDs(requestType);
-      
+
       if(!requests.isEmpty()) {
         logger.debug("filterMembers: processing " + requests.size() + " requests for type " + requestType);
         Iterator<InternalDistributedMember> itr = requests.iterator();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/80cbc3f5/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
index 7b263bf..22ac457 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
@@ -82,7 +82,8 @@ public interface DataSerializableFixedID extends SerializationVersions {
     case FOO:
       return new FOO(in);
   */
-  
+  public static final short VIEW_REJECT_MESSAGE = -158;
+
   public static final short NETWORK_PARTITION_MESSAGE = -157;
   public static final short SUSPECT_MEMBERS_MESSAGE = -156;
   

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/80cbc3f5/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index 3095885..2c8a147 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@ -33,12 +33,7 @@ import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.cache.Region;
 import com.gemstone.gemfire.cache.RegionShortcut;
-import com.gemstone.gemfire.distributed.internal.DistributionConfig;
-import com.gemstone.gemfire.distributed.internal.DistributionException;
-import com.gemstone.gemfire.distributed.internal.DistributionManager;
-import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
-import com.gemstone.gemfire.distributed.internal.InternalLocator;
-import com.gemstone.gemfire.distributed.internal.MembershipListener;
+import com.gemstone.gemfire.distributed.internal.*;
 import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
@@ -122,7 +117,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     } while (System.currentTimeMillis() < giveup);
   }
 
-  
+
   /**
    * SQLFire uses a colocated locator in a dm-type=normal VM.  This tests that
    * the locator can resume control as coordinator after all locators have been
@@ -189,8 +184,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
         service.lock("foo2", 0, 0);
       }
     });
-      
-      
+
     // cause elder failover.  vm1 will become the lock grantor
     system.disconnect();
     
@@ -204,6 +198,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
             public boolean done() {
               return service.isLockGrantor();
             }
+
             @Override
             public String description() {
               return "waiting to become lock grantor after shutting down locator/grantor";
@@ -332,11 +327,11 @@ public class LocatorDUnitTest extends DistributedTestCase {
             async2.join();
             Object result1 = async1.getReturnValue();
             if (result1 instanceof Exception) {
-              throw (Exception)result1;
+              throw (Exception) result1;
             }
             Object result2 = async2.getReturnValue();
             if (result2 instanceof Exception) {
-              throw (Exception)result2;
+              throw (Exception) result2;
             }
             // verify that they found each other
             SerializableCallable verify = new SerializableCallable("verify no split-brain") {
@@ -347,7 +342,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
                 }
                 Assert.assertTrue(sys.getDM().getViewMembers().size() == 2,
                     "expected 2 members but found " + sys.getDM().getViewMembers().size()
-                    );
+                );
                 return true;
               }
             };
@@ -368,8 +363,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
         loc1.invoke(r);
       }
     }
-    
   }
+
   /**
    * test lead member selection
    */
@@ -379,7 +374,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     VM vm1 = host.getVM(1);
     VM vm2 = host.getVM(2);
     VM vm3 = host.getVM(3);
-    
+
     port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
     DistributedTestUtils.deleteLocatorStateFile(port1);
     final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
@@ -388,69 +383,69 @@ public class LocatorDUnitTest extends DistributedTestCase {
     properties.put("locators", locators);
     properties.put("enable-network-partition-detection", "true");
     properties.put("disable-auto-reconnect", "true");
-    
+
     File logFile = new File("");
     if (logFile.exists()) {
       logFile.delete();
     }
     Locator locator = Locator.startLocatorAndDS(port1, logFile, properties);
     try {
-    DistributedSystem sys = locator.getDistributedSystem();
-    
-    Object[] connectArgs = new Object[]{ properties };
-    
-    SerializableRunnable disconnect =
-      new SerializableRunnable("Disconnect from " + locators) {
-          public void run() {
-            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-            if (sys != null && sys.isConnected()) {
-              sys.disconnect();
+      DistributedSystem sys = locator.getDistributedSystem();
+
+      Object[] connectArgs = new Object[] { properties };
+
+      SerializableRunnable disconnect =
+          new SerializableRunnable("Disconnect from " + locators) {
+            public void run() {
+              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+              if (sys != null && sys.isConnected()) {
+                sys.disconnect();
+              }
             }
-          }
-        };
-        
-    assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
-    
-    // connect three vms and then watch the lead member selection as they
-    // are disconnected/reconnected
-    properties.put("name", "vm1");
-    DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
-        "getDistributedMember", connectArgs);
-    
-//    assertTrue(MembershipManagerHelper.getLeadMember(sys) != null);
-    assertLeadMember(mem1, sys, 5000);
-    
-    properties.put("name", "vm2");
-    DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
-        "getDistributedMember", connectArgs);
-    assertLeadMember(mem1, sys, 5000);
-    
-    properties.put("name", "vm3");
-    DistributedMember mem3 = (DistributedMember)vm3.invoke(this.getClass(),
-        "getDistributedMember", connectArgs);
-    assertLeadMember(mem1, sys, 5000);
-    
-    // after disconnecting the first vm, the second one should become the leader
-    vm1.invoke(disconnect);
-    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
-    assertLeadMember(mem2, sys, 5000);
-    
-    properties.put("name", "vm1");
-    mem1 = (DistributedMember)vm1.invoke(this.getClass(),
-        "getDistributedMember", connectArgs);
-    assertLeadMember(mem2, sys, 5000);
-    
-    vm2.invoke(disconnect);
-    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem2);
-    assertLeadMember(mem3, sys, 5000);
-    
-    vm1.invoke(disconnect);
-    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
-    assertLeadMember(mem3, sys, 5000);
+          };
+
+      assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
+
+      // connect three vms and then watch the lead member selection as they
+      // are disconnected/reconnected
+      properties.put("name", "vm1");
+      DistributedMember mem1 = (DistributedMember) vm1.invoke(this.getClass(),
+          "getDistributedMember", connectArgs);
+
+      //    assertTrue(MembershipManagerHelper.getLeadMember(sys) != null);
+      assertLeadMember(mem1, sys, 5000);
+
+      properties.put("name", "vm2");
+      DistributedMember mem2 = (DistributedMember) vm2.invoke(this.getClass(),
+          "getDistributedMember", connectArgs);
+      assertLeadMember(mem1, sys, 5000);
+
+      properties.put("name", "vm3");
+      DistributedMember mem3 = (DistributedMember) vm3.invoke(this.getClass(),
+          "getDistributedMember", connectArgs);
+      assertLeadMember(mem1, sys, 5000);
+
+      // after disconnecting the first vm, the second one should become the leader
+      vm1.invoke(disconnect);
+      MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
+      assertLeadMember(mem2, sys, 5000);
+
+      properties.put("name", "vm1");
+      mem1 = (DistributedMember) vm1.invoke(this.getClass(),
+          "getDistributedMember", connectArgs);
+      assertLeadMember(mem2, sys, 5000);
+
+      vm2.invoke(disconnect);
+      MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem2);
+      assertLeadMember(mem3, sys, 5000);
+
+      vm1.invoke(disconnect);
+      MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
+      assertLeadMember(mem3, sys, 5000);
 
-    vm3.invoke(disconnect);
-    MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem3);
-    assertLeadMember(null, sys, 5000);
+      vm3.invoke(disconnect);
+      MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem3);
+      assertLeadMember(null, sys, 5000);
 
     } finally {
       locator.stop();
@@ -467,13 +462,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
         }
         return (lead == null);
       }
+
       public String description() {
         return null;
       }
     };
     Wait.waitForCriterion(ev, timeout, 200, true);
   }
-  
+
   /**
    * test lead member and coordinator failure with network partition detection
    * enabled.  It would be nice for this test to have more than two "server"
@@ -536,44 +532,43 @@ public class LocatorDUnitTest extends DistributedTestCase {
           }
         }
       });
-      
-      Object[] connectArgs = new Object[]{ properties };
-      
-      SerializableRunnable crashLocator =
-        new SerializableRunnable("Crash locator") {
-          public void run() {
-            Locator loc = Locator.getLocators().iterator().next();
-            DistributedSystem msys = loc.getDistributedSystem();
-            MembershipManagerHelper.crashDistributedSystem(msys);
-            loc.stop();
-          }
-      };
 
+      Object[] connectArgs = new Object[] { properties };
+
+      SerializableRunnable crashLocator =
+          new SerializableRunnable("Crash locator") {
+            public void run() {
+              Locator loc = Locator.getLocators().iterator().next();
+              DistributedSystem msys = loc.getDistributedSystem();
+              MembershipManagerHelper.crashDistributedSystem(msys);
+              loc.stop();
+            }
+          };
 
       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
-      
-//      properties.put("log-level", getDUnitLogLevel());
-      
-      DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+
+      //      properties.put("log-level", getDUnitLogLevel());
+
+      DistributedMember mem1 = (DistributedMember) vm1.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
       vm2.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
       assertLeadMember(mem1, sys, 5000);
-      
+
       assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
-      
+
       // crash the second vm and the locator.  Should be okay
       DistributedTestUtils.crashDistributedSystem(vm2);
       locvm.invoke(crashLocator);
-      
+
       assertTrue("Distributed system should not have disconnected",
           vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
       
       // ensure quorumLost is properly invoked
-      DistributionManager dm = (DistributionManager)((InternalDistributedSystem)sys).getDistributionManager();
+      DistributionManager dm = (DistributionManager) ((InternalDistributedSystem) sys).getDistributionManager();
       MyMembershipListener listener = new MyMembershipListener();
       dm.addMembershipListener(listener);
-  
+
       // disconnect the first vm and demonstrate that the third vm and the
       // locator notice the failure and exit
       DistributedTestUtils.crashDistributedSystem(vm1);
@@ -588,6 +583,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
         public boolean done() {
           return !sys.isConnected();
         }
+
         public String description() {
           return null;
         }
@@ -599,20 +595,18 @@ public class LocatorDUnitTest extends DistributedTestCase {
       // quorumLost should be invoked if we get a ForcedDisconnect in this situation
       assertTrue("expected quorumLost to be invoked", listener.quorumLostInvoked);
       assertTrue("expected suspect processing initiated by TCPConduit", listener.suspectReasons.contains(Connection.INITIATING_SUSPECT_PROCESSING));
-    }
-    finally {
+    } finally {
       if (locator != null) {
         locator.stop();
       }
       LogWriter bLogger =
-        new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+          new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
       bLogger.info("<ExpectedException action=remove>service failure</ExpectedException>");
       bLogger.info("<ExpectedException action=remove>java.net.ConnectException</ExpectedException>");
       bLogger.info("<ExpectedException action=remove>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
       disconnectAllFromDS();
     }
   }
-  
 
   /**
    * test lead member failure and normal coordinator shutdown with network partition detection
@@ -671,31 +665,31 @@ public class LocatorDUnitTest extends DistributedTestCase {
           }
         }
       });
-      
-      Object[] connectArgs = new Object[]{ properties };
-      
+
+      Object[] connectArgs = new Object[] { properties };
+
       SerializableRunnable crashSystem =
-        new SerializableRunnable("Crash system") {
-          public void run() {
-            DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
-            msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
-            MembershipManagerHelper.crashDistributedSystem(msys);
-          }
-      };
+          new SerializableRunnable("Crash system") {
+            public void run() {
+              DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
+              msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+              MembershipManagerHelper.crashDistributedSystem(msys);
+            }
+          };
 
       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
-      
-      DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+
+      DistributedMember mem1 = (DistributedMember) vm1.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
-      DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+      DistributedMember mem2 = (DistributedMember) vm2.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
 
       assertEquals(mem1, MembershipManagerHelper.getLeadMember(sys));
-      
+
       assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
-      
+
       MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
 
       // crash the lead vm. Should be okay
@@ -705,7 +699,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       
       assertTrue("Distributed system should not have disconnected",
           isSystemConnected());
-      
+
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
       
@@ -714,13 +708,13 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       // stop the locator normally.  This should also be okay
       locator.stop();
-      
+
       if (!Locator.getLocators().isEmpty()) {
         // log this for debugging purposes before throwing assertion error
         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().warning("found locator " + Locator.getLocators().iterator().next());
       }
       assertTrue("locator is not stopped", Locator.getLocators().isEmpty());
-      
+
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
       
@@ -733,7 +727,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       		mem2, vm2.invoke(() -> LocatorDUnitTest.getLeadMember()));
       
       SerializableRunnable disconnect =
-        new SerializableRunnable("Disconnect from " + locators) {
+          new SerializableRunnable("Disconnect from " + locators) {
             public void run() {
               DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
               if (sys != null && sys.isConnected()) {
@@ -746,8 +740,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       // locator notice the failure and exit
       vm2.invoke(disconnect);
       locvm.invoke(stopLocator);
-    }
-    finally {
+    } finally {
       MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
       if (locator != null) {
         locator.stop();
@@ -801,7 +794,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 
     SerializableRunnable stopLocator = getStopLocatorRunnable();
-    
+
     try {
       final String uname = getUniqueName();
       File logFile = new File("");
@@ -812,51 +805,50 @@ public class LocatorDUnitTest extends DistributedTestCase {
           File lf = new File("");
           try {
             Locator.startLocatorAndDS(port2, lf, properties);
-          }
-          catch (IOException ios) {
+          } catch (IOException ios) {
             com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
           }
         }
       });
-      
-      Object[] connectArgs = new Object[]{ properties };
-      
+
+      Object[] connectArgs = new Object[] { properties };
+
       SerializableRunnable crashSystem =
-        new SerializableRunnable("Crash system") {
-          public void run() {
-            DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
-            msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>Possible loss of quorum</ExpectedException>");
-            hook = new TestHook();
-            MembershipManagerHelper.getMembershipManager(msys).registerTestHook(hook);
-            try {
-              MembershipManagerHelper.crashDistributedSystem(msys);
-            } finally {
-              hook.reset();
+          new SerializableRunnable("Crash system") {
+            public void run() {
+              DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
+              msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>Possible loss of quorum</ExpectedException>");
+              hook = new TestHook();
+              MembershipManagerHelper.getMembershipManager(msys).registerTestHook(hook);
+              try {
+                MembershipManagerHelper.crashDistributedSystem(msys);
+              } finally {
+                hook.reset();
+              }
             }
-          }
-      };
+          };
 
       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
-      
-      final DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+
+      final DistributedMember mem1 = (DistributedMember) vm1.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
-      final DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+      final DistributedMember mem2 = (DistributedMember) vm2.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
 
       assertEquals(mem1, MembershipManagerHelper.getLeadMember(sys));
-      
+
       assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
-      
+
       // crash the lead vm. Should be okay. it should hang in test hook thats
       // why call is asynchronous.
       //vm1.invokeAsync(crashSystem);
 
       assertTrue("Distributed system should not have disconnected",
           isSystemConnected());
-      
+
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
       
@@ -869,12 +861,12 @@ public class LocatorDUnitTest extends DistributedTestCase {
       
       // request member removal for first peer from second peer.
       vm2.invoke(new SerializableRunnable("Request Member Removal") {
-        
+
         @Override
         public void run() {
           DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
           MembershipManager mmgr = MembershipManagerHelper.getMembershipManager(msys);
-          
+
           // check for shutdown cause in MembershipManager. Following call should
           // throw DistributedSystemDisconnectedException which should have cause as
           // ForceDisconnectException.
@@ -894,8 +886,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
         }
       });
 
-    }
-    finally {
+    } finally {
       if (locator != null) {
         locator.stop();
       }
@@ -939,7 +930,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 
     SerializableRunnable disconnect =
-      new SerializableRunnable("Disconnect from " + locators) {
+        new SerializableRunnable("Disconnect from " + locators) {
           public void run() {
             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
             if (sys != null && sys.isConnected()) {
@@ -949,11 +940,11 @@ public class LocatorDUnitTest extends DistributedTestCase {
           }
         };
     SerializableRunnable expectedException =
-      new SerializableRunnable("Add expected exceptions") {
-        public void run() {
-          MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
-        }
-    };
+        new SerializableRunnable("Add expected exceptions") {
+          public void run() {
+            MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
+          }
+        };
     try {
       final String uname = getUniqueName();
       locvm.invoke(new SerializableRunnable() {
@@ -961,8 +952,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
           File lf = new File("");
           try {
             Locator.startLocatorAndDS(port2, lf, properties);
-          }
-          catch (IOException ios) {
+          } catch (IOException ios) {
             com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator1", ios);
           }
         }
@@ -972,42 +962,42 @@ public class LocatorDUnitTest extends DistributedTestCase {
       locator = Locator.startLocatorAndDS(port1, logFile, properties);
       DistributedSystem sys = locator.getDistributedSystem();
       sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
-      Object[] connectArgs = new Object[]{ properties };
-      
+      Object[] connectArgs = new Object[] { properties };
+
       SerializableRunnable crashLocator =
-        new SerializableRunnable("Crash locator") {
-          public void run() {
-            Locator loc = Locator.getLocators().iterator().next();
-            DistributedSystem msys = loc.getDistributedSystem();
-            msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
-            msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
-            MembershipManagerHelper.crashDistributedSystem(msys);
-            loc.stop();
-          }
-      };
+          new SerializableRunnable("Crash locator") {
+            public void run() {
+              Locator loc = Locator.getLocators().iterator().next();
+              DistributedSystem msys = loc.getDistributedSystem();
+              msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+              msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+              MembershipManagerHelper.crashDistributedSystem(msys);
+              loc.stop();
+            }
+          };
 
       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
-      
-      DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+
+      DistributedMember mem1 = (DistributedMember) vm1.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
       vm1.invoke(expectedException);
-      DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+      DistributedMember mem2 = (DistributedMember) vm2.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
       
       DistributedMember loc1Mbr = (DistributedMember)locvm.invoke(() -> this.getLocatorDistributedMember());
 
       assertLeadMember(mem1, sys, 5000);
-      
+
       assertEquals(loc1Mbr, MembershipManagerHelper.getCoordinator(sys));
-      
+
       // crash the lead locator.  Should be okay
       locvm.invoke(crashLocator);
       Wait.pause(10 * 1000);
 
       assertTrue("Distributed system should not have disconnected",
           sys.isConnected());
-      
+
       assertTrue("Distributed system should not have disconnected",
           vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
       
@@ -1025,11 +1015,10 @@ public class LocatorDUnitTest extends DistributedTestCase {
       assertEquals(sys.getDistributedMember(),
           MembershipManagerHelper.getCoordinator(sys));
       assertEquals(mem2, MembershipManagerHelper.getLeadMember(sys));
-      
-    }
-    finally {
+
+    } finally {
       vm2.invoke(disconnect);
-      
+
       if (locator != null) {
         locator.stop();
       }
@@ -1053,17 +1042,17 @@ public class LocatorDUnitTest extends DistributedTestCase {
     props.setProperty("locators", locators);
 
     final String expected = "java.net.ConnectException";
-    final String addExpected = 
-      "<ExpectedException action=add>" + expected + "</ExpectedException>";
-    final String removeExpected = 
-      "<ExpectedException action=remove>" + expected + "</ExpectedException>";
-      
+    final String addExpected =
+        "<ExpectedException action=add>" + expected + "</ExpectedException>";
+    final String removeExpected =
+        "<ExpectedException action=remove>" + expected + "</ExpectedException>";
+
     LogWriter bgexecLogger =
-          new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+        new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
     bgexecLogger.info(addExpected);
-    
+
     boolean exceptionOccurred = true;
-    String oldValue = (String)System.getProperties().put("p2p.joinTimeout", "15000");
+    String oldValue = (String) System.getProperties().put("p2p.joinTimeout", "15000");
     try {
       DistributedSystem.connect(props);
       exceptionOccurred = false;
@@ -1074,7 +1063,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     } catch (GemFireConfigException ex) {
       String s = ex.getMessage();
       assertTrue(s.indexOf("Locator does not exist") >= 0);
-      
+
     } catch (Exception ex) {
       // if you see this fail, determine if unexpected exception is expected
       // if expected then add in a catch block for it above this catch
@@ -1114,14 +1103,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
     DistributedTestUtils.deleteLocatorStateFile(port1);
     final String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
     final String uniqueName = getUniqueName();
-    
+
     vm0.invoke(new SerializableRunnable("Start locator " + locators) {
-        public void run() {
-          File logFile = new File("");
-          try {
-            Properties locProps = new Properties();
-            locProps.setProperty("mcast-port", "0");
-            locProps.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+      public void run() {
+        File logFile = new File("");
+        try {
+          Properties locProps = new Properties();
+          locProps.setProperty("mcast-port", "0");
+          locProps.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 
             Locator.startLocatorAndDS(port, logFile, locProps);
           } catch (IOException ex) {
@@ -1131,22 +1120,22 @@ public class LocatorDUnitTest extends DistributedTestCase {
       });
     try {
 
-    SerializableRunnable connect =
-      new SerializableRunnable("Connect to " + locators) {
-          public void run() {
-            //System.setProperty("p2p.joinTimeout", "5000");
-            Properties props = new Properties();
-            props.setProperty("mcast-port", "0");
-            props.setProperty("locators", locators);
-            DistributedSystem.connect(props);
-          }
-        };
-    vm1.invoke(connect);
-    vm2.invoke(connect);
+      SerializableRunnable connect =
+          new SerializableRunnable("Connect to " + locators) {
+            public void run() {
+              //System.setProperty("p2p.joinTimeout", "5000");
+              Properties props = new Properties();
+              props.setProperty("mcast-port", "0");
+              props.setProperty("locators", locators);
+              DistributedSystem.connect(props);
+            }
+          };
+      vm1.invoke(connect);
+      vm2.invoke(connect);
 
-    Properties props = new Properties();
-    props.setProperty("mcast-port", "0");
-    props.setProperty("locators", locators);
+      Properties props = new Properties();
+      props.setProperty("mcast-port", "0");
+      props.setProperty("locators", locators);
 
     system = (InternalDistributedSystem)DistributedSystem.connect(props);
     
@@ -1193,14 +1182,6 @@ public class LocatorDUnitTest extends DistributedTestCase {
     }
   }
 
-//  public void testRepeat() throws Exception {
-//    for (int i=0; i<10; i++) {
-//      System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> run #"+i);
-//      testLocatorBecomesCoordinator();
-//      tearDown();
-//      setUp();
-//    }
-//  }
   /**
    * Tests starting one locator in a remote VM and having multiple
    * members of the distributed system join it.  This ensures that
@@ -1211,10 +1192,10 @@ public class LocatorDUnitTest extends DistributedTestCase {
   public void testLocatorBecomesCoordinator() throws Exception {
     disconnectAllFromDS();
     final String expected = "java.net.ConnectException";
-    final String addExpected = 
-      "<ExpectedException action=add>" + expected + "</ExpectedException>";
-    final String removeExpected = 
-      "<ExpectedException action=remove>" + expected + "</ExpectedException>";
+    final String addExpected =
+        "<ExpectedException action=add>" + expected + "</ExpectedException>";
+    final String removeExpected =
+        "<ExpectedException action=remove>" + expected + "</ExpectedException>";
 
     Host host = Host.getHost(0);
     VM vm0 = host.getVM(0);
@@ -1229,23 +1210,23 @@ public class LocatorDUnitTest extends DistributedTestCase {
     vm0.invoke(getStartSBLocatorRunnable(port, getUniqueName()+"1"));
     try {
 
-    final Properties props = new Properties();
-    props.setProperty("mcast-port", "0");
-    props.setProperty("locators", locators);
-    props.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+      final Properties props = new Properties();
+      props.setProperty("mcast-port", "0");
+      props.setProperty("locators", locators);
+      props.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 
-    SerializableRunnable connect =
-      new SerializableRunnable("Connect to " + locators) {
-          public void run() {
-            //System.setProperty("p2p.joinTimeout", "5000");
-            DistributedSystem sys = getSystem(props);
-            sys.getLogWriter().info(addExpected);
-          }
-        };
-    vm1.invoke(connect);
-    vm2.invoke(connect);
+      SerializableRunnable connect =
+          new SerializableRunnable("Connect to " + locators) {
+            public void run() {
+              //System.setProperty("p2p.joinTimeout", "5000");
+              DistributedSystem sys = getSystem(props);
+              sys.getLogWriter().info(addExpected);
+            }
+          };
+      vm1.invoke(connect);
+      vm2.invoke(connect);
 
-    system = (InternalDistributedSystem)getSystem(props);
+      system = (InternalDistributedSystem) getSystem(props);
 
     final DistributedMember coord = MembershipManagerHelper.getCoordinator(system);
     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator before termination of locator is " + coord);
@@ -1263,7 +1244,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       }
     };
     Wait.waitForCriterion(ev, 15000, 200, true);
-    DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system); 
+    DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system);
     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator after shutdown of locator was " +
         newCoord);
     if (newCoord == null || coord.equals(newCoord)) {
@@ -1293,23 +1274,23 @@ public class LocatorDUnitTest extends DistributedTestCase {
       new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
     bgexecLogger.info(removeExpected);
 
-    SerializableRunnable disconnect =
-      new SerializableRunnable("Disconnect from " + locators) {
-          public void run() {
-            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-            if (sys != null && sys.isConnected()) {
-              sys.disconnect();
+      SerializableRunnable disconnect =
+          new SerializableRunnable("Disconnect from " + locators) {
+            public void run() {
+              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+              if (sys != null && sys.isConnected()) {
+                sys.disconnect();
+              }
+              // connectExceptions occur during disconnect, so we need the
+              // expectedexception hint to be in effect until this point
+              LogWriter bLogger =
+                  new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+              bLogger.info(removeExpected);
             }
-            // connectExceptions occur during disconnect, so we need the
-            // expectedexception hint to be in effect until this point
-            LogWriter bLogger =
-              new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
-            bLogger.info(removeExpected);
-          }
-        };
-    vm1.invoke(disconnect);
-    vm2.invoke(disconnect);
-    vm0.invoke(getStopLocatorRunnable());
+          };
+      vm1.invoke(disconnect);
+      vm2.invoke(disconnect);
+      vm0.invoke(getStopLocatorRunnable());
     } finally {
       vm0.invoke(getStopLocatorRunnable());
     }
@@ -1326,7 +1307,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
   public static void resetRefreshWait() {
     System.getProperties().remove("p2p.gossipRefreshRate");
   }
-  
+
   public static boolean isSystemConnected() {
     DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
     if (sys != null && sys.isConnected()) {
@@ -1334,12 +1315,10 @@ public class LocatorDUnitTest extends DistributedTestCase {
     }
     return false;
   }
-  
 
   static boolean beforeFailureNotificationReceived;
   static boolean afterFailureNotificationReceived;
 
-
   /**
    * Tests starting multiple locators in multiple VMs.
    */
@@ -1357,15 +1336,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
     final int port2 = freeTCPPorts[1];
     this.port2 = port2;
     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
-    final String host0 = NetworkUtils.getServerHostName(host); 
+    final String host0 = NetworkUtils.getServerHostName(host);
     final String locators = host0 + "[" + port1 + "]," +
-                            host0 + "[" + port2 + "]";
+        host0 + "[" + port2 + "]";
 
     final Properties dsProps = new Properties();
     dsProps.setProperty("locators", locators);
     dsProps.setProperty("mcast-port", "0");
     dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
-//    dsProps.setProperty("log-level", "finest");
     final String uniqueName = getUniqueName();
 
     vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
@@ -1396,14 +1374,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
       try {
 
         SerializableRunnable connect =
-          new SerializableRunnable("Connect to " + locators) {
-          public void run() {
-            Properties props = new Properties();
-            props.setProperty("mcast-port", "0");
-            props.setProperty("locators", locators);
-            DistributedSystem.connect(props);
-          }
-        };
+            new SerializableRunnable("Connect to " + locators) {
+              public void run() {
+                Properties props = new Properties();
+                props.setProperty("mcast-port", "0");
+                props.setProperty("locators", locators);
+                DistributedSystem.connect(props);
+              }
+            };
         vm1.invoke(connect);
         vm2.invoke(connect);
 
@@ -1411,19 +1389,19 @@ public class LocatorDUnitTest extends DistributedTestCase {
         props.setProperty("mcast-port", "0");
         props.setProperty("locators", locators);
 
-        system = (InternalDistributedSystem)DistributedSystem.connect(props);
+        system = (InternalDistributedSystem) DistributedSystem.connect(props);
 
         WaitCriterion ev = new WaitCriterion() {
           public boolean done() {
             try {
               return system.getDM().getViewMembers().size() >= 3;
-            }
-            catch (Exception e) {
+            } catch (Exception e) {
               e.printStackTrace();
               fail("unexpected exception");
             }
             return false; // NOTREACHED
           }
+
           public String description() {
             return null;
           }
@@ -1436,14 +1414,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
         system.disconnect();
 
         SerializableRunnable disconnect =
-          new SerializableRunnable("Disconnect from " + locators) {
-          public void run() {
-            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-            if (sys != null && sys.isConnected()) {
-              sys.disconnect();
-            }
-          }
-        };
+            new SerializableRunnable("Disconnect from " + locators) {
+              public void run() {
+                DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+                if (sys != null && sys.isConnected()) {
+                  sys.disconnect();
+                }
+              }
+            };
         vm1.invoke(disconnect);
         vm2.invoke(disconnect);
 
@@ -1456,6 +1434,158 @@ public class LocatorDUnitTest extends DistributedTestCase {
   }
   
   /**
+   * Tests starting multiple locators at the same time and ensuring that the locators
+   * end up only have 1 master.
+   * GEODE-870
+   */
+  public void testMultipleLocatorsRestartingAtSameTime() throws Exception {
+    disconnectAllFromDS();
+    Host host = Host.getHost(0);
+    VM vm0 = host.getVM(0);
+    VM vm1 = host.getVM(1);
+    VM vm2 = host.getVM(2);
+    VM vm3 = host.getVM(3);
+    VM vm4 = host.getVM(4);
+
+    int[] freeTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(3);
+    this.port1 = freeTCPPorts[0];
+    this.port2 = freeTCPPorts[1];
+    int port3 = freeTCPPorts[2];
+    deleteLocatorStateFile(port1, port2, port3);
+    final String host0 = getServerHostName(host);
+    final String locators = host0 + "[" + port1 + "]," +
+        host0 + "[" + port2 + "]," +
+        host0 + "[" + port3 + "]";
+
+    final Properties dsProps = new Properties();
+    dsProps.setProperty("locators", locators);
+    dsProps.setProperty("mcast-port", "0");
+    dsProps.setProperty("log-level", "FINE");
+    dsProps.setProperty("enable-network-partition-detection", "true");
+    dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+    final String uniqueName = getUniqueName();
+
+    startLocatorSync(vm0, new Object[] { port1, dsProps });
+    startLocatorSync(vm1, new Object[] { port2, dsProps });
+    startLocatorSync(vm2, new Object[] { port3, dsProps });
+    try {
+      try {
+
+        SerializableRunnable connect =
+            new SerializableRunnable("Connect to " + locators) {
+              public void run() {
+                Properties props = new Properties();
+                props.setProperty("mcast-port", "0");
+                props.setProperty("locators", locators);
+                props.setProperty("log-level", "FINE");
+                props.setProperty("enable-network-partition-detection", "true");
+                DistributedSystem.connect(props);
+              }
+            };
+        vm3.invoke(connect);
+        vm4.invoke(connect);
+
+        Properties props = new Properties();
+        props.setProperty("mcast-port", "0");
+        props.setProperty("locators", locators);
+
+        system = (InternalDistributedSystem) DistributedSystem.connect(props);
+
+        WaitCriterion waitCriterion = new WaitCriterion() {
+          public boolean done() {
+            try {
+              return system.getDM().getViewMembers().size() >= 3;
+            } catch (Exception e) {
+              e.printStackTrace();
+              fail("unexpected exception");
+            }
+            return false; // NOTREACHED
+          }
+
+          public String description() {
+            return null;
+          }
+        };
+        DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
+
+        // three applications plus
+        assertEquals(6, system.getDM().getViewMembers().size());
+
+        vm0.invoke(getStopLocatorRunnable());
+        vm1.invoke(getStopLocatorRunnable());
+        vm2.invoke(getStopLocatorRunnable());
+
+        final String newLocators = host0 + "[" + port2 + "]," +
+            host0 + "[" + port3 + "]";
+        dsProps.setProperty("locators", newLocators);
+
+        startLocatorAsync(vm1, new Object[] { port2, dsProps });
+        startLocatorAsync(vm2, new Object[] { port3, dsProps });
+
+        waitCriterion = new WaitCriterion() {
+          public boolean done() {
+            try {
+              return system.getDM().getAllHostedLocators().size() == 2;
+            } catch (Exception e) {
+              e.printStackTrace();
+              fail("unexpected exception");
+            }
+            return false; // NOTREACHED
+          }
+
+          public String description() {
+            return null;
+          }
+        };
+        DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
+
+      } finally {
+        system.disconnect();
+        SerializableRunnable disconnect =
+            new SerializableRunnable("Disconnect from " + locators) {
+              public void run() {
+                DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+                if (sys != null && sys.isConnected()) {
+                  sys.disconnect();
+                }
+              }
+            };
+        vm3.invoke(disconnect);
+        vm4.invoke(disconnect);
+        vm2.invoke(getStopLocatorRunnable());
+        vm1.invoke(getStopLocatorRunnable());
+      }
+    } finally {
+    }
+  }
+
+  private void startLocatorSync(VM vm, Object[] args) {
+    vm.invoke(new SerializableRunnable("Starting process on " + args[0], args) {
+      public void run() {
+        File logFile = new File("");
+        try {
+          Locator.startLocatorAndDS((int) args[0], logFile, (Properties) args[1]);
+        } catch (IOException ex) {
+          fail("While starting process on port " + args[0], ex);
+        }
+      }
+    });
+  }
+
+  private void startLocatorAsync(VM vm, Object[] args) {
+    vm.invokeAsync(new SerializableRunnable("Starting process on " + args[0], args) {
+      public void run() {
+        File logFile = new File("");
+        try {
+          Locator.startLocatorAndDS((int) args[0], logFile, (Properties) args[1]);
+        } catch (IOException ex) {
+          fail("While starting process on port " + args[0], ex);
+        }
+      }
+    });
+  }
+
+  /**
    * Tests starting multiple locators in multiple VMs.
    */
   public void testMultipleMcastLocators() throws Exception {
@@ -1475,11 +1605,11 @@ public class LocatorDUnitTest extends DistributedTestCase {
     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
     final int mcastport = AvailablePort.getRandomAvailablePort(AvailablePort.MULTICAST);
     
-    final String host0 = NetworkUtils.getServerHostName(host); 
+    final String host0 = NetworkUtils.getServerHostName(host);
     final String locators = host0 + "[" + port1 + "]," +
-                            host0 + "[" + port2 + "]";
+        host0 + "[" + port2 + "]";
     final String uniqueName = getUniqueName();
-    
+
     vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
         public void run() {
           File logFile = new File("");
@@ -1519,7 +1649,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       });
 
     SerializableRunnable connect =
-      new SerializableRunnable("Connect to " + locators) {
+        new SerializableRunnable("Connect to " + locators) {
           public void run() {
             Properties props = new Properties();
             props.setProperty("mcast-port", String.valueOf(mcastport));
@@ -1541,17 +1671,17 @@ public class LocatorDUnitTest extends DistributedTestCase {
       props.setProperty("mcast-ttl", "0");
       props.setProperty("enable-network-partition-detection", "true");
 
-      system = (InternalDistributedSystem)DistributedSystem.connect(props);
+      system = (InternalDistributedSystem) DistributedSystem.connect(props);
       WaitCriterion ev = new WaitCriterion() {
         public boolean done() {
           try {
             return system.getDM().getViewMembers().size() == 5;
-          }
-          catch (Exception e) {
+          } catch (Exception e) {
             com.gemstone.gemfire.test.dunit.Assert.fail("unexpected exception", e);
           }
           return false; // NOTREACHED
         }
+
         public String description() {
           return "waiting for 5 members - have " + system.getDM().getViewMembers().size();
         }
@@ -1560,7 +1690,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       system.disconnect();
 
       SerializableRunnable disconnect =
-        new SerializableRunnable("Disconnect from " + locators) {
+          new SerializableRunnable("Disconnect from " + locators) {
             public void run() {
               DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
               if (sys != null && sys.isConnected()) {
@@ -1570,8 +1700,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
           };
       vm1.invoke(disconnect);
       vm2.invoke(disconnect);
-    }
-    finally {
+    } finally {
       SerializableRunnable stop = getStopLocatorRunnable();
       vm0.invoke(stop);
       vm3.invoke(stop);
@@ -1581,7 +1710,6 @@ public class LocatorDUnitTest extends DistributedTestCase {
     }
   }
 
-
   /**
    * Tests that a VM can connect to a locator that is hosted in its
    * own VM.
@@ -1599,14 +1727,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
     final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
 
-    Properties props = new Properties();
-    props.setProperty("mcast-port", "0");
-    props.setProperty("locators", locators);
-    props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
-    system = (InternalDistributedSystem)DistributedSystem.connect(props);
-    system.disconnect();
+      Properties props = new Properties();
+      props.setProperty("mcast-port", "0");
+      props.setProperty("locators", locators);
+      props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+      system = (InternalDistributedSystem) DistributedSystem.connect(props);
+      system.disconnect();
     } finally {
-    locator.stop();
+      locator.stop();
     }
   }
 
@@ -1619,7 +1747,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     Host host = Host.getHost(0);
     VM vm1 = host.getVM(1);
     Locator locator = null;
-    
+
     try {
       port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
       DistributedTestUtils.deleteLocatorStateFile(port1);
@@ -1632,37 +1760,36 @@ public class LocatorDUnitTest extends DistributedTestCase {
       properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
       File logFile = new File("");
       locator = Locator.startLocatorAndDS(port1, logFile, properties);
-  
+
       final Properties properties2 = new Properties();
       properties2.put("mcast-port", "0");
       properties2.put("locators", locators);
       properties2.put(DistributionConfig.ENABLE_NETWORK_PARTITION_DETECTION_NAME, "false");
       properties2.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
       properties2.put("disable-auto-reconnect", "true");
-      
+
       vm1.invoke(new SerializableRunnable("try to connect") {
         public void run() {
           DistributedSystem s = null;
           try {
             s = DistributedSystem.connect(properties2);
-            boolean enabled = ((InternalDistributedSystem)s).getConfig().getEnableNetworkPartitionDetection();
+            boolean enabled = ((InternalDistributedSystem) s).getConfig().getEnableNetworkPartitionDetection();
             s.disconnect();
             if (!enabled) {
               fail("should not have been able to connect with different enable-network-partition-detection settings");
             }
-          }
-          catch (GemFireConfigException e) {
+          } catch (GemFireConfigException e) {
             fail("should have been able to connect and have enable-network-partion-detection enabled");
           }
         }
       });
-      
+
       locator.stop();
-      
+
       // now start the locator with enable-network-partition-detection=false
       logFile = new File("");
-      locator = Locator.startLocatorAndDS(port1, logFile , properties2);
-  
+      locator = Locator.startLocatorAndDS(port1, logFile, properties2);
+
       vm1.invoke(new SerializableRunnable("try to connect") {
         public void run() {
           DistributedSystem s = null;
@@ -1670,17 +1797,15 @@ public class LocatorDUnitTest extends DistributedTestCase {
             s = DistributedSystem.connect(properties);
             s.disconnect();
             fail("should not have been able to connect with different enable-network-partition-detection settings");
-          }
-          catch (GemFireConfigException e) {
+          } catch (GemFireConfigException e) {
             // passed
           }
         }
       });
-      
+
       locator.stop();
       locator = null;
-    }
-    finally {
+    } finally {
       if (locator != null) {
         locator.stop();
       }
@@ -1697,16 +1822,16 @@ public class LocatorDUnitTest extends DistributedTestCase {
     //VM vm1 = host.getVM(1);
 
     port1 =
-      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+        AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
     File logFile1 = new File("");
     DistributedTestUtils.deleteLocatorStateFile(port1);
     Locator locator1 = Locator.startLocator(port1, logFile1);
-    
+
     try {
 
-    int port2 =
-      AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-    File logFile2 = new File("");
+      int port2 =
+          AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+      File logFile2 = new File("");
 
     DistributedTestUtils.deleteLocatorStateFile(port2);
     
@@ -1733,21 +1858,21 @@ public class LocatorDUnitTest extends DistributedTestCase {
     connect.run();
     //vm1.invoke(connect);
 
-    SerializableRunnable disconnect =
-      new SerializableRunnable("Disconnect from " + locators) {
-          public void run() {
-            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-            if (sys != null && sys.isConnected()) {
-              sys.disconnect();
+      SerializableRunnable disconnect =
+          new SerializableRunnable("Disconnect from " + locators) {
+            public void run() {
+              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+              if (sys != null && sys.isConnected()) {
+                sys.disconnect();
+              }
             }
-          }
-        };
+          };
 
-    disconnect.run();
-    //vm1.invoke(disconnect);
+      disconnect.run();
+      //vm1.invoke(disconnect);
 
     } finally {
-    locator1.stop();
+      locator1.stop();
     }
   }
 
@@ -1763,10 +1888,10 @@ public class LocatorDUnitTest extends DistributedTestCase {
       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
     DistributedTestUtils.deleteLocatorStateFile(port1);
     File logFile = new File("");
-    File stateFile = new File("locator"+port1+"state.dat");
+    File stateFile = new File("locator" + port1 + "state.dat");
     VM vm0 = Host.getHost(0).getVM(0);
     final Properties p = new Properties();
-    p.setProperty(DistributionConfig.LOCATORS_NAME, Host.getHost(0).getHostName() + "["+port1+"]");
+    p.setProperty(DistributionConfig.LOCATORS_NAME, Host.getHost(0).getHostName() + "[" + port1 + "]");
     p.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
     p.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
     if (stateFile.exists()) {
@@ -1787,7 +1912,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     
     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Stopping locator");
     locator.stop();
-    
+
     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Starting locator");
     locator = Locator.startLocatorAndDS(port1, logFile, p);
     
@@ -1798,14 +1923,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
     });
     
     } finally {
-    locator.stop();
+      locator.stop();
     }
 
   }
   
   /** return the distributed member id for the ds on this vm */
   public static DistributedMember getDistributedMember(Properties props) {
-    props.put("name", "vm_"+VM.getCurrentVMNum());
+    props.put("name", "vm_" + VM.getCurrentVMNum());
     DistributedSystem sys = DistributedSystem.connect(props);
     sys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
@@ -1816,7 +1941,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
   /** find a running locator and return its distributed member id */
   public static DistributedMember getLocatorDistributedMember() {
     return (Locator.getLocators().iterator().next())
-      .getDistributedSystem().getDistributedMember();
+        .getDistributedSystem().getDistributedMember();
   }
   
   /** find the lead member and return its id */
@@ -1837,7 +1962,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       }
     };
   }
-  
+
   private SerializableRunnable getStartSBLocatorRunnable(final int port, final String name) {
     return new SerializableRunnable("Start locator on port " + port) {
       public void run() {
@@ -1859,26 +1984,25 @@ public class LocatorDUnitTest extends DistributedTestCase {
       }
     };
   }
-  
+
   protected void nukeJChannel(DistributedSystem sys) {
     sys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
     try {
       MembershipManagerHelper.crashDistributedSystem(sys);
-    }
-    catch (DistributedSystemDisconnectedException se) {
+    } catch (DistributedSystemDisconnectedException se) {
       // it's okay for the system to already be shut down
     }
     sys.getLogWriter().info("<ExpectedException action=remove>service failure</ExpectedException>");
     sys.getLogWriter().info("<ExpectedException action=remove>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
   }
 
-  
   //New test hook which blocks before closing channel.
   class TestHook implements MembershipTestHook {
 
     volatile boolean unboundedWait = true;
+
     @Override
     public void beforeMembershipFailure(String reason, Throwable cause) {
       System.out.println("Inside TestHook.beforeMembershipFailure with " + cause);
@@ -1901,22 +2025,26 @@ public class LocatorDUnitTest extends DistributedTestCase {
     }
 
   }
+
   class MyMembershipListener implements MembershipListener {
     boolean quorumLostInvoked;
     List<String> suspectReasons = new ArrayList<>(50);
-    
-    public void memberJoined(InternalDistributedMember id) {  }
-    public void memberDeparted(InternalDistributedMember id, boolean crashed) { }
+
+    public void memberJoined(InternalDistributedMember id) {
+    }
+
+    public void memberDeparted(InternalDistributedMember id, boolean crashed) {
+    }
+
     public void memberSuspect(InternalDistributedMember id,
         InternalDistributedMember whoSuspected, String reason) {
       suspectReasons.add(reason);
     }
+
     public void quorumLost(Set<InternalDistributedMember> failures,
         List<InternalDistributedMember> remaining) {
       quorumLostInvoked = true;
       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("quorumLost invoked in test code");
     }
   }
-  
-  
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/80cbc3f5/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
index 353cdc7..4caf815 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/test/dunit/SerializableRunnable.java
@@ -49,8 +49,9 @@ import java.io.Serializable;
 public abstract class SerializableRunnable implements SerializableRunnableIF {
 
   private static final long serialVersionUID = 7584289978241650456L;
-  
+
   private String name;
+  private Object[] args;
 
   public SerializableRunnable() {
     this.name = null;
@@ -70,11 +71,16 @@ public abstract class SerializableRunnable implements SerializableRunnableIF {
   public SerializableRunnable(String name) {
     this.name = name;
   }
-  
+
+  public SerializableRunnable(String name, Object[] args) {
+    this.name = name;
+    this.args = args;
+  }
+
   public void setName(String newName) {
     this.name = newName;
   }
-  
+
   public String getName() {
     return this.name;
   }


[083/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
index 0000000,c731721..6c58790
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
@@@ -1,0 -1,3142 +1,3142 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import java.io.ByteArrayInputStream;
+ import java.io.DataInput;
+ import java.io.DataInputStream;
+ import java.io.DataOutput;
+ import java.io.IOException;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CopyHelper;
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.DeltaSerializationException;
+ import com.gemstone.gemfire.GemFireIOException;
+ import com.gemstone.gemfire.InvalidDeltaException;
+ import com.gemstone.gemfire.SerializationException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.EntryEvent;
+ import com.gemstone.gemfire.cache.EntryNotFoundException;
+ import com.gemstone.gemfire.cache.EntryOperation;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.SerializedCacheValue;
+ import com.gemstone.gemfire.cache.TransactionId;
+ import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
+ import com.gemstone.gemfire.cache.query.QueryException;
+ import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexProtocol;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexUtils;
+ import com.gemstone.gemfire.cache.util.TimestampedEntryEvent;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.DistributionMessage;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.ByteArrayDataInput;
+ import com.gemstone.gemfire.internal.DSFIDFactory;
+ import com.gemstone.gemfire.internal.DataSerializableFixedID;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.InternalDataSerializer;
+ import com.gemstone.gemfire.internal.Sendable;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.FilterRoutingInfo.FilterInfo;
+ import com.gemstone.gemfire.internal.cache.delta.Delta;
+ import com.gemstone.gemfire.internal.cache.lru.Sizeable;
+ import com.gemstone.gemfire.internal.cache.partitioned.PartitionMessage;
+ import com.gemstone.gemfire.internal.cache.partitioned.PutMessage;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerHelper;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+ import com.gemstone.gemfire.internal.cache.tx.DistTxKeyInfo;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventCallbackArgument;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.lang.StringUtils;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.OffHeapRegionEntryHelper;
+ import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
+ import com.gemstone.gemfire.internal.offheap.Releasable;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ENTRY_EVENT_NEW_VALUE;
+ import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.ENTRY_EVENT_OLD_VALUE;
+ 
+ import com.gemstone.gemfire.internal.util.ArrayUtils;
+ import com.gemstone.gemfire.internal.util.BlobHelper;
+ import com.gemstone.gemfire.pdx.internal.PeerTypeRegistration;
+ 
+ /**
+  * Implementation of an entry event
+  */
+ // must be public for DataSerializableFixedID
+ public class EntryEventImpl
+   implements EntryEvent, InternalCacheEvent, DataSerializableFixedID, EntryOperation
+              , Releasable
+ {
+   private static final Logger logger = LogService.getLogger();
+   
+   // PACKAGE FIELDS //
+   public transient LocalRegion region;
+   private transient RegionEntry re;
+ 
+   protected KeyInfo keyInfo;
+ 
+   //private long eventId;
+   /** the event's id. Scoped by distributedMember. */
+   protected EventID eventID;
+ 
+   private Object newValue = null;
+   /**
+    * If we ever serialize the new value then it should be
+    * stored in this field in case we need the serialized form
+    * again later. This was added to fix bug 43781.
+    * Note that we also have the "newValueBytes" field.
+    * But it is only non-null if setSerializedNewValue was called.
+    */
+   private byte[] cachedSerializedNewValue = null;
+   @Retained(ENTRY_EVENT_OLD_VALUE)
+   private Object oldValue = null;
+   protected Delta delta = null;
+  
+   protected short eventFlags = 0x0000;
+ 
+   protected TXId txId = null;
+ 
+   protected Operation op;
+ 
+   /* To store the operation/modification type */
+   private transient EnumListenerEvent eventType;
+ 
+   /**
+    * This field will be null unless this event is used for a putAll operation.
+    *
+    * @since 5.0
+    */
+   protected transient DistributedPutAllOperation putAllOp;
+ 
+   /**
+    * This field will be null unless this event is used for a removeAll operation.
+    *
+    * @since 8.1
+    */
+   protected transient DistributedRemoveAllOperation removeAllOp;
+ 
+   /**
+    * The member that originated this event
+    *
+    * @since 5.0
+    */
+   protected DistributedMember distributedMember;
+ 
+   
+   /**
+    * transient storage for the message that caused the event
+    */
+   transient DistributionMessage causedByMessage;
+   
+   
+   //private static long eventID = 0;
+ 
+   /**
+    * The originating membershipId of this event.
+    *
+    * @since 5.1
+    */
+   protected ClientProxyMembershipID context = null;
+   
+   /**
+    * A custom context object that can be used for any other contextual
+    * information. Currently used by SQL Fabric to pass around evaluated rows
+    * from raw byte arrays and routing object.
+    */
+   private transient Object contextObj = null;
+ 
+   /**
+    * this holds the bytes representing the change in value effected by this
+    * event.  It is used when the value implements the Delta interface.
+    */
+   private byte[] deltaBytes = null;
+ 
+   
+   /** routing information for cache clients for this event */
+   private FilterInfo filterInfo;
+   
+   /**new value stored in serialized form*/
+   protected byte[] newValueBytes;
+   /**old value stored in serialized form*/
+   private byte[] oldValueBytes;
+   
+   /** version tag for concurrency checks */
+   protected VersionTag versionTag;
+ 
+   /** boolean to indicate that this operation should be optimized by not fetching from HDFS*/
+   private transient boolean fetchFromHDFS = true;
+   
+   private transient boolean isPutDML = false;
+ 
+   /** boolean to indicate that the RegionEntry for this event was loaded from HDFS*/
+   private transient boolean loadedFromHDFS= false;
+   
+   private transient boolean isCustomEviction = false;
+   
+   /** boolean to indicate that the RegionEntry for this event has been evicted*/
+   private transient boolean isEvicted = false;
+   
+   private transient boolean isPendingSecondaryExpireDestroy = false;
+   
+   public final static Object SUSPECT_TOKEN = new Object();
+   
+   public EntryEventImpl() {
+   }
+   
+   /**
+    * create a new entry event that will be used for conveying version information
+    * and anything else of use while processing another event
+    * @return the empty event object
+    */
+   @Retained
+   public static EntryEventImpl createVersionTagHolder() {
+     return createVersionTagHolder(null);
+   }
+   
+   /**
+    * create a new entry event that will be used for conveying version information
+    * and anything else of use while processing another event
+    * @return the empty event object
+    */
+   @Retained
+   public static EntryEventImpl createVersionTagHolder(VersionTag tag) {
+     EntryEventImpl result = new EntryEventImpl();
+     result.setVersionTag(tag);
+     result.disallowOffHeapValues();
+     return result;
+   }
+ 
+   /**
+    * Reads the contents of this message from the given input.
+    */
+   public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+     this.eventID = (EventID)DataSerializer.readObject(in);
+     Object key = DataSerializer.readObject(in);
+     Object value = DataSerializer.readObject(in);
+     this.keyInfo = new KeyInfo(key, value, null);
+     this.op = Operation.fromOrdinal(in.readByte());
+     this.eventFlags = in.readShort();
+     this.keyInfo.setCallbackArg(DataSerializer.readObject(in));
+     this.txId = (TXId)DataSerializer.readObject(in);
+ 
+     if (in.readBoolean()) {     // isDelta
+       this.delta = (Delta)DataSerializer.readObject(in);
+     }
+     else {
+       // OFFHEAP Currently values are never deserialized to off heap memory. If that changes then this code needs to change.
+       if (in.readBoolean()) {     // newValueSerialized
+         this.newValueBytes = DataSerializer.readByteArray(in);
+         this.cachedSerializedNewValue = this.newValueBytes;
+         this.newValue = CachedDeserializableFactory.create(this.newValueBytes);
+       }
+       else {
+         this.newValue = DataSerializer.readObject(in);
+       }
+     }
+ 
+     // OFFHEAP Currently values are never deserialized to off heap memory. If that changes then this code needs to change.
+     if (in.readBoolean()) {     // oldValueSerialized
+       this.oldValueBytes = DataSerializer.readByteArray(in);
+       this.oldValue = CachedDeserializableFactory.create(this.oldValueBytes);
+     }
+     else {
+       this.oldValue = DataSerializer.readObject(in);
+     }
+     this.distributedMember = DSFIDFactory.readInternalDistributedMember(in);
+     this.context = ClientProxyMembershipID.readCanonicalized(in);
+     this.tailKey = DataSerializer.readLong(in);
+   }
+ 
+   @Retained
+   protected EntryEventImpl(LocalRegion region, Operation op, Object key,
+       boolean originRemote, DistributedMember distributedMember,
+       boolean generateCallbacks, boolean fromRILocalDestroy) {
+     this.region = region;
+     this.op = op;
+     this.keyInfo = this.region.getKeyInfo(key);
+     setOriginRemote(originRemote);
+     setGenerateCallbacks(generateCallbacks);
+     this.distributedMember = distributedMember;
+     setFromRILocalDestroy(fromRILocalDestroy);
+   }
+ 
+   /**
+    * Doesn't specify oldValue as this will be filled in later as part of an
+    * operation on the region, or lets it default to null.
+    */
+   @Retained
+   protected EntryEventImpl(
+       final LocalRegion region,
+       Operation op, Object key, @Retained(ENTRY_EVENT_NEW_VALUE) Object newVal,
+       Object callbackArgument,
+       boolean originRemote, DistributedMember distributedMember,
+       boolean generateCallbacks, boolean initializeId) {
+ 
+     this.region = region;
+     this.op = op;
+     this.keyInfo = this.region.getKeyInfo(key, newVal, callbackArgument);
+ 
+     if (newVal instanceof Delta) {
+       this.delta = (Delta)newVal;
+     }
+     else if (!Token.isInvalid(newVal)) {
+       basicSetNewValue(newVal);
+     }
+ 
+     this.txId = this.region.getTXId();
+     /**
+      * this might set txId for events done from a thread that has a tx even
+      * though the op is non-tx. For example region ops.
+      */
+     if (newVal == Token.LOCAL_INVALID) {
+       setLocalInvalid(true);
+     }
+     setOriginRemote(originRemote);
+     setGenerateCallbacks(generateCallbacks);
+     this.distributedMember = distributedMember;
+   }
+ 
+   /**
+    * Called by BridgeEntryEventImpl to use existing EventID
+    */
+   @Retained
+   protected EntryEventImpl(LocalRegion region, Operation op, Object key,
+       @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue, Object callbackArgument, boolean originRemote,
+       DistributedMember distributedMember, boolean generateCallbacks,
+       EventID eventID) {
+     this(region, op, key, newValue,
+         callbackArgument, originRemote, distributedMember, generateCallbacks,
+         true /* initializeId */);
+     Assert.assertTrue(eventID != null || !(region instanceof PartitionedRegion));
+     this.setEventId(eventID);
+   }
+ 
+   /**
+    * create an entry event from another entry event
+    */
+   @Retained
+   public EntryEventImpl(@Retained({ENTRY_EVENT_NEW_VALUE, ENTRY_EVENT_OLD_VALUE}) EntryEventImpl other) {
+     this(other, true);
+   }
+   
+   @Retained
+   public EntryEventImpl(@Retained({ENTRY_EVENT_NEW_VALUE, ENTRY_EVENT_OLD_VALUE}) EntryEventImpl other, boolean setOldValue) {
+     region = other.region;
+ 
+     this.eventID = other.eventID;
+     basicSetNewValue(other.basicGetNewValue());
+     this.newValueBytes = other.newValueBytes;
+     this.cachedSerializedNewValue = other.cachedSerializedNewValue;
+     this.re = other.re;
+     this.delta = other.delta;
+     if (setOldValue) {
+       retainAndSetOldValue(other.basicGetOldValue());
+       this.oldValueBytes = other.oldValueBytes;
+     }
+     this.eventFlags = other.eventFlags;
+     setEventFlag(EventFlags.FLAG_CALLBACKS_INVOKED, false);
+     txId = other.txId;
+     op = other.op;
+     distributedMember = other.distributedMember;
+     this.filterInfo = other.filterInfo;
+     this.keyInfo = other.keyInfo.isDistKeyInfo() ? new DistTxKeyInfo(
+         (DistTxKeyInfo) other.keyInfo) : new KeyInfo(other.keyInfo);
+     if (other.getRawCallbackArgument() instanceof GatewaySenderEventCallbackArgument) {
+       this.keyInfo
+           .setCallbackArg((new GatewaySenderEventCallbackArgument(
+               (GatewaySenderEventCallbackArgument) other
+                   .getRawCallbackArgument())));
+     }
+     this.context = other.context;
+     this.deltaBytes = other.deltaBytes;
+     this.tailKey = other.tailKey;
+     this.versionTag = other.versionTag;
+     //set possible duplicate 
+     this.setPossibleDuplicate(other.isPossibleDuplicate()); 
+   }
+ 
+   @Retained
+   public EntryEventImpl(Object key2) {
+     this.keyInfo = new KeyInfo(key2, null, null);
+   }
+   
+   /**
+    * This constructor is used to create a bridge event in server-side
+    * command classes.  Events created with this are not intended to be
+    * used in cache operations.
+    * @param id the identity of the client's event
+    */
+   @Retained
+   public EntryEventImpl(EventID id) {
+     this.eventID = id;
+     this.offHeapOk = false;
+   }
+ 
+   /**
+    * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
+    * EntryEventImpl if the region parameter is a PartitionedRegion.
+    */  
+   @Retained
+   public static EntryEventImpl create(LocalRegion region,
+       Operation op,
+       Object key, @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue, Object callbackArgument,
+       boolean originRemote, DistributedMember distributedMember) {
+     return create(region,op,key,newValue,callbackArgument,originRemote,distributedMember,true,true);
+   }
+   
+   /**
+    * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
+    * EntryEventImpl if the region parameter is a PartitionedRegion.
+    */
+   @Retained
+   public static EntryEventImpl create(LocalRegion region,
+       Operation op,
+       Object key,
+       @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue,
+       Object callbackArgument,
+       boolean originRemote,
+       DistributedMember distributedMember,
+       boolean generateCallbacks) {
+     return create(region, op, key, newValue, callbackArgument, originRemote,
+         distributedMember, generateCallbacks,true);
+   }
+   
+   /**
+    * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
+    * EntryEventImpl if the region parameter is a PartitionedRegion.
+    *  
+    * Called by BridgeEntryEventImpl to use existing EventID
+    * 
+    * {@link EntryEventImpl#EntryEventImpl(LocalRegion, Operation, Object, Object, Object, boolean, DistributedMember, boolean, EventID)}
+    */ 
+   @Retained
+   public static EntryEventImpl create(LocalRegion region, Operation op, Object key,
+       @Retained(ENTRY_EVENT_NEW_VALUE) Object newValue, Object callbackArgument, boolean originRemote,
+       DistributedMember distributedMember, boolean generateCallbacks,
+       EventID eventID) {
+     EntryEventImpl entryEvent = new EntryEventImpl(region,op,key,newValue,callbackArgument,originRemote,distributedMember,generateCallbacks,eventID);
+     return entryEvent;
+   }
+   
+   /**
+    * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
+    * EntryEventImpl if the region parameter is a PartitionedRegion.
+    * 
+    * {@link EntryEventImpl#EntryEventImpl(LocalRegion, Operation, Object, boolean, DistributedMember, boolean, boolean)}
+    */
+   @Retained
+   public static EntryEventImpl create(LocalRegion region, Operation op, Object key,
+       boolean originRemote, DistributedMember distributedMember,
+       boolean generateCallbacks, boolean fromRILocalDestroy) {
+     EntryEventImpl entryEvent = new EntryEventImpl(region,op,key,originRemote,distributedMember,generateCallbacks,fromRILocalDestroy);
+     return entryEvent;
+   }  
+   
+   /**
+    * Creates and returns an EntryEventImpl.  Generates and assigns a bucket id to the
+    * EntryEventImpl if the region parameter is a PartitionedRegion.
+    * 
+    * This creator does not specify the oldValue as this will be filled in later as part of an
+    * operation on the region, or lets it default to null.
+    * 
+    * {@link EntryEventImpl#EntryEventImpl(LocalRegion, Operation, Object, Object, Object, boolean, DistributedMember, boolean, boolean)}
+    */
+   @Retained
+   public static EntryEventImpl create(final LocalRegion region,
+       Operation op, Object key, @Retained(ENTRY_EVENT_NEW_VALUE) Object newVal,
+       Object callbackArgument,
+       boolean originRemote, DistributedMember distributedMember,
+       boolean generateCallbacks, boolean initializeId)  {
+     EntryEventImpl entryEvent = new EntryEventImpl(region,op,key,newVal,callbackArgument,
+         originRemote,distributedMember,generateCallbacks,initializeId);
+     return entryEvent;
+   }
+   
+   /**
+    * Creates a PutAllEvent given the distributed operation, the region, and the
+    * entry data.
+    *
+    * @since 5.0
+    */
+   @Retained
+   static EntryEventImpl createPutAllEvent(
+       DistributedPutAllOperation putAllOp, LocalRegion region,
+       Operation entryOp, Object entryKey, @Retained(ENTRY_EVENT_NEW_VALUE) Object entryNewValue)
+   {
+     EntryEventImpl e;
+     if (putAllOp != null) {
+       EntryEventImpl event = putAllOp.getBaseEvent();
+       if (event.isBridgeEvent()) {
+         e = EntryEventImpl.create(region, entryOp, entryKey, entryNewValue,
+             event.getRawCallbackArgument(), false, event.distributedMember,
+             event.isGenerateCallbacks());
+         e.setContext(event.getContext());
+       } else {
+         e = EntryEventImpl.create(region, entryOp, entryKey, entryNewValue, event.getCallbackArgument(),
+             false, region.getMyId(), event.isGenerateCallbacks());
+       }
+       
+     } else {
+       e = EntryEventImpl.create(region, entryOp, entryKey, entryNewValue, null,
+           false, region.getMyId(), true);
+     }
+     
+     e.putAllOp = putAllOp;
+     return e;
+   }
+   
+   protected static EntryEventImpl createRemoveAllEvent(
+       DistributedRemoveAllOperation op, 
+       LocalRegion region,
+       Object entryKey) {
+     EntryEventImpl e;
+     final Operation entryOp = Operation.REMOVEALL_DESTROY;
+     if (op != null) {
+       EntryEventImpl event = op.getBaseEvent();
+       if (event.isBridgeEvent()) {
+         e = EntryEventImpl.create(region, entryOp, entryKey, null,
+             event.getRawCallbackArgument(), false, event.distributedMember,
+             event.isGenerateCallbacks());
+         e.setContext(event.getContext());
+       } else {
+         e = EntryEventImpl.create(region, entryOp, entryKey, null, event.getCallbackArgument(),
+             false, region.getMyId(), event.isGenerateCallbacks());
+       }
+       
+     } else {
+       e = EntryEventImpl.create(region, entryOp, entryKey, null, null,
+           false, region.getMyId(), true);
+     }
+     
+     e.removeAllOp = op;
+     return e;
+   }
+   public boolean isBulkOpInProgress() {
+     return getPutAllOperation() != null || getRemoveAllOperation() != null;
+   }
+   
+   /** return the putAll operation for this event, if any */
+   public DistributedPutAllOperation getPutAllOperation() {
+     return this.putAllOp;
+   }
+   public DistributedPutAllOperation setPutAllOperation(DistributedPutAllOperation nv) {
+     DistributedPutAllOperation result = this.putAllOp;
+     if (nv != null && nv.getBaseEvent() != null) {
+       setCallbackArgument(nv.getBaseEvent().getCallbackArgument());
+     }
+     this.putAllOp = nv;
+     return result;
+   }
+   public DistributedRemoveAllOperation getRemoveAllOperation() {
+     return this.removeAllOp;
+   }
+   public DistributedRemoveAllOperation setRemoveAllOperation(DistributedRemoveAllOperation nv) {
+     DistributedRemoveAllOperation result = this.removeAllOp;
+     if (nv != null && nv.getBaseEvent() != null) {
+       setCallbackArgument(nv.getBaseEvent().getCallbackArgument());
+     }
+     this.removeAllOp = nv;
+     return result;
+   }
+ 
+   private final boolean testEventFlag(short mask)
+   {
+     return EventFlags.isSet(this.eventFlags, mask);
+   }
+ 
+   private final void setEventFlag(short mask, boolean on)
+   {
+     this.eventFlags = EventFlags.set(this.eventFlags, mask, on);
+   }
+ 
+   public DistributedMember getDistributedMember()
+   {
+     return this.distributedMember;
+   }
+ 
+   /////////////////////// INTERNAL BOOLEAN SETTERS
+   public void setOriginRemote(boolean b)
+   {
+     setEventFlag(EventFlags.FLAG_ORIGIN_REMOTE, b);
+   }
+ 
+   public void setLocalInvalid(boolean b)
+   {
+     setEventFlag(EventFlags.FLAG_LOCAL_INVALID, b);
+   }
+ 
+   void setGenerateCallbacks(boolean b)
+   {
+     setEventFlag(EventFlags.FLAG_GENERATE_CALLBACKS, b);
+   }
+ 
+   /** set the the flag telling whether callbacks should be invoked for a partitioned region */
+   public void setInvokePRCallbacks(boolean b) {
+     setEventFlag(EventFlags.FLAG_INVOKE_PR_CALLBACKS, b);
+   }
+ 
+   /** get the flag telling whether callbacks should be invoked for a partitioned region */
+   public boolean getInvokePRCallbacks() {
+     return testEventFlag(EventFlags.FLAG_INVOKE_PR_CALLBACKS);
+   }
+   
+   public boolean getInhibitDistribution() {
+     return testEventFlag(EventFlags.FLAG_INHIBIT_DISTRIBUTION);
+   }
+   
+   public void setInhibitDistribution(boolean b) {
+     setEventFlag(EventFlags.FLAG_INHIBIT_DISTRIBUTION, b);
+   }
+   
+   /** was the entry destroyed or missing and allowed to be destroyed again? */
+   public boolean getIsRedestroyedEntry() {
+     return testEventFlag(EventFlags.FLAG_REDESTROYED_TOMBSTONE);
+   }
+   
+   public void setIsRedestroyedEntry(boolean b) {
+     setEventFlag(EventFlags.FLAG_REDESTROYED_TOMBSTONE, b);
+   }
+   
+   public void isConcurrencyConflict(boolean b) {
+     setEventFlag(EventFlags.FLAG_CONCURRENCY_CONFLICT, b);
+   }
+   
+   public boolean isConcurrencyConflict() {
+     return testEventFlag(EventFlags.FLAG_CONCURRENCY_CONFLICT);
+   }
+ 
+   /** set the DistributionMessage that caused this event */
+   public void setCausedByMessage(DistributionMessage msg) {
+     this.causedByMessage = msg;
+   }
+ 
+   /**
+    * get the PartitionMessage that caused this event, or null if
+    * the event was not caused by a PartitionMessage
+    */
+   public PartitionMessage getPartitionMessage() {
+     if (this.causedByMessage != null && this.causedByMessage instanceof PartitionMessage) {
+       return (PartitionMessage)this.causedByMessage;
+   }
+     return null;
+   }
+ 
+   /**
+    * get the RemoteOperationMessage that caused this event, or null if
+    * the event was not caused by a RemoteOperationMessage
+    */
+   public RemoteOperationMessage getRemoteOperationMessage() {
+     if (this.causedByMessage != null && this.causedByMessage instanceof RemoteOperationMessage) {
+       return (RemoteOperationMessage)this.causedByMessage;
+     }
+     return null;
+   }
+ 
+   /////////////// BOOLEAN GETTERS
+   public boolean isLocalLoad()
+   {
+     return this.op.isLocalLoad();
+   }
+ 
+   public boolean isNetSearch()
+   {
+     return this.op.isNetSearch();
+   }
+ 
+   public boolean isNetLoad()
+   {
+     return this.op.isNetLoad();
+   }
+ 
+   public boolean isDistributed()
+   {
+     return this.op.isDistributed();
+   }
+ 
+   public boolean isExpiration()
+   {
+     return this.op.isExpiration();
+   }
+   
+   public boolean isEviction() {
+     return this.op.isEviction();
+   }
+ 
+   public final boolean isCustomEviction() {
+     return this.isCustomEviction;
+   }
+   
+   public final void setCustomEviction(boolean customEvict) {
+     this.isCustomEviction = customEvict;
+   }
+   
+   public final void setEvicted() {
+     this.isEvicted = true;
+   }
+   
+   public final boolean isEvicted() {
+     return this.isEvicted;
+   }
+   
+   public final boolean isPendingSecondaryExpireDestroy() {
+     return this.isPendingSecondaryExpireDestroy;
+   }
+   
+   public final void setPendingSecondaryExpireDestroy (boolean value) {
+     this.isPendingSecondaryExpireDestroy = value;
+   }
+   // Note that isOriginRemote is sometimes set to false even though the event
+   // was received from a peer.  This is done to force distribution of the
+   // message to peers and to cause concurrency version stamping to be performed.
+   // This is done by all one-hop operations, like RemoteInvalidateMessage.
+   public boolean isOriginRemote()
+   {
+     return testEventFlag(EventFlags.FLAG_ORIGIN_REMOTE);
+   }
+ 
+   /* return whether this event originated from a WAN gateway and carries a WAN version tag */
+   public boolean isFromWANAndVersioned() {
+     return (this.versionTag != null && this.versionTag.isGatewayTag());
+   }
+   
+   /* return whether this event originated in a client and carries a version tag */
+   public boolean isFromBridgeAndVersioned() {
+     return (this.context != null) && (this.versionTag != null);
+   }
+ 
+   public boolean isGenerateCallbacks()
+   {
+     return testEventFlag(EventFlags.FLAG_GENERATE_CALLBACKS);
+   }
+ 
+   public void setNewEventId(DistributedSystem sys) {
+     Assert.assertTrue(this.eventID == null, "Double setting event id");
+     EventID newID = new EventID(sys);
+     if (this.eventID != null) {
+       if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
+         logger.trace(LogMarker.BRIDGE_SERVER, "Replacing event ID with {} in event {}", newID, this);
+       }
+     }
+     this.eventID = newID;
+   }
+   
+   public void reserveNewEventId(DistributedSystem sys, int count) {
+     Assert.assertTrue(this.eventID == null, "Double setting event id");
+     this.eventID = new EventID(sys);
+     if (count > 1) {
+       this.eventID.reserveSequenceId(count-1);
+     }
+   }
+ 
+   public void setEventId(EventID id)
+   {
+     this.eventID = id;
+   }
+ 
+   /**
+    * Return the event id, if any
+    * @return null if no event id has been set
+    */
+   public final EventID getEventId() {
+     return this.eventID;
+   }
+ 
+   public boolean isBridgeEvent() {
+     return hasClientOrigin();
+   }
+   public boolean hasClientOrigin() {
+     return getContext() != null;
+   }
+ 
+   /**
+    * sets the ID of the client that initiated this event
+    */
+   public void setContext(ClientProxyMembershipID contx) {
+     Assert.assertTrue(contx != null);
+     this.context = contx;
+   }
+ 
+   /**
+    * gets the ID of the client that initiated this event.  Null if a server-initiated event
+    */
+   public ClientProxyMembershipID getContext()
+   {
+     return this.context;
+   }
+ 
+   // INTERNAL
+   boolean isLocalInvalid()
+   {
+     return testEventFlag(EventFlags.FLAG_LOCAL_INVALID);
+   }
+ 
+   /////////////////////////////////////////////////
+ 
+   /**
+    * Returns the key.
+    *
+    * @return the key.
+    */
+   public Object getKey()
+   {
+     return keyInfo.getKey();
+   }
+ 
+   /**
+    * Returns the value in the cache prior to this event. When passed to an event
+    * handler after an event occurs, this value reflects the value that was in
+    * the cache in this VM, not necessarily the value that was in the cache VM
+    * that initiated the operation.
+    *
+    * @return the value in the cache prior to this event.
+    */
+   public final Object getOldValue() {
+     try {
+       if (isOriginRemote() && this.region.isProxy()) {
+         return null;
+       }
+       @Unretained Object ov = basicGetOldValue();
+       if (ov == null) {
+         return null;
+       } else if (ov == Token.NOT_AVAILABLE) {
+         return AbstractRegion.handleNotAvailable(ov);
+       }
+       boolean doCopyOnRead = getRegion().isCopyOnRead();
+       if (ov != null) {
+         if (ov instanceof StoredObject) {
+           // TODO OFFHEAP: returns off-heap PdxInstance
+           return ((StoredObject) ov).getValueAsDeserializedHeapObject();
+         } else
+         if (ov instanceof CachedDeserializable) {
+           CachedDeserializable cd = (CachedDeserializable)ov;
+           if (doCopyOnRead) {
+             return cd.getDeserializedWritableCopy(this.region, this.re);
+           } else {
+             return cd.getDeserializedValue(this.region, this.re);
+           }
+         }
+         else {
+           if (doCopyOnRead) {
+             return CopyHelper.copy(ov);
+           } else {
+             return ov;
+           }
+         }
+       }
+       return null;
+     } catch(IllegalArgumentException i) {
+       IllegalArgumentException iae = new IllegalArgumentException(LocalizedStrings.DONT_RELEASE.toLocalizedString("Error while deserializing value for key="+getKey()));
+       iae.initCause(i);
+       throw iae;
+     }
+   }
+ 
+   /**
+    * Like getRawNewValue except that if the result is an off-heap reference then copy it to the heap.
+    * ALERT: If there is a Delta, returns that, not the (applied) new value.
+    * TODO OFFHEAP: to prevent the heap copy use getRawNewValue instead
+    */
+   public final Object getRawNewValueAsHeapObject() {
+     if (this.delta != null) {
+       return this.delta;
+     }
+     return OffHeapHelper.getHeapForm(OffHeapHelper.copyIfNeeded(basicGetNewValue()));
+   }
+   
+   /**
+    * If new value is a Delta return it.
+    * Else if new value is off-heap return the StoredObject form (unretained OFF_HEAP_REFERENCE). 
+    * Its refcount is not inced by this call and the returned object can only be safely used for the lifetime of the EntryEventImpl instance that returned the value.
+    * Else return the raw form.
+    */
+   @Unretained(ENTRY_EVENT_NEW_VALUE)
+   public final Object getRawNewValue() {
+     if (this.delta != null) return this.delta;
+     return basicGetNewValue();
+   }
+ 
+   @Unretained(ENTRY_EVENT_NEW_VALUE)
+   public Object getValue() {
+     return basicGetNewValue();
+   }
+   
+   /**
+    * Returns the delta that represents the new value; null if no delta.
+    * @return the delta that represents the new value; null if no delta.
+    */
+   public final Delta getDeltaNewValue() {
+     return this.delta;
+   }
+ 
+   /**
+    *  Applies the delta 
+    */
+   private Object applyDeltaWithCopyOnRead(boolean doCopyOnRead) {
+     //try {
+       if (applyDelta(true)) {
+         Object applied = basicGetNewValue();
+         // if applyDelta returns true then newValue should not be off-heap
+         assert !(applied instanceof StoredObject);
+         if (applied == this.oldValue && doCopyOnRead) {
+           applied = CopyHelper.copy(applied);
+         }
+         return applied;
+       }
+     //} catch (EntryNotFoundException ex) {
+       // only (broken) product code has the opportunity to call this before
+       // this.oldValue is set. If oldValue is not set yet, then
+       // we most likely haven't synchronized on the region entry yet.
+       // (If we have, then make sure oldValue is set before
+       // calling this method).
+       //throw new AssertionError("too early to call getNewValue");
+     //}
+     return null;
+   }
+ 
+   @Released(ENTRY_EVENT_NEW_VALUE)
+   protected void basicSetNewValue(@Retained(ENTRY_EVENT_NEW_VALUE) Object v) {
+     if (v == this.newValue) return;
+     if (this.offHeapOk) {
+       OffHeapHelper.releaseAndTrackOwner(this.newValue, this);
+     }
 -    if (v instanceof Chunk) {
++    if (v instanceof ObjectChunk) {
+       ReferenceCountHelper.setReferenceCountOwner(this);
 -      if (!((Chunk) v).retain()) {
++      if (!((ObjectChunk) v).retain()) {
+         ReferenceCountHelper.setReferenceCountOwner(null);
+         this.newValue = null;
+         return;
+       }
+       ReferenceCountHelper.setReferenceCountOwner(null);
+     }
+     this.newValue = v;
+     this.cachedSerializedNewValue = null;
+   }
+   /**
+    * Returns true if this event has a reference to an off-heap new or old value.
+    */
+   public boolean hasOffHeapValue() {
 -    return (this.newValue instanceof Chunk) || (this.oldValue instanceof Chunk);
++    return (this.newValue instanceof ObjectChunk) || (this.oldValue instanceof ObjectChunk);
+   }
+   
+   @Unretained
+   protected final Object basicGetNewValue() {
+     Object result = this.newValue;
 -    if (!this.offHeapOk && result instanceof Chunk) {
++    if (!this.offHeapOk && result instanceof ObjectChunk) {
+       //this.region.getCache().getLogger().info("DEBUG new value already freed " + System.identityHashCode(result));
+       throw new IllegalStateException("Attempt to access off heap value after the EntryEvent was released.");
+     }
+     return result;
+   }
+   
+   private class OldValueOwner {
+     private EntryEventImpl getEvent() {
+       return EntryEventImpl.this;
+     }
+     @Override
+     public int hashCode() {
+       return getEvent().hashCode();
+     }
+ 
+     @Override
+     public boolean equals(Object obj) {
+       if (obj instanceof OldValueOwner) {
+         return getEvent().equals(((OldValueOwner) obj).getEvent());
+       } else {
+         return false;
+       }
+     }
+     @Override
+     public String toString() {
+       return "OldValueOwner " + getEvent().toString();
+     }
+   }
+ 
+   /**
+    * Note if v might be an off-heap reference that you did not retain for this EntryEventImpl
+    * then call retainsAndSetOldValue instead of this method.
+    * @param v the caller should have already retained this off-heap reference.
+    */
+   @Released(ENTRY_EVENT_OLD_VALUE)
+   private void basicSetOldValue(@Unretained(ENTRY_EVENT_OLD_VALUE) Object v) {
+     @Released final Object curOldValue = this.oldValue;
+     if (v == curOldValue) return;
+     if (this.offHeapOk) {
 -      if (curOldValue instanceof Chunk) {
++      if (curOldValue instanceof ObjectChunk) {
+         if (ReferenceCountHelper.trackReferenceCounts()) {
+           OffHeapHelper.releaseAndTrackOwner(curOldValue, new OldValueOwner());
+         } else {
+           OffHeapHelper.release(curOldValue);
+         }
+       }
+     }
+     
+     this.oldValue = v;
+   }
+ 
+   @Released(ENTRY_EVENT_OLD_VALUE)
+   private void retainAndSetOldValue(@Retained(ENTRY_EVENT_OLD_VALUE) Object v) {
+     if (v == this.oldValue) return;
+     
 -    if (v instanceof Chunk) {
++    if (v instanceof ObjectChunk) {
+       if (ReferenceCountHelper.trackReferenceCounts()) {
+         ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
 -        boolean couldNotRetain = (!((Chunk) v).retain());
++        boolean couldNotRetain = (!((ObjectChunk) v).retain());
+         ReferenceCountHelper.setReferenceCountOwner(null);
+         if (couldNotRetain) {
+           this.oldValue = null;
+           return;
+         }
+       } else {
 -        if (!((Chunk) v).retain()) {
++        if (!((ObjectChunk) v).retain()) {
+           this.oldValue = null;
+           return;
+         }
+       }
+     }
+     basicSetOldValue(v);
+   }
+ 
+   @Unretained(ENTRY_EVENT_OLD_VALUE)
+   private Object basicGetOldValue() {
+     @Unretained(ENTRY_EVENT_OLD_VALUE)
+     Object result = this.oldValue;
 -    if (!this.offHeapOk && result instanceof Chunk) {
++    if (!this.offHeapOk && result instanceof ObjectChunk) {
+       //this.region.getCache().getLogger().info("DEBUG old value already freed " + System.identityHashCode(result));
+       throw new IllegalStateException("Attempt to access off heap value after the EntryEvent was released.");
+     }
+     return result;
+   }
+ 
+   /**
+    * Like getRawOldValue except that if the result is an off-heap reference then copy it to the heap.
+    * To avoid the heap copy use getRawOldValue instead.
+    */
+   public final Object getRawOldValueAsHeapObject() {
+     return OffHeapHelper.getHeapForm(OffHeapHelper.copyIfNeeded(basicGetOldValue()));
+   }
+   /*
+    * If the old value is off-heap return the StoredObject form (unretained OFF_HEAP_REFERENCE). 
+    * Its refcount is not inced by this call and the returned object can only be safely used for the lifetime of the EntryEventImpl instance that returned the value.
+    * Else return the raw form.
+    */
+   @Unretained
+   public final Object getRawOldValue() {
+     return basicGetOldValue();
+   }
+   /**
+    * Just like getRawOldValue except if the raw old value is off-heap deserialize it.
+    * Note that in some cases sqlf ignores the request to deserialize.
+    */
+   @Unretained(ENTRY_EVENT_OLD_VALUE)
+   public final Object getOldValueAsOffHeapDeserializedOrRaw() {
+     Object result = basicGetOldValue();
+     if (result instanceof StoredObject) {
+       result = ((StoredObject) result).getDeserializedForReading();
+     }
+     return AbstractRegion.handleNotAvailable(result); // fixes 49499
+   }
+ 
+   /**
+    * Added this function to expose isCopyOnRead function to the
+    * child classes of EntryEventImpl  
+    * 
+    */
+   protected boolean isRegionCopyOnRead() {
+     return getRegion().isCopyOnRead();
+   }
+  
+   /**
+    * Returns the value in the cache after this event.
+    *
+    * @return the value in the cache after this event.
+    */
+   public final Object getNewValue() {
+     
+     boolean doCopyOnRead = getRegion().isCopyOnRead();
+     try {
+       if (applyDelta(true)) {
+         @Unretained(ENTRY_EVENT_NEW_VALUE)
+         Object applied = basicGetNewValue();
+         if (applied == this.oldValue && doCopyOnRead) {
+           applied = CopyHelper.copy(applied);
+         }
+         return applied;
+       }
+     } catch (EntryNotFoundException ex) {
+       // only (broken) product code has the opportunity to call this before
+       // this.oldValue is set. If oldValue is not set yet, then
+       // we most likely haven't synchronized on the region entry yet.
+       // (If we have, then make sure oldValue is set before
+       // calling this method).
+       throw new AssertionError("too early to call getNewValue");
+     }
+     Object nv = basicGetNewValue();
+     if (nv != null) {
+       if (nv == Token.NOT_AVAILABLE) {
+         // I'm not sure this can even happen
+         return AbstractRegion.handleNotAvailable(nv);
+       }
+       if (nv instanceof StoredObject) {
+         // TODO OFFHEAP currently we copy offheap new value to the heap here. Check callers of this method to see if they can be optimized to use offheap values.
+         // TODO OFFHEAP: returns off-heap PdxInstance
+         return ((StoredObject) nv).getValueAsDeserializedHeapObject();
+       } else
+       if (nv instanceof CachedDeserializable) {
+         CachedDeserializable cd = (CachedDeserializable)nv;
+         Object v = null;
+         if (doCopyOnRead) {
+           v = cd.getDeserializedWritableCopy(this.region, this.re);
+         } else {
+           v = cd.getDeserializedValue(this.region, this.re);
+         }
+         assert !(v instanceof CachedDeserializable) : "for key "+this.getKey()+" found nested CachedDeserializable";
+         return v;
+       }
+       else {
+         if (doCopyOnRead) {
+           return CopyHelper.copy(nv);
+         } else {
+           return nv;
+         }
+       }
+     }
+     return null;
+   }
+ 
+   public final String getNewValueStringForm() {
+     return StringUtils.forceToString(basicGetNewValue());
+   }
+   public final String getOldValueStringForm() {
+     return StringUtils.forceToString(basicGetOldValue());
+   }
+   
+   protected boolean applyDelta(boolean throwOnNullOldValue)
+       throws EntryNotFoundException {
+     if (this.newValue != null || this.delta == null) {
+       return false;
+     }
+     if (this.oldValue == null) {
+       if (throwOnNullOldValue) {
+         // !!!:ezoerner:20080611 It would be nice if the client got this
+         // exception
+         throw new EntryNotFoundException(
+             "Cannot apply a delta without an existing value");
+       }
+       return false;
+     }
+     // swizzle BucketRegion in event for Delta.
+     // !!!:ezoerner:20090602 this is way ugly; this whole class severely
+     // needs refactoring
+     LocalRegion originalRegion = this.region;
+     try {
+       if (originalRegion instanceof BucketRegion) {
+         this.region = ((BucketRegion)this.region).getPartitionedRegion();
+       }
+       basicSetNewValue(this.delta.apply(this));
+     } finally {
+       this.region = originalRegion;
+     }
+     return true;
+   }
+ 
+   /** Set a deserialized value */
+   public final void setNewValue(@Retained(ENTRY_EVENT_NEW_VALUE) Object obj) {
+     if (obj instanceof Delta) {
+       this.delta = (Delta)obj;
+       basicSetNewValue(null);
+     }
+     else {
+       basicSetNewValue(obj);
+     }
+   }
+ 
+   public TransactionId getTransactionId()
+   {
+     return this.txId;
+   }
+ 
+   public void setTransactionId(TransactionId txId)
+   {
+     this.txId = (TXId)txId;
+   }
+ 
+   /**
+    * Answer true if this event resulted from a loader.
+    *
+    * @return true if isLocalLoad or isNetLoad
+    */
+   public boolean isLoad()
+   {
+     return this.op.isLoad();
+   }
+ 
+   public void setRegion(LocalRegion r)
+   {
+     this.region = r;
+   }
+ 
+   /**
+    * @see com.gemstone.gemfire.cache.CacheEvent#getRegion()
+    */
+   public final LocalRegion getRegion() {
+     return region;
+   }
+ 
+   public Operation getOperation()
+   {
+     return this.op;
+   }
+ 
+   public void setOperation(Operation op)
+   {
+     this.op = op;
+     PartitionMessage prm = getPartitionMessage();
+     if (prm != null) {
+       prm.setOperation(this.op);
+     }
+   }
+ 
+   /**
+    * @see com.gemstone.gemfire.cache.CacheEvent#getCallbackArgument()
+    */
+   public Object getCallbackArgument()
+   {
+     Object result = this.keyInfo.getCallbackArg();
+     while (result instanceof WrappedCallbackArgument) {
+       WrappedCallbackArgument wca = (WrappedCallbackArgument)result;
+       result = wca.getOriginalCallbackArg();
+     }
+     if (result == Token.NOT_AVAILABLE) {
+       result = AbstractRegion.handleNotAvailable(result);
+     }
+     return result;
+   }
+   public boolean isCallbackArgumentAvailable() {
+     return this.getRawCallbackArgument() != Token.NOT_AVAILABLE;
+   }
+ 
+   /**
+    * Returns the value of the EntryEventImpl field.
+    * This is for internal use only. Customers should always call
+    * {@link #getCallbackArgument}
+    * @since 5.5 
+    */
+   public Object getRawCallbackArgument() {
+     return this.keyInfo.getCallbackArg();
+   }
+   
+   /**
+    * Sets the value of raw callback argument field.
+    */
+   public void setRawCallbackArgument(Object newCallbackArgument) {
+     this.keyInfo.setCallbackArg(newCallbackArgument);
+   }
+ 
+   public void setCallbackArgument(Object newCallbackArgument) {
+     if (this.keyInfo.getCallbackArg() instanceof WrappedCallbackArgument) {
+       ((WrappedCallbackArgument)this.keyInfo.getCallbackArg())
+           .setOriginalCallbackArgument(newCallbackArgument);
+     }
+     else {
+       this.keyInfo.setCallbackArg(newCallbackArgument);
+     }
+   }
+ 
+   /**
+    * @return null if new value is not serialized; otherwise returns a SerializedCacheValueImpl containing the new value.
+    */
+   public SerializedCacheValue<?> getSerializedNewValue() {
+     // In the case where there is a delta that has not been applied yet,
+     // do not apply it here since it would not produce a serialized new
+     // value (return null instead to indicate the new value is not
+     // in serialized form).
+     @Unretained(ENTRY_EVENT_NEW_VALUE)
+     final Object tmp = basicGetNewValue();
+     if (tmp instanceof CachedDeserializable) {
+       if (tmp instanceof StoredObject) {
+         if (!((StoredObject) tmp).isSerialized()) {
+           // TODO OFFHEAP can we handle offheap byte[] better?
+           return null;
+         }
+       }
+       byte[] bytes = this.newValueBytes;
+       if (bytes == null) {
+         bytes = this.cachedSerializedNewValue;
+       }
+       return new SerializedCacheValueImpl(this, getRegion(), this.re,
+           (CachedDeserializable)tmp, bytes);
+     } else {
+       // Note we return null even if cachedSerializedNewValue is not null.
+       // This is because some callers of this method use it to indicate
+       // that a CacheDeserializable should be created during deserialization.
+       return null;
+     }
+   }
+   
+   /**
+    * Implement this interface if you want to call {@link #exportNewValue}.
+    * 
+    * @author darrel
+    *
+    */
+   public interface NewValueImporter {
+     /**
+      * @return true if the importer prefers the value to be in serialized form.
+      */
+     boolean prefersNewSerialized();
+ 
+     /**
+      * Only return true if the importer can use the value before the event that exported it is released.
+      * If false is returned then off-heap values will be copied to the heap for the importer.
+      * @return true if the importer can deal with the value being an unretained OFF_HEAP_REFERENCE.
+      */
+     boolean isUnretainedNewReferenceOk();
+ 
+     /**
+      * Import a new value that is currently in object form.
+      * @param nv the new value to import; unretained if isUnretainedNewReferenceOk returns true
+      * @param isSerialized true if the imported new value represents data that needs to be serialized; false if the imported new value is a simple sequence of bytes.
+      */
+     void importNewObject(@Unretained(ENTRY_EVENT_NEW_VALUE) Object nv, boolean isSerialized);
+ 
+     /**
+      * Import a new value that is currently in byte array form.
+      * @param nv the new value to import
+      * @param isSerialized true if the imported new value represents data that needs to be serialized; false if the imported new value is a simple sequence of bytes.
+      */
+     void importNewBytes(byte[] nv, boolean isSerialized);
+   }
+   
+   /**
+    * Export the event's new value to the given importer.
+    */
+   public final void exportNewValue(NewValueImporter importer) {
+     final boolean prefersSerialized = importer.prefersNewSerialized();
+     if (prefersSerialized) {
+       if (getCachedSerializedNewValue() != null) {
+         importer.importNewBytes(getCachedSerializedNewValue(), true);
+         return;
+       } else {
+       if (this.newValueBytes != null && this.newValue instanceof CachedDeserializable) {
+         importer.importNewBytes(this.newValueBytes, true);
+         return;
+       }
+       }
+     }
+     @Unretained(ENTRY_EVENT_NEW_VALUE) 
+     final Object nv = getRawNewValue();
+     if (nv instanceof StoredObject) {
+       @Unretained(ENTRY_EVENT_NEW_VALUE)
+       final StoredObject so = (StoredObject) nv;
+       final boolean isSerialized = so.isSerialized();
 -      if (nv instanceof Chunk) {
++      if (nv instanceof ObjectChunk) {
+         if (importer.isUnretainedNewReferenceOk()) {
+           importer.importNewObject(nv, isSerialized);
+         } else {
+           if (!isSerialized || prefersSerialized) {
+             byte[] bytes = so.getValueAsHeapByteArray();
+             importer.importNewBytes(bytes, isSerialized);
+             if (isSerialized) {
+               setCachedSerializedNewValue(bytes);
+             }
+           } else {
+             // TODO OFFHEAP: returns off-heap PdxInstance which is not ok since isUnretainedNewReferenceOk returned false
+             importer.importNewObject(so.getValueAsDeserializedHeapObject(), true);
+           }
+         }
+       } else {
+         importer.importNewObject(nv, isSerialized);
+       }
+     } else if (nv instanceof byte[]) {
+       importer.importNewBytes((byte[])nv, false);
+     } else if (nv instanceof CachedDeserializable) {
+       CachedDeserializable cd = (CachedDeserializable) nv;
+       Object cdV = cd.getValue();
+       if (cdV instanceof byte[]) {
+         importer.importNewBytes((byte[]) cdV, true);
+         setCachedSerializedNewValue((byte[]) cdV);
+       } else {
+         importer.importNewObject(cdV, true);
+       }
+     } else {
+       importer.importNewObject(nv, true);
+     }
+   }
+   /**
+    * Implement this interface if you want to call {@link #exportOldValue}.
+    * 
+    * @author darrel
+    *
+    */
+   public interface OldValueImporter {
+     /**
+      * @return true if the importer prefers the value to be in serialized form.
+      */
+     boolean prefersOldSerialized();
+ 
+     /**
+      * Only return true if the importer can use the value before the event that exported it is released.
+      * @return true if the importer can deal with the value being an unretained OFF_HEAP_REFERENCE.
+      */
+     boolean isUnretainedOldReferenceOk();
+     
+     /**
+      * @return return true if you want the old value to possibly be an instanceof CachedDeserializable; false if you want the value contained in a CachedDeserializable.
+      */
+     boolean isCachedDeserializableValueOk();
+ 
+     /**
+      * Import an old value that is currently in object form.
+      * @param ov the old value to import; unretained if isUnretainedOldReferenceOk returns true
+      * @param isSerialized true if the imported old value represents data that needs to be serialized; false if the imported old value is a simple sequence of bytes.
+      */
+     void importOldObject(@Unretained(ENTRY_EVENT_OLD_VALUE) Object ov, boolean isSerialized);
+ 
+     /**
+      * Import an old value that is currently in byte array form.
+      * @param ov the old value to import
+      * @param isSerialized true if the imported old value represents data that needs to be serialized; false if the imported old value is a simple sequence of bytes.
+      */
+     void importOldBytes(byte[] ov, boolean isSerialized);
+   }
+   
+   /**
+    * Export the event's old value to the given importer.
+    */
+   public final void exportOldValue(OldValueImporter importer) {
+     final boolean prefersSerialized = importer.prefersOldSerialized();
+     if (prefersSerialized) {
+       if (this.oldValueBytes != null && this.oldValue instanceof CachedDeserializable) {
+         importer.importOldBytes(this.oldValueBytes, true);
+         return;
+       }
+     }
+     @Unretained(ENTRY_EVENT_OLD_VALUE)
+     final Object ov = getRawOldValue();
+     if (ov instanceof StoredObject) {
+       final StoredObject so = (StoredObject) ov;
+       final boolean isSerialized = so.isSerialized();
 -      if (ov instanceof Chunk) {
++      if (ov instanceof ObjectChunk) {
+         if (importer.isUnretainedOldReferenceOk()) {
+           importer.importOldObject(ov, isSerialized);
+         } else {
+           if (!isSerialized || prefersSerialized) {
+             importer.importOldBytes(so.getValueAsHeapByteArray(), isSerialized);
+           } else {
+             // TODO OFFHEAP: returns off-heap PdxInstance which is not ok since isUnretainedNewReferenceOk returned false
+            importer.importOldObject(so.getValueAsDeserializedHeapObject(), true);
+           }
+         }
+       } else {
+         importer.importOldObject(ov, isSerialized);
+       }
+     } else if (ov instanceof byte[]) {
+       importer.importOldBytes((byte[])ov, false);
+     } else if (!importer.isCachedDeserializableValueOk() && ov instanceof CachedDeserializable) {
+       CachedDeserializable cd = (CachedDeserializable) ov;
+       Object cdV = cd.getValue();
+       if (cdV instanceof byte[]) {
+         importer.importOldBytes((byte[]) cdV, true);
+       } else {
+         importer.importOldObject(cdV, true);
+       }
+     } else {
+       importer.importOldObject(ov, true);
+     }
+   }
+ 
+   /**
+    * If applyDelta is true then first attempt to apply a delta (if we have one) and return the value.
+    * Else if new value is a Delta return it.
+    * Else if new value is off-heap return the StoredObject form (unretained OFF_HEAP_REFERENCE). 
+    * Its refcount is not inced by this call and the returned object can only be safely used for the lifetime of the EntryEventImpl instance that returned the value.
+    * Else return the raw form.
+    */
+   @Unretained(ENTRY_EVENT_NEW_VALUE)
+   public final Object getRawNewValue(boolean applyDelta) {
+     if (applyDelta) {
+       boolean doCopyOnRead = getRegion().isCopyOnRead();
+       Object newValueWithDelta = applyDeltaWithCopyOnRead(doCopyOnRead);
+       if (newValueWithDelta != null) {
+         return newValueWithDelta;
+       }
+       // if applyDelta is true and we have already applied the delta then
+       // just return the applied value instead of the delta object.
+       @Unretained(ENTRY_EVENT_NEW_VALUE)
+       Object newValue = basicGetNewValue();
+       if (newValue != null) return newValue;
+     }
+     return getRawNewValue();
+   }
+   /**
+    * Just like getRawNewValue(true) except if the raw new value is off-heap deserialize it.
+    * Note that in some cases sqlf ignores the request to deserialize.
+    */
+   @Unretained(ENTRY_EVENT_NEW_VALUE)
+   public final Object getNewValueAsOffHeapDeserializedOrRaw() {
+     Object result = getRawNewValue(true);
+     if (result instanceof StoredObject) {
+       result = ((StoredObject) result).getDeserializedForReading();
+     }
+     return AbstractRegion.handleNotAvailable(result); // fixes 49499
+   }
+ 
+   /**
+    * If the new value is stored off-heap return a retained OFF_HEAP_REFERENCE (caller must release).
+    * @return a retained OFF_HEAP_REFERENCE if the new value is off-heap; otherwise returns null
+    */
+   @Retained(ENTRY_EVENT_NEW_VALUE)
+   public StoredObject getOffHeapNewValue() {
+     final Object tmp = basicGetNewValue();
+     if (tmp instanceof StoredObject) {
+       StoredObject result = (StoredObject) tmp;
+       if (!result.retain()) {
+         return null;
+       }
+       return result;
+     } else {
+       return null;
+     }
+   }
+   
+   /**
+    * If the old value is stored off-heap return a retained OFF_HEAP_REFERENCE (caller must release).
+    * @return a retained OFF_HEAP_REFERENCE if the old value is off-heap; otherwise returns null
+    */
+   @Retained(ENTRY_EVENT_OLD_VALUE)
+   public StoredObject getOffHeapOldValue() {
+     final Object tmp = basicGetOldValue();
+     if (tmp instanceof StoredObject) {
+       StoredObject result = (StoredObject) tmp;
+       if (!result.retain()) {
+         return null;
+       }
+       return result;
+     } else {
+       return null;
+     }
+   }
+ 
+   /**
+    * Result may be unretained because sqlf getDeserializedForReading returns unretained.
+    */
+   public final Object getDeserializedValue() {
+     if (this.delta == null) {
+       final Object val = basicGetNewValue();
+       if (val instanceof StoredObject) {
+         // TODO OFFHEAP: returns off-heap PdxInstance
+         return ((StoredObject) val).getValueAsDeserializedHeapObject();
+       } else 
+       if (val instanceof CachedDeserializable) {
+         return ((CachedDeserializable)val).getDeserializedForReading();
+       }
+       else {
+         return val;
+       }
+     }
+     else {
+       return this.delta;
+     }
+   }
+ 
+   public final byte[] getSerializedValue() {
+     if (this.newValueBytes == null) {
+       final Object val;
+       if (this.delta == null) {
+         val = basicGetNewValue();
+         if (val instanceof byte[]) {
+           return (byte[])val;
+         }
+         else if (val instanceof CachedDeserializable) {
+           return ((CachedDeserializable)val).getSerializedValue();
+         }
+       }
+       else {
+         val = this.delta;
+       }
+       try {
+         return CacheServerHelper.serialize(val);
+       } catch (IOException ioe) {
+         throw new GemFireIOException("unexpected exception", ioe);
+       }
+     }
+     else {
+       return this.newValueBytes;
+     }
+   }
+ 
+   /**
+    * Forces this entry's new value to be in serialized form.
+    * @since 5.0.2
+    */
+   public void makeSerializedNewValue() {
+     makeSerializedNewValue(false);
+   }
+ 
+   /**
+    * @param isSynced true if RegionEntry currently under synchronization
+    */
+   private final void makeSerializedNewValue(boolean isSynced) {
+     Object obj = basicGetNewValue();
+ 
+     // ezoerner:20080611 In the case where there is an unapplied
+     // delta, do not apply the delta or serialize yet unless entry is
+     // under synchronization (isSynced is true) 
+     if (isSynced) {
+       this.setSerializationDeferred(false);
+     }
+     else if (obj == null && this.delta != null) {
+       // defer serialization until setNewValueInRegion
+       this.setSerializationDeferred(true);
+       return;
+     }
+     basicSetNewValue(getCachedDeserializable(obj, this));
+   }
+ 
+   public static Object getCachedDeserializable(Object obj) {
+     return getCachedDeserializable(obj, null);
+   }
+ 
+   public static Object getCachedDeserializable(Object obj, EntryEventImpl ev) {
+     if (obj instanceof byte[]
+                             || obj == null
+                             || obj instanceof CachedDeserializable
+                             || obj == Token.NOT_AVAILABLE
+                             || Token.isInvalidOrRemoved(obj)
+                             // don't serialize delta object already serialized
+                             || obj instanceof com.gemstone.gemfire.Delta
+                             || obj instanceof Delta) { // internal delta
+       return obj;
+     }
+     final CachedDeserializable cd;
+     // avoid unneeded serialization of byte[][] used by SQLFabric that
+     // will end up being deserialized in any case (serialization is cheap
+     //   for byte[][] anyways)
+     if (obj instanceof byte[][]) {
+       int objSize = Sizeable.PER_OBJECT_OVERHEAD + 4;
+       for (byte[] bytes : (byte[][])obj) {
+         if (bytes != null) {
+           objSize += CachedDeserializableFactory.getByteSize(bytes);
+         }
+         else {
+           objSize += Sizeable.PER_OBJECT_OVERHEAD;
+         }
+       }
+       cd = CachedDeserializableFactory.create(obj, objSize);
+     }
+     else {
+       final byte[] b = serialize(obj);
+       cd = CachedDeserializableFactory.create(b);
+       if (ev != null) {
+         ev.newValueBytes = b;
+         ev.cachedSerializedNewValue = b;
+       }
+     }
+     return cd;
+   }
+   public void setCachedSerializedNewValue(byte[] v) {
+     this.cachedSerializedNewValue = v;
+   }
+   public byte[] getCachedSerializedNewValue() {
+     return this.cachedSerializedNewValue;
+   }
+ 
+   public final void setSerializedNewValue(byte[] serializedValue) {
+     Object newVal = null;
+     if (serializedValue != null) {
+       if (CachedDeserializableFactory.preferObject()) {
+         newVal = deserialize(serializedValue);
+       } else {
+         newVal = CachedDeserializableFactory.create(serializedValue);
+       }
+       if (newVal instanceof Delta) {
+         this.delta = (Delta)newVal;
+         newVal = null;
+         // We need the newValueBytes field and the newValue field to be in sync.
+         // In the case of non-null delta set both fields to null.
+         serializedValue = null;
+       }
+     }
+     this.newValueBytes = serializedValue;
+     basicSetNewValue(newVal);
+     this.cachedSerializedNewValue = serializedValue;
+   }
+ 
+   public void setSerializedOldValue(byte[] serializedOldValue){
+     this.oldValueBytes = serializedOldValue;
+     final Object ov;
+     if (CachedDeserializableFactory.preferObject()) {
+       ov = deserialize(serializedOldValue);
+     }
+     else if (serializedOldValue != null) {
+       ov = CachedDeserializableFactory.create(serializedOldValue);
+     }
+     else {
+       ov = null;
+     }
+     retainAndSetOldValue(ov);
+   }
+ 
+   /**
+    * If true (the default) then preserve old values in events.
+    * If false then mark non-null values as being NOT_AVAILABLE.
+    */
+   private static final boolean EVENT_OLD_VALUE = !Boolean.getBoolean("gemfire.disable-event-old-value");
+ 
+   
+   void putExistingEntry(final LocalRegion owner, RegionEntry entry) throws RegionClearedException {
+     putExistingEntry(owner, entry, false, null);
+   }
+   
+   /**
+    * Put a newValue into the given, write synced, existing, region entry.
+    * Sets oldValue in event if hasn't been set yet.
+    * @param oldValueForDelta Used by Delta Propagation feature
+    * 
+    * @throws RegionClearedException
+    */
+   void putExistingEntry(final LocalRegion owner, final RegionEntry reentry,
+      boolean requireOldValue, Object oldValueForDelta) throws RegionClearedException {
+     makeUpdate();
+     // only set oldValue if it hasn't already been set to something
+     if (this.oldValue == null) {
+       if (!reentry.isInvalidOrRemoved()) {
+         if (requireOldValue ||
+             EVENT_OLD_VALUE
+             || this.region instanceof HARegion // fix for bug 37909
+             || GemFireCacheImpl.sqlfSystem()
+             ) {
+           @Retained Object ov;
+           if (ReferenceCountHelper.trackReferenceCounts()) {
+             ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
+             if (GemFireCacheImpl.sqlfSystem()) {
+               ov = reentry.getValueOffHeapOrDiskWithoutFaultIn(this.region);
+             } else {
+               ov = reentry._getValueRetain(owner, true);
+             }
+             ReferenceCountHelper.setReferenceCountOwner(null);
+           } else {
+             if (GemFireCacheImpl.sqlfSystem()) {
+               ov = reentry.getValueOffHeapOrDiskWithoutFaultIn(this.region);
+             } else {
+               ov = reentry._getValueRetain(owner, true);
+             }
+           }
+           if (ov == null) ov = Token.NOT_AVAILABLE;
+           // ov has already been retained so call basicSetOldValue instead of retainAndSetOldValue
+           basicSetOldValue(ov);
+         } else {
+           basicSetOldValue(Token.NOT_AVAILABLE);
+         }
+       }
+     }
+     if (this.oldValue == Token.NOT_AVAILABLE) {
+       FilterProfile fp = this.region.getFilterProfile();
+       if (this.op.guaranteesOldValue() || 
+           (fp != null /* #41532 */&& fp.entryRequiresOldValue(this.getKey()))) {
+         setOldValueForQueryProcessing();
+       }
+     }
+ 
+     //setNewValueInRegion(null);
+     setNewValueInRegion(owner, reentry, oldValueForDelta);
+   }
+ 
+   /**
+    * If we are currently a create op then turn us into an update
+    *
+    * @since 5.0
+    */
+   void makeUpdate()
+   {
+     setOperation(this.op.getCorrespondingUpdateOp());
+   }
+ 
+   /**
+    * If we are currently an update op then turn us into a create
+    *
+    * @since 5.0
+    */
+   void makeCreate()
+   {
+     setOperation(this.op.getCorrespondingCreateOp());
+   }
+ 
+   /**
+    * Put a newValue into the given, write synced, new, region entry.
+    * @throws RegionClearedException
+    */
+   void putNewEntry(final LocalRegion owner, final RegionEntry reentry)
+       throws RegionClearedException {
+     if (!this.op.guaranteesOldValue()) {  // preserves oldValue for CM ops in clients
+       basicSetOldValue(null);
+     }
+     makeCreate();
+     setNewValueInRegion(owner, reentry, null);
+   }
+ 
+   void setRegionEntry(RegionEntry re) {
+     this.re = re;
+   }
+ 
+   RegionEntry getRegionEntry() {
+     return this.re;
+   }
+ 
+   @Retained(ENTRY_EVENT_NEW_VALUE)
+   private void setNewValueInRegion(final LocalRegion owner,
+       final RegionEntry reentry, Object oldValueForDelta) throws RegionClearedException {
+     
+     boolean wasTombstone = reentry.isTombstone();
+     
+     // put in newValue
+ 
+     if (applyDelta(this.op.isCreate())) {
+       if (this.isSerializationDeferred()) {
+         makeSerializedNewValue(true);
+       }
+     }
+ 
+     // If event contains new value, then it may mean that the delta bytes should
+     // not be applied. This is possible if the event originated locally.
+     if (this.deltaBytes != null && this.newValue == null) {
+       processDeltaBytes(oldValueForDelta);
+     }
+ 
+     if (owner!=null) {
+       owner.generateAndSetVersionTag(this, reentry);
+     } else {
+       this.region.generateAndSetVersionTag(this, reentry);
+     }
+     
+     Object v = this.newValue;
+     if (v == null) {
+       v = isLocalInvalid() ? Token.LOCAL_INVALID : Token.INVALID;
+     }
+     else {
+       this.region.regionInvalid = false;
+     }
+ 
+     reentry.setValueResultOfSearch(this.op.isNetSearch());
+ 
+     //dsmith:20090524
+     //This is a horrible hack, but we need to get the size of the object
+     //When we store an entry. This code is only used when we do a put
+     //in the primary.
+     if(v instanceof com.gemstone.gemfire.Delta && region.isUsedForPartitionedRegionBucket()) {
+       int vSize;
+       Object ov = basicGetOldValue();
+       if(ov instanceof CachedDeserializable && !GemFireCacheImpl.DELTAS_RECALCULATE_SIZE) {
+         vSize = ((CachedDeserializable) ov).getValueSizeInBytes();
+       } else {
+         vSize = CachedDeserializableFactory.calcMemSize(v, region.getObjectSizer(), false);
+       }
+       v = CachedDeserializableFactory.create(v, vSize);
+       basicSetNewValue(v);
+     }
+ 
+     Object preparedV = reentry.prepareValueForCache(this.region, v, this, this.hasDelta());
+     if (preparedV != v) {
+       v = preparedV;
 -      if (v instanceof Chunk) {
 -        if (!((Chunk) v).isCompressed()) { // fix bug 52109
++      if (v instanceof ObjectChunk) {
++        if (!((ObjectChunk) v).isCompressed()) { // fix bug 52109
+           // If we put it off heap and it is not compressed then remember that value.
+           // Otherwise we want to remember the decompressed value in the event.
+           basicSetNewValue(v);
+         }
+       }
+     }
+     boolean isTombstone = (v == Token.TOMBSTONE);
+     boolean success = false;
+     boolean calledSetValue = false;
+     try {
+     setNewValueBucketSize(owner, v);
+     
+     // ezoerner:20081030 
+     // last possible moment to do index maintenance with old value in
+     // RegionEntry before new value is set.
+     // As part of an update, this is a remove operation as prelude to an add that
+     // will come after the new value is set.
+     // If this is an "update" from INVALID state, treat this as a create instead
+     // for the purpose of index maintenance since invalid entries are not
+     // indexed.
+     
+     if ((this.op.isUpdate() && !reentry.isInvalid()) || this.op.isInvalidate()) {
+       IndexManager idxManager = IndexUtils.getIndexManager(this.region, false);
+       if (idxManager != null) {
+         try {
+           idxManager.updateIndexes(reentry,
+                                    IndexManager.REMOVE_ENTRY,
+                                    this.op.isUpdate() ?
+                                      IndexProtocol.BEFORE_UPDATE_OP :
+                                      IndexProtocol.OTHER_OP);
+         }
+         catch (QueryException e) {
+           throw new IndexMaintenanceException(e);
+         }
+       }
+     }
+     final IndexUpdater indexUpdater = this.region.getIndexUpdater();
+     if (indexUpdater != null) {
+       final LocalRegion indexRegion;
+       if (owner != null) {
+         indexRegion = owner;
+       }
+       else {
+         indexRegion = this.region;
+       }
+       try {
+         indexUpdater.onEvent(indexRegion, this, reentry);
+         calledSetValue = true;
+         reentry.setValueWithTombstoneCheck(v, this); // already called prepareValueForCache
+         success = true;
+       } finally {
+         indexUpdater.postEvent(indexRegion, this, reentry, success);
+       }
+     }
+     else {
+       calledSetValue = true;
+       reentry.setValueWithTombstoneCheck(v, this); // already called prepareValueForCache
+       success = true;
+     }
+     } finally {
 -      if (!success && reentry instanceof OffHeapRegionEntry && v instanceof Chunk) {
 -        OffHeapRegionEntryHelper.releaseEntry((OffHeapRegionEntry)reentry, (Chunk)v);
++      if (!success && reentry instanceof OffHeapRegionEntry && v instanceof ObjectChunk) {
++        OffHeapRegionEntryHelper.releaseEntry((OffHeapRegionEntry)reentry, (ObjectChunk)v);
+       }      
+     }
+     if (logger.isTraceEnabled()) {
+       if (v instanceof CachedDeserializable) {
+         logger.trace("EntryEventImpl.setNewValueInRegion: put CachedDeserializable({},{})",
+             this.getKey(), ((CachedDeserializable)v).getStringForm());
+       }
+       else {
+         logger.trace("EntryEventImpl.setNewValueInRegion: put({},{})",
+             this.getKey(), StringUtils.forceToString(v));
+       }
+     }
+ 
+     if (!isTombstone  &&  wasTombstone) {
+       owner.unscheduleTombstone(reentry);
+     }
+   }
+ 
+   /**
+    * The size the new value contributes to a pr bucket.
+    * Note if this event is not on a pr then this value will be 0.
+    */
+   private transient int newValueBucketSize;
+   public int getNewValueBucketSize() {
+     return this.newValueBucketSize;
+   }
+   private void setNewValueBucketSize(LocalRegion lr, Object v) {
+     if (lr == null) {
+       lr = this.region;
+     }
+     this.newValueBucketSize = lr.calculateValueSize(v);
+   }
+ 
+   private void processDeltaBytes(Object oldValueInVM) {
+     if (!this.region.hasSeenEvent(this)) {
+       if (oldValueInVM == null || Token.isInvalidOrRemoved(oldValueInVM)) {
+         this.region.getCachePerfStats().incDeltaFailedUpdates();
+         throw new InvalidDeltaException("Old value not found for key "
+             + this.keyInfo.getKey());
+       }
+       FilterProfile fp = this.region.getFilterProfile();
+       // If compression is enabled then we've already gotten a new copy due to the
+       // serializaion and deserialization that occurs.
+       boolean copy = this.region.getCompressor() == null &&
+           (this.region.isCopyOnRead()
+           || this.region.getCloningEnabled()
+           || (fp != null && fp.getCqCount() > 0));
+       Object value = oldValueInVM;
+       boolean wasCD = false;
+       if (value instanceof CachedDeserializable) {
+         wasCD = true;
+         if (copy) {
+           value = ((CachedDeserializable)value).getDeserializedWritableCopy(this.region, re);
+         } else {
+           value = ((CachedDeserializable)value).getDeserializedValue(
+               this.region, re);
+         }
+       } else {
+         if (copy) {
+           value = CopyHelper.copy(value);
+         }
+       }
+       boolean deltaBytesApplied = false;
+       try {
+         long start = CachePerfStats.getStatTime();
+         ((com.gemstone.gemfire.Delta)value).fromDelta(new DataInputStream(
+             new ByteArrayInputStream(getDeltaBytes())));
+         this.region.getCachePerfStats().endDeltaUpdate(start);
+         deltaBytesApplied = true;
+       } catch (RuntimeException rte) {
+         throw rte;
+       } catch (VirtualMachineError e) {
+         SystemFailure.initiateFailure(e);
+         throw e;
+       } catch (Throwable t) {
+         SystemFailure.checkFailure();
+         throw new DeltaSerializationException(
+             "Exception while deserializing delta bytes.", t);
+       } finally {
+         if (!deltaBytesApplied) {
+           this.region.getCachePerfStats().incDeltaFailedUpdates();
+         }
+       }
+       if (logger.isDebugEnabled()) {
+         logger.debug("Delta has been applied for key {}", getKey());
+       }
+       // assert event.getNewValue() == null;
+       if (wasCD) {
+         CachedDeserializable old = (CachedDeserializable)oldValueInVM;
+         int valueSize;
+         if (GemFireCacheImpl.DELTAS_RECALCULATE_SIZE) {
+           valueSize = CachedDeserializableFactory.calcMemSize(value, region
+               .getObjectSizer(), false);
+         } else {
+           valueSize = old.getValueSizeInBytes();
+         }
+         value = CachedDeserializableFactory.create(value, valueSize);
+       }
+       setNewValue(value);
+       if (this.causedByMessage != null
+           && this.causedByMessage instanceof PutMessage) {
+         ((PutMessage)this.causedByMessage).setDeltaValObj(value);
+       }
+     } else {
+       this.region.getCachePerfStats().incDeltaFailedUpdates();
+       throw new InvalidDeltaException(
+           "Cache encountered replay of event containing delta bytes for key "
+               + this.keyInfo.getKey());
+     }
+   }
+ 
+   void setTXEntryOldValue(Object oldVal, boolean mustBeAvailable) {
+     if (Token.isInvalidOrRemoved(oldVal)) {
+       oldVal = null;
+     }
+     else {
+       if (mustBeAvailable || oldVal == null || EVENT_OLD_VALUE) {
+         // set oldValue to oldVal
+       }
+       else {
+         oldVal = Token.NOT_AVAILABLE;
+       }
+     }
+     retainAndSetOldValue(oldVal);
+   }
+ 
+   void putValueTXEntry(final TXEntryState tx) {
+     Object v = basicGetNewValue();
+     if (v == null) {
+       if (deltaBytes != null) {
+         // since newValue is null, and we have deltaBytes
+         // there must be a nearSidePendingValue
+         processDeltaBytes(tx.getNearSidePendingValue());
+         v = basicGetNewValue();
+       } else if (this.delta != null) {
+         v = this.delta;
+       } else {
+         v = isLocalInvalid() ? Token.LOCAL_INVALID : Token.INVALID;
+       }
+     }
+ 
+     if (this.op != Operation.LOCAL_INVALIDATE
+         && this.op != Operation.LOCAL_DESTROY) {
+       // fix for bug 34387
+       tx.setPendingValue(OffHeapHelper.copyIfNeeded(v)); // TODO OFFHEAP optimize
+     }
+     tx.setCallbackArgument(getCallbackArgument());
+   }
+ 
+   /** @return false if entry doesn't exist */
+   public boolean setOldValueFromRegion()
+   {
+     try {
+       RegionEntry re = this.region.getRegionEntry(getKey());
+       if (re == null) return false;
+       ReferenceCountHelper.skipRefCountTracking();
+       Object v = re._getValueRetain(this.region, true);
+       ReferenceCountHelper.unskipRefCountTracking();
+       try {
+         return setOldValue(v);
+       } finally {
+         OffHeapHelper.releaseWithNoTracking(v);
+       }
+     }
+     catch (EntryNotFoundException ex) {
+       return false;
+     }
+   }
+ 
+   /** Return true if old value is the DESTROYED token */
+   boolean oldValueIsDestroyedToken()
+   {
+     return this.oldValue == Token.DESTROYED || this.oldValue == Token.TOMBSTONE;
+   }
+ 
+   void setOldValueDestroyedToken()
+   {
+     basicSetOldValue(Token.DESTROYED);
+   }
+ 
+   /**
+    * @return false if value 'v' indicates that entry does not exist
+    */
+   public boolean setOldValue(Object v) {
+     return setOldValue(v, false);
+   }
+   
+   
+   /**
+    * @param force true if the old value should be forcibly set, used
+    * for HARegions, methods like putIfAbsent, etc.,
+    * where the old value must be available.
+    * @return false if value 'v' indicates that entry does not exist
+    */
+   public boolean setOldValue(Object v, boolean force) {
+     if (v == null || Token.isRemoved(v)) {
+       return false;
+     }
+     else {
+       if (Token.isInvalid(v)) {
+         v = null;
+       }
+       else {
+         if (force ||
+             (this.region instanceof HARegion) // fix for bug 37909
+             ) {
+           // set oldValue to "v".
+         } else if (EVENT_OLD_VALUE) {
+           // TODO Rusty add compression support here
+           // set oldValue to "v".
+         } else {
+           v = Token.NOT_AVAILABLE;
+         }
+       }
+       retainAndSetOldValue(v);
+       return true;
+     }
+   }
+ 
+   /**
+    * sets the old value for concurrent map operation results received
+    * from a server.
+    */
+   public void setConcurrentMapOldValue(Object v) {
+     if (Token.isRemoved(v)) {
+       return;
+     } else {
+       if (Token.isInvalid(v)) {
+         v = null;
+       }   
+       retainAndSetOldValue(v);
+     }
+   }
+ 
+   /** Return true if new value available */
+   public boolean hasNewValue() {
+     Object tmp = this.newValue;
+     if (tmp == null && hasDelta()) {
+       // ???:ezoerner:20080611 what if applying the delta would produce
+       // null or (strangely) NOT_AVAILABLE.. do we need to apply it here to
+       // find out?
+       return true;
+     }
+     return  tmp != null && tmp != Token.NOT_AVAILABLE;
+   }
+ 
+   public final boolean hasOldValue() {
+     return this.oldValue != null && this.oldValue != Token.NOT_AVAILABLE;
+   }
+   public final boolean isOldValueAToken() {
+     return this.oldValue instanceof Token;
+   }
+ 
+   /**
+    * This should only be used in case of internal delta and <B>not for Delta of
+    * Delta Propagation feature</B>.
+    * 
+    * @return boolean
+    */
+   public boolean hasDelta() {
+     return (this.delta != null);
+   }
+ 
+   public boolean isOldValueAvailable() {
+     if (isOriginRemote() && this.region.isProxy()) {
+       return false;
+     } else {
+       return basicGetOldValue() != Token.NOT_AVAILABLE;
+     }
+   }
+   
+   public void oldValueNotAvailable() {
+     basicSetOldValue(Token.NOT_AVAILABLE);
+   }
+ 
+   public static Object deserialize(byte[] bytes) {
+     return deserialize(bytes, null, null);
+   }
+ 
+   public static Object deserialize(byte[] bytes, Version version,
+       ByteArrayDataInput in) {
+     if (bytes == null)
+       return null;
+     try {
+       return BlobHelper.deserializeBlob(bytes, version, in);
+     }
+     catch (IOException e) {
+       throw new SerializationException(LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_DESERIALIZING.toLocalizedString(), e);
+     }
+     catch (ClassNotFoundException e) {
+       // fix for bug 43602
+       throw new SerializationException(LocalizedStrings.EntryEventImpl_A_CLASSNOTFOUNDEXCEPTION_WAS_THROWN_WHILE_TRYING_TO_DESERIALIZE_CACHED_VALUE.toLocalizedString(), e);
+     }
+   }
+ 
+   /**
+    * If a PdxInstance is returned then it will have an unretained reference
+    * to Chunk's off-heap address.
+    */
 -  public static @Unretained Object deserializeChunk(Chunk bytes) {
++  public static @Unretained Object deserializeChunk(ObjectChunk bytes) {
+     if (bytes == null)
+       return null;
+     try {
+       return BlobHelper.deserializeOffHeapBlob(bytes);
+     }
+     catch (IOException e) {
+       throw new SerializationException(LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_DESERIALIZING.toLocalizedString(), e);
+     }
+     catch (ClassNotFoundException e) {
+       // fix for bug 43602
+       throw new SerializationException(LocalizedStrings.EntryEventImpl_A_CLASSNOTFOUNDEXCEPTION_WAS_THROWN_WHILE_TRYING_TO_DESERIALIZE_CACHED_VALUE.toLocalizedString(), e);
+     }
+   }
+ 
+   /**
+    * Serialize an object into a <code>byte[]</code>
+    *
+    * @throws IllegalArgumentException
+    *           If <code>obj</code> should not be serialized
+    */
+   public static byte[] serialize(Object obj) {
+     return serialize(obj, null);
+   }
+ 
+    /**
+      * Serialize an object into a <code>byte[]</code>
+      *
+      * @throws IllegalArgumentException
+      *           If <code>obj</code> should not be serialized
+      */
+   public static byte[] serialize(Object obj, Version version)
+   {
+     if (obj == null || obj == Token.NOT_AVAILABLE
+         || Token.isInvalidOrRemoved(obj))
+       throw new IllegalArgumentException(LocalizedStrings.EntryEventImpl_MUST_NOT_SERIALIZE_0_IN_THIS_CONTEXT.toLocalizedString(obj));
+     try {
+       return BlobHelper.serializeToBlob(obj, version);
+     }
+     catch (IOException e) {
+       throw new SerializationException(LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString(), e);
+     }
+   }
+   
+   
+   /**
+    * Serialize an object into a <code>byte[]</code> . If the byte array
+    * provided by the wrapper is sufficient to hold the data, it is used
+    * otherwise a new byte array gets created & its reference is stored in the
+    * wrapper. The User Bit is also appropriately set as Serialized
+    * 
+    * @param wrapper
+    *                Object of type BytesAndBitsForCompactor which is used to fetch
+    *                the serialized data. The byte array of the wrapper is used
+    *                if possible else a the new byte array containing the data is
+    *                set in the wrapper.
+    * @throws IllegalArgumentException
+    *                 If <code>obj</code> should not be serialized
+    */
+   public static void fillSerializedValue(BytesAndBitsForCompactor wrapper,
+                                          Object obj, byte userBits) {
+     if (obj == null || obj == Token.NOT_AVAILABLE
+         || Token.isInvalidOrRemoved(obj))
+       throw new IllegalArgumentException(
+         LocalizedStrings.EntryEvents_MUST_NOT_SERIALIZE_0_IN_THIS_CONTEXT.toLocalizedString(obj));
+     try {
+       HeapDataOutputStream hdos = null;
+       if (wrapper.getBytes().length < 32) {
+         hdos = new HeapDataOutputStream(Version.CURRENT);
+       }
+       else {
+         hdos = new HeapDataOutputStream(wrapper.getBytes());
+       }
+       DataSerializer.writeObject(obj, hdos);
+       // return hdos.toByteArray();
+       hdos.sendTo(wrapper, userBits);
+     }
+     catch (IOException e) {
+       RuntimeException e2 = new IllegalArgumentException(
+         LocalizedStrings.EntryEventImpl_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString());
+       e2.initCause(e);
+       throw e2;
+     }
+   }
+ 
+   protected String getShortClassName() {
+     String cname = getClass().getName();
+     return cname.substring(getClass().getPackage().getName().length()+1);
+   }
+ 
+   @Override
+   public String toString() {
+     StringBuilder buf = new StringBuilder();
+     buf.append(getShortClassName());
+     buf.append("[");
+ 
+     buf.append("op=");
+     buf.append(getOperation());
+     buf.append(";key=");
+     buf.append(this.getKey());
+     buf.append(";oldValue=");
+     try {
+       ArrayUtils.objectStringNonRecursive(basicGetOldValue(), buf);
+     } catch (IllegalStateException ex) {
+       buf.append("OFFHEAP_VALUE_FREED");
+     }
+     buf.append(";newValue=");
+     try {
+       ArrayUtils.objectStringNonRecursive(basicGetNewValue(), buf);
+     } catch (IllegalStateException ex) {
+       buf.append("OFFHEAP_VALUE_FREED");
+     }
+     buf.append(";callbackArg=");
+     buf.append(this.getRawCallbackArgument());
+     buf.append(";originRemote=");
+     buf.append(isOriginRemote());
+     buf.append(";originMember=");
+     buf.append(getDistributedMember());
+ //    if (this.partitionMessage != null) {
+ //      buf.append("; partitionMessage=");
+ //      buf.append(this.partitionMessage);
+ //    }
+     if (this.isPossibleDuplicate()) {
+       buf.append(";posDup");
+     }
+     if (callbacksInvoked()) { 
+       buf.append(";callbacksInvoked");
+     }
+     if (this.versionTag != null) {
+       buf.append(";version=").append(this.versionTag);
+     }
+     if (getContext() != null) {
+       buf.append(";context=");
+       buf.append(getContext());
+     }
+     if (this.eventID != null) {
+       buf.append(";id=");
+       buf.append(this.eventID);
+     }
+     if (this.deltaBytes != null) {
+       buf.append(";[" + this.deltaBytes.length + " deltaBytes]");
+     }
+ //    else {
+ //      buf.append(";[no deltaBytes]");
+ //    }
+     if (this.filterInfo != null) {
+       buf.append(";routing=");
+       buf.append(this.filterInfo);
+     }
+     if (this.isFromServer()) {
+       buf.append(";isFromServer");
+     }
+     if (this.isConcurrencyConflict()) {
+       buf.append(";isInConflict");
+     }
+     if (this.getInhibitDistribution()) {
+       buf.append(";inhibitDistribution");
+     }
+     buf.append("]");
+     return buf.toString();
+   }
+ 
+   public int getDSFID() {
+     return ENTRY_EVENT;
+   }
+ 
+   public void toData(DataOutput out) throws IOException
+   {
+     DataSerializer.writeObject(this.eventID, out);    
+     DataSerializer.writeObject(this.getKey(), out);
+     DataSerializer.writeObject(this.keyInfo.getValue(), out);
+     out.writeByte(this.op.ordinal);
+     out.writeShort(this.eventFlags & EventFlags.FLAG_TRANSIENT_MASK);
+     DataSerializer.writeObject(this.getRawCallbackArgument(), out);
+     DataSerializer.writeObject(this.txId, out);
+ 
+     {
+       boolean isDelta = this.delta != null;
+       out.writeBoolean(isDelta);
+       if (isDelta) {
+         DataSerializer.writeObject(this.delta, out);
+       }
+       else {
+         Object nv = basicGetNewValue();
+         boolean newValueSerialized = nv instanceof CachedDeserializable;
+         if (newValueSerialized) {
+           if (nv instanceof StoredObject) {
+             newValueSerialized = ((StoredObject) nv).isSerialized();
+           }
+         }
+         out.writeBoolean(newValueSerialized);
+         if (newValueSerialized) {
+           if (this.newValueBytes != null) {
+             DataSerializer.writeByteArray(this.newValueBytes, out);
+           } else if (this.cachedSerializedNewValue != null) {
+             DataSerializer.writeByteArray(this.cachedSerializedNewValue, out);
+           } else {
+             CachedDeserializable cd = (CachedDeserializable)nv;
+             DataSerializer.writeObjectAsByteArray(cd.getValue(), out);
+           }
+         }
+         else {
+           DataSerializer.writeObject(nv, out);
+         }
+       }  
+     }
+ 
+     {
+       Object ov = basicGetOldValue();
+       boolean oldValueSerialized = ov instanceof CachedDeserializable;
+       if (old

<TRUNCATED>


[072/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
index 0000000,85e078d..4a5a9df
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
@@@ -1,0 -1,439 +1,439 @@@
+ /*
+  * 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 com.gemstone.gemfire.pdx.internal;
+ 
+ import java.io.IOException;
+ import java.nio.ByteBuffer;
+ import java.util.Date;
+ 
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.InternalGemFireException;
+ import com.gemstone.gemfire.pdx.PdxSerializationException;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream;
+ import com.gemstone.gemfire.internal.tcp.ImmutableByteBufferInputStream;
+ 
+ /**
+  * Used by PdxReaderImpl to manage the raw bytes of a PDX.
+  * 
+  * @author darrel
+  * @since 6.6
+  */
+ public class PdxInputStream extends ImmutableByteBufferInputStream {
+ 
+   /**
+    * Create a pdx input stream by whose contents are the first length
+    * bytes from the given input stream.
+    * @param existing the input stream whose content will go into this stream. Note that this existing stream will be read by this class (a copy is not made) so it should not be changed externally.
+    * @param length the number of bytes to put in this stream
+    */
+   public PdxInputStream(ByteBufferInputStream existing, int length) {
+     super(existing, length);
+   }
+ 
+   /**
+    * Create a pdx input stream whose contents are the given bytes
+    * @param bytes the content of this stream. Note that this byte array will be read by this class (a copy is not made) so it should not be changed externally.
+    */
+   public PdxInputStream(byte[] bytes) {
+     super(bytes);
+   }
+ 
+   /**
+    * Create a pdx input stream whose contents are the given bytes
+    * @param bb the content of this stream. Note that bb will be read by this class (a copy is not made) so it should not be changed externally.
+    */
+   public PdxInputStream(ByteBuffer bb) {
+     super(bb);
+   }
+ 
+   /**
+    * Create a pdx input stream by copying another. A somewhat shallow copy is made.
+    * @param copy the input stream to copy. Note that this copy stream will be read by this class (a copy is not made) so it should not be changed externally.
+    */
+   public PdxInputStream(PdxInputStream copy) {
+     super(copy);
+   }
+   
+   public PdxInputStream() {
+     // for serialization
+   }
+ 
 -  public PdxInputStream(Chunk blob) {
++  public PdxInputStream(ObjectChunk blob) {
+     super(blob);
+   }
+ 
+   public String readString(int positionForField) {
+       position(positionForField);
+       return readString();
+   }
+ 
+   public Object readObject(int positionForField) {
+       position(positionForField);
+       return readObject();
+   }
+ 
+   public char[] readCharArray(int positionForField) {
+       position(positionForField);
+       return readCharArray();
+   }
+ 
+   public boolean[] readBooleanArray(int positionForField) {
+       position(positionForField);
+       return readBooleanArray();
+   }
+ 
+   public byte[] readByteArray(int positionForField) {
+       position(positionForField);
+       return readByteArray();
+   }
+ 
+   public short[] readShortArray(int positionForField) {
+       position(positionForField);
+       return readShortArray();
+   }
+ 
+   public int[] readIntArray(int positionForField) {
+       position(positionForField);
+       return readIntArray();
+   }
+ 
+   public long[] readLongArray(int positionForField) {
+       position(positionForField);
+       return readLongArray();
+   }
+ 
+   public float[] readFloatArray(int positionForField) {
+       position(positionForField);
+       return readFloatArray();
+   }
+ 
+   public double[] readDoubleArray(int positionForField) {
+       position(positionForField);
+       return readDoubleArray();
+   }
+ 
+   public String[] readStringArray(int positionForField) {
+       position(positionForField);
+       return readStringArray();
+   }
+ 
+   public Object[] readObjectArray(int positionForField) {
+       position(positionForField);
+       return readObjectArray();
+   }
+ 
+   public byte[][] readArrayOfByteArrays(int positionForField) {
+       position(positionForField);
+       return readArrayOfByteArrays();
+   }
+ 
+   public Date readDate(int offset) {
+     long time = readLong(offset);
+     return convertLongToDate(time);
+   }
+ 
+   @Override
+   public boolean readBoolean(int pos) {
+     try {
+       return super.readBoolean(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX boolean field", e);
+     }
+   }
+ 
+   @Override
+   public byte readByte(int pos) {
+     try {
+       return super.readByte(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX byte field", e);
+     }
+   }
+ 
+   @Override
+   public char readChar(int pos) {
+     try {
+       return super.readChar(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX char field", e);
+     }
+ 
+   }
+ 
+   @Override
+   public double readDouble(int pos) {
+     try {
+       return super.readDouble(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX double field", e);
+     }
+   }
+ 
+   @Override
+   public float readFloat(int pos) {
+     try {
+       return super.readFloat(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX float field", e);
+     }
+   }
+ 
+   @Override
+   public int readInt(int pos) {
+     try {
+       return super.readInt(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX int field", e);
+     }
+   }
+ 
+   @Override
+   public long readLong(int pos) {
+     try {
+       return super.readLong(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX long field", e);
+     }
+   }
+ 
+   @Override
+   public short readShort(int pos) {
+     try {
+       return super.readShort(pos);
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX short field", e);
+     }
+   }
+ 
+   @Override
+   public void position(int absPos) {
+     try {
+       super.position(absPos);
+     } catch (IllegalArgumentException e) {
+       throw new PdxSerializationException("Internal error; failed to set position to " + absPos, e);
+     }
+   }
+ 
+   public String readString() {
+     try {
+       return DataSerializer.readString(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public Object readObject() {
+     try {
+       return DataSerializer.readObject(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     } catch (ClassNotFoundException e) {
+       throw new PdxSerializationException("Class not found deserializing a PDX field", e);
+     }
+   }
+ 
+   public char[] readCharArray() {
+     try {
+       return DataSerializer.readCharArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public boolean[] readBooleanArray() {
+     try {
+       return DataSerializer.readBooleanArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public byte[] readByteArray() {
+     try {
+       return DataSerializer.readByteArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public short[] readShortArray() {
+     try {
+       return DataSerializer.readShortArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public int[] readIntArray() {
+     try {
+       return DataSerializer.readIntArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public long[] readLongArray() {
+     try {
+       return DataSerializer.readLongArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public float[] readFloatArray() {
+     try {
+       return DataSerializer.readFloatArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public double[] readDoubleArray() {
+     try {
+       return DataSerializer.readDoubleArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public String[] readStringArray() {
+     try {
+       return DataSerializer.readStringArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     }
+   }
+ 
+   public Object[] readObjectArray() {
+     try {
+       return DataSerializer.readObjectArray(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     } catch (ClassNotFoundException e) {
+       throw new PdxSerializationException("Class not found while deserializing a PDX field", e);
+     }
+   }
+ 
+   public byte[][] readArrayOfByteArrays() {
+     try {
+       return DataSerializer.readArrayOfByteArrays(this);
+     } catch (IOException e) {
+       throw new PdxSerializationException("Exception deserializing a PDX field", e);
+     } catch (ClassNotFoundException ex) {
+       throw new InternalGemFireException(
+           "ClassNotFoundException should never be thrown but it was", ex);
+     }
+   }
+ 
+   public Date readDate() {
+     long time = readLong();
+     return convertLongToDate(time);
+   }
+ 
+   @Override
+   public boolean readBoolean() {
+     try {
+       return super.readBoolean();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX boolean field", e);
+     }
+   }
+ 
+   @Override
+   public byte readByte() {
+     try {
+       return super.readByte();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX byte field", e);
+     }
+   }
+ 
+   @Override
+   public char readChar() {
+     try {
+       return super.readChar();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX char field", e);
+     }
+   }
+ 
+   @Override
+   public double readDouble() {
+     try {
+       return super.readDouble();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX double field", e);
+     }
+   }
+ 
+   @Override
+   public float readFloat() {
+     try {
+       return super.readFloat();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX float field", e);
+     }
+   }
+ 
+   @Override
+   public int readInt() {
+     try {
+       return super.readInt();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX int field", e);
+     }
+   }
+ 
+   @Override
+   public long readLong() {
+     try {
+       return super.readLong();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX long field", e);
+     }
+   }
+ 
+   @Override
+   public short readShort() {
+     try {
+       return super.readShort();
+     } catch (IndexOutOfBoundsException e) {
+       throw new PdxSerializationException("Failed reading a PDX short field", e);
+     }
+   }
+   
+   @Override
+   public ByteSource slice(int startOffset, int endOffset) {
+     try {
+       return super.slice(startOffset, endOffset);
+     } catch (IllegalArgumentException e) {
+       throw new PdxSerializationException("Internal error; failed to slice start=" + startOffset + " end="+ endOffset, e);
+     }
+   }
+ 
+   private Date convertLongToDate(long v) {
+     Date result = null;
+     if (v != -1L) {
+       result = new Date(v);
+     }
+     return result;
+   }
+ }


[049/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
index e0b2810,0000000..1d9bd2d
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
@@@ -1,94 -1,0 +1,92 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.pdx.internal.PdxType;
 +
 +/**
 + * Retrieve the PDXType, given an integer PDX id, from a server.
 + * @author dsmith
 + * @since 6.6
 + */
 +public class GetPDXTypeByIdOp {
 +  /**
 +   * Get a PdxType from the given pool.
 +   * @param pool the pool to use to communicate with the server.
 +   */
 +  public static PdxType execute(ExecutablePool pool,
 +                             int pdxId)
 +  {
 +    AbstractOp op = new GetPDXTypeByIdOpImpl(pdxId);
 +    return (PdxType) pool.execute(op);
 +  }
 +                                                               
 +  private GetPDXTypeByIdOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class GetPDXTypeByIdOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public GetPDXTypeByIdOpImpl(int pdxId) {
 +      super(MessageType.GET_PDX_TYPE_BY_ID, 1);
 +      getMessage().addIntPart(pdxId);
 +    }
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      return processObjResponse(msg, "getPDXTypeById");
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGetPDXTypeById();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeByIdSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGetPDXTypeById(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    //Don't send the transaction id for this message type.
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
 +    
-     //TODO - no idea what this mumbo jumbo means, but it's on
-     //most of the other messages like this.
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
index 2990192,0000000..262cb9a
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
@@@ -1,112 -1,0 +1,112 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.util.Map;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +import com.gemstone.gemfire.pdx.internal.PdxType;
 +
 +/**
 + * Retrieve all known PDX types.
 + * 
 + * @author bakera
 + * @since 7.0
 + */
 +public class GetPDXTypesOp {
 +
 +  public static Map<Integer, PdxType> execute(ExecutablePool pool) {
 +    AbstractOp op = new GetPDXTypesOpImpl();
 +    return (Map<Integer, PdxType>) pool.execute(op);
 +  }
 +                                                               
 +  private GetPDXTypesOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class GetPDXTypesOpImpl extends AbstractOp {
 +    public GetPDXTypesOpImpl() {
 +      super(MessageType.GET_PDX_TYPES, 1);
 +      getMessage().addIntPart(0); // must have at least one part
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      Part part = msg.getPart(0);
 +      int msgType = msg.getMessageType();
 +      if (msgType == MessageType.RESPONSE) {
 +        return (Map<Integer, PdxType>) part.getObject();
 +
 +      } else {
 +        if (msgType == MessageType.EXCEPTION) {
 +          String s = "While performing a remote " + "getPdxTypes";
 +          throw new ServerOperationException(s, (Throwable) part.getObject());
 +
 +        } else if (isErrorResponse(msgType)) {
 +          throw new ServerOperationException(part.getString());
 +
 +        } else {
 +          throw new InternalGemFireError("Unexpected message type "
 +              + MessageType.getString(msgType));
 +        }
 +      }
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return 0;
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +    }
 +    
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected boolean participateInTransaction() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
index 59b99f0,0000000..27d80b1
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
@@@ -1,91 -1,0 +1,91 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Tell a server to become the primary host of a server-to-client queue
 + * @author darrel
 + * @since 5.7
 + */
 +public class MakePrimaryOp {
 +  /**
 +   * Tell the given server to become the primary host of a server-to-client queue
 +   * @param pool the pool to use to communicate with the server.
 +   * @param conn the connection to do the execution on
 +   * @param sentClientReady true if the client ready message has already been sent
 +   */
 +  public static void execute(ExecutablePool pool, Connection conn, boolean sentClientReady)
 +  {
 +    AbstractOp op = new MakePrimaryOpImpl(sentClientReady);
 +    pool.executeOn(conn, op);
 +  }
 +                                                               
 +  private MakePrimaryOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class MakePrimaryOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public MakePrimaryOpImpl(boolean sentClientReady) {
 +      super(MessageType.MAKE_PRIMARY, 1);
 +      getMessage().addBytesPart(new byte[] {(byte)(sentClientReady?0x01:0x00)});
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "makePrimary");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startMakePrimary();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endMakePrimarySend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endMakePrimary(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
index e0bc81b,0000000..e70d50a
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
@@@ -1,97 -1,0 +1,97 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.ServerLocation;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Ping a server to see if it is still alive.
 + * @author darrel
 + * @since 5.7
 + */
 +public class PingOp {
 +  /**
 +   * Ping the specified server to see if it is still alive
 +   * @param pool the pool to use to communicate with the server.
 +   * @param server the server to do the execution on
 +   */
 +  public static void execute(ExecutablePool pool, ServerLocation server)
 +  {
 +    AbstractOp op = new PingOpImpl();
 +    pool.executeOn(server, op, false,false);
 +  }
 +                                                               
 +  private PingOp() {
 +    // no instances allowed
 +  }
 +
 +  static class PingOpImpl extends AbstractOp {
 +    
 +    private long startTime;
 +    
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public PingOpImpl() {
 +      super(MessageType.PING, 0);
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +      Message.messageType.set(null);
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      startTime = System.currentTimeMillis();
 +      getMessage().send(false);
 +      Message.messageType.set(MessageType.PING);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "ping");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startPing();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endPingSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endPing(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
index 0b65c56,0000000..4ee680a
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
@@@ -1,101 -1,0 +1,101 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +import java.util.Iterator;
 +import java.util.List;
 +
 +/**
 + * Send the primary server acknowledgement on the events this client
 + * has received and processed from it.
 + * @author darrel
 + * @since 5.7
 + */
 +public class PrimaryAckOp {
 +  /**
 +   * Send the primary server acknowledgement on the events this client
 +   * has received and processed from it
 +   * using connections from the given pool
 +   * to communicate with the server.
 +   * @param connection 
 +   * @param pool the pool to use to communicate with the server.
 +   * @param events list of events to acknowledge
 +   */
 +  public static void execute(Connection connection, ExecutablePool pool,
 +                             List events)
 +  {
 +    AbstractOp op = new PrimaryAckOpImpl(events);
 +    pool.executeOn(connection, op);
 +  }
 +                                                               
 +  private PrimaryAckOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class PrimaryAckOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public PrimaryAckOpImpl(List events) {
 +      super(MessageType.PERIODIC_ACK, events.size());
 +      for (Iterator i = events.iterator(); i.hasNext();) {
 +        getMessage().addObjPart(i.next());
 +      }
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "primaryAck");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startPrimaryAck();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endPrimaryAckSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endPrimaryAck(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
index 53b8fa9,0000000..2747fa8
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
@@@ -1,124 -1,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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.InternalGemFireError;
 +import com.gemstone.gemfire.cache.client.ServerConnectivityException;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.distributed.internal.ServerLocation;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +
 +public class ProxyCacheCloseOp {
 +
 +  public static Object executeOn(ServerLocation location, ExecutablePool pool,
 +      Properties securityProps, boolean keepAlive) {
 +    AbstractOp op = new ProxyCacheCloseOpImpl(pool, securityProps, keepAlive);
 +    return pool.executeOn(location, op);
 +  }
 +
 +  private ProxyCacheCloseOp() {
 +    // no instances allowed
 +  }
 +
 +  static class ProxyCacheCloseOpImpl extends AbstractOp {
 +
 +    public ProxyCacheCloseOpImpl(ExecutablePool pool, Properties securityProps,
 +        boolean keepAlive) {
 +      super(MessageType.REMOVE_USER_AUTH, 1);
-       getMessage().setEarlyAck(Message.MESSAGE_HAS_SECURE_PART);
++      getMessage().setMessageHasSecurePartFlag();
 +      getMessage().addBytesPart(keepAlive ? new byte[] {1} : new byte[] {0});
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
 +      HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
 +      byte[] secureBytes = null;
 +      hdos.writeLong(cnx.getConnectionID());
 +      Object userId = UserAttributes.userAttributes.get().getServerToId().get(cnx.getServer());
 +      if (userId == null) {
 +        // This will ensure that this op is retried on another server, unless
 +        // the retryCount is exhausted. Fix for Bug 41501
 +        throw new ServerConnectivityException(
 +            "Connection error while authenticating user");
 +      }
 +      hdos.writeLong((Long)userId);
 +      try {
 +        secureBytes = ((ConnectionImpl)cnx).getHandShake().encryptBytes(
 +            hdos.toByteArray());
 +      } finally {
 +        hdos.close();
 +      }
 +      getMessage().setSecurePart(secureBytes);
 +      getMessage().send(false);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      Part part = msg.getPart(0);
 +      final int msgType = msg.getMessageType();
 +      if (msgType == MessageType.REPLY) {
 +        return part.getObject();
 +      }
 +      else if (msgType == MessageType.EXCEPTION) {
 +        String s = "While performing a remote proxy cache close";
 +        throw new ServerOperationException(s, (Throwable)part.getObject());
 +        // Get the exception toString part.
 +        // This was added for c++ thin client and not used in java
 +        // Part exceptionToStringPart = msg.getPart(1);
 +      }
 +      else if (isErrorResponse(msgType)) {
 +        throw new ServerOperationException(part.getString());
 +      }
 +      else {
 +        throw new InternalGemFireError("Unexpected message type "
 +            + MessageType.getString(msgType));
 +      }
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.REQUESTDATAERROR;
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startGet();
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endGetSend(start, hasFailed());
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endGet(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
index a003538,0000000..d2631fc
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
@@@ -1,91 -1,0 +1,91 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Tells the server we are ready to receive server-to-client events
 + * from durable subscriptions.
 + * @author darrel
 + * @since 5.7
 + */
 +public class ReadyForEventsOp {
 +  /**
 +   * Tells the primary server we are ready to receive server-to-client events
 +   * from durable subscriptions.
 +   * @param pool the pool to use to communicate with the server.
 +   * @param primary 
 +   */
 +  public static void execute(ExecutablePool pool, QueueConnectionImpl primary)
 +  {
 +    AbstractOp op = new ReadyForEventsOpImpl();
 +    pool.executeOn(primary, op);
 +  }
 +                                                               
 +  private ReadyForEventsOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class ReadyForEventsOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public ReadyForEventsOpImpl() {
 +      super(MessageType.CLIENT_READY, 1);
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "readyForEvents");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startReadyForEvents();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endReadyForEventsSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endReadyForEvents(start, hasTimedOut(), hasFailed());
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
index b2b975f,0000000..869ad64
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
@@@ -1,138 -1,0 +1,138 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.IOException;
 +
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.SerializationException;
 +import com.gemstone.gemfire.internal.InternalDataSerializer.SerializerAttributesHolder;
 +import com.gemstone.gemfire.internal.cache.ClientServerObserver;
 +import com.gemstone.gemfire.internal.cache.ClientServerObserverHolder;
 +import com.gemstone.gemfire.internal.cache.EventID;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.util.BlobHelper;
 +
 +public class RegisterDataSerializersOp {
 +
 +  public static void execute(ExecutablePool pool,
 +      DataSerializer[] dataSerializers, EventID eventId) {
 +    AbstractOp op = new RegisterDataSerializersOpImpl(dataSerializers,
 +        eventId);
 +    pool.execute(op);
 +  }
 +  
 +  public static void execute(ExecutablePool pool,
 +      SerializerAttributesHolder[] holders, EventID eventId) {
 +    AbstractOp op = new RegisterDataSerializersOpImpl(holders,
 +        eventId);
 +    pool.execute(op);
 +  }
 +  
 +  private RegisterDataSerializersOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class RegisterDataSerializersOpImpl extends AbstractOp {
 +
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public RegisterDataSerializersOpImpl(DataSerializer[] dataSerializers,
 +        EventID eventId) {
 +      super(MessageType.REGISTER_DATASERIALIZERS, dataSerializers.length * 2 + 1);
 +      for(int i = 0; i < dataSerializers.length; i++) {
 +        DataSerializer dataSerializer = dataSerializers[i];
 +         // strip '.class' off these class names
 +        String className = dataSerializer.getClass().toString().substring(6);
 +        try {
 +          getMessage().addBytesPart(BlobHelper.serializeToBlob(className));
 +        } catch (IOException ex) {
 +          throw new SerializationException("failed serializing object", ex);
 +        }
 +        getMessage().addIntPart(dataSerializer.getId());
 +      }
 +      getMessage().addBytesPart(eventId.calcBytes());
 +      // // CALLBACK FOR TESTING PURPOSE ONLY ////
 +      if (PoolImpl.IS_INSTANTIATOR_CALLBACK) {
 +        ClientServerObserver bo = ClientServerObserverHolder.getInstance();
 +        bo.beforeSendingToServer(eventId);
 +      }
 +   }
 +    
 +    /**
 +     * @throws SerializationException
 +     *           Thrown when serialization fails.
 +     */
 +    public RegisterDataSerializersOpImpl(SerializerAttributesHolder[] holders,
 +        EventID eventId) {
 +      super(MessageType.REGISTER_DATASERIALIZERS, holders.length * 2 + 1);
 +      for (int i = 0; i < holders.length; i++) {
 +        try {
 +          getMessage().addBytesPart(
 +              BlobHelper.serializeToBlob(holders[i].getClassName()));
 +        } catch (IOException ex) {
 +          throw new SerializationException("failed serializing object", ex);
 +        }
 +        getMessage().addIntPart(holders[i].getId());
 +      }
 +      getMessage().addBytesPart(eventId.calcBytes());
 +      // // CALLBACK FOR TESTING PURPOSE ONLY ////
 +      if (PoolImpl.IS_INSTANTIATOR_CALLBACK) {
 +        ClientServerObserver bo = ClientServerObserverHolder.getInstance();
 +        bo.beforeSendingToServer(eventId);
 +      }
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "registerDataSerializers");
 +      return null;
 +    }
 +    
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startRegisterDataSerializers();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endRegisterDataSerializersSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endRegisterDataSerializers(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
index 93d3756,0000000..0d5a137
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
@@@ -1,180 -1,0 +1,180 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.IOException;
 +
 +import com.gemstone.gemfire.Instantiator;
 +import com.gemstone.gemfire.SerializationException;
 +import com.gemstone.gemfire.internal.InternalInstantiator.InstantiatorAttributesHolder;
 +import com.gemstone.gemfire.internal.cache.ClientServerObserver;
 +import com.gemstone.gemfire.internal.cache.ClientServerObserverHolder;
 +import com.gemstone.gemfire.internal.cache.EventID;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.util.BlobHelper;
 +
 +/**
 + * Register a bunch of instantiators on a server
 + * @author darrel
 + * @since 5.7
 + */
 +public class RegisterInstantiatorsOp {
 +  /**
 +   * Register a bunch of instantiators on a server
 +   * using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   * @param instantiators the instantiators to register
 +   * @param eventId the id of this event
 +   */
 +  public static void execute(ExecutablePool pool,
 +                             Instantiator[] instantiators,
 +                             EventID eventId)
 +  {
 +    AbstractOp op = new RegisterInstantiatorsOpImpl(instantiators, eventId);
 +    pool.execute(op, Integer.MAX_VALUE);
 +  }
 +
 +  /**
 +   * Register a bunch of instantiators on a server using connections from the
 +   * given pool to communicate with the server.
 +   * 
 +   * @param pool
 +   *          the pool to use to communicate with the server.
 +   * @param holders
 +   *          the {@link InstantiatorAttributesHolder}s containing info about
 +   *          the instantiators to register
 +   * @param eventId
 +   *          the id of this event
 +   */
 +  public static void execute(ExecutablePool pool,
 +      Object[] holders, EventID eventId) {
 +    AbstractOp op = new RegisterInstantiatorsOpImpl(holders,
 +        eventId);
 +    pool.execute(op, Integer.MAX_VALUE);
 +  }
 +
 +  private RegisterInstantiatorsOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class RegisterInstantiatorsOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public RegisterInstantiatorsOpImpl(Instantiator[] instantiators,
 +                                       EventID eventId) {
 +      super(MessageType.REGISTER_INSTANTIATORS, instantiators.length * 3 + 1);
 +      for(int i = 0; i < instantiators.length; i++) {
 +        Instantiator instantiator = instantiators[i];
 +         // strip '.class' off these class names
 +        String className = instantiator.getClass().toString().substring(6);
 +        String instantiatedClassName = instantiator.getInstantiatedClass().toString().substring(6);
 +        try {
 +          getMessage().addBytesPart(BlobHelper.serializeToBlob(className));
 +          getMessage().addBytesPart(BlobHelper.serializeToBlob(instantiatedClassName));
 +        } catch (IOException ex) {
 +          throw new SerializationException("failed serializing object", ex);
 +        }
 +        getMessage().addIntPart(instantiator.getId());
 +      }
 +      getMessage().addBytesPart(eventId.calcBytes());
 +//     // // CALLBACK FOR TESTING PURPOSE ONLY ////
 +      if (PoolImpl.IS_INSTANTIATOR_CALLBACK) {
 +        ClientServerObserver bo = ClientServerObserverHolder.getInstance();
 +        bo.beforeSendingToServer(eventId);
 +      }
 +    }
 +
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException
 +     *           if serialization fails
 +     */
 +    public RegisterInstantiatorsOpImpl(Object[] holders,
 +        EventID eventId) {
 +      super(MessageType.REGISTER_INSTANTIATORS, holders.length * 3 + 1);
 +      for (Object obj : holders) {
 +        String instantiatorClassName = null;
 +        String instantiatedClassName = null;
 +        int id = 0;
 +        if (obj instanceof Instantiator) {
 +          instantiatorClassName = ((Instantiator)obj).getClass().getName();
 +          instantiatedClassName = ((Instantiator)obj).getInstantiatedClass()
 +              .getName();
 +          id = ((Instantiator)obj).getId();
 +        } else {
 +          instantiatorClassName = ((InstantiatorAttributesHolder)obj)
 +              .getInstantiatorClassName();
 +          instantiatedClassName = ((InstantiatorAttributesHolder)obj)
 +              .getInstantiatedClassName();
 +          id = ((InstantiatorAttributesHolder)obj).getId();
 +        }
 +        try {
 +          getMessage().addBytesPart(
 +              BlobHelper.serializeToBlob(instantiatorClassName));
 +          getMessage().addBytesPart(
 +              BlobHelper.serializeToBlob(instantiatedClassName));
 +        } catch (IOException ex) {
 +          throw new SerializationException("failed serializing object", ex);
 +        }
 +        getMessage().addIntPart(id);
 +      }
 +      getMessage().addBytesPart(eventId.calcBytes());
 +      // // // CALLBACK FOR TESTING PURPOSE ONLY ////
 +      if (PoolImpl.IS_INSTANTIATOR_CALLBACK) {
 +        ClientServerObserver bo = ClientServerObserverHolder.getInstance();
 +        bo.beforeSendingToServer(eventId);
 +      }
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "registerInstantiators");
 +      return null;
 +    }
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return false;
 +    }
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startRegisterInstantiators();
 +    }
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endRegisterInstantiatorsSend(start, hasFailed());
 +    }
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endRegisterInstantiators(start, hasTimedOut(), hasFailed());
 +    }
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
index 2793f32,0000000..6f01b96
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
@@@ -1,99 -1,0 +1,99 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Does a Rollback on the server
 + * @since 6.6
 + * @author sbawaska
 + */
 +public class RollbackOp {
 +
 +  /**
 +   * Does a rollback on the server for given transaction
 +   * @param pool the pool to use to communicate with the server.
 +   * @param txId the id of the transaction to rollback
 +   */
 +  public static void execute(ExecutablePool pool, int txId) {
 +    RollbackOpImpl op = new RollbackOpImpl(txId);
 +    pool.execute(op);
 +  }
 +  
 +  private RollbackOp() {
 +    // no instance allowed
 +  }
 +  
 +  private static class RollbackOpImpl extends AbstractOp {
 +    private int txId;
 +
 +    protected RollbackOpImpl(int txId) {
 +      super(MessageType.ROLLBACK, 1);
 +      getMessage().setTransactionId(txId);
 +      this.txId = txId;
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      return "Rollback(txId="+this.txId+")";
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "rollback");
 +      return null;
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.EXCEPTION;
 +    }
 +
 +    @Override
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startRollback();
 +    }
 +
 +    @Override
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endRollbackSend(start, hasFailed());
 +    }
 +
 +    @Override
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endRollback(start, hasTimedOut(), hasFailed());
 +    }
 +     
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
index 6d69083,0000000..42cc225
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
@@@ -1,92 -1,0 +1,92 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Does a region size on a server
 + * @author gregp
 + * @since 6.6
 + */
 +public class SizeOp {
 +  /**
 +   * Does a region size on a server using connections from the given pool
 +   * to communicate with the server.
 +   * @param pool the pool to use to communicate with the server.
 +   * @param region the name of the region to do the entry keySet on
 +   */
 +  public static Integer execute(InternalPool pool,
 +                            String region)
 +  {
 +    AbstractOp op = new SizeOpImpl(region);
 +    return (Integer)pool.execute(op);
 +  }
 +                                                               
 +  private SizeOp() {
 +    // no instances allowed
 +  }
 +  
 +  private static class SizeOpImpl extends AbstractOp {
 +    /**
 +     * @throws com.gemstone.gemfire.SerializationException if serialization fails
 +     */
 +    public SizeOpImpl(String region) {
 +      super(MessageType.SIZE, 1);
 +      getMessage().addStringPart(region);
 +    }
 +
 +    @Override  
 +    protected Object processResponse(Message msg) throws Exception {
 +      
 +      return processObjResponse(msg, "size");
 +    }
 +    @Override  
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.SIZE_ERROR;
 +    }
 +    @Override  
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startSize();
 +    }
 +    @Override  
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endSizeSend(start, hasFailed());
 +    }
 +    @Override  
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endSize(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
index 1fecc7d,0000000..64ee66e
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
@@@ -1,93 -1,0 +1,93 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +
 +/**
 + * Indicates to the server that a transaction is
 + * failing over to this server. The server then
 + * performs the necessary bootstrapping for the tx.
 + * @author sbawaska
 + * @since 6.6
 + */
 +public class TXFailoverOp {
 +
 +  public static void execute(ExecutablePool pool, int txId) {
 +    pool.execute(new TXFailoverOpImpl(txId));
 +  }
 +  
 +  private TXFailoverOp() {
 +    // no instance
 +  }
 +  
 +  private static class TXFailoverOpImpl extends AbstractOp {
 +    int txId;
 +
 +    protected TXFailoverOpImpl(int txId) {
 +      super(MessageType.TX_FAILOVER, 1);
 +      getMessage().setTransactionId(txId);
 +      this.txId = txId;
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      return "TXFailoverOp(txId="+this.txId+")";
 +    }
 +
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      processAck(msg, "txFailover");
 +      return null;
 +    }
 +
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.EXCEPTION;
 +    }
 +
 +    @Override  
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startTxFailover();
 +    }
 +    @Override  
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endTxFailoverSend(start, hasFailed());
 +    }
 +    @Override  
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endTxFailover(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
index 48d66f2,0000000..34ecf4d
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
@@@ -1,163 -1,0 +1,163 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import com.gemstone.gemfire.GemFireException;
 +import com.gemstone.gemfire.cache.CommitConflictException;
 +import com.gemstone.gemfire.cache.SynchronizationCommitConflictException;
 +import com.gemstone.gemfire.cache.client.ServerOperationException;
 +import com.gemstone.gemfire.internal.cache.TXCommitMessage;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.tier.MessageType;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 +
 +/**
 + * TXSynchronizationOp sends JTA beforeCompletion and afterCompletion
 + * messages to the server pool.
 + * 
 + * @author bruce
 + *
 + */
 +public class TXSynchronizationOp {
 +
 +  public static enum CompletionType {
 +    BEFORE_COMPLETION, AFTER_COMPLETION
 +  }
 +
 +  /**
 +   * @param pool
 +   * @param status - the status of an afterCompletion notification
 +   * @param txId - the transaction identifier
 +   * @param type - BEFORE_COMPLETION or AFTER_COMPLETION
 +   * @return the server's commit message
 +   */
 +  public static TXCommitMessage execute(InternalPool pool, int status, int txId, CompletionType type) {
 +    Impl impl = new Impl(status, txId, type);
 +    pool.execute(impl);
 +    return impl.tXCommitMessageResponse;
 +  }
 +  
 +  static class Impl extends AbstractOp {
 +
 +    private int status;
 +    private CompletionType type;
 +    TXCommitMessage tXCommitMessageResponse;
 +
 +    /**
 +     * @param status
 +     * @param type
 +     */
 +    public Impl(int status, int txId, CompletionType type) {
 +      super(MessageType.TX_SYNCHRONIZATION, (type==CompletionType.AFTER_COMPLETION)? 3 : 2);
 +      this.status = status;
 +      this.type = type;
 +      getMessage().addIntPart(type.ordinal());
 +      getMessage().addIntPart(txId);
 +      if (type == CompletionType.AFTER_COMPLETION) {
 +        getMessage().addIntPart(status);
 +      }
 +    }
 +    
 +    @Override
 +    public String toString() {
 +      return "TXSynchronization(threadTxId=" + TXManagerImpl.getCurrentTXUniqueId()
 +      +"; "+this.type + "; status=" + this.status + ")";
 +    }
 +
 +    @Override
 +  protected void processAck(Message msg, String opName)
 +    throws Exception
 +  {
 +    final int msgType = msg.getMessageType();
 +    if (msgType == MessageType.REPLY) {
 +      return;
 +    } else {
 +      Part part = msg.getPart(0);
 +      if (msgType == MessageType.EXCEPTION) {
 +        Throwable t = (Throwable) part.getObject();
 +        if (t instanceof CommitConflictException ||
 +            t instanceof SynchronizationCommitConflictException) {
 +          throw (GemFireException)t;
 +        }
 +      }
 +      super.processAck(msg, opName);
 +    }
 +  }
 +
 +    
 +    /* (non-Javadoc)
 +     * @see com.gemstone.gemfire.cache.client.internal.AbstractOp#processResponse(com.gemstone.gemfire.internal.cache.tier.sockets.Message)
 +     */
 +    @Override
 +    protected Object processResponse(Message msg) throws Exception {
 +      if (this.type == CompletionType.BEFORE_COMPLETION) {
 +        try {
 +          processAck(msg, type.toString());
 +        } catch (ServerOperationException e) {
 +          if (e.getCause() instanceof SynchronizationCommitConflictException) {
 +            throw (SynchronizationCommitConflictException)e.getCause();
 +          }
 +        }
 +        return null;
 +      } else {
 +        TXCommitMessage rcs = (TXCommitMessage)processObjResponse(msg, this.type.toString());
 +        this.tXCommitMessageResponse = rcs;
 +        return rcs;
 +      }
 +    }
 +
 +    /* (non-Javadoc)
 +     * @see com.gemstone.gemfire.cache.client.internal.AbstractOp#isErrorResponse(int)
 +     */
 +    @Override
 +    protected boolean isErrorResponse(int msgType) {
 +      return msgType == MessageType.REQUESTDATAERROR;
 +    }
 +
 +    @Override  
 +    protected long startAttempt(ConnectionStats stats) {
 +      return stats.startTxSynchronization();
 +    }
 +    @Override  
 +    protected void endSendAttempt(ConnectionStats stats, long start) {
 +      stats.endTxSynchronizationSend(start, hasFailed());
 +    }
 +    @Override  
 +    protected void endAttempt(ConnectionStats stats, long start) {
 +      stats.endTxSynchronization(start, hasTimedOut(), hasFailed());
 +    }
 +
 +    @Override
 +    protected void processSecureBytes(Connection cnx, Message message)
 +        throws Exception {
 +    }
 +
 +    @Override
 +    protected boolean needsUserId() {
 +      return false;
 +    }
 +
 +    @Override
 +    protected void sendMessage(Connection cnx) throws Exception {
-       getMessage().setEarlyAck((byte)(getMessage().getEarlyAckByte() & Message.MESSAGE_HAS_SECURE_PART));
++      getMessage().clearMessageHasSecurePartFlag();
 +      getMessage().send(false);
 +    }
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/AbstractHoplog.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/AbstractHoplog.java
index 636dd91,0000000..d2fdbe7
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/AbstractHoplog.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/AbstractHoplog.java
@@@ -1,357 -1,0 +1,357 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.hdfs.internal.hoplog;
 +
 +import java.io.IOException;
 +import java.util.regex.Matcher;
 +
++import com.gemstone.gemfire.internal.hll.ICardinality;
 +import org.apache.hadoop.conf.Configuration;
 +import org.apache.hadoop.fs.FileStatus;
 +import org.apache.hadoop.fs.FileSystem;
 +import org.apache.hadoop.fs.Path;
 +import org.apache.hadoop.io.BytesWritable;
 +import org.apache.hadoop.io.Text;
 +import org.apache.hadoop.io.compress.CompressionCodec;
 +import org.apache.hadoop.io.compress.GzipCodec;
 +import org.apache.hadoop.io.compress.Lz4Codec;
 +import org.apache.hadoop.io.compress.SnappyCodec;
 +
 +import com.gemstone.gemfire.cache.hdfs.HDFSIOException;
 +import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreImpl;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.ICardinality;
 +import com.gemstone.gemfire.cache.hdfs.internal.org.apache.hadoop.io.SequenceFile;
 +import com.gemstone.gemfire.cache.hdfs.internal.org.apache.hadoop.io.SequenceFile.CompressionType;
 +import com.gemstone.gemfire.cache.hdfs.internal.org.apache.hadoop.io.SequenceFile.Writer.Option;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.SortedOplogStatistics;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import org.apache.hadoop.hbase.util.FSUtils;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +/**
 + * Abstract class for {@link Hoplog} with common functionality
 + */
 +public abstract class AbstractHoplog implements Hoplog {
 +  protected final FSProvider fsProvider;
 +  
 +  // path of the oplog file
 +  protected volatile Path path;
 +  private volatile HoplogDescriptor hfd;
 +  protected Configuration conf;
 +  protected SortedOplogStatistics stats;
 +  protected Long hoplogModificationTime;
 +  protected Long hoplogSize;
 +
 +  protected HoplogReaderActivityListener readerListener;
 +  
 +  // logger instance
 +  protected static final Logger logger = LogService.getLogger();
 +  
 +  protected static String logPrefix;
 +  // THIS CONSTRUCTOR SHOULD BE USED FOR LONER ONLY
 +  AbstractHoplog(FileSystem inputFS, Path filePath, SortedOplogStatistics stats)
 +      throws IOException {
 +    logPrefix = "<" + filePath.getName() + "> ";
 +    this.fsProvider = new FSProvider(inputFS);
 +    initialize(filePath, stats, inputFS);
 +  }
 +
 +  public AbstractHoplog(HDFSStoreImpl store, Path filePath,
 +      SortedOplogStatistics stats) throws IOException {
 +    logPrefix = "<" + filePath.getName() + "> ";
 +    this.fsProvider = new FSProvider(store);
 +    initialize(filePath, stats, store.getFileSystem());
 +  }
 +
 +  private void initialize(Path path, SortedOplogStatistics stats, FileSystem fs) {
 +    this.conf = fs.getConf();
 +    this.stats = stats;
 +    this.path = fs.makeQualified(path);
 +    this.hfd = new HoplogDescriptor(this.path.getName());
 +  }
 +  
 +  @Override
 +  public abstract void close() throws IOException; 
 +  @Override
 +  public abstract HoplogReader getReader() throws IOException;
 +
 +  @Override
 +  public abstract HoplogWriter createWriter(int keys) throws IOException;
 +
 +  @Override
 +  abstract public void close(boolean clearCache) throws IOException;
 +
 +  @Override
 +  public void setReaderActivityListener(HoplogReaderActivityListener listener) {
 +    this.readerListener = listener;
 +  }
 +  
 +  @Override
 +  public String getFileName() {
 +    return this.hfd.getFileName();
 +  }
 +  
 +  public final int compareTo(Hoplog o) {
 +    return hfd.compareTo( ((AbstractHoplog)o).hfd);
 +  }
 +
 +  @Override
 +  public ICardinality getEntryCountEstimate() throws IOException {
 +    return null;
 +  }
 +  
 +  @Override
 +  public synchronized void rename(String name) throws IOException {
 +    if (logger.isDebugEnabled())
 +      logger.debug("{}Renaming hoplog to " + name, logPrefix);
 +    Path parent = path.getParent();
 +    Path newPath = new Path(parent, name);
 +    fsProvider.getFS().rename(path, new Path(parent, newPath));
 +
 +    // close the old reader and let the new one get created lazily
 +    close();
 +    
 +    // update path to point to the new path
 +    path = newPath;
 +    this.hfd = new HoplogDescriptor(this.path.getName());
 +    logPrefix = "<" + path.getName() + "> ";
 +  }
 +  
 +  @Override
 +  public synchronized void delete() throws IOException {
 +    if (logger.isDebugEnabled())
 +      logger.debug("{}Deleting hoplog", logPrefix);
 +    close();
 +    this.hoplogModificationTime = null;
 +    this.hoplogSize = null;
 +    fsProvider.getFS().delete(path, false);
 +  }
 +
 +  @Override
 +  public long getModificationTimeStamp() {
 +    initHoplogSizeTimeInfo();
 +
 +    // modification time will not be null if this hoplog is existing. Otherwise
 +    // invocation of this method should is invalid
 +    if (hoplogModificationTime == null) {
 +      throw new IllegalStateException();
 +    }
 +    
 +    return hoplogModificationTime;
 +  }
 +
 +  @Override
 +  public long getSize() {
 +    initHoplogSizeTimeInfo();
 +    
 +    // size will not be null if this hoplog is existing. Otherwise
 +    // invocation of this method should is invalid
 +    if (hoplogSize == null) {
 +      throw new IllegalStateException();
 +    }
 +    
 +    return hoplogSize;
 +  }
 +  
 +  private synchronized void initHoplogSizeTimeInfo() {
 +    if (hoplogSize != null && hoplogModificationTime != null) {
 +      // time and size info is already initialized. no work needed here
 +      return;
 +    }
 +
 +    try {
 +      FileStatus[] filesInfo = FSUtils.listStatus(fsProvider.getFS(), path, null);
 +      if (filesInfo != null && filesInfo.length == 1) {
 +        this.hoplogModificationTime = filesInfo[0].getModificationTime();
 +        this.hoplogSize = filesInfo[0].getLen();
 +      }
 +      // TODO else condition may happen if user deletes hoplog from the file system.
 +    } catch (IOException e) {
 +      logger.error(LocalizedMessage.create(LocalizedStrings.HOPLOG_FAILED_TO_READ_HDFS_FILE, path), e);
 +      throw new HDFSIOException(
 +          LocalizedStrings.HOPLOG_FAILED_TO_READ_HDFS_FILE.toLocalizedString(path),e);
 +    }
 +  }
 +  public static SequenceFile.Writer getSequenceFileWriter(Path path, 
 +      Configuration conf, Logger logger) throws IOException {
 +    return getSequenceFileWriter(path,conf, logger, null); 
 +  }
 +  
 +  /**
 +   * 
 +   * @param path
 +   * @param conf
 +   * @param logger
 +   * @param version - is being used only for testing. Should be passed as null for other purposes. 
 +   * @return SequenceFile.Writer 
 +   * @throws IOException
 +   */
 +  public static SequenceFile.Writer getSequenceFileWriter(Path path, 
 +    Configuration conf, Logger logger, Version version) throws IOException {
 +    Option optPath = SequenceFile.Writer.file(path);
 +    Option optKey = SequenceFile.Writer.keyClass(BytesWritable.class);
 +    Option optVal = SequenceFile.Writer.valueClass(BytesWritable.class);
 +    Option optCom = withCompression(logger);
 +    if (logger.isDebugEnabled())
 +      logger.debug("{}Started creating hoplog " + path, logPrefix);
 +    
 +    if (version == null)
 +      version = Version.CURRENT;
 +    //Create a metadata option with the gemfire version, for future versioning
 +    //of the key and value format
 +    SequenceFile.Metadata metadata = new SequenceFile.Metadata();
 +    metadata.set(new Text(Meta.GEMFIRE_VERSION.name()), new Text(String.valueOf(version.ordinal())));
 +    Option optMeta = SequenceFile.Writer.metadata(metadata);
 +    
 +    SequenceFile.Writer writer = SequenceFile.createWriter(conf, optPath, optKey, optVal, optCom, optMeta);
 +    
 +    return writer;
 +  }
 +  
 +  private static Option withCompression(Logger logger) {
 +    String prop = System.getProperty(HoplogConfig.COMPRESSION);
 +    if (prop != null) {
 +      CompressionCodec codec;
 +      if (prop.equalsIgnoreCase("SNAPPY")) {
 +        codec = new SnappyCodec();
 +      } else if (prop.equalsIgnoreCase("LZ4")) {
 +        codec = new Lz4Codec();
 +      } else if (prop.equals("GZ")) {
 +        codec = new GzipCodec();
 +      } else {
 +        throw new IllegalStateException("Unsupported codec: " + prop);
 +      }
 +      if (logger.isDebugEnabled())
 +        logger.debug("{}Using compression codec " + codec, logPrefix);
 +      return SequenceFile.Writer.compression(CompressionType.BLOCK, codec);
 +    }
 +    return SequenceFile.Writer.compression(CompressionType.NONE, null);
 +  }
 +  
 +  public static final class HoplogDescriptor implements Comparable<HoplogDescriptor> {
 +     private final String fileName;
 +     private final String bucket;
 +     private final int sequence;
 +     private final long timestamp;
 +     private final String extension;
 +     
 +     HoplogDescriptor(final String fileName) {
 +       this.fileName = fileName;
 +       final Matcher matcher = AbstractHoplogOrganizer.HOPLOG_NAME_PATTERN.matcher(fileName);
 +       final boolean matched = matcher.find();
 +       assert matched;
 +       this.bucket = matcher.group(1);
 +       this.sequence = Integer.valueOf(matcher.group(3));
 +       this.timestamp = Long.valueOf(matcher.group(2)); 
 +       this.extension = matcher.group(4);
 +     }
 +     
 +     public final String getFileName() {
 +       return fileName;
 +     }
 +     
 +     @Override
 +     public boolean equals(Object o) {
 +       if (this == o) {
 +         return true;
 +       }
 +       
 +       if (!(o instanceof HoplogDescriptor)) {
 +         return false;
 +       }
 +       
 +       final HoplogDescriptor other = (HoplogDescriptor)o;
 +       // the two files should belong to same bucket
 +       assert this.bucket.equals(other.bucket);
 +       
 +       // compare sequence first
 +       if (this.sequence != other.sequence) {
 +         return false;
 +       }
 +       
 +       // sequence is same, compare timestamps
 +       if (this.timestamp != other.timestamp) {
 +         return false;
 +       }
 +       
 +       return extension.equals(other.extension);
 +     }
 +
 +    @Override
 +    public int compareTo(HoplogDescriptor o) {
 +      if (this == o) {
 +        return 0;
 +      }
 +      
 +      // the two files should belong to same bucket
 +      assert this.bucket.equals(o.bucket);
 +      
 +      // compare sequence first
 +      if (sequence > o.sequence) {
 +        return -1;
 +      } else if (sequence < o.sequence) {
 +        return 1;
 +      }
 +      
 +      // sequence is same, compare timestamps
 +      if(timestamp > o.timestamp) {
 +        return -1; 
 +      } else if (timestamp < o.timestamp) {
 +        return 1;
 +      }
 +      
 +      //timestamp is the same, compare the file extension. It's
 +      //possible a major compaction and minor compaction could finish
 +      //at the same time and create the same timestamp and sequence number
 +      //it doesn't matter which file we look at first in that case.
 +      return extension.compareTo(o.extension);
 +    }
 +     
 +     
 +  }
 +  
 +  protected static final class FSProvider {
 +    final FileSystem fs;
 +    final HDFSStoreImpl store;
 +    
 +    // THIS METHOD IS FOR TESTING ONLY
 +    FSProvider(FileSystem fs) {
 +      this.fs = fs;
 +      this.store = null;
 +    }
 +    
 +    FSProvider(HDFSStoreImpl store) {
 +      this.store = store;
 +      fs = null;
 +    }
 +    
 +    public FileSystem getFS() throws IOException {
 +      if (store != null) {
 +        return store.getFileSystem();
 +      }
 +      return fs;
 +    }
 +
 +    public FileSystem checkFileSystem() {
 +      store.checkAndClearFileSystem();
 +      return store.getCachedFileSystem();
 +    }
 +  }
 +}


[078/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
index 0000000,4bfd44b..a6495e2
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
@@@ -1,0 -1,1100 +1,1116 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
+ 
+ import java.io.EOFException;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
+ import java.net.Socket;
+ import java.net.SocketTimeoutException;
+ import java.nio.ByteBuffer;
+ import java.nio.channels.SocketChannel;
+ import java.util.concurrent.Semaphore;
+ import java.util.concurrent.TimeUnit;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.SerializationException;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.SocketUtils;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.TXManagerImpl;
+ import com.gemstone.gemfire.internal.cache.tier.MessageType;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.internal.util.BlobHelper;
+ 
+ /**
+  * This class encapsulates the wire protocol. It provides accessors to
+  * encode and decode a message and  serialize it out to the wire.
+  *
+  * <PRE>
+  * msgType       - int   - 4 bytes type of message, types enumerated below
+  *
+  * msgLength     - int - 4 bytes   total length of variable length payload
+  *
+  * numberOfParts - int - 4 bytes   number of elements (LEN-BYTE* pairs)
+  *                     contained in the payload. Message can
+  *                       be a multi-part message
+  *
+  * transId       - int - 4 bytes  filled in by the requestor, copied back into
+  *                    the response
+  *
+  * flags         - byte- 1 byte   filled in by the requestor
+  * len1
+  * part1
+  * .
+  * .
+  * .
+  * lenn
+  * partn
+  * </PRE>
+  *
+  * We read the fixed length 16 bytes into a byte[] and populate a bytebuffer
+  * We read the fixed length header tokens from the header
+  * parse the header and use information contained in there to read the payload.
+  *
+  * <P>
+  *
+  * See also <a href="package-summary.html#messages">package description</a>.
+  *
+  * @see com.gemstone.gemfire.internal.cache.tier.MessageType
+  *
+  */
+ public class Message  {
+ 
++  /**
++   * maximum size of an outgoing message.  See GEODE-478
++   */
++  static final int MAX_MESSAGE_SIZE = Integer.getInteger("gemfire.client.max-message-size", 1073741824).intValue();
++
+   private static final Logger logger = LogService.getLogger();
+   
+   private static final int PART_HEADER_SIZE = 5; // 4 bytes for length, 1 byte for isObject
+   
+   private static final int FIXED_LENGTH = 17;
+ 
+   private static final ThreadLocal<ByteBuffer> tlCommBuffer = new ThreadLocal<>();
+ 
+   protected int msgType;
+   protected int payloadLength=0;
+   protected int numberOfParts =0;
+   protected int transactionId = TXManagerImpl.NOTX;
+   protected int currentPart = 0;
+   protected Part[] partsList = null;
+   protected ByteBuffer cachedCommBuffer;
+   protected Socket socket = null;
+   protected SocketChannel sockCh = null;
+   protected OutputStream os = null;
+   protected InputStream is = null;
+   protected boolean messageModified = true;
+   /** is this message a retry of a previously sent message? */
+   protected boolean isRetry;
+   private byte flags = 0x00;
+   protected MessageStats msgStats = null;
+   protected ServerConnection sc = null;
+   private int maxIncomingMessageLength = -1;
+   private Semaphore dataLimiter = null;
+ //  private int MAX_MSGS = -1;
+   private Semaphore msgLimiter = null;
+   private boolean hdrRead = false;  
+   private int chunkSize = 1024;//Default Chunk Size.
+ 
+   protected Part securePart = null;
+   private boolean isMetaRegion = false;
+ 
+ 
+   // These two statics are fields shoved into the flags byte for transmission.
+   // The MESSAGE_IS_RETRY bit is stripped out during deserialization but the other
+   // is left in place
+   public static final byte MESSAGE_HAS_SECURE_PART = (byte)0x02;
+   public static final byte MESSAGE_IS_RETRY = (byte)0x04;
+   
+   public static final byte MESSAGE_IS_RETRY_MASK = (byte)0xFB;
+ 
+   // Tentative workaround to avoid OOM stated in #46754.
+   public static final ThreadLocal<Integer> messageType = new ThreadLocal<Integer>();
+   
+   Version version;
+   
+   /**
+    * Creates a new message with the given number of parts
+    */
+   public Message(int numberOfParts, Version destVersion) {
+     this.version = destVersion;
+     Assert.assertTrue(destVersion != null, "Attempt to create an unversioned message");
+     partsList = new Part[numberOfParts];
+     this.numberOfParts = numberOfParts;
+     for (int i=0;i<partsList.length;i++) {
+       partsList[i] = new Part();
+     }
+   }
+ 
+   public boolean isSecureMode() {    
+     return securePart != null;
+   }
+   
+   public byte[] getSecureBytes()
+     throws IOException, ClassNotFoundException {
+     return (byte[])this.securePart.getObject();
+   }
+   
+   public void setMessageType(int msgType) {
+     this.messageModified = true;
+     if (!MessageType.validate(msgType)) {
+       throw new IllegalArgumentException(LocalizedStrings.Message_INVALID_MESSAGETYPE.toLocalizedString());
+     }
+     this.msgType = msgType;
+   }
+   
+   public void setVersion(Version clientVersion) {
+     this.version = clientVersion;
+   }
+ 
+   public void setMessageHasSecurePartFlag() {
+     this.flags = (byte)(this.flags | MESSAGE_HAS_SECURE_PART);
+   }
+   
+   public void clearMessageHasSecurePartFlag() {
+     this.flags = (byte)(this.flags & MESSAGE_HAS_SECURE_PART);
+   }
+ 
+   /**
+    *  Sets and builds the {@link Part}s that are sent
+    *  in the payload of the Message
+    * @param numberOfParts
+    */
+   public void setNumberOfParts(int numberOfParts) {
+     //TODO:hitesh need to add security header here from server
+     //need to insure it is not chunked message
+     //should we look message type to avoid internal message like ping
+     this.messageModified = true;
+     this.currentPart=0;
+     this.numberOfParts = numberOfParts;
+     if (numberOfParts > this.partsList.length) {
+       Part[] newPartsList = new Part[numberOfParts];
+       for (int i=0;i<numberOfParts;i++) {
+         if (i < this.partsList.length) {
+           newPartsList[i] = this.partsList[i];
+         } else {
+           newPartsList[i] = new Part();
+         }
+       }
+       this.partsList = newPartsList;
+     }
+   }
++  
++  /**
++   * For boundary testing we may need to inject mock parts
++   * @param parts
++   */
++  void setParts(Part[] parts) {
++    this.partsList = parts;
++  }
+ 
+   public void setTransactionId(int transactionId) {
+     this.messageModified = true;
+     this.transactionId = transactionId;
+   }
+   
+   public void setIsRetry() {
+     this.isRetry = true;
+   }
+   
+   /**
+    * This returns true if the message has been marked as having been previously
+    * transmitted to a different server.
+    */
+   public boolean isRetry() {
+     return this.isRetry;
+   }
+ 
+   /*Sets size for HDOS chunk.*/
+   public void setChunkSize(int chunkSize) {
+     this.chunkSize = chunkSize;
+   }
+   
+   /**
+    * When building a Message this will return the number of the
+    * next Part to be added to the message
+    */
+   public int getNextPartNumber() {
+     return this.currentPart;
+   }
+ 
+   public void addStringPart(String str) {
+     if (str==null) {
+       addRawPart((byte[])null, false);
+     }
+     else {
+       HeapDataOutputStream hdos = new HeapDataOutputStream(str);
+       this.messageModified = true;
+       Part part = partsList[this.currentPart];
+       part.setPartState(hdos, false);
+       this.currentPart++;
+     }
+   }
+ 
+   /*
+    * Adds a new part to this message that contains a <code>byte</code>
+    * array (as opposed to a serialized object).
+    *
+    * @see #addPart(byte[], boolean)
+    */
+   public void addBytesPart(byte[] newPart) {
+     addRawPart(newPart, false);
+   }
+ 
+   public void addStringOrObjPart(Object o) {
+     if (o instanceof String || o == null) {
+       addStringPart((String)o);
+     } else {
+       // Note even if o is a byte[] we need to serialize it.
+       // This could be cleaned up but it would require C client code to change.
+       serializeAndAddPart(o, false);
+     }
+   }
+ 
+   public void addDeltaPart(HeapDataOutputStream hdos) {
+     this.messageModified = true;
+     Part part = partsList[this.currentPart];
+     part.setPartState(hdos, false);
+     this.currentPart++;
+   }
+ 
+   public void addObjPart(Object o) {
+     addObjPart(o, false);
+   }
+   /**
+    * Like addObjPart(Object) but also prefers to reference
+    * objects in the part instead of copying them into a byte buffer.
+    */
+   public void addObjPartNoCopying(Object o) {
+     if (o == null || o instanceof byte[]) {
+       addRawPart((byte[])o, false);
+     } else {
+       serializeAndAddPartNoCopying(o);
+     }
+   }
+   public void addObjPart(Object o, boolean zipValues) {
+     if (o == null || o instanceof byte[]) {
+       addRawPart((byte[])o, false);
+     } else {
+       serializeAndAddPart(o, zipValues);
+     }
+   }
+   public void addPartInAnyForm(@Unretained Object o, boolean isObject) {
+     if (o == null) {
+       addRawPart((byte[])o, false);
+     } else if (o instanceof byte[]) {
+       addRawPart((byte[])o, isObject);
+     } else if (o instanceof StoredObject) {
+       // It is possible it is an off-heap StoredObject that contains a simple non-object byte[].
+       this.messageModified = true;
+       Part part = partsList[this.currentPart];
+       part.setPartState((StoredObject)o, isObject);
+       this.currentPart++;
+     } else {
+       serializeAndAddPart(o, false);
+     }
+   }
+   
+   private void serializeAndAddPartNoCopying(Object o) {
+     HeapDataOutputStream hdos;
+     Version v = version;
+     if (version.equals(Version.CURRENT)){
+       v = null;
+     }
+     // create the HDOS with a flag telling it that it can keep any byte[] or ByteBuffers/ByteSources passed to it.
+     hdos = new HeapDataOutputStream(chunkSize, v, true);
+     // TODO OFFHEAP: Change Part to look for an HDOS and just pass a reference to its DirectByteBuffer.
+     // Then change HDOS sendTo(SocketChannel...) to use the GatheringByteChannel to write a bunch of bbs.
+     // TODO OFFHEAP This code optimizes one part which works pretty good for getAll since all the values are
+     // returned in one part. But the following seems even better...
+     // BETTER: change Message to consolidate all the part hdos bb lists into a single bb array and have it do the GatheringByteChannel write.
+     // Message can use slice for the small parts (msg header and part header) that are not in the parts data (its a byte array, Chunk, or HDOS).
+     // EVEN BETTER: the message can have a single HDOS which owns a direct comm buffer. It can reserve space if it does not yet know the value to write (for example the size of the message or part).
+     // If we write something to the HDOS that is direct then it does not need to be copied.
+     // But large heap byte arrays will need to be copied to the hdos (the socket write does this anyway).
+     // If the direct buffer is full then we can allocate another one. If a part is already in a heap byte array
+     // then we could defer copying it by slicing the current direct bb and then adding the heap byte array
+     // as bb using ByteBuffer.wrap. Once we have all the data in the HDOS we can finally generate the header
+     // and then start working on sending the ByteBuffers to the channel. If we have room in a direct bb then
+     // we can copy a heap bb to it. Otherwise we can write the bb ahead of it which would free up room to copy
+     // the heap bb to the existing direct bb without needing to allocate extra direct bbs.
+     // Delaying the flush uses more direct memory but reduces the number of system calls.
+     try {
+       BlobHelper.serializeTo(o, hdos);
+     } catch (IOException ex) {
+       throw new SerializationException("failed serializing object", ex);
+     }
+     this.messageModified = true;
+     Part part = partsList[this.currentPart];
+     part.setPartState(hdos, true);
+     this.currentPart++;
+     
+   }
+ 
+   private void serializeAndAddPart(Object o, boolean zipValues) {
+     if (zipValues) {
+       throw new UnsupportedOperationException("zipValues no longer supported");    
+       
+     } else {
+       HeapDataOutputStream hdos;
+       Version v = version;
+       if (version.equals(Version.CURRENT)){
+         v = null;
+       }
+       hdos = new HeapDataOutputStream(chunkSize, v);
+       try {
+         BlobHelper.serializeTo(o, hdos);
+       } catch (IOException ex) {
+         throw new SerializationException("failed serializing object", ex);
+       }
+       this.messageModified = true;
+       Part part = partsList[this.currentPart];
+       part.setPartState(hdos, true);
+       this.currentPart++;
+     }
+   }
+ 
+   public void addIntPart(int v) {
+     this.messageModified = true;
+     Part part = partsList[this.currentPart];
+     part.setInt(v);
+     this.currentPart++;
+   }
+   
+   public void addLongPart(long v) {
+     this.messageModified = true;
+     Part part = partsList[this.currentPart];
+     part.setLong(v);
+     this.currentPart++;
+   }
+   
+   /**
+    * Adds a new part to this message that may contain a serialized
+    * object.
+    */
+   public void addRawPart(byte[] newPart,boolean isObject) {
+     this.messageModified = true;
+     Part part = partsList[this.currentPart];
+     part.setPartState(newPart, isObject);
+     this.currentPart++;
+   }
+ 
+   public int getMessageType() {
+     return this.msgType;
+   }
+ 
+   public int getPayloadLength() {
+     return this.payloadLength;
+   }
+ 
+   public int getHeaderLength() {
+     return FIXED_LENGTH;
+   }
+ 
+   public int getNumberOfParts() {
+     return this.numberOfParts;
+   }
+ 
+   public int getTransactionId() {
+     return this.transactionId;
+   }
+   
+   public Part getPart(int index) {
+     if (index < this.numberOfParts) {
+       Part p = partsList[index];
+       if (this.version != null) {
+         p.setVersion(this.version);
+       }
+       return p;
+     }
+     return null;
+   }
+ 
+   public static ByteBuffer setTLCommBuffer(ByteBuffer bb) {
+     ByteBuffer result = tlCommBuffer.get();
+     tlCommBuffer.set(bb);
+     return result;
+   }
+ 
+   public ByteBuffer getCommBuffer() {
+     if (this.cachedCommBuffer != null) {
+       return this.cachedCommBuffer;
+     }
+     else {
+       return tlCommBuffer.get();
+     }
+   }
+ 
+   public void clear() {
+     this.isRetry = false;
+     int len = this.payloadLength;
+     if (len != 0) {
+       this.payloadLength = 0;
+     }
+     if (this.hdrRead) {
+       if (this.msgStats != null) {
+         this.msgStats.decMessagesBeingReceived(len);
+       }
+     }
+     ByteBuffer buffer = getCommBuffer();
+     if (buffer != null) {
+       buffer.clear();
+     }
+     clearParts();
+     if (len != 0 && this.dataLimiter != null) {
+       this.dataLimiter.release(len);
+       this.dataLimiter = null;
+       this.maxIncomingMessageLength = 0;
+     }
+     if (this.hdrRead) {
+       if (this.msgLimiter != null) {
+         this.msgLimiter.release(1);
+         this.msgLimiter = null;
+       }
+       this.hdrRead = false;
+     }
+     this.flags = 0;
+   }
+ 
+   protected void packHeaderInfoForSending(int msgLen, boolean isSecurityHeader) {
+     //TODO:hitesh setting second bit of flags byte for client 
+     //this is not require but this makes all changes easily at client side right now
+     //just see this bit and process security header
+     byte flagsByte = this.flags;
+     if (isSecurityHeader) {
+       flagsByte |= MESSAGE_HAS_SECURE_PART;
+     }
+     if (this.isRetry) {
+       flagsByte |= MESSAGE_IS_RETRY;
+     }
+     getCommBuffer()
+       .putInt(this.msgType)
+       .putInt(msgLen)
+       .putInt(this.numberOfParts)
+       .putInt(this.transactionId)
+       .put(flagsByte);
+   }
+ 
+   protected Part getSecurityPart() {
+     if (this.sc != null ) {
+       //look types right put get etc
+      return this.sc.updateAndGetSecurityPart(); 
+     }
+     return null;
+   }
+ 
+   public void setSecurePart(byte[] bytes) {
+     this.securePart = new Part();
+     this.securePart.setPartState(bytes, false);
+   }
+ 
+   public void setMetaRegion(boolean isMetaRegion) {
+     this.isMetaRegion = isMetaRegion;
+   }
+ 
+   public boolean getAndResetIsMetaRegion() {
+     boolean isMetaRegion = this.isMetaRegion;
+     this.isMetaRegion = false;
+     return isMetaRegion;
+   }
+ 
+   /**
+    * Sends this message out on its socket.
+    */
+   protected void sendBytes(boolean clearMessage) throws IOException {
+     if (this.sc != null) {
+       // Keep track of the fact that we are making progress.
+       this.sc.updateProcessingMessage();
+     }
+     if (this.socket != null) {
+       final ByteBuffer cb = getCommBuffer();
+       if (cb == null) {
+         throw new IOException("No buffer");
+       }
++      int msgLen = 0;
+       synchronized(cb) {
 -        int numOfSecureParts = 0;
 -        Part securityPart = this.getSecurityPart();
 -        boolean isSecurityHeader = false;
++        long totalPartLen = 0;
++        long headerLen = 0;
++        int partsToTransmit = this.numberOfParts;
+         
 -        if (securityPart != null) {
 -          isSecurityHeader = true;
 -          numOfSecureParts = 1;
 -        }
 -        else if (this.securePart != null) {
 -          // This is a client sending this message.
 -          securityPart = this.securePart;
 -          isSecurityHeader = true;
 -          numOfSecureParts = 1;          
 -        }
 -
 -        int totalPartLen = 0;
 -        for (int i=0;i<this.numberOfParts;i++){
++        for (int i=0; i < this.numberOfParts; i++) {
+           Part part = this.partsList[i];
++          headerLen += PART_HEADER_SIZE;
+           totalPartLen += part.getLength();
+         }
+ 
 -        if(numOfSecureParts == 1) {
++        Part securityPart = this.getSecurityPart();
++        if (securityPart == null) {
++          securityPart = this.securePart;
++        }
++        if (securityPart != null) {
++          headerLen += PART_HEADER_SIZE;
+           totalPartLen += securityPart.getLength();
++          partsToTransmit++;
+         }
 -        int msgLen = (PART_HEADER_SIZE * (this.numberOfParts + numOfSecureParts)) + totalPartLen;
++
++        if ( (headerLen + totalPartLen) > Integer.MAX_VALUE ) {
++          throw new MessageTooLargeException("Message size (" + (headerLen + totalPartLen) 
++              + ") exceeds maximum integer value");
++        }
++        
++        msgLen = (int)(headerLen + totalPartLen);
++        
++        if (msgLen > MAX_MESSAGE_SIZE) {
++          throw new MessageTooLargeException("Message size(" + msgLen
++              + ") exceeds gemfire.client.max-message-size setting (" + MAX_MESSAGE_SIZE + ")");
++        }
++        
+         cb.clear();
 -        packHeaderInfoForSending(msgLen, isSecurityHeader);
 -        for (int i=0;i<this.numberOfParts + numOfSecureParts;i++) {
 -          Part part = null;
 -          if(i == this.numberOfParts) {
 -            part = securityPart;
 -          }
 -          else {
 -            part = partsList[i];
 -          }
++        packHeaderInfoForSending(msgLen, (securityPart != null));
++        for (int i=0; i < partsToTransmit; i++) {
++          Part part = (i == this.numberOfParts) ? securityPart : partsList[i];
++
+           if (cb.remaining() < PART_HEADER_SIZE) {
+             flushBuffer();
+           }
++          
+           int partLen = part.getLength();
+           cb.putInt(partLen);
+           cb.put(part.getTypeCode());
+           if (partLen <= cb.remaining()) {
 -            part.sendTo(cb);
++            part.writeTo(cb);
+           } else {
+             flushBuffer();
 -            // send partBytes
+             if (this.sockCh != null) {
 -              part.sendTo(this.sockCh, cb);
++              part.writeTo(this.sockCh, cb);
+             } else {
 -              part.sendTo(this.os, cb);
++              part.writeTo(this.os, cb);
+             }
+             if (this.msgStats != null) {
+               this.msgStats.incSentBytes(partLen);
+             }
+           }
+         }
+         if (cb.position() != 0) {
+           flushBuffer();
+         }
+         this.messageModified = false;
+         if (this.sockCh == null) {
+           this.os.flush();
+         }
+       }
+       if(clearMessage) {
+         clearParts();
+       }
+     }
+     else {
+       throw new IOException(LocalizedStrings.Message_DEAD_CONNECTION.toLocalizedString());
+     }
+   }
+ 
+   protected void flushBuffer() throws IOException {
+     final ByteBuffer cb = getCommBuffer();
+     if (this.sockCh != null) {
+       cb.flip();
+       do {
+         this.sockCh.write(cb);
+       } while (cb.remaining() > 0);
+     } else {
+       this.os.write(cb.array(), 0, cb.position());
+     }
+     if (this.msgStats != null) {
+       this.msgStats.incSentBytes(cb.position());
+     }
+     cb.clear();
+   }
+ 
+   private void read()
+   throws IOException {
+     clearParts();
+     //TODO:Hitesh ??? for server changes make sure sc is not null as this class also used by client :(
+     readHeaderAndPayload();
+   }
+ 
+   /**
+    * Read the actual bytes of the header off the socket
+    */
+   protected final void fetchHeader() throws IOException {
+     final ByteBuffer cb = getCommBuffer();
+     cb.clear();
+     // msgType is invalidated here and can be used as an indicator
+     // of problems reading the message
+     this.msgType = MessageType.INVALID;
+ 
+     int hdr = 0;
+ 
+     final int headerLength = getHeaderLength();
+     if (this.sockCh != null) {
+       cb.limit(headerLength);
+       do {
+         int bytesRead = this.sockCh.read(cb);
+         //System.out.println("DEBUG: fetchHeader read " + bytesRead + " bytes commBuffer=" + cb);
+         if (bytesRead == -1) {
+           throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_HEADER.toLocalizedString());
+         }
+         if (this.msgStats != null) {
+           this.msgStats.incReceivedBytes(bytesRead);
+         }
+       } while (cb.remaining() > 0);
+       cb.flip();
+     } else {
+       do {
+         int bytesRead = -1;
+         try {
+           bytesRead = this.is.read(cb.array(),hdr, headerLength-hdr);
+         }
+         catch (SocketTimeoutException e) {
+ //          bytesRead = 0;
+           // TODO add a cancellation check
+           throw e;
+         }
+         if (bytesRead == -1) {
+           throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_HEADER.toLocalizedString());
+         }
+         hdr += bytesRead;
+         if (this.msgStats != null) {
+           this.msgStats.incReceivedBytes(bytesRead);
+         }
+       } while (hdr < headerLength);
+ 
+       // now setup the commBuffer for the caller to parse it
+       cb.rewind();
+     }
+   }
+ 
+   private void readHeaderAndPayload()
+   throws IOException {
+     //TODO:Hitesh ???
+     fetchHeader();
+     final ByteBuffer cb = getCommBuffer();
+     final int type = cb.getInt();
+     final int len = cb.getInt();
+     final int numParts = cb.getInt();
+     final int txid = cb.getInt();
+     byte bits = cb.get();
+     cb.clear();
+ 
+     if (!MessageType.validate(type)) {
+       throw new IOException(LocalizedStrings.Message_INVALID_MESSAGE_TYPE_0_WHILE_READING_HEADER.toLocalizedString(Integer.valueOf(type)));
+     }
+     int timeToWait = 0;
+     if (this.sc != null) {
+       // Keep track of the fact that a message is being processed.
+       this.sc.setProcessingMessage();
+       timeToWait = sc.getClientReadTimeout();
+     }
+     this.hdrRead = true;
+     if (this.msgLimiter != null) {
+         for (;;) {
+           this.sc.getCachedRegionHelper().checkCancelInProgress(null);
+           boolean interrupted = Thread.interrupted();
+           try {
+             if (timeToWait == 0) {
+               this.msgLimiter.acquire(1);
+             } 
+             else {
+               if (!this.msgLimiter.tryAcquire(1, timeToWait, TimeUnit.MILLISECONDS)) {
+                 if (this.msgStats != null
+                     && this.msgStats instanceof CacheServerStats) {
+                   ((CacheServerStats)this.msgStats).incConnectionsTimedOut();
+                 }
+                 throw new IOException(LocalizedStrings.Message_OPERATION_TIMED_OUT_ON_SERVER_WAITING_ON_CONCURRENT_MESSAGE_LIMITER_AFTER_WAITING_0_MILLISECONDS.toLocalizedString(Integer.valueOf(timeToWait)));
+               }
+             }
+             break;
+           }
+           catch (InterruptedException e) {
+             interrupted = true;
+           }
+           finally {
+             if (interrupted) {
+               Thread.currentThread().interrupt();
+             }
+           }
+         } // for
+     }
+     if (len > 0) {
+       if (this.maxIncomingMessageLength > 0 && len > this.maxIncomingMessageLength) {
+         throw new IOException(LocalizedStrings.Message_MESSAGE_SIZE_0_EXCEEDED_MAX_LIMIT_OF_1.toLocalizedString(new Object[] {Integer.valueOf(len), Integer.valueOf(this.maxIncomingMessageLength)}));
+       }
+       if (this.dataLimiter != null) {
+         for (;;) {
+           if (sc != null) {
+             this.sc.getCachedRegionHelper().checkCancelInProgress(null);
+           }
+           boolean interrupted = Thread.interrupted();
+           try {
+             if (timeToWait == 0) {
+               this.dataLimiter.acquire(len);
+             } 
+             else {
+               int newTimeToWait = timeToWait;
+               if (this.msgLimiter != null) {
+                 // may have waited for msg limit so recalc time to wait
+                 newTimeToWait -= (int)sc.getCurrentMessageProcessingTime();
+               }
+               if (newTimeToWait <= 0 || !this.msgLimiter.tryAcquire(1, newTimeToWait, TimeUnit.MILLISECONDS)) {
+                 throw new IOException(LocalizedStrings.Message_OPERATION_TIMED_OUT_ON_SERVER_WAITING_ON_CONCURRENT_DATA_LIMITER_AFTER_WAITING_0_MILLISECONDS.toLocalizedString(timeToWait));
+               }
+             }
+             this.payloadLength = len; // makes sure payloadLength gets set now so we will release the semaphore
+             break; // success
+           }
+           catch (InterruptedException e) {
+             interrupted = true;
+           }
+           finally {
+             if (interrupted) {
+               Thread.currentThread().interrupt();
+             }
+           }
+         }
+       }
+     }
+     if (this.msgStats != null) {
+       this.msgStats.incMessagesBeingReceived(len);
+       this.payloadLength = len; // makes sure payloadLength gets set now so we will dec on clear
+     }
+     
+     this.isRetry = (bits & MESSAGE_IS_RETRY) != 0;
+     bits = (byte)(bits & MESSAGE_IS_RETRY_MASK);
+     this.flags = bits;
+     // TODO why is the msgType set twice, here and after reading the payload fields?
+     this.msgType = type;
+ 
+     readPayloadFields(numParts, len);
+ 
+     // Set the header and payload fields only after receiving all the
+     // socket data, providing better message consistency in the face
+     // of exceptional conditions (e.g. IO problems, timeouts etc.)
+     this.msgType = type;
+     this.payloadLength = len;
+     // this.numberOfParts = numParts;  Already set in setPayloadFields via setNumberOfParts
+     this.transactionId = txid;
+     this.flags = bits;
+     if (this.sc != null) {
+       // Keep track of the fact that a message is being processed.
+       this.sc.updateProcessingMessage();
+     }
+   }
+ 
+   protected void readPayloadFields(final int numParts, final int len)
+   throws IOException {
+     //TODO:Hitesh
+     if (len > 0 && numParts <= 0 ||
+         len <= 0 && numParts > 0) {
+       throw new IOException(LocalizedStrings.Message_PART_LENGTH_0_AND_NUMBER_OF_PARTS_1_INCONSISTENT.toLocalizedString(
+             new Object[] {Integer.valueOf(len), Integer.valueOf(numParts)}));
+     }
+ 
+     Integer msgType = messageType.get();
+     if (msgType != null && msgType == MessageType.PING) {
+       messageType.set(null); // set it to null right away.
+       int pingParts = 10; // Some number which will not throw OOM but still be acceptable for a ping operation.
+       if (numParts > pingParts) {
+         throw new IOException("Part length ( " + numParts
+             + " ) is  inconsistent for " + MessageType.getString(msgType)
+             + " operation.");
+       }
+     }
+     setNumberOfParts(numParts);
+     if (numParts <= 0)
+       return;
+   
+     if (len < 0) {
+       logger.info(LocalizedMessage.create(LocalizedStrings.Message_RPL_NEG_LEN__0, len));
+       throw new IOException(LocalizedStrings.Message_DEAD_CONNECTION.toLocalizedString());
+     }    
+     
+     final ByteBuffer cb = getCommBuffer();
+     cb.clear();
+     cb.flip();
+ 
+     int readSecurePart = 0;
+     //TODO:Hitesh look if securePart can be cached here
+     readSecurePart = checkAndSetSecurityPart();
+     
+     int bytesRemaining = len;
+     for (int i = 0; ((i < numParts + readSecurePart) || ((readSecurePart == 1) && (cb
+         .remaining() > 0))); i++) {
+       int bytesReadThisTime = readPartChunk(bytesRemaining);
+       bytesRemaining -= bytesReadThisTime;
+ 
+       Part part;
+       
+       if(i < numParts) {
+         part = this.partsList[i];
+       }
+       else {
+         part = this.securePart;
+       }
+       
+       int partLen = cb.getInt();
+       byte partType = cb.get();
+       byte[] partBytes = null;
+       if (partLen > 0) {
+         partBytes = new byte[partLen];
+         int alreadyReadBytes = cb.remaining();
+         if (alreadyReadBytes > 0) {
+           if (partLen < alreadyReadBytes) {
+             alreadyReadBytes = partLen;
+           }
+           cb.get(partBytes, 0, alreadyReadBytes);
+         }
+         // now we need to read partLen - alreadyReadBytes off the wire
+         int off = alreadyReadBytes;
+         int remaining = partLen - off;
+         while (remaining > 0) {
+           if (this.sockCh != null) {
+             int bytesThisTime = remaining;
+             cb.clear();
+             if (bytesThisTime > cb.capacity()) {
+               bytesThisTime = cb.capacity();
+             }
+             cb.limit(bytesThisTime);
+             int res = this.sockCh.read(cb);
+             if (res != -1) {
+               cb.flip();
+               bytesRemaining -= res;
+               remaining -= res;
+               cb.get(partBytes, off, res);
+               off += res;
+               if (this.msgStats != null) {
+                 this.msgStats.incReceivedBytes(res);
+               }
+             } else {
+               throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_A_PART.toLocalizedString());
+             }
+           } else {
+             int res = 0;
+             try {
+               res = this.is.read(partBytes, off, remaining);
+             }
+             catch (SocketTimeoutException e) {
+               // TODO: add cancellation check
+               throw e;
+             }
+             if (res != -1) {
+               bytesRemaining -= res;
+               remaining -= res;
+               off += res;
+               if (this.msgStats != null) {
+                 this.msgStats.incReceivedBytes(res);
+               }
+             } else {
+               throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_A_PART.toLocalizedString());
+             }
+           }
+         }
+       }
+       part.init(partBytes, partType);
+     }
+   }
+ 
+   protected int checkAndSetSecurityPart() {
+     if ((this.flags | MESSAGE_HAS_SECURE_PART) == this.flags) {
+       this.securePart = new Part();
+       return 1;
+     }
+     else {
+       this.securePart = null;
+       return 0;
+     }
+   }
+ 
+   /**
+    * @param bytesRemaining the most bytes we can read
+    * @return the number of bytes read into commBuffer
+    */
+   private int readPartChunk(int bytesRemaining) throws IOException {
+     final ByteBuffer cb = getCommBuffer();
+     if (cb.remaining() >= PART_HEADER_SIZE) {
+       // we already have the next part header in commBuffer so just return
+       return 0;
+     }
+     if (cb.position() != 0) {
+       cb.compact();
+     } else {
+       cb.position(cb.limit());
+       cb.limit(cb.capacity());
+     }
+     int bytesRead = 0;
+     if (this.sc != null) {
+       // Keep track of the fact that we are making progress
+       this.sc.updateProcessingMessage();
+     }
+     if (this.sockCh != null) {
+       int remaining = cb.remaining();
+       if (remaining > bytesRemaining) {
+         remaining = bytesRemaining;
+         cb.limit(cb.position()+bytesRemaining);
+       }
+       while (remaining > 0) {
+         int res = this.sockCh.read(cb);
+         if (res != -1) {
+           remaining -= res;
+           bytesRead += res;
+           if (this.msgStats != null) {
+             this.msgStats.incReceivedBytes(res);
+           }
+         } else {
+           throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_PAYLOAD.toLocalizedString());
+         }
+       }
+ 
+     } else {
+       int bufSpace = cb.capacity() - cb.position();
+       int bytesToRead = bufSpace;
+       if (bytesRemaining < bytesToRead) {
+         bytesToRead = bytesRemaining;
+       }
+       int pos = cb.position();
+       while (bytesToRead > 0) {
+         int res = 0;
+         try {
+           res = this.is.read(cb.array(), pos, bytesToRead);
+         }
+         catch (SocketTimeoutException e) {
+           // TODO add a cancellation check
+           throw e;
+         }
+         if (res != -1) {
+           bytesToRead -= res;
+           pos += res;
+           bytesRead += res;
+           if (this.msgStats != null) {
+             this.msgStats.incReceivedBytes(res);
+           }
+         } else {
+           throw new EOFException(LocalizedStrings.Message_THE_CONNECTION_HAS_BEEN_RESET_WHILE_READING_THE_PAYLOAD.toLocalizedString());
+         }
+       }
+       cb.position(pos);
+     }
+     cb.flip();
+     return bytesRead;
+   }
+ 
+   /**
+    * Gets rid of all the parts that have been added to this message.
+    */
+   public void clearParts() {
+     for (int i=0; i< partsList.length; i++){
+       partsList[i].clear();
+     }
+     this.currentPart=0;
+   }
+ 
+   @Override
+   public String toString() {
+     StringBuffer sb = new StringBuffer();
+     sb.append("type=").append(MessageType.getString(msgType));
+     sb.append("; payloadLength=").append(payloadLength);
+     sb.append("; numberOfParts=").append(numberOfParts);
+     sb.append("; transactionId=").append(transactionId);
+     sb.append("; currentPart=").append(currentPart);
+     sb.append("; messageModified=").append(messageModified);
+     sb.append("; flags=").append(Integer.toHexString(flags));
+     for (int i = 0; i < numberOfParts; i ++) {
+       sb.append("; part[").append(i).append("]={");
+       sb.append(this.partsList[i].toString());
+       sb.append("}");
+     }
+     return sb.toString();
+   }
+ 
+   
+   public void setComms(ServerConnection sc, Socket socket, ByteBuffer bb, MessageStats msgStats) throws IOException {
+     this.sc = sc;
+     setComms(socket, bb, msgStats);
+   }
+ 
+   public void setComms(Socket socket, ByteBuffer bb, MessageStats msgStats) throws IOException {
+     this.sockCh = socket.getChannel();
+     if (this.sockCh == null) {
+       setComms(socket, SocketUtils.getInputStream(socket), SocketUtils.getOutputStream(socket), bb, msgStats);
+     } else {
+       setComms(socket, null, null,  bb, msgStats);
+     }
+   }
+   
+   public void setComms(Socket socket, InputStream is, OutputStream os, ByteBuffer bb, MessageStats msgStats)
+     throws IOException
+   {
+     Assert.assertTrue(socket != null);
+     this.socket = socket;
+     this.sockCh = socket.getChannel();
+     this.is = is;
+     this.os = os;
+     this.cachedCommBuffer = bb;
+     this.msgStats = msgStats;
+   }
+   /**
+    * Undo any state changes done by setComms.
+    * @since 5.7
+    */
+   public void unsetComms() {
+     this.socket = null;
+     this.sockCh = null;
+     this.is = null;
+     this.os = null;
+     this.cachedCommBuffer = null;
+     this.msgStats = null;
+   }
+ 
+   /**
+    * Sends this message to its receiver over its
+    * setOutputStream?? output stream.
+    */
+   public void send()
+   throws IOException {
+     send(true);
+   }
+   
+   public void send(ServerConnection servConn)
+   throws IOException {
+     if (this.sc != servConn) throw new IllegalStateException("this.sc was not correctly set");
+     send(true);
+   }
+   
+   /**
+    * Sends this message to its receiver over its
+    * setOutputStream?? output stream.
+    */
+   public void send(boolean clearMessage)
+   throws IOException {
+     sendBytes(clearMessage);
+   }
+ 
+   /**
+    *  Populates the stats of this <code>Message</code> with information
+    *  received via its socket
+    */
+   public void recv()
+   throws IOException {
+     if (this.socket != null) {
+       synchronized(getCommBuffer()) {
+         read();
+       }
+     }
+     else {
+       throw new IOException(LocalizedStrings.Message_DEAD_CONNECTION.toLocalizedString());
+     }
+   }
+   public void recv(ServerConnection sc, int maxMessageLength, Semaphore dataLimiter, Semaphore msgLimiter)
+   throws IOException {
+     this.sc = sc;
+     this.maxIncomingMessageLength = maxMessageLength;
+     this.dataLimiter = dataLimiter;
+     this.msgLimiter = msgLimiter;
+     recv();
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
index 0000000,0000000..e5cac59
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
@@@ -1,0 -1,0 +1,29 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
++
++import java.io.IOException;
++
++public class MessageTooLargeException extends IOException {
++
++  private static final long serialVersionUID = -8970585803331525833L;
++  
++  public MessageTooLargeException(String message) {
++    super(message);
++  }
++
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
index 0000000,f5f6326..80b5c0a
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
@@@ -1,0 -1,452 +1,452 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
+ 
+ import com.gemstone.gemfire.internal.*;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializable;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.DataAsAddress;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ 
+ import java.io.*;
+ import java.nio.*;
+ import java.nio.channels.*;
+ 
+ /**
+  * Represents one unit of information (essentially a <code>byte</code>
+  * array) in the wire protocol.  Each server connection runs in its
+  * own thread to maximize concurrency and improve response times to
+  * edge requests
+  *
+  * @see Message
+  *
+  * @author Sudhir Menon
+  * @since 2.0.2
+  */
+ public class Part {
+   private static final byte BYTE_CODE = 0;
+   private static final byte OBJECT_CODE = 1;
+   
+   private Version version;
+   /**
+    * Used to represent and empty byte array for bug 36279
+    * @since 5.1
+    */
+   private static final byte EMPTY_BYTEARRAY_CODE = 2;
+   private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+ 
+   /** The payload of this part.
+    * Could be null, a byte[] or a HeapDataOutputStream on the send side.
+    * Could be null, or a byte[] on the receiver side.
+    */
+   private Object part;
+ 
+   /** Is the payload (<code>part</code>) a serialized object? */
+   private byte typeCode;
+ 
+   public void init(byte[] v, byte tc) {
+     if (tc == EMPTY_BYTEARRAY_CODE) {
+       this.part = EMPTY_BYTE_ARRAY;
+     }
+     else {
+       this.part = v;
+     }
+     this.typeCode = tc;
+   }
+ 
+ 
+   public void clear() {
+     this.part = null;
+     this.typeCode = BYTE_CODE;
+   }
+ 
+   public boolean isNull() {
+     if (this.part == null) {
+       return true;
+     }
+     if (isObject() && this.part instanceof byte[]) {
+       byte[] b = (byte[])this.part;
+       if (b.length == 1 && b[0] == DSCODE.NULL) {
+         return true;
+       }
+     }
+     return false;
+   }
+   public boolean isObject() {
+     return this.typeCode == OBJECT_CODE;
+   }
+   public boolean isBytes() {
+     return this.typeCode == BYTE_CODE || this.typeCode == EMPTY_BYTEARRAY_CODE;
+   }
+ 
+   public void setPartState(byte[] b, boolean isObject) {
+     if (isObject) {
+       this.typeCode = OBJECT_CODE;
+     } else if (b != null && b.length == 0) {
+       this.typeCode = EMPTY_BYTEARRAY_CODE;
+       b = EMPTY_BYTE_ARRAY;
+     } else {
+       this.typeCode = BYTE_CODE;
+     }
+     this.part = b;
+   }
+   
+   public void setPartState(HeapDataOutputStream os, boolean isObject) {
+     if (isObject) {
+       this.typeCode = OBJECT_CODE;
+       this.part = os;
+     } else if (os != null && os.size() == 0) {
+       this.typeCode = EMPTY_BYTEARRAY_CODE;
+       this.part = EMPTY_BYTE_ARRAY;
+     } else {
+       this.typeCode = BYTE_CODE;
+       this.part = os;
+     }
+   }
+   public void setPartState(StoredObject so, boolean isObject) {
+     if (isObject) {
+       this.typeCode = OBJECT_CODE;
+     } else if (so.getValueSizeInBytes() == 0) {
+       this.typeCode = EMPTY_BYTEARRAY_CODE;
+       this.part = EMPTY_BYTE_ARRAY;
+       return;
+     } else {
+       this.typeCode = BYTE_CODE;
+     }
+     if (so instanceof DataAsAddress) {
+       this.part = ((DataAsAddress)so).getRawBytes();
+     } else {
 -      this.part = (Chunk)so;
++      this.part = (ObjectChunk)so;
+     }
+   }
+   public byte getTypeCode() {
+     return this.typeCode;
+   }
+   /**
+    * Return the length of the part. The length is the number of bytes needed
+    * for its serialized form.
+    */
+   public int getLength() {
+     if (this.part == null) {
+       return 0;
+     } else if (this.part instanceof byte[]) {
+       return ((byte[])this.part).length;
 -    } else if (this.part instanceof Chunk) {
 -      return ((Chunk) this.part).getValueSizeInBytes();
++    } else if (this.part instanceof ObjectChunk) {
++      return ((ObjectChunk) this.part).getValueSizeInBytes();
+     } else {
+       return ((HeapDataOutputStream)this.part).size();
+     }
+   }
+   public String getString() {
+     if (this.part == null) {
+       return null;
+     }
+     if (!isBytes()) {
+       Assert.assertTrue(false, "expected String part to be of type BYTE, part ="
+           + this.toString());
+     }
+     return CacheServerHelper.fromUTF((byte[])this.part);
+   }
+   
+   public int getInt() {
+     if (!isBytes()) {
+       Assert.assertTrue(false, "expected int part to be of type BYTE, part = "
+           + this.toString()); 
+     }
+     if (getLength() != 4) {
+       Assert.assertTrue(false, 
+           "expected int length to be 4 but it was " + getLength()
+           + "; part = " + this.toString());
+     }
+     byte[] bytes = getSerializedForm();
+     return decodeInt(bytes, 0);
+   }
+ 
+   public static int decodeInt(byte[] bytes, int offset) {
+     return (((bytes[offset + 0]) << 24) & 0xFF000000)
+         | (((bytes[offset + 1]) << 16) & 0x00FF0000)
+         | (((bytes[offset + 2]) << 8) & 0x0000FF00)
+         | ((bytes[offset + 3]) & 0x000000FF);
+   }
+ 
+   public void setInt(int v) {
+     byte[] bytes = new byte[4];
+     encodeInt(v, bytes);
+     this.typeCode = BYTE_CODE;
+     this.part = bytes;
+   }
+ 
+   /**
+    * @since 5.7
+    */
+   public static void encodeInt(int v, byte[] bytes) {
+     encodeInt(v, bytes, 0);
+   }
+ 
+   public static void encodeInt(int v, byte[] bytes, int offset) {
+     // encode an int into the given byte array
+     bytes[offset + 0] = (byte) ((v & 0xFF000000) >> 24);
+     bytes[offset + 1] = (byte) ((v & 0x00FF0000) >> 16);
+     bytes[offset + 2] = (byte) ((v & 0x0000FF00) >> 8 );
+     bytes[offset + 3] = (byte) (v & 0x000000FF);
+   }
+   
+   public void setLong(long v) {
+     byte[] bytes = new byte[8];
+     bytes[0] = (byte) ((v & 0xFF00000000000000l) >> 56);
+     bytes[1] = (byte) ((v & 0x00FF000000000000l) >> 48);
+     bytes[2] = (byte) ((v & 0x0000FF0000000000l) >> 40);
+     bytes[3] = (byte) ((v & 0x000000FF00000000l) >> 32);
+     bytes[4] = (byte) ((v & 0x00000000FF000000l) >> 24);
+     bytes[5] = (byte) ((v & 0x0000000000FF0000l) >> 16);
+     bytes[6] = (byte) ((v & 0x000000000000FF00l) >>  8);
+     bytes[7] = (byte) (v & 0xFF);
+     this.typeCode = BYTE_CODE;
+     this.part = bytes;
+   }
+ 
+   public long getLong() {
+     if (!isBytes()) {
+       Assert.assertTrue(false, "expected long part to be of type BYTE, part = "
+           + this.toString()); 
+     }
+     if (getLength() != 8) {
+       Assert.assertTrue(false, 
+           "expected long length to be 8 but it was " + getLength()
+           + "; part = " + this.toString());
+     }
+     byte[] bytes = getSerializedForm();
+     return ((((long)bytes[0]) << 56) & 0xFF00000000000000l) |
+            ((((long)bytes[1]) << 48) & 0x00FF000000000000l) |
+            ((((long)bytes[2]) << 40) & 0x0000FF0000000000l) |
+            ((((long)bytes[3]) << 32) & 0x000000FF00000000l) |
+            ((((long)bytes[4]) << 24) & 0x00000000FF000000l) |
+            ((((long)bytes[5]) << 16) & 0x0000000000FF0000l) |
+            ((((long)bytes[6]) <<  8) & 0x000000000000FF00l) |
+            (        bytes[7]         & 0x00000000000000FFl);
+   }
+ 
+ 
+   public byte[] getSerializedForm() {
+     if (this.part == null) {
+       return null;
+     } else if (this.part instanceof byte[]) {
+       return (byte[])this.part;
+     } else {
+       return null; // should not be called on sender side?
+     }
+   }
+   public Object getObject(boolean unzip) throws IOException, ClassNotFoundException {
+     if (isBytes()) {
+       return this.part;
+     }
+     else {
+       if (this.version != null) {
+         return CacheServerHelper.deserialize((byte[])this.part, this.version,
+             unzip);
+       }
+       else {
+         return CacheServerHelper.deserialize((byte[])this.part, unzip);
+       }
+     }
+   }
+   public Object getObject() throws IOException, ClassNotFoundException {
+     return getObject(false);
+   }
+ 
+   public Object getStringOrObject() throws IOException, ClassNotFoundException {
+     if (isObject()) {
+       return getObject();
+     } else {
+       return getString();
+     }
+   }
+   
+   /**
+    * Write the contents of this part to the specified output stream.
+    * This is only called for parts that will not fit into the commBuffer
+    * so they need to be written directly to the stream.
+    * A stream is used because the client is configured for old IO (instead of nio).
+    * @param buf the buffer to use if any data needs to be copied to one
+    */
 -  public final void sendTo(OutputStream out, ByteBuffer buf) throws IOException {
++  public final void writeTo(OutputStream out, ByteBuffer buf) throws IOException {
+     if (getLength() > 0) {
+       if (this.part instanceof byte[]) {
+         byte[] bytes = (byte[])this.part;
+         out.write(bytes, 0, bytes.length);
 -      } else if (this.part instanceof Chunk) {
 -        Chunk c = (Chunk) this.part;
++      } else if (this.part instanceof ObjectChunk) {
++        ObjectChunk c = (ObjectChunk) this.part;
+         ByteBuffer cbb = c.createDirectByteBuffer();
+         if (cbb != null) {
+           HeapDataOutputStream.writeByteBufferToStream(out,  buf, cbb);
+         } else {
+           int bytesToSend = c.getDataSize();
+           long addr = c.getAddressForReading(0, bytesToSend);
+           while (bytesToSend > 0) {
+             if (buf.remaining() == 0) {
+               HeapDataOutputStream.flushStream(out,  buf);
+             }
+             buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
+             addr++;
+             bytesToSend--;
+           }
+         }
+       } else {
+         HeapDataOutputStream hdos = (HeapDataOutputStream)this.part;
+         hdos.sendTo(out, buf);
+         hdos.rewind();
+       }
+     }
+   }
+   /**
+    * Write the contents of this part to the specified byte buffer.
+    * Precondition: caller has already checked the length of this part
+    * and it will fit into "buf".
+    */
 -  public final void sendTo(ByteBuffer buf) {
++  public final void writeTo(ByteBuffer buf) {
+     if (getLength() > 0) {
+       if (this.part instanceof byte[]) {
+         buf.put((byte[])this.part);
 -      } else if (this.part instanceof Chunk) {
 -        Chunk c = (Chunk) this.part;
++      } else if (this.part instanceof ObjectChunk) {
++        ObjectChunk c = (ObjectChunk) this.part;
+         ByteBuffer bb = c.createDirectByteBuffer();
+         if (bb != null) {
+           buf.put(bb);
+         } else {
+           int bytesToSend = c.getDataSize();
+           long addr = c.getAddressForReading(0, bytesToSend);
+           while (bytesToSend > 0) {
+             buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
+             addr++;
+             bytesToSend--;
+           }
+         }
+       } else {
+         HeapDataOutputStream hdos = (HeapDataOutputStream)this.part;
+         hdos.sendTo(buf);
+         hdos.rewind();
+       }
+     }
+   }
+   /**
+    * Write the contents of this part to the specified socket channel
+    * using the specified byte buffer.
+    * This is only called for parts that will not fit into the commBuffer
+    * so they need to be written directly to the socket.
+    * Precondition: buf contains nothing that needs to be sent
+    */
 -  public final void sendTo(SocketChannel sc, ByteBuffer buf) throws IOException {
++  public final void writeTo(SocketChannel sc, ByteBuffer buf) throws IOException {
+     if (getLength() > 0) {
+       final int BUF_MAX = buf.capacity();
+       if (this.part instanceof byte[]) {
+         final byte[] bytes = (byte[])this.part;
+         int off = 0;
+         int len = bytes.length;
+         buf.clear();
+         while (len > 0) {
+           int bytesThisTime = len;
+           if (bytesThisTime > BUF_MAX) {
+             bytesThisTime = BUF_MAX;
+           }
+           buf.put(bytes, off, bytesThisTime);
+           len -= bytesThisTime;
+           off += bytesThisTime;
+           buf.flip();
+           while (buf.remaining() > 0) {
+             sc.write(buf);
+           }
+           buf.clear();
+         }
 -      } else if (this.part instanceof Chunk) {
++      } else if (this.part instanceof ObjectChunk) {
+         // instead of copying the Chunk to buf try to create a direct ByteBuffer and
+         // just write it directly to the socket channel.
 -        Chunk c = (Chunk) this.part;
++        ObjectChunk c = (ObjectChunk) this.part;
+         ByteBuffer bb = c.createDirectByteBuffer();
+         if (bb != null) {
+           while (bb.remaining() > 0) {
+             sc.write(bb);
+           }
+         } else {
+           int len = c.getDataSize();
+           long addr = c.getAddressForReading(0, len);
+           buf.clear();
+           while (len > 0) {
+             int bytesThisTime = len;
+             if (bytesThisTime > BUF_MAX) {
+               bytesThisTime = BUF_MAX;
+             }
+             len -= bytesThisTime;
+             while (bytesThisTime > 0) {
+               buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
+               addr++;
+               bytesThisTime--;
+             }
+             buf.flip();
+             while (buf.remaining() > 0) {
+               sc.write(buf);
+             }
+             buf.clear();
+           }
+         }
+       } else {
+         HeapDataOutputStream hdos = (HeapDataOutputStream)this.part;
+         hdos.sendTo(sc, buf);
+         hdos.rewind();
+       }
+     }
+   }
+   
+   static private String typeCodeToString(byte c) {
+     switch (c) {
+     case BYTE_CODE:
+       return "BYTE_CODE";
+     case OBJECT_CODE:
+       return "OBJECT_CODE";
+     case EMPTY_BYTEARRAY_CODE:
+       return "EMPTY_BYTEARRAY_CODE";
+     default:
+       return "unknown code " + c;
+     }
+   }
+ 
+   @Override
+   public String toString() {
+     StringBuffer sb = new StringBuffer();
+     sb.append("partCode=");
+     sb.append(typeCodeToString(this.typeCode));
+     sb.append(" partLength=" + getLength());
+ //    sb.append(" partBytes=");
+ //    byte[] b = getSerializedForm();
+ //    if (b == null) {
+ //      sb.append("null");
+ //    }
+ //    else {
+ //      sb.append("(");
+ //      for (int i = 0; i < b.length; i ++) {
+ //        sb.append(Integer.toString(b[i]));
+ //        sb.append(" ");
+ //      }
+ //      sb.append(")");
+ //    }
+     return sb.toString();
+   }
+ 
+   public void setVersion(Version clientVersion) {
+     this.version = clientVersion;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
index 0000000,82e8114..1975601
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
@@@ -1,0 -1,209 +1,210 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.tier.sockets.command;
+ 
+ import com.gemstone.gemfire.cache.SynchronizationCommitConflictException;
+ import com.gemstone.gemfire.cache.client.internal.TXSynchronizationOp.CompletionType;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.ReplyException;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.cache.TXCommitMessage;
+ import com.gemstone.gemfire.internal.cache.TXManagerImpl;
+ import com.gemstone.gemfire.internal.cache.TXStateProxy;
+ import com.gemstone.gemfire.internal.cache.TXSynchronizationRunnable;
+ import com.gemstone.gemfire.internal.cache.tier.Command;
+ import com.gemstone.gemfire.internal.cache.tier.MessageType;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
++import com.gemstone.gemfire.internal.cache.tier.sockets.MessageTooLargeException;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
+ 
+ import java.io.IOException;
+ import java.util.concurrent.Executor;
+ 
+ import javax.transaction.Status;
+ 
+ public class TXSynchronizationCommand extends BaseCommand {
+ 
+   private final static TXSynchronizationCommand singleton = new TXSynchronizationCommand();
+ 
+   public static Command getCommand() {
+     return singleton;
+   }
+ 
+   /* (non-Javadoc)
+    * @see com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand#shouldMasqueradeForTx(com.gemstone.gemfire.internal.cache.tier.sockets.Message, com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection)
+    */
+   @Override
+   protected boolean shouldMasqueradeForTx(Message msg, ServerConnection servConn) {
+     // masquerading is done in the waiting thread pool
+     return false;
+   }
+ 
+   /* (non-Javadoc)
+    * @see com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand#cmdExecute(com.gemstone.gemfire.internal.cache.tier.sockets.Message, com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection, long)
+    */
+   @Override
+   public void cmdExecute(final Message msg, final ServerConnection servConn, long start)
+       throws IOException, ClassNotFoundException, InterruptedException {
+     
+     servConn.setAsTrue(REQUIRES_RESPONSE);
+ 
+     CompletionType type = CompletionType.values()[msg.getPart(0).getInt()];
+     /*int txIdInt =*/ msg.getPart(1).getInt();  // [bruce] not sure if we need to transmit this
+     final Part statusPart;
+     if (type == CompletionType.AFTER_COMPLETION) {
+       statusPart = msg.getPart(2);
+     } else {
+       statusPart = null;
+     }
+     
+     final TXManagerImpl txMgr = (TXManagerImpl)servConn.getCache().getCacheTransactionManager();
+     final InternalDistributedMember member = (InternalDistributedMember)servConn.getProxyID().getDistributedMember();
+ 
+     // get the tx state without associating it with this thread.  That's done later
+     final TXStateProxy txProxy = txMgr.masqueradeAs(msg, member, true);
+     
+     // we have to run beforeCompletion and afterCompletion in the same thread
+     // because beforeCompletion obtains locks for the thread and afterCompletion
+     // releases them
+     if (txProxy != null) {
+       final boolean isDebugEnabled = logger.isDebugEnabled();
+       try {
+         if (type == CompletionType.BEFORE_COMPLETION) {
+           Runnable beforeCompletion = new Runnable() {
+                 @SuppressWarnings("synthetic-access")
+                 public void run() {
+                   TXStateProxy txState = null;
+                   Throwable failureException = null;
+                   try {
+                     txState = txMgr.masqueradeAs(msg, member, false);
+                     if (isDebugEnabled) {
+                       logger.debug("Executing beforeCompletion() notification for transaction {}", msg.getTransactionId());
+                     }
+                     txState.setIsJTA(true);
+                     txState.beforeCompletion();
+                     try {
+                       writeReply(msg, servConn);
+                     } catch (IOException e) {
+                       if (isDebugEnabled) {
+                         logger.debug("Problem writing reply to client", e);
+                       }
+                     }
+                     servConn.setAsTrue(RESPONDED);
+                   } catch (ReplyException e) {
+                     failureException = e.getCause();
+                   } catch (InterruptedException e) {
+                     Thread.currentThread().interrupt();
+                   } catch (Exception e) {
+                     failureException = e;
+                   } finally {
+                     txMgr.unmasquerade(txState);
+                   }
+                   if (failureException != null) {
+                     try {
+                       writeException(msg, failureException, false, servConn);
+                     } catch (IOException ioe) {
+                       if (isDebugEnabled) {
+                         logger.debug("Problem writing reply to client", ioe);
+                       }
+                     }
+                     servConn.setAsTrue(RESPONDED);
+                   }
+                 }
+               };
+           TXSynchronizationRunnable sync = new TXSynchronizationRunnable(beforeCompletion);
+           txProxy.setSynchronizationRunnable(sync);
+           Executor exec = InternalDistributedSystem.getConnectedInstance().getDistributionManager().getWaitingThreadPool();
+           exec.execute(sync);
+           sync.waitForFirstExecution();
+         } else {
+           Runnable afterCompletion = new Runnable() {
+                 @SuppressWarnings("synthetic-access")
+                 public void run() {
+                   TXStateProxy txState = null;
+                   try {
+                     txState = txMgr.masqueradeAs(msg, member, false);
+                     int status = statusPart.getInt();
+                     if (isDebugEnabled) {
+                       logger.debug("Executing afterCompletion({}) notification for transaction {}", status, msg.getTransactionId());
+                     }
+                     txState.setIsJTA(true);
+                     txState.afterCompletion(status);
+                     // GemFire commits during afterCompletion - send the commit info back to the client
+                     // where it can be applied to the local cache
+                     TXCommitMessage cmsg = txState.getCommitMessage();
+                     try {
+                       CommitCommand.writeCommitResponse(cmsg, msg, servConn);
+                       txMgr.removeHostedTXState(txState.getTxId());
+                     } catch (IOException e) {
+                       // not much can be done here
 -                      if (isDebugEnabled) {
 -                        logger.debug("Problem writing reply to client", e);
++                      if (isDebugEnabled || (e instanceof MessageTooLargeException)) {
++                        logger.warn("Problem writing reply to client", e);
+                       }
+                     }
+                     servConn.setAsTrue(RESPONDED);
+                   } catch (RuntimeException e) {
+                     try {
+                       writeException(msg, e, false, servConn);
+                     } catch (IOException ioe) {
+                       if (isDebugEnabled) {
+                         logger.debug("Problem writing reply to client", ioe);
+                       }
+                     }
+                     servConn.setAsTrue(RESPONDED);
+                   } catch (InterruptedException e) {
+                     Thread.currentThread().interrupt();
+                   } finally {
+                     txMgr.unmasquerade(txState);
+                   }
+                 }
+               };
+           // if there was a beforeCompletion call then there will be a thread
+           // sitting in the waiting pool to execute afterCompletion.  Otherwise
+           // we have failed-over and may need to do beforeCompletion & hope that it works
+           TXSynchronizationRunnable sync = txProxy.getSynchronizationRunnable();
+           if (sync != null) {
+             sync.runSecondRunnable(afterCompletion);
+           } else {
+             if (statusPart.getInt() == Status.STATUS_COMMITTED) {
+               TXStateProxy txState = txMgr.masqueradeAs(msg, member, false);
+               try {
+                 if (isDebugEnabled) {
+                   logger.debug("Executing beforeCompletion() notification for transaction {} after failover", msg.getTransactionId());
+                 }
+                 txState.setIsJTA(true);
+                 txState.beforeCompletion();
+               } finally {
+                 txMgr.unmasquerade(txState);
+               }
+             }
+             afterCompletion.run();
+           }
+         }
+       } catch (Exception e) {
+         writeException(msg, MessageType.EXCEPTION, e, false, servConn);
+         servConn.setAsTrue(RESPONDED);
+       }
+       if (isDebugEnabled) {
+         logger.debug("Sent tx synchronization response");
+       }
+     }
+   }
+ 
+ }


[054/100] [abbrv] incubator-geode git commit: GEODE-829: pulse gradle uses the dependency versions in the property file

Posted by ud...@apache.org.
GEODE-829: pulse gradle uses the dependency versions in the property file


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/01c0a2c5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/01c0a2c5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/01c0a2c5

Branch: refs/heads/feature/GEODE-870
Commit: 01c0a2c547b8c8f254b52ae024469c201ef789d5
Parents: 53b6319
Author: Jinmei Liao <ji...@pivotal.io>
Authored: Fri Feb 19 12:47:11 2016 -0800
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Fri Feb 19 13:16:32 2016 -0800

----------------------------------------------------------------------
 gemfire-pulse/build.gradle            | 68 +++++++++++-------------------
 gradle/dependency-versions.properties |  9 ++++
 2 files changed, 34 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/01c0a2c5/gemfire-pulse/build.gradle
----------------------------------------------------------------------
diff --git a/gemfire-pulse/build.gradle b/gemfire-pulse/build.gradle
index c13efa2..4e8d982 100755
--- a/gemfire-pulse/build.gradle
+++ b/gemfire-pulse/build.gradle
@@ -14,18 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-buildscript {
-  repositories {
-    maven {
-      url "https://plugins.gradle.org/m2/"
-    }
-  }
-  dependencies {
-    classpath "org.ajoberstar:gradle-git:1.3.2"
-  }
-}
-
 apply plugin: 'war'
 
 sourceSets {
@@ -38,41 +26,35 @@ sourceSets {
 }
 
 dependencies {
-  compile 'org.apache.commons:com.springsource.org.apache.commons.beanutils:1.8.0'
-  compile 'org.apache.commons:com.springsource.org.apache.commons.collections:3.2.0'
-  compile 'org.apache.commons:com.springsource.org.apache.commons.digester:1.8.1'
-  compile 'org.apache.commons:com.springsource.org.apache.commons.logging:1.1.1'
-  compile 'commons-lang:commons-lang:2.6'
-  compile 'org.springframework.ldap:spring-ldap-core:1.3.2.RELEASE'
-  compile 'org.springframework.security:spring-security-config:3.1.7.RELEASE'
-  compile 'org.springframework.security:spring-security-core:3.1.7.RELEASE'
-  compile 'org.springframework.security:spring-security-ldap:3.1.7.RELEASE'
-  compile 'org.springframework.security:spring-security-web:3.1.7.RELEASE'
-  compile 'org.springframework:spring-tx:3.2.12.RELEASE'
-
-  providedCompile 'commons-logging:commons-logging:1.1.3'
-  providedCompile 'commons-codec:commons-codec:1.6'
-  providedCompile 'org.apache.httpcomponents:fluent-hc:4.3.3'
-  providedCompile 'org.apache.httpcomponents:httpclient:4.3.3'
-  providedCompile 'org.apache.httpcomponents:httpclient-cache:4.3.3'
-  providedCompile 'org.apache.httpcomponents:httpcore:4.3.2'
-  providedCompile 'org.apache.httpcomponents:httpmime:4.3.3'
-
-  provided 'org.mortbay.jetty:servlet-api:2.5-20081211'
-  provided 'com.google.guava:guava:15.0'
+  compile 'commons-beanutils:commons-beanutils:'+project.'commons-beanutils.version'
+  compile 'commons-collections:commons-collections:'+project.'commons-collections.version'
+  compile 'commons-digester:commons-digester:'+project.'commons-digester.version'
+  compile 'commons-lang:commons-lang:'+project.'commons-lang.version'
+  compile 'org.springframework.ldap:spring-ldap-core:'+project.'spring-ldap-core.version'
+  compile 'org.springframework.security:spring-security-config:'+project.'spring-security.version'
+  compile 'org.springframework.security:spring-security-core:'+project.'spring-security.version'
+  compile 'org.springframework.security:spring-security-ldap:'+project.'spring-security.version'
+  compile 'org.springframework.security:spring-security-web:'+project.'spring-security.version'
+  compile 'org.springframework:spring-tx:'+project.'spring-tx.version'
+
+  providedCompile 'commons-logging:commons-logging:'+project.'commons-logging.version'
+
+  provided 'org.mortbay.jetty:servlet-api:'+project.'mortbay-jetty-servlet-api.version'
+  provided 'com.google.guava:guava:'+project.'guava.version'
 
   testCompile project(':gemfire-junit')
 
-  testCompile 'org.apache.tomcat.embed:tomcat-embed-core:7.0.30'
-  testCompile 'org.apache.tomcat.embed:tomcat-embed-jasper:7.0.30'
-  testCompile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:7.0.30'
-  testCompile 'org.seleniumhq.selenium:selenium-firefox-driver:2.52.0'
-  testCompile 'org.seleniumhq.selenium:selenium-api:2.52.0'
-  testCompile 'org.seleniumhq.selenium:selenium-remote-driver:2.52.0'
-  testCompile 'org.seleniumhq.selenium:selenium-support:2.52.0'
+  testCompile 'org.apache.tomcat.embed:tomcat-embed-core:'+project.'tomcat7.version'
+  testCompile 'org.apache.tomcat.embed:tomcat-embed-jasper:'+project.'tomcat7.version'
+  testCompile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:'+project.'tomcat7.version'
+  testCompile 'org.seleniumhq.selenium:selenium-firefox-driver:'+project.'selenium.version'
+  testCompile 'org.seleniumhq.selenium:selenium-api:'+project.'selenium.version'
+  testCompile 'org.seleniumhq.selenium:selenium-remote-driver:'+project.'selenium.version'
+  testCompile 'org.seleniumhq.selenium:selenium-support:'+project.'selenium.version'
+
+  testRuntime 'com.google.code.gson:gson:'+project.'google-gson.version'
+  testRuntime 'org.apache.commons:commons-exec:'+project.'commons-exec.version'
 
-  testRuntime 'com.google.code.gson:gson:2.3.1'
-  testRuntime 'org.apache.commons:commons-exec:1.3'
 }
 
 def generatedResources = "$buildDir/generated-resources/main"

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/01c0a2c5/gradle/dependency-versions.properties
----------------------------------------------------------------------
diff --git a/gradle/dependency-versions.properties b/gradle/dependency-versions.properties
index 6aa7023..611ee7a 100644
--- a/gradle/dependency-versions.properties
+++ b/gradle/dependency-versions.properties
@@ -33,6 +33,9 @@ commons-io.version = 2.3
 commons-lang.version = 2.5
 commons-logging.version = 1.1.1
 commons-modeler.version = 2.0
+commons-beanutils.version = 1.8.0
+commons-digester.version=2.1
+commons-exec.version=1.3
 derby.version = 10.2.2.0
 dom4j.version = 1.6.1
 fastutil.version = 7.0.2
@@ -83,6 +86,9 @@ spring-data-commons.version = 1.9.1.RELEASE
 spring-data-gemfire.version = 1.7.2.RELEASE
 spring-hateos.version = 0.16.0.RELEASE
 spring-shell.version = 1.1.0.RELEASE
+spring-ldap-core.version = 1.3.2.RELEASE
+spring-security.version = 3.1.7.RELEASE
+spring-tx.version = 3.2.12.RELEASE
 springframework.version = 4.2.4.RELEASE
 stephenc-findbugs.version = 1.3.9-1
 spymemcached.version = 2.9.0
@@ -92,3 +98,6 @@ system-rules.version = 1.15.0
 tempus-fugit.version = 1.1
 tomcat6.version = 6.0.37
 tomcat7.version = 7.0.30
+mortbay-jetty-servlet-api.version=2.5-20081211
+selenium.version=2.52.0
+google-gson.version=2.3.1
\ No newline at end of file


[012/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/ConcurrentIndexInitOnOverflowRegionDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/ConcurrentIndexInitOnOverflowRegionDUnitTest.java
index 5528299,0000000..ca90f00
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/ConcurrentIndexInitOnOverflowRegionDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/ConcurrentIndexInitOnOverflowRegionDUnitTest.java
@@@ -1,468 -1,0 +1,467 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.internal.index;
 +
 +import java.io.IOException;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.DiskStore;
 +import com.gemstone.gemfire.cache.EvictionAction;
 +import com.gemstone.gemfire.cache.EvictionAlgorithm;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.data.Portfolio;
 +import com.gemstone.gemfire.cache.query.data.PortfolioData;
 +import com.gemstone.gemfire.cache.query.internal.index.IndexManager.TestHook;
 +import com.gemstone.gemfire.cache.query.partitioned.PRQueryDUnitHelper;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +
 +/**
 + * @author shobhit
 + * 
 + */
 +public class ConcurrentIndexInitOnOverflowRegionDUnitTest extends CacheTestCase {
 +
 +  PRQueryDUnitHelper PRQHelp = new PRQueryDUnitHelper("");
 +
 +  String name;
 +
 +  final int redundancy = 0;
 +
 +  private int cnt = 0;
 +
 +  private int cntDest = 1;
 +
 +  public static volatile boolean hooked = false;
 +
 +  private static int bridgeServerPort;
 +  
 +  /**
 +   * @param name
 +   */
 +  public ConcurrentIndexInitOnOverflowRegionDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  /**
 +  *
 +  */
 +  public void testAsyncIndexInitDuringEntryDestroyAndQueryOnRR() {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +
 +    name = "PartionedPortfoliosPR";
 +    // Create Overflow Persistent Partition Region
 +    vm0.invoke(new CacheSerializableRunnable(
 +        "Create local region with synchronous index maintenance") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = PRQHelp.getCache();
 +        Region partitionRegion = null;
 +        IndexManager.testHook = null;
 +        try {
 +          DiskStore ds = cache.findDiskStore("disk");
 +          if (ds == null) {
 +            ds = cache.createDiskStoreFactory().setDiskDirs(getDiskDirs())
 +                .create("disk");
 +          }
 +          AttributesFactory attr = new AttributesFactory();
 +          attr.setValueConstraint(PortfolioData.class);
 +          attr.setIndexMaintenanceSynchronous(true);
 +          EvictionAttributesImpl evicAttr = new EvictionAttributesImpl()
 +              .setAction(EvictionAction.OVERFLOW_TO_DISK);
 +          evicAttr.setAlgorithm(EvictionAlgorithm.LRU_ENTRY).setMaximum(1);
 +          attr.setEvictionAttributes(evicAttr);
 +          attr.setDataPolicy(DataPolicy.REPLICATE);
 +          // attr.setPartitionAttributes(new
 +          // PartitionAttributesFactory().setTotalNumBuckets(1).create());
 +          attr.setDiskStoreName("disk");
 +          RegionFactory regionFactory = cache.createRegionFactory(attr.create());
 +          partitionRegion = regionFactory.create(name);
 +        } catch (IllegalStateException ex) {
 +          LogWriterUtils.getLogWriter().warning("Creation caught IllegalStateException", ex);
 +        }
 +        assertNotNull("Region " + name + " not in cache", cache.getRegion(name));
 +        assertNotNull("Region ref null", partitionRegion);
 +        assertTrue("Region ref claims to be destroyed",
 +            !partitionRegion.isDestroyed());
 +        // Create Indexes
 +        try {
 +          Index index = cache.getQueryService().createIndex("statusIndex",
 +              "p.status", "/" + name + " p");
 +          assertNotNull(index);
 +        } catch (Exception e1) {
 +          e1.printStackTrace();
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +
 +    // Start changing the value in Region which should turn into a deadlock if
 +    // the fix is not there
 +    AsyncInvocation asyncInv1 = vm0.invokeAsync(new CacheSerializableRunnable(
 +        "Change value in region") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = PRQHelp.getCache();
 +
 +        // Do a put in region.
 +        Region r = PRQHelp.getCache().getRegion(name);
 +
 +        for (int i = 0; i < 100; i++) {
 +          r.put(i, new PortfolioData(i));
 +        }
 +
 +        assertNull(IndexManager.testHook);
 +        IndexManager.testHook = new IndexManagerTestHook();
 +
 +        // Destroy one of the values.
 +        PRQHelp.getCache().getLogger().fine("Destroying the value");
 +        r.destroy(1);
 +
 +        IndexManager.testHook = null;
 +      }
 +    });
 +
 +    AsyncInvocation asyncInv2 = vm0.invokeAsync(new CacheSerializableRunnable(
 +        "Run query on region") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = PRQHelp.getCache();
 +
 +        while (!hooked) {
 +          Wait.pause(100);
 +        }
 +        // Create and hence initialize Index
 +        try {
 +          Index index = cache.getQueryService().createIndex("idIndex",
 +              "p.ID", "/" + name + " p");
 +          assertNotNull(index);
 +        } catch (Exception e1) {
 +          e1.printStackTrace();
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +
 +    // If we take more than 30 seconds then its a deadlock.
 +    ThreadUtils.join(asyncInv2, 30 * 1000);
 +    ThreadUtils.join(asyncInv1, 30 * 1000);
 +  }
 +
 +  /**
 +  *
 +  */
 +  public void testAsyncIndexInitDuringEntryPutUsingClientOnRR() {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    
 +    IgnoredException.addIgnoredException("Unexpected IOException:");
 +    IgnoredException.addIgnoredException("java.net.SocketException");
 +
 +    name = "PartionedPortfoliosPR";
 +    // Create Overflow Persistent Partition Region
 +    vm0.invoke(new CacheSerializableRunnable(
 +        "Create local region with synchronous index maintenance") {
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = PRQHelp.getCache();
 +        
 +        Region partitionRegion = null;
 +        IndexManager.testHook = null;
 +        try {
 +          CacheServer bridge = cache.addCacheServer();
 +          bridge.setPort(0);
 +          bridge.start();
 +          bridgeServerPort = bridge.getPort();
 +          
 +          DiskStore ds = cache.findDiskStore("disk");
 +          if (ds == null) {
 +            ds = cache.createDiskStoreFactory().setDiskDirs(getDiskDirs())
 +                .create("disk");
 +          }
 +          AttributesFactory attr = new AttributesFactory();
 +          attr.setValueConstraint(PortfolioData.class);
 +          attr.setIndexMaintenanceSynchronous(true);
 +          EvictionAttributesImpl evicAttr = new EvictionAttributesImpl()
 +              .setAction(EvictionAction.OVERFLOW_TO_DISK);
 +          evicAttr.setAlgorithm(EvictionAlgorithm.LRU_ENTRY).setMaximum(1);
 +          attr.setEvictionAttributes(evicAttr);
 +          attr.setDataPolicy(DataPolicy.REPLICATE);
 +          // attr.setPartitionAttributes(new
 +          // PartitionAttributesFactory().setTotalNumBuckets(1).create());
 +          attr.setDiskStoreName("disk");
 +          RegionFactory regionFactory = cache.createRegionFactory(attr.create());
 +          partitionRegion = regionFactory.create(name);
 +        } catch (IllegalStateException ex) {
 +          LogWriterUtils.getLogWriter().warning("Creation caught IllegalStateException", ex);
 +        } catch (IOException e) {
 +          e.printStackTrace();
 +        }
 +        assertNotNull("Region " + name + " not in cache", cache.getRegion(name));
 +        assertNotNull("Region ref null", partitionRegion);
 +        assertTrue("Region ref claims to be destroyed", !partitionRegion.isDestroyed());
 +        // Create Indexes
 +        try {
 +          Index index = cache.getQueryService().createIndex("idIndex",
 +              "p.ID", "/" + name + " p");
 +          assertNotNull(index);
 +        } catch (Exception e1) {
 +          e1.printStackTrace();
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +
 +    
-     final int port = vm0.invokeInt(ConcurrentIndexInitOnOverflowRegionDUnitTest.class,
-     "getCacheServerPort");
++    final int port = vm0.invoke(() -> ConcurrentIndexInitOnOverflowRegionDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +
 +    // Start changing the value in Region which should turn into a deadlock if
 +    // the fix is not there
 +    vm1.invoke(new CacheSerializableRunnable(
 +        "Change value in region") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        disconnectFromDS();
 +        ClientCache clientCache = new ClientCacheFactory().addPoolServer(host0, port).create();
 +
 +        // Do a put in region.
 +        Region r = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(name);
 +
 +        for (int i = 0; i < 100; i++) {
 +          r.put(i, new PortfolioData(i));
 +        }
 +      }
 +    });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Set Test Hook") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        // Set test hook before client operation
 +        assertNull(IndexManager.testHook);
 +        IndexManager.testHook = new IndexManagerTestHook();
 +      }
 +    });
 +
 +    AsyncInvocation asyncInv1 = vm1.invokeAsync(new CacheSerializableRunnable("Change value in region") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        ClientCache clientCache = ClientCacheFactory.getAnyInstance();
 +
 +        // Do a put in region.
 +        Region r = clientCache.getRegion(name);
 +
 +        // Destroy one of the values.
 +        clientCache.getLogger().fine("Destroying the value");
 +        r.destroy(1);
 +      }
 +    });
 +
 +    AsyncInvocation asyncInv2 = vm0.invokeAsync(new CacheSerializableRunnable(
 +        "Run query on region") {
 +
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = PRQHelp.getCache();
 +
 +        while (!hooked) {
 +          Wait.pause(100);
 +        }
 +        // Create Indexes
 +        try {
 +          Index index = cache.getQueryService().createIndex("statusIndex",
 +              "p.status", "/" + name + " p");
 +          assertNotNull(index);
 +        } catch (Exception e1) {
 +          e1.printStackTrace();
 +          fail("Index creation failed");
 +        }
 +      }
 +    });
 +
 +    // If we take more than 30 seconds then its a deadlock.
 +    ThreadUtils.join(asyncInv2, 30 * 1000);
 +    ThreadUtils.join(asyncInv1, 30 * 1000);
 +    
 +    vm0.invoke(new CacheSerializableRunnable("Set Test Hook") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        assertNotNull(IndexManager.testHook);
 +        IndexManager.testHook = null;
 +      }
 +    });
 +
 +  }
 +
 +  /**
 +   * This tests if index updates are blocked while region.clear() is
 +   * called and indexes are being reinitialized.
 +   */
 +  public void testIndexUpdateWithRegionClear() {
 +    
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +
 +    final String regionName = "portfolio";
 +    
 +    hooked = false;
 +    
 +    // Create region and an index on it
 +    vm0.invoke(new CacheSerializableRunnable("Create region and index") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Cache cache = PRQHelp.getCache();
 +        Region region = cache.createRegionFactory(RegionShortcut.LOCAL).create(regionName);
 +        QueryService qService = cache.getQueryService();
 +        
 +        try {
 +          qService.createIndex("idIndex", "ID", "/"+regionName);
 +          qService.createIndex("secIdIndex", "pos.secId", "/" + regionName + " p, p.positions.values pos");
 +        } catch (Exception e) {
 +          fail("Index creation failed." + e);
 +        }
 +      }
 +    });
 +
 +    final class LocalTestHook implements TestHook {
 +
 +      @Override
 +      public void hook(int spot) throws RuntimeException {
 +        switch (spot) {
 +        case 6: // processAction in IndexManager
 +          hooked = true;
 +          //wait untill some thread unhooks.
 +          while (hooked) { Wait.pause(20); }
 +          break;
 +        default:
 +          break;
 +        }
 +      }
 +      
 +    }
 +    
 +    // Asynch invocation for continuous index updates
 +    AsyncInvocation indexUpdateAsysnch = vm0.invokeAsync(new CacheSerializableRunnable("index updates") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        
 +        Region region = PRQHelp.getCache().getRegion(regionName);
 +        for (int i=0; i<100; i++) {
 +          if (i == 50) IndexManager.testHook = new LocalTestHook();
 +          region.put(i, new Portfolio(i));
 +          if (i == 50) Wait.pause(20);
 +        }
 +      }
 +    });
 + 
 +    // Region.clear() which should block other region updates.
 +    vm0.invoke(new CacheSerializableRunnable("Clear the region") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region region = PRQHelp.getCache().getRegion(regionName);
 +        
 +        while(!hooked) {
 +          Wait.pause(100);
 +        }
 +        if (hooked) {
 +          hooked = false;
 +          IndexManager.testHook = null;
 +          region.clear();
 +        }
 +
 +        try {
 +            QueryService qservice = PRQHelp.getCache().getQueryService();
 +            Index index = qservice.getIndex(region, "idIndex");
 +            if (((CompactRangeIndex)index).getIndexStorage().size() > 1) {
 +              fail("After clear region size is supposed to be zero as all index updates are blocked. Current region size is: "+ region.size());
 +            }
 +        } finally {
 +          IndexManager.testHook = null;  
 +        }
 +      }
 +    });
 +
 +    // Kill asynch thread
 +    ThreadUtils.join(indexUpdateAsysnch, 20000);
 +
 +    //Verify region size which must be 50
 +    vm0.invoke(new CacheSerializableRunnable("Check region size") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region region = PRQHelp.getCache().getRegion(regionName);
 +        if (region.size() > 50) {
 +          fail("After clear region size is supposed to be 50 as all index updates are blocked " + region.size());
 +        }
 +      }
 +    });
 +  }
 +
 +  public class IndexManagerTestHook implements
 +      com.gemstone.gemfire.cache.query.internal.index.IndexManager.TestHook {
 +    public void hook(final int spot) throws RuntimeException {
 +      switch (spot) {
 +      case 6: // Before Index update and after region entry lock.
 +        hooked = true;
 +        LogWriterUtils.getLogWriter().fine("IndexManagerTestHook is hooked.");
 +        Wait.pause(10000);
 +        hooked = false;
 +        break;
 +      default:
 +        break;
 +      }
 +    }
 +  }
 +
 +  private static int getCacheServerPort() {
 +    return bridgeServerPort;
 +  }
 +}


[060/100] [abbrv] incubator-geode git commit: Fixing a couple of a files that were renamed to directories

Posted by ud...@apache.org.
Fixing a couple of a files that were renamed to directories

These two files should have been moved to the appropriate directory
under geode-core. Instead, the file was moved to a file named after the
directory.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/9eb7a058
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/9eb7a058
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/9eb7a058

Branch: refs/heads/feature/GEODE-870
Commit: 9eb7a058ed83e3e0b4351db6502cce4dc6cfdc8f
Parents: 5beaaed
Author: Dan Smith <up...@apache.org>
Authored: Fri Feb 19 17:12:56 2016 -0800
Committer: Dan Smith <up...@apache.org>
Committed: Fri Feb 19 17:12:56 2016 -0800

----------------------------------------------------------------------
 .../gemstone/gemfire/management/internal/beans  | 106 -------------------
 .../beans/DistributedSystemBridgeJUnitTest.java | 106 +++++++++++++++++++
 .../test/java/com/gemstone/gemfire/test/fake    |  99 -----------------
 .../com/gemstone/gemfire/test/fake/Fakes.java   |  99 +++++++++++++++++
 4 files changed, 205 insertions(+), 205 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9eb7a058/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans
deleted file mode 100644
index 84b39d4..0000000
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans
+++ /dev/null
@@ -1,106 +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 com.gemstone.gemfire.management.internal.beans;
-
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.*;
-
-import java.io.IOException;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.InOrder;
-
-import com.gemstone.gemfire.admin.internal.BackupDataStoreHelper;
-import com.gemstone.gemfire.admin.internal.FinishBackupRequest;
-import com.gemstone.gemfire.admin.internal.PrepareBackupRequest;
-import com.gemstone.gemfire.distributed.internal.DM;
-import com.gemstone.gemfire.distributed.internal.locks.DLockService;
-import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
-import com.gemstone.gemfire.internal.cache.persistence.BackupManager;
-import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberManager;
-import com.gemstone.gemfire.test.fake.Fakes;
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class DistributedSystemBridgeJUnitTest {
-  
-  private GemFireCacheImpl cache;
-  private BackupManager backupManager;
-
-  @Before
-  public void createCache() throws IOException {
-    cache = Fakes.cache();
-    PersistentMemberManager memberManager = mock(PersistentMemberManager.class);
-    backupManager = mock(BackupManager.class);
-    when(cache.startBackup(any())).thenReturn(backupManager);
-    when(cache.getPersistentMemberManager()).thenReturn(memberManager);
-    when(cache.getBackupManager()).thenReturn(backupManager);
-    
-    DLockService dlock = mock(DLockService.class);
-    when(dlock.lock(any(), anyLong(), anyLong())).thenReturn(true);
-    
-    DLockService.addLockServiceForTests(BackupDataStoreHelper.LOCK_SERVICE_NAME, dlock);
-    GemFireCacheImpl.setInstanceForTests(cache);
-  }
-  
-  @After
-  public void clearCache() {
-    GemFireCacheImpl.setInstanceForTests(null);
-    DLockService.removeLockServiceForTests(BackupDataStoreHelper.LOCK_SERVICE_NAME);
-  }
-  
-  @Test
-  public void testSucessfulBackup() throws Exception {
-    DM dm = cache.getDistributionManager();
-    
-    DistributedSystemBridge bridge = new DistributedSystemBridge(null);
-    bridge.backupAllMembers("/tmp", null);
-    
-    InOrder inOrder = inOrder(dm, backupManager);
-    inOrder.verify(dm).putOutgoing(isA(PrepareBackupRequest.class));
-    inOrder.verify(backupManager).prepareBackup();
-    inOrder.verify(dm).putOutgoing(isA(FinishBackupRequest.class));
-    inOrder.verify(backupManager).finishBackup(any(), any(), eq(false));
-  }
-
-  @Test
-  public void testPrepareErrorAbortsBackup() throws Exception {
-    DM dm = cache.getDistributionManager();
-    PersistentMemberManager memberManager = mock(PersistentMemberManager.class);
-    BackupManager backupManager = mock(BackupManager.class);
-    when(cache.startBackup(any())).thenReturn(backupManager);
-    when(cache.getPersistentMemberManager()).thenReturn(memberManager);
-    when(cache.getBackupManager()).thenReturn(backupManager);
-    when(dm.putOutgoing(isA(PrepareBackupRequest.class))).thenThrow(new RuntimeException("Fail the prepare"));
-    
-    
-    DistributedSystemBridge bridge = new DistributedSystemBridge(null);
-    try {
-      bridge.backupAllMembers("/tmp", null);
-      fail("Should have failed with an exception");
-    } catch(RuntimeException expected) {
-      
-    }
-    
-    verify(dm).putOutgoing(isA(FinishBackupRequest.class));
-    verify(backupManager).finishBackup(any(), any(), eq(true));
-  }
-}
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java
new file mode 100644
index 0000000..84b39d4
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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 com.gemstone.gemfire.management.internal.beans;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.io.IOException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.InOrder;
+
+import com.gemstone.gemfire.admin.internal.BackupDataStoreHelper;
+import com.gemstone.gemfire.admin.internal.FinishBackupRequest;
+import com.gemstone.gemfire.admin.internal.PrepareBackupRequest;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.locks.DLockService;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.persistence.BackupManager;
+import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberManager;
+import com.gemstone.gemfire.test.fake.Fakes;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class DistributedSystemBridgeJUnitTest {
+  
+  private GemFireCacheImpl cache;
+  private BackupManager backupManager;
+
+  @Before
+  public void createCache() throws IOException {
+    cache = Fakes.cache();
+    PersistentMemberManager memberManager = mock(PersistentMemberManager.class);
+    backupManager = mock(BackupManager.class);
+    when(cache.startBackup(any())).thenReturn(backupManager);
+    when(cache.getPersistentMemberManager()).thenReturn(memberManager);
+    when(cache.getBackupManager()).thenReturn(backupManager);
+    
+    DLockService dlock = mock(DLockService.class);
+    when(dlock.lock(any(), anyLong(), anyLong())).thenReturn(true);
+    
+    DLockService.addLockServiceForTests(BackupDataStoreHelper.LOCK_SERVICE_NAME, dlock);
+    GemFireCacheImpl.setInstanceForTests(cache);
+  }
+  
+  @After
+  public void clearCache() {
+    GemFireCacheImpl.setInstanceForTests(null);
+    DLockService.removeLockServiceForTests(BackupDataStoreHelper.LOCK_SERVICE_NAME);
+  }
+  
+  @Test
+  public void testSucessfulBackup() throws Exception {
+    DM dm = cache.getDistributionManager();
+    
+    DistributedSystemBridge bridge = new DistributedSystemBridge(null);
+    bridge.backupAllMembers("/tmp", null);
+    
+    InOrder inOrder = inOrder(dm, backupManager);
+    inOrder.verify(dm).putOutgoing(isA(PrepareBackupRequest.class));
+    inOrder.verify(backupManager).prepareBackup();
+    inOrder.verify(dm).putOutgoing(isA(FinishBackupRequest.class));
+    inOrder.verify(backupManager).finishBackup(any(), any(), eq(false));
+  }
+
+  @Test
+  public void testPrepareErrorAbortsBackup() throws Exception {
+    DM dm = cache.getDistributionManager();
+    PersistentMemberManager memberManager = mock(PersistentMemberManager.class);
+    BackupManager backupManager = mock(BackupManager.class);
+    when(cache.startBackup(any())).thenReturn(backupManager);
+    when(cache.getPersistentMemberManager()).thenReturn(memberManager);
+    when(cache.getBackupManager()).thenReturn(backupManager);
+    when(dm.putOutgoing(isA(PrepareBackupRequest.class))).thenThrow(new RuntimeException("Fail the prepare"));
+    
+    
+    DistributedSystemBridge bridge = new DistributedSystemBridge(null);
+    try {
+      bridge.backupAllMembers("/tmp", null);
+      fail("Should have failed with an exception");
+    } catch(RuntimeException expected) {
+      
+    }
+    
+    verify(dm).putOutgoing(isA(FinishBackupRequest.class));
+    verify(backupManager).finishBackup(any(), any(), eq(true));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9eb7a058/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java
new file mode 100644
index 0000000..84b39d4
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/beans/DistributedSystemBridgeJUnitTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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 com.gemstone.gemfire.management.internal.beans;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.io.IOException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.InOrder;
+
+import com.gemstone.gemfire.admin.internal.BackupDataStoreHelper;
+import com.gemstone.gemfire.admin.internal.FinishBackupRequest;
+import com.gemstone.gemfire.admin.internal.PrepareBackupRequest;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.locks.DLockService;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.persistence.BackupManager;
+import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberManager;
+import com.gemstone.gemfire.test.fake.Fakes;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class DistributedSystemBridgeJUnitTest {
+  
+  private GemFireCacheImpl cache;
+  private BackupManager backupManager;
+
+  @Before
+  public void createCache() throws IOException {
+    cache = Fakes.cache();
+    PersistentMemberManager memberManager = mock(PersistentMemberManager.class);
+    backupManager = mock(BackupManager.class);
+    when(cache.startBackup(any())).thenReturn(backupManager);
+    when(cache.getPersistentMemberManager()).thenReturn(memberManager);
+    when(cache.getBackupManager()).thenReturn(backupManager);
+    
+    DLockService dlock = mock(DLockService.class);
+    when(dlock.lock(any(), anyLong(), anyLong())).thenReturn(true);
+    
+    DLockService.addLockServiceForTests(BackupDataStoreHelper.LOCK_SERVICE_NAME, dlock);
+    GemFireCacheImpl.setInstanceForTests(cache);
+  }
+  
+  @After
+  public void clearCache() {
+    GemFireCacheImpl.setInstanceForTests(null);
+    DLockService.removeLockServiceForTests(BackupDataStoreHelper.LOCK_SERVICE_NAME);
+  }
+  
+  @Test
+  public void testSucessfulBackup() throws Exception {
+    DM dm = cache.getDistributionManager();
+    
+    DistributedSystemBridge bridge = new DistributedSystemBridge(null);
+    bridge.backupAllMembers("/tmp", null);
+    
+    InOrder inOrder = inOrder(dm, backupManager);
+    inOrder.verify(dm).putOutgoing(isA(PrepareBackupRequest.class));
+    inOrder.verify(backupManager).prepareBackup();
+    inOrder.verify(dm).putOutgoing(isA(FinishBackupRequest.class));
+    inOrder.verify(backupManager).finishBackup(any(), any(), eq(false));
+  }
+
+  @Test
+  public void testPrepareErrorAbortsBackup() throws Exception {
+    DM dm = cache.getDistributionManager();
+    PersistentMemberManager memberManager = mock(PersistentMemberManager.class);
+    BackupManager backupManager = mock(BackupManager.class);
+    when(cache.startBackup(any())).thenReturn(backupManager);
+    when(cache.getPersistentMemberManager()).thenReturn(memberManager);
+    when(cache.getBackupManager()).thenReturn(backupManager);
+    when(dm.putOutgoing(isA(PrepareBackupRequest.class))).thenThrow(new RuntimeException("Fail the prepare"));
+    
+    
+    DistributedSystemBridge bridge = new DistributedSystemBridge(null);
+    try {
+      bridge.backupAllMembers("/tmp", null);
+      fail("Should have failed with an exception");
+    } catch(RuntimeException expected) {
+      
+    }
+    
+    verify(dm).putOutgoing(isA(FinishBackupRequest.class));
+    verify(backupManager).finishBackup(any(), any(), eq(true));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9eb7a058/geode-core/src/test/java/com/gemstone/gemfire/test/fake
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/fake b/geode-core/src/test/java/com/gemstone/gemfire/test/fake
deleted file mode 100644
index ffb4896..0000000
--- a/geode-core/src/test/java/com/gemstone/gemfire/test/fake
+++ /dev/null
@@ -1,99 +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 com.gemstone.gemfire.test.fake;
-
-import static org.mockito.Mockito.*;
-
-import java.net.UnknownHostException;
-
-import org.junit.Assert;
-
-import com.gemstone.gemfire.CancelCriterion;
-import com.gemstone.gemfire.distributed.internal.DistributionConfig;
-import com.gemstone.gemfire.distributed.internal.DistributionManager;
-import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
-import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
-import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
-
-/**
- * Factory methods for fake objects for use in test.
- * 
- * These fakes are essentially mock objects with some limited
- * functionality. For example the fake cache can return a fake
- * distributed system.
- * 
- * All of the fakes returned by this class are Mockito.mocks, so
- * they can be modified by using Mockito stubbing, ie
- * 
- * <pre>
- * cache = Fakes.cache();
- * Mockito.when(cache.getName()).thenReturn(...)
- * <pre>
- * 
- * Please help extend this class by adding other commonly
- * used objects to this collection of fakes.
- */
-public class Fakes {
-  
-  /**
-   * A fake cache, which contains a fake distributed
-   * system, distribution manager, etc.
-   */
-  public static GemFireCacheImpl cache() {
-    GemFireCacheImpl cache = mock(GemFireCacheImpl.class);
-    InternalDistributedSystem system = mock(InternalDistributedSystem.class);
-    DistributionConfig config = mock(DistributionConfig.class);
-    DistributionManager distributionManager = mock(DistributionManager.class);
-    CancelCriterion systemCancelCriterion = mock(CancelCriterion.class);
-    
-    InternalDistributedMember member;
-    try {
-      member = new InternalDistributedMember("localhost", 5555);
-    } catch (UnknownHostException e) {
-      throw new RuntimeException(e);
-    }
-    
-    
-    when(cache.getDistributedSystem()).thenReturn(system);
-    when(cache.getMyId()).thenReturn(member);
-    when(cache.getDistributionManager()).thenReturn(distributionManager);
-    when(cache.getCancelCriterion()).thenReturn(systemCancelCriterion);
-    
-    when(system.getDistributedMember()).thenReturn(member);
-    when(system.getConfig()).thenReturn(config);
-    when(system.getDistributionManager()).thenReturn(distributionManager);
-    when(system.getCancelCriterion()).thenReturn(systemCancelCriterion);
-    
-    when(distributionManager.getId()).thenReturn(member);
-    when(distributionManager.getConfig()).thenReturn(config);
-    when(distributionManager.getSystem()).thenReturn(system);
-    when(distributionManager.getCancelCriterion()).thenReturn(systemCancelCriterion);
-    
-    return cache;
-  }
-
-  /**
-   * A fake distributed system, which contains a fake distribution manager.
-   */
-  public static InternalDistributedSystem distributedSystem() {
-    return cache().getDistributedSystem();
-  }
-
-  private Fakes() {
-  }
-
-}
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java b/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java
new file mode 100644
index 0000000..ffb4896
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java
@@ -0,0 +1,99 @@
+/*
+ * 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 com.gemstone.gemfire.test.fake;
+
+import static org.mockito.Mockito.*;
+
+import java.net.UnknownHostException;
+
+import org.junit.Assert;
+
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+
+/**
+ * Factory methods for fake objects for use in test.
+ * 
+ * These fakes are essentially mock objects with some limited
+ * functionality. For example the fake cache can return a fake
+ * distributed system.
+ * 
+ * All of the fakes returned by this class are Mockito.mocks, so
+ * they can be modified by using Mockito stubbing, ie
+ * 
+ * <pre>
+ * cache = Fakes.cache();
+ * Mockito.when(cache.getName()).thenReturn(...)
+ * <pre>
+ * 
+ * Please help extend this class by adding other commonly
+ * used objects to this collection of fakes.
+ */
+public class Fakes {
+  
+  /**
+   * A fake cache, which contains a fake distributed
+   * system, distribution manager, etc.
+   */
+  public static GemFireCacheImpl cache() {
+    GemFireCacheImpl cache = mock(GemFireCacheImpl.class);
+    InternalDistributedSystem system = mock(InternalDistributedSystem.class);
+    DistributionConfig config = mock(DistributionConfig.class);
+    DistributionManager distributionManager = mock(DistributionManager.class);
+    CancelCriterion systemCancelCriterion = mock(CancelCriterion.class);
+    
+    InternalDistributedMember member;
+    try {
+      member = new InternalDistributedMember("localhost", 5555);
+    } catch (UnknownHostException e) {
+      throw new RuntimeException(e);
+    }
+    
+    
+    when(cache.getDistributedSystem()).thenReturn(system);
+    when(cache.getMyId()).thenReturn(member);
+    when(cache.getDistributionManager()).thenReturn(distributionManager);
+    when(cache.getCancelCriterion()).thenReturn(systemCancelCriterion);
+    
+    when(system.getDistributedMember()).thenReturn(member);
+    when(system.getConfig()).thenReturn(config);
+    when(system.getDistributionManager()).thenReturn(distributionManager);
+    when(system.getCancelCriterion()).thenReturn(systemCancelCriterion);
+    
+    when(distributionManager.getId()).thenReturn(member);
+    when(distributionManager.getConfig()).thenReturn(config);
+    when(distributionManager.getSystem()).thenReturn(system);
+    when(distributionManager.getCancelCriterion()).thenReturn(systemCancelCriterion);
+    
+    return cache;
+  }
+
+  /**
+   * A fake distributed system, which contains a fake distribution manager.
+   */
+  public static InternalDistributedSystem distributedSystem() {
+    return cache().getDistributedSystem();
+  }
+
+  private Fakes() {
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9eb7a058/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java b/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java
new file mode 100644
index 0000000..ffb4896
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/test/fake/Fakes.java
@@ -0,0 +1,99 @@
+/*
+ * 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 com.gemstone.gemfire.test.fake;
+
+import static org.mockito.Mockito.*;
+
+import java.net.UnknownHostException;
+
+import org.junit.Assert;
+
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+
+/**
+ * Factory methods for fake objects for use in test.
+ * 
+ * These fakes are essentially mock objects with some limited
+ * functionality. For example the fake cache can return a fake
+ * distributed system.
+ * 
+ * All of the fakes returned by this class are Mockito.mocks, so
+ * they can be modified by using Mockito stubbing, ie
+ * 
+ * <pre>
+ * cache = Fakes.cache();
+ * Mockito.when(cache.getName()).thenReturn(...)
+ * <pre>
+ * 
+ * Please help extend this class by adding other commonly
+ * used objects to this collection of fakes.
+ */
+public class Fakes {
+  
+  /**
+   * A fake cache, which contains a fake distributed
+   * system, distribution manager, etc.
+   */
+  public static GemFireCacheImpl cache() {
+    GemFireCacheImpl cache = mock(GemFireCacheImpl.class);
+    InternalDistributedSystem system = mock(InternalDistributedSystem.class);
+    DistributionConfig config = mock(DistributionConfig.class);
+    DistributionManager distributionManager = mock(DistributionManager.class);
+    CancelCriterion systemCancelCriterion = mock(CancelCriterion.class);
+    
+    InternalDistributedMember member;
+    try {
+      member = new InternalDistributedMember("localhost", 5555);
+    } catch (UnknownHostException e) {
+      throw new RuntimeException(e);
+    }
+    
+    
+    when(cache.getDistributedSystem()).thenReturn(system);
+    when(cache.getMyId()).thenReturn(member);
+    when(cache.getDistributionManager()).thenReturn(distributionManager);
+    when(cache.getCancelCriterion()).thenReturn(systemCancelCriterion);
+    
+    when(system.getDistributedMember()).thenReturn(member);
+    when(system.getConfig()).thenReturn(config);
+    when(system.getDistributionManager()).thenReturn(distributionManager);
+    when(system.getCancelCriterion()).thenReturn(systemCancelCriterion);
+    
+    when(distributionManager.getId()).thenReturn(member);
+    when(distributionManager.getConfig()).thenReturn(config);
+    when(distributionManager.getSystem()).thenReturn(system);
+    when(distributionManager.getCancelCriterion()).thenReturn(systemCancelCriterion);
+    
+    return cache;
+  }
+
+  /**
+   * A fake distributed system, which contains a fake distribution manager.
+   */
+  public static InternalDistributedSystem distributedSystem() {
+    return cache().getDistributedSystem();
+  }
+
+  private Fakes() {
+  }
+
+}


[071/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index 0000000,b3f627a..3095885
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@@ -1,0 -1,1913 +1,1922 @@@
+ /*
+  * 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 com.gemstone.gemfire.distributed;
+ 
+ import java.io.File;
+ import java.io.FileReader;
+ import java.io.IOException;
+ import java.io.LineNumberReader;
+ import java.util.ArrayList;
+ import java.util.List;
+ import java.util.Properties;
+ import java.util.Set;
+ 
+ import com.gemstone.gemfire.ForcedDisconnectException;
+ import com.gemstone.gemfire.GemFireConfigException;
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.SystemConnectException;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionShortcut;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.distributed.internal.DistributionException;
+ import com.gemstone.gemfire.distributed.internal.DistributionManager;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.InternalLocator;
+ import com.gemstone.gemfire.distributed.internal.MembershipListener;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
+ import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
+ import com.gemstone.gemfire.distributed.internal.membership.NetView;
+ import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.AvailablePort;
+ import com.gemstone.gemfire.internal.AvailablePortHelper;
+ import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+ import com.gemstone.gemfire.internal.logging.LocalLogWriter;
+ import com.gemstone.gemfire.internal.tcp.Connection;
+ import com.gemstone.gemfire.test.dunit.AsyncInvocation;
+ import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+ import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
+ import com.gemstone.gemfire.test.dunit.Host;
+ import com.gemstone.gemfire.test.dunit.IgnoredException;
+ import com.gemstone.gemfire.test.dunit.LogWriterUtils;
+ import com.gemstone.gemfire.test.dunit.NetworkUtils;
+ import com.gemstone.gemfire.test.dunit.SerializableCallable;
+ import com.gemstone.gemfire.test.dunit.SerializableRunnable;
+ import com.gemstone.gemfire.test.dunit.ThreadUtils;
+ import com.gemstone.gemfire.test.dunit.VM;
+ import com.gemstone.gemfire.test.dunit.Wait;
+ import com.gemstone.gemfire.test.dunit.WaitCriterion;
+ 
+ /**
+  * Tests the ability of the {@link Locator} API to start and stop
+  * locators running in remote VMs.
+  *
+  * @since 4.0
+  */
+ public class LocatorDUnitTest extends DistributedTestCase {
+ 
+   static TestHook hook;
+   
+   /**
+    * Creates a new <code>LocatorDUnitTest</code>
+    */
+   public LocatorDUnitTest(String name) {
+     super(name);
+   }
+ 
+   private static final String WAIT2_MS_NAME = "LocatorDUnitTest.WAIT2_MS";
+   private static final int WAIT2_MS_DEFAULT = 5000; // 2000 -- see bug 36470
+   private static final int WAIT2_MS 
+       = Integer.getInteger(WAIT2_MS_NAME, WAIT2_MS_DEFAULT).intValue();
+   
+   private int port1;
+   private int port2;
+   
+   @Override
+   public void setUp() throws Exception {
+     super.setUp();
+     port1 = -1;
+     port2 = -1;
+     IgnoredException.addIgnoredException("Removing shunned member");
+   }
+   
+   @Override
+   protected final void preTearDown() throws Exception {
+     if (Locator.hasLocator()) {
+       Locator.getLocator().stop();
+     }
+     // delete locator state files so they don't accidentally
+     // get used by other tests
+     if (port1 > 0) {
+       DistributedTestUtils.deleteLocatorStateFile(port1);
+     }
+     if (port2 > 0) {
+       DistributedTestUtils.deleteLocatorStateFile(port2);
+     }
+   }
+   
+   ////////  Test Methods
+ 
++  public void testRepeat() throws Exception {
++    long giveup = System.currentTimeMillis() + (120 * 60000);
++    do {
++      testCollocatedLocatorWithSecurity();
++      tearDown(); setUp();
++    } while (System.currentTimeMillis() < giveup);
++  }
++
+   
+   /**
+    * SQLFire uses a colocated locator in a dm-type=normal VM.  This tests that
+    * the locator can resume control as coordinator after all locators have been
+    * shut down and one is restarted.  It's necessary to have a lock service
+    * start so elder failover is forced to happen.  Prior to fixing how this worked
+    * it hung with the restarted locator trying to become elder again because
+    * it put its address at the beginning of the new view it sent out.
+    */
+   public void testCollocatedLocatorWithSecurity() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM vm3 = host.getVM(3);
+     
+     port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+ 
+     final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("start-locator", locators);
+     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
+     properties.put("security-peer-auth-init","com.gemstone.gemfire.distributed.AuthInitializer.create");
+     properties.put("security-peer-authenticator","com.gemstone.gemfire.distributed.MyAuthenticator.create");
+     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+     properties.put(DistributionConfig.USE_CLUSTER_CONFIGURATION_NAME, "false");
+     system = (InternalDistributedSystem)DistributedSystem.connect(properties);
+     InternalDistributedMember mbr = system.getDistributedMember();
+     assertEquals("expected the VM to have NORMAL vmKind",
+         DistributionManager.NORMAL_DM_TYPE, system.getDistributedMember().getVmKind());
+     
+     properties.remove("start-locator");
+     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
+     properties.put("locators", locators);
+     SerializableRunnable startSystem = new SerializableRunnable("start system") {
+       public void run() {
+         system = (InternalDistributedSystem)DistributedSystem.connect(properties);
+       }
+     };
+     vm1.invoke(startSystem);
+     vm2.invoke(startSystem);
+ 
+     // ensure that I, as a collocated locator owner, can create a cache region
+     Cache cache = CacheFactory.create(system);
+     Region r = cache.createRegionFactory(RegionShortcut.REPLICATE).create("test region");
+     assertNotNull("expected to create a region", r);
+     
+     // create a lock service and have every vm get a lock
+     DistributedLockService service = DistributedLockService.create("test service", system);
+     service.becomeLockGrantor();
+     service.lock("foo0", 0, 0);
+     
+     vm1.invoke(new SerializableRunnable("get the lock service and lock something") {
+       public void run() {
+         final DistributedLockService service = DistributedLockService.create("test service", system);
+         service.lock("foo1", 0, 0);
+       }
+     });
+ 
+     vm2.invoke(new SerializableRunnable("get the lock service and lock something") {
+       public void run() {
+         final DistributedLockService service = DistributedLockService.create("test service", system);
+         service.lock("foo2", 0, 0);
+       }
+     });
+       
+       
+     // cause elder failover.  vm1 will become the lock grantor
+     system.disconnect();
+     
+     try {
+       vm1.invoke(new SerializableRunnable("ensure grantor failover") {
+         public void run() {
+           final DistributedLockService service = DistributedLockService.getServiceNamed("test service");
+           service.lock("foo3", 0, 0);
+           Wait.waitForCriterion(new WaitCriterion() {
+             @Override
+             public boolean done() {
+               return service.isLockGrantor();
+             }
+             @Override
+             public String description() {
+               return "waiting to become lock grantor after shutting down locator/grantor";
+             }
+             
+           }, DistributionConfig.DEFAULT_MEMBER_TIMEOUT * 2, 1000, true);
+           assertTrue(service.isLockGrantor());
+         }
+       });
+   
+       properties.put("start-locator", locators);
+       properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
+       system = (InternalDistributedSystem)DistributedSystem.connect(properties);
 -      System.out.println("done connecting distributed system");
++      System.out.println("done connecting distributed system.  Membership view is " +
++        MembershipManagerHelper.getMembershipManager(system).getView());
+       
+       assertEquals("should be the coordinator", system.getDistributedMember(), MembershipManagerHelper.getCoordinator(system));
+       NetView view = MembershipManagerHelper.getMembershipManager(system).getView();
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("view after becoming coordinator is " + view);
+       assertNotSame("should not be the first member in the view ("+view+")", system.getDistributedMember(), view.get(0));
+       
+       service = DistributedLockService.create("test service", system);
+ 
+       // now force a non-elder VM to get a lock.  This will hang if the bug is not fixed 
+       vm2.invoke(new SerializableRunnable("get the lock service and lock something") {
+         public void run() {
+           final DistributedLockService service = DistributedLockService.getServiceNamed("test service");
+           service.lock("foo4", 0, 0);
+         }
+       });
+ 
+       assertFalse("should not have become lock grantor", service.isLockGrantor());
+       
+       // Now demonstrate that a new member can join and use the lock service
+       properties.remove("start-locator");
+       vm3.invoke(startSystem);
+       vm3.invoke(new SerializableRunnable("get the lock service and lock something(2)") {
+         public void run() {
+           final DistributedLockService service = DistributedLockService.create("test service", system);
+           service.lock("foo5", 0, 0);
+         }
+       });
+       
+     } finally {
+       disconnectAllFromDS();
+     }
+   }
+ 
+   /**
+    * Bug 30341 concerns race conditions in JGroups that allow two locators to start up in a
+    * split-brain configuration.  To work around this we have always told customers that they
+    * need to stagger the starting of locators.  This test configures two locators to start up
+    * simultaneously and shows that they find each other and form a single system.
+    * 
+    * @throws Exception
+    */
+   public void testStartTwoLocators() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM loc1 = host.getVM(1);
+     VM loc2 = host.getVM(2);
+     
+     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = ports[0];
+     this.port1 = port1;
+     final int port2 = ports[1];
+     this.port2 = port2; // for cleanup in tearDown2
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     DistributedTestUtils.deleteLocatorStateFile(port2);
+     final String host0 = NetworkUtils.getServerHostName(host); 
+     final String locators = host0 + "[" + port1 + "]," +
+                             host0 + "[" + port2 + "]";
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("locators", locators);
+     properties.put("enable-network-partition-detection", "false");
+     properties.put("disable-auto-reconnect", "true");
+     properties.put("member-timeout", "2000");
+     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
+     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+     SerializableCallable startLocator1 = new SerializableCallable("start locator1") {
+       @Override
+       public Object call() throws Exception {
+         try {
+           System.setProperty("p2p.joinTimeout", "5000"); // set a short join timeout.  default is 17000ms
+           Locator myLocator = Locator.startLocatorAndDS(port1, new File(""), properties);
+         } catch (SystemConnectException e) {
+           return Boolean.FALSE;
+         } catch (GemFireConfigException e) {
+           return Boolean.FALSE;
+         } finally {
+           System.getProperties().remove("p2p.joinTimeout");
+         }
+         return Boolean.TRUE;
+       }
+     };
+     SerializableCallable startLocator2 = new SerializableCallable("start locator2") {
+       @Override
+       public Object call() throws Exception {
+         try {
+           System.setProperty("p2p.joinTimeout", "5000"); // set a short join timeout.  default is 17000ms
+           Locator myLocator = Locator.startLocatorAndDS(port2, new File(""), properties);
+         } catch (SystemConnectException e) {
+           return Boolean.FALSE;
+         } finally {
+           System.getProperties().remove("p2p.joinTimeout");
+         }
+         return Boolean.TRUE;
+       }
+     };
+     AsyncInvocation async1 = null;
+     AsyncInvocation async2 = null;
+     try {
+       async2 = loc2.invokeAsync(startLocator2);
+       Wait.pause(2000);
+       async1 = loc1.invokeAsync(startLocator1);
+     } finally {
+       try {
+         if (async1 != null) {
+           async1.join(45000);
+           if (async1.isAlive()) {
+             ThreadUtils.dumpAllStacks();
+           }
+           if (async2 != null) {
+             async2.join();
+             Object result1 = async1.getReturnValue();
+             if (result1 instanceof Exception) {
+               throw (Exception)result1;
+             }
+             Object result2 = async2.getReturnValue();
+             if (result2 instanceof Exception) {
+               throw (Exception)result2;
+             }
+             // verify that they found each other
+             SerializableCallable verify = new SerializableCallable("verify no split-brain") {
+               public Object call() {
+                 InternalDistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+                 if (sys == null) {
+                   fail("no distributed system found");
+                 }
+                 Assert.assertTrue(sys.getDM().getViewMembers().size() == 2,
+                     "expected 2 members but found " + sys.getDM().getViewMembers().size()
+                     );
+                 return true;
+               }
+             };
+             loc2.invoke(verify);
+             loc1.invoke(verify);
+           }
+         }
+       } finally {
+         SerializableRunnable r = new SerializableRunnable("stop locator") {
+           public void run() {
+             Locator loc = Locator.getLocator();
+             if (loc != null) {
+               loc.stop();
+             }
+           }
+         };
+         loc2.invoke(r);
+         loc1.invoke(r);
+       }
+     }
+     
+   }
+   /**
+    * test lead member selection
+    */
+   public void testLeadMemberSelection() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM vm3 = host.getVM(3);
+     
+     port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("locators", locators);
+     properties.put("enable-network-partition-detection", "true");
+     properties.put("disable-auto-reconnect", "true");
+     
+     File logFile = new File("");
+     if (logFile.exists()) {
+       logFile.delete();
+     }
+     Locator locator = Locator.startLocatorAndDS(port1, logFile, properties);
+     try {
+     DistributedSystem sys = locator.getDistributedSystem();
+     
+     Object[] connectArgs = new Object[]{ properties };
+     
+     SerializableRunnable disconnect =
+       new SerializableRunnable("Disconnect from " + locators) {
+           public void run() {
+             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+             if (sys != null && sys.isConnected()) {
+               sys.disconnect();
+             }
+           }
+         };
+         
+     assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
+     
+     // connect three vms and then watch the lead member selection as they
+     // are disconnected/reconnected
+     properties.put("name", "vm1");
+     DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+         "getDistributedMember", connectArgs);
+     
+ //    assertTrue(MembershipManagerHelper.getLeadMember(sys) != null);
+     assertLeadMember(mem1, sys, 5000);
+     
+     properties.put("name", "vm2");
+     DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+         "getDistributedMember", connectArgs);
+     assertLeadMember(mem1, sys, 5000);
+     
+     properties.put("name", "vm3");
+     DistributedMember mem3 = (DistributedMember)vm3.invoke(this.getClass(),
+         "getDistributedMember", connectArgs);
+     assertLeadMember(mem1, sys, 5000);
+     
+     // after disconnecting the first vm, the second one should become the leader
+     vm1.invoke(disconnect);
+     MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
+     assertLeadMember(mem2, sys, 5000);
+     
+     properties.put("name", "vm1");
+     mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+         "getDistributedMember", connectArgs);
+     assertLeadMember(mem2, sys, 5000);
+     
+     vm2.invoke(disconnect);
+     MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem2);
+     assertLeadMember(mem3, sys, 5000);
+     
+     vm1.invoke(disconnect);
+     MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
+     assertLeadMember(mem3, sys, 5000);
+ 
+     vm3.invoke(disconnect);
+     MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem3);
+     assertLeadMember(null, sys, 5000);
+ 
+     } finally {
+       locator.stop();
+     }
+   }
+ 
+   private void assertLeadMember(final DistributedMember member,
+       final DistributedSystem sys, long timeout) {
+     WaitCriterion ev = new WaitCriterion() {
+       public boolean done() {
+         DistributedMember lead = MembershipManagerHelper.getLeadMember(sys);
+         if (member != null) {
+           return member.equals(lead);
+         }
+         return (lead == null);
+       }
+       public String description() {
+         return null;
+       }
+     };
+     Wait.waitForCriterion(ev, timeout, 200, true);
+   }
+   
+   /**
+    * test lead member and coordinator failure with network partition detection
+    * enabled.  It would be nice for this test to have more than two "server"
+    * vms, to demonstrate that they all exit when the leader and potential-
+    * coordinator both disappear in the loss-correlation-window, but there
+    * are only four vms available for dunit testing.
+    * <p>
+    * So, we start two locators with admin distributed systems, then start
+    * two regular distributed members.
+    * <p>
+    * We kill the second locator (which is not
+    * the view coordinator) and then kill the non-lead member.  That should be
+    * okay - the lead and remaining locator continue to run.
+    * <p>
+    * We then kill the lead member and demonstrate that the original locator
+    * (which is now the sole remaining member) shuts itself down.
+    */
+   public void testLeadAndCoordFailure() throws Exception {
+     IgnoredException.addIgnoredException("Possible loss of quorum due");
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM locvm = host.getVM(3);
+     Locator locator = null;
+     
+     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = ports[0];
+     this.port1 = port1;
+     final int port2 = ports[1];
+     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
+     final String host0 = NetworkUtils.getServerHostName(host); 
+     final String locators = host0 + "[" + port1 + "]," +
+                             host0 + "[" + port2 + "]";
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("locators", locators);
+     properties.put("enable-network-partition-detection", "true");
+     properties.put("disable-auto-reconnect", "true");
+     properties.put("member-timeout", "2000");
+     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
+ //    properties.put("log-level", "fine");
+     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+     
+     try {
+       final String uname = getUniqueName();
+       File logFile = new File("");
+       locator = Locator.startLocatorAndDS(port1, logFile, properties);
+       final DistributedSystem sys = locator.getDistributedSystem();
+       sys.getLogWriter().info("<ExpectedException action=add>java.net.ConnectException</ExpectedException>");
+       MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
+       locvm.invoke(new SerializableRunnable() {
+         public void run() {
+           File lf = new File("");
+           try {
+             Locator.startLocatorAndDS(port2, lf, properties);
+           }
+           catch (IOException ios) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
+           }
+         }
+       });
+       
+       Object[] connectArgs = new Object[]{ properties };
+       
+       SerializableRunnable crashLocator =
+         new SerializableRunnable("Crash locator") {
+           public void run() {
+             Locator loc = Locator.getLocators().iterator().next();
+             DistributedSystem msys = loc.getDistributedSystem();
+             MembershipManagerHelper.crashDistributedSystem(msys);
+             loc.stop();
+           }
+       };
+ 
+ 
+       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
+       
+ //      properties.put("log-level", getDUnitLogLevel());
+       
+       DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+       vm2.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+       assertLeadMember(mem1, sys, 5000);
+       
+       assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
+       
+       // crash the second vm and the locator.  Should be okay
+       DistributedTestUtils.crashDistributedSystem(vm2);
+       locvm.invoke(crashLocator);
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+       
+       // ensure quorumLost is properly invoked
+       DistributionManager dm = (DistributionManager)((InternalDistributedSystem)sys).getDistributionManager();
+       MyMembershipListener listener = new MyMembershipListener();
+       dm.addMembershipListener(listener);
+   
+       // disconnect the first vm and demonstrate that the third vm and the
+       // locator notice the failure and exit
+       DistributedTestUtils.crashDistributedSystem(vm1);
+ 
+       /* This vm is watching vm1, which is watching vm2 which is watching locvm.
+        * It will take 3 * (3 * member-timeout) milliseconds to detect the full
+        * failure and eject the lost members from the view.
+        */
+       
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("waiting for my distributed system to disconnect due to partition detection");
+       WaitCriterion ev = new WaitCriterion() {
+         public boolean done() {
+           return !sys.isConnected();
+         }
+         public String description() {
+           return null;
+         }
+       };
+       Wait.waitForCriterion(ev, 12 * 2000, 200, true);
+       if (sys.isConnected()) {
+         fail("Distributed system did not disconnect as expected - network partition detection is broken");
+       }
+       // quorumLost should be invoked if we get a ForcedDisconnect in this situation
+       assertTrue("expected quorumLost to be invoked", listener.quorumLostInvoked);
+       assertTrue("expected suspect processing initiated by TCPConduit", listener.suspectReasons.contains(Connection.INITIATING_SUSPECT_PROCESSING));
+     }
+     finally {
+       if (locator != null) {
+         locator.stop();
+       }
+       LogWriter bLogger =
+         new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+       bLogger.info("<ExpectedException action=remove>service failure</ExpectedException>");
+       bLogger.info("<ExpectedException action=remove>java.net.ConnectException</ExpectedException>");
+       bLogger.info("<ExpectedException action=remove>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+       disconnectAllFromDS();
+     }
+   }
+   
+ 
+   /**
+    * test lead member failure and normal coordinator shutdown with network partition detection
+    * enabled.
+    * <p>
+    * Start two locators with admin distributed systems, then start
+    * two regular distributed members.
+    * <p>
+    * We kill the lead member and demonstrate that the other members continue
+    * to operate normally.
+    * <p>
+    * We then shut down the group coordinator and observe the second locator
+    * pick up the job and the remaining member continues to operate normally.
+    */
+   public void testLeadFailureAndCoordShutdown() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM locvm = host.getVM(3);
+     Locator locator = null;
+     
+     final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = ports[0];
+     this.port1 = port1;
+     final int port2 = ports[1];
+     this.port2 = port2;
+     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
+     final String host0 = NetworkUtils.getServerHostName(host);
+     final String locators = host0 + "[" + port1 + "],"
+           + host0 + "[" + port2 + "]";
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("locators", locators);
+     properties.put("enable-network-partition-detection", "true");
+     properties.put("disable-auto-reconnect", "true");
+     properties.put("member-timeout", "2000");
+     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+     SerializableRunnable stopLocator = getStopLocatorRunnable();
+     
+     try {
+       final String uname = getUniqueName();
+       File logFile = new File("");
+       locator = Locator.startLocatorAndDS(port1, logFile, properties);
+       DistributedSystem sys = locator.getDistributedSystem();
+       locvm.invoke(new SerializableRunnable() {
+         public void run() {
+           File lf = new File("");
+           try {
+             Locator.startLocatorAndDS(port2, lf, properties);
+             MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
+           }
+           catch (IOException ios) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
+           }
+         }
+       });
+       
+       Object[] connectArgs = new Object[]{ properties };
+       
+       SerializableRunnable crashSystem =
+         new SerializableRunnable("Crash system") {
+           public void run() {
+             DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
+             msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+             MembershipManagerHelper.crashDistributedSystem(msys);
+           }
+       };
+ 
+       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
+       
+       DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+       DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+ 
+       assertEquals(mem1, MembershipManagerHelper.getLeadMember(sys));
+       
+       assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
+       
+       MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
+ 
+       // crash the lead vm. Should be okay
+       vm1.invoke(crashSystem);
+ 
+       Wait.pause(4 * 2000); // 4 x the member-timeout
+       
+       assertTrue("Distributed system should not have disconnected",
+           isSystemConnected());
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+       
+       assertTrue("Distributed system should not have disconnected",
+           locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+ 
+       // stop the locator normally.  This should also be okay
+       locator.stop();
+       
+       if (!Locator.getLocators().isEmpty()) {
+         // log this for debugging purposes before throwing assertion error
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().warning("found locator " + Locator.getLocators().iterator().next());
+       }
+       assertTrue("locator is not stopped", Locator.getLocators().isEmpty());
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+       
+       assertTrue("Distributed system should not have disconnected",
+           locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+ 
+       // the remaining non-locator member should now be the lead member
+       assertEquals("This test sometimes fails.  If the log contains " +
+       		"'failed to collect all ACKs' it is a false failure.",
+       		mem2, vm2.invoke(() -> LocatorDUnitTest.getLeadMember()));
+       
+       SerializableRunnable disconnect =
+         new SerializableRunnable("Disconnect from " + locators) {
+             public void run() {
+               DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+               if (sys != null && sys.isConnected()) {
+                 sys.disconnect();
+               }
+             }
+           };
+ 
+       // disconnect the first vm and demonstrate that the third vm and the
+       // locator notice the failure and exit
+       vm2.invoke(disconnect);
+       locvm.invoke(stopLocator);
+     }
+     finally {
+       MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
+       if (locator != null) {
+         locator.stop();
+       }
+       try {
+         locvm.invoke(stopLocator);
+       } catch (Exception e) {
+         com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().severe("failed to stop locator in vm 3", e);
+       }
+     }
+   }
+ 
+   /**
+    * test lead member failure and normal coordinator shutdown with network partition detection
+    * enabled.
+    * <p>
+    * Start one locators with admin distributed systems, then start
+    * two regular distributed members.
+    * <p>
+    * We kill the lead member and demonstrate that the other members continue
+    * to operate normally.
+    * <p>
+    * We then shut down the group coordinator and observe the second locator
+    * pick up the job and the remaining member continues to operate normally.
+    */
+   // disabled on trunk - should be reenabled on cedar_dev_Oct12
+   // this test leaves a CloserThread around forever that logs "pausing" messages every 500 ms
+   public void testForceDisconnectAndPeerShutdownCause() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM locvm = host.getVM(3);
+     Locator locator = null;
+     
+     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = ports[0];
+     this.port1 = port1;
+     final int port2 = ports[1];
+     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
+     final String host0 = NetworkUtils.getServerHostName(host);
+     final String locators = host0 + "[" + port1 + "]," + host0 + "[" + port2 + "]";
+ 
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("locators", locators);
+     properties.put("enable-network-partition-detection", "true");
+     properties.put("disable-auto-reconnect", "true");
+     properties.put("member-timeout", "2000");
+     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
+     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+     SerializableRunnable stopLocator = getStopLocatorRunnable();
+     
+     try {
+       final String uname = getUniqueName();
+       File logFile = new File("");
+       locator = Locator.startLocatorAndDS(port1, logFile, properties);
+       DistributedSystem sys = locator.getDistributedSystem();
+       locvm.invoke(new SerializableRunnable() {
+         public void run() {
+           File lf = new File("");
+           try {
+             Locator.startLocatorAndDS(port2, lf, properties);
+           }
+           catch (IOException ios) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator2", ios);
+           }
+         }
+       });
+       
+       Object[] connectArgs = new Object[]{ properties };
+       
+       SerializableRunnable crashSystem =
+         new SerializableRunnable("Crash system") {
+           public void run() {
+             DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
+             msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>Possible loss of quorum</ExpectedException>");
+             hook = new TestHook();
+             MembershipManagerHelper.getMembershipManager(msys).registerTestHook(hook);
+             try {
+               MembershipManagerHelper.crashDistributedSystem(msys);
+             } finally {
+               hook.reset();
+             }
+           }
+       };
+ 
+       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
+       
+       final DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+       final DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+ 
+       assertEquals(mem1, MembershipManagerHelper.getLeadMember(sys));
+       
+       assertEquals(sys.getDistributedMember(), MembershipManagerHelper.getCoordinator(sys));
+       
+       // crash the lead vm. Should be okay. it should hang in test hook thats
+       // why call is asynchronous.
+       //vm1.invokeAsync(crashSystem);
+ 
+       assertTrue("Distributed system should not have disconnected",
+           isSystemConnected());
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+       
+       assertTrue("Distributed system should not have disconnected",
+           locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+ 
+       vm2.invokeAsync(crashSystem);
+ 
+       Wait.pause(1000); // 4 x the member-timeout
+       
+       // request member removal for first peer from second peer.
+       vm2.invoke(new SerializableRunnable("Request Member Removal") {
+         
+         @Override
+         public void run() {
+           DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
+           MembershipManager mmgr = MembershipManagerHelper.getMembershipManager(msys);
+           
+           // check for shutdown cause in MembershipManager. Following call should
+           // throw DistributedSystemDisconnectedException which should have cause as
+           // ForceDisconnectException.
+           try {
+             msys.getLogWriter().info("<ExpectedException action=add>Membership: requesting removal of </ExpectedException>");
+             mmgr.requestMemberRemoval(mem1, "test reasons");
+             msys.getLogWriter().info("<ExpectedException action=remove>Membership: requesting removal of </ExpectedException>");
+             fail("It should have thrown exception in requestMemberRemoval");
+           } catch (DistributedSystemDisconnectedException e) {
+             Throwable cause = e.getCause();
+             assertTrue(
+                 "This should have been ForceDisconnectException but found "
+                     + cause, cause instanceof ForcedDisconnectException);
+           } finally {
+             hook.reset();
+           }
+         }
+       });
+ 
+     }
+     finally {
+       if (locator != null) {
+         locator.stop();
+       }
+       locvm.invoke(stopLocator);
+       assertTrue("locator is not stopped", Locator.getLocators().isEmpty());
+     }
+   }
+ 
+   /**
+    * test lead member shutdown and coordinator crashing with network partition detection
+    * enabled.
+    * <p>
+    * Start two locators with admin distributed systems, then start
+    * two regular distributed members.
+    * <p>
+    * We kill the coordinator and shut down the lead member and observe the second locator
+    * pick up the job and the remaining member continue to operate normally.
+    */
+   public void testLeadShutdownAndCoordFailure() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM locvm = host.getVM(3);
+     Locator locator = null;
+     
+     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = ports[0];
+     this.port1 = port1;
+     final int port2 = ports[1];
+     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
+     final String host0 = NetworkUtils.getServerHostName(host);
+     final String locators = host0 + "[" + port1 + "],"
+           + host0 + "[" + port2 + "]";
+     final Properties properties = new Properties();
+     properties.put("mcast-port", "0");
+     properties.put("locators", locators);
+     properties.put("enable-network-partition-detection", "true");
+     properties.put("disable-auto-reconnect", "true");
+     properties.put("member-timeout", "2000");
+     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+     SerializableRunnable disconnect =
+       new SerializableRunnable("Disconnect from " + locators) {
+           public void run() {
+             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+             if (sys != null && sys.isConnected()) {
+               sys.disconnect();
+             }
+             MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
+           }
+         };
+     SerializableRunnable expectedException =
+       new SerializableRunnable("Add expected exceptions") {
+         public void run() {
+           MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
+         }
+     };
+     try {
+       final String uname = getUniqueName();
+       locvm.invoke(new SerializableRunnable() {
+         public void run() {
+           File lf = new File("");
+           try {
+             Locator.startLocatorAndDS(port2, lf, properties);
+           }
+           catch (IOException ios) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("Unable to start locator1", ios);
+           }
+         }
+       });
+ 
+       File logFile = new File("");
+       locator = Locator.startLocatorAndDS(port1, logFile, properties);
+       DistributedSystem sys = locator.getDistributedSystem();
+       sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+       Object[] connectArgs = new Object[]{ properties };
+       
+       SerializableRunnable crashLocator =
+         new SerializableRunnable("Crash locator") {
+           public void run() {
+             Locator loc = Locator.getLocators().iterator().next();
+             DistributedSystem msys = loc.getDistributedSystem();
+             msys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+             msys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+             MembershipManagerHelper.crashDistributedSystem(msys);
+             loc.stop();
+           }
+       };
+ 
+       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
+       
+       DistributedMember mem1 = (DistributedMember)vm1.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+       vm1.invoke(expectedException);
+       DistributedMember mem2 = (DistributedMember)vm2.invoke(this.getClass(),
+           "getDistributedMember", connectArgs);
+       
+       DistributedMember loc1Mbr = (DistributedMember)locvm.invoke(() -> this.getLocatorDistributedMember());
+ 
+       assertLeadMember(mem1, sys, 5000);
+       
+       assertEquals(loc1Mbr, MembershipManagerHelper.getCoordinator(sys));
+       
+       // crash the lead locator.  Should be okay
+       locvm.invoke(crashLocator);
+       Wait.pause(10 * 1000);
+ 
+       assertTrue("Distributed system should not have disconnected",
+           sys.isConnected());
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+ 
+       // disconnect the first vm and demonstrate that the non-lead vm and the
+       // locator notice the failure and continue to run
+       vm1.invoke(disconnect);
+       Wait.pause(10 * 1000);
+       
+       assertTrue("Distributed system should not have disconnected",
+           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
+       
+       assertEquals(sys.getDistributedMember(),
+           MembershipManagerHelper.getCoordinator(sys));
+       assertEquals(mem2, MembershipManagerHelper.getLeadMember(sys));
+       
+     }
+     finally {
+       vm2.invoke(disconnect);
+       
+       if (locator != null) {
+         locator.stop();
+       }
+       locvm.invoke(getStopLocatorRunnable());
+     }
+   }
+ 
+   /**
+    * Tests that attempting to connect to a distributed system in which
+    * no locator is defined throws an exception.
+    */
+   public void testNoLocator() {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     int port =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
+     Properties props = new Properties();
+     props.setProperty("mcast-port", "0");
+     props.setProperty("locators", locators);
+ 
+     final String expected = "java.net.ConnectException";
+     final String addExpected = 
+       "<ExpectedException action=add>" + expected + "</ExpectedException>";
+     final String removeExpected = 
+       "<ExpectedException action=remove>" + expected + "</ExpectedException>";
+       
+     LogWriter bgexecLogger =
+           new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+     bgexecLogger.info(addExpected);
+     
+     boolean exceptionOccurred = true;
+     String oldValue = (String)System.getProperties().put("p2p.joinTimeout", "15000");
+     try {
+       DistributedSystem.connect(props);
+       exceptionOccurred = false;
+ 
+     } catch (DistributionException ex) {
+       // I guess it can throw this too...
+ 
+     } catch (GemFireConfigException ex) {
+       String s = ex.getMessage();
+       assertTrue(s.indexOf("Locator does not exist") >= 0);
+       
+     } catch (Exception ex) {
+       // if you see this fail, determine if unexpected exception is expected
+       // if expected then add in a catch block for it above this catch
+       com.gemstone.gemfire.test.dunit.Assert.fail("Failed with unexpected exception", ex);
+     }
+     finally {
+       if (oldValue == null) {
+         System.getProperties().remove("p2p.joinTimeout");
+       } else {
+         System.getProperties().put("p2p.joinTimeout", oldValue);
+       }
+       bgexecLogger.info(removeExpected);
+     }
+ 
+     if (!exceptionOccurred) {
+       fail("Should have thrown a GemFireConfigException");
+     }
+   }
+ 
+   /**
+    * Tests starting one locator in a remote VM and having multiple
+    * members of the distributed system join it.  This ensures that
+    * members start up okay, and that handling of a stopped locator
+    * is correct.
+    * <p>The locator is then restarted and is shown to take over the
+    * role of membership coordinator.
+    */
+   public void testOneLocator() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm0 = host.getVM(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+ 
+     final int port =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     final String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
+     final String uniqueName = getUniqueName();
+     
+     vm0.invoke(new SerializableRunnable("Start locator " + locators) {
+         public void run() {
+           File logFile = new File("");
+           try {
+             Properties locProps = new Properties();
+             locProps.setProperty("mcast-port", "0");
+             locProps.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+             Locator.startLocatorAndDS(port, logFile, locProps);
+           } catch (IOException ex) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port, ex);
+           }
+         }
+       });
+     try {
+ 
+     SerializableRunnable connect =
+       new SerializableRunnable("Connect to " + locators) {
+           public void run() {
+             //System.setProperty("p2p.joinTimeout", "5000");
+             Properties props = new Properties();
+             props.setProperty("mcast-port", "0");
+             props.setProperty("locators", locators);
+             DistributedSystem.connect(props);
+           }
+         };
+     vm1.invoke(connect);
+     vm2.invoke(connect);
+ 
+     Properties props = new Properties();
+     props.setProperty("mcast-port", "0");
+     props.setProperty("locators", locators);
+ 
+     system = (InternalDistributedSystem)DistributedSystem.connect(props);
+     
+     final DistributedMember coord = MembershipManagerHelper.getCoordinator(system);
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator before termination of locator is " + coord);
+ 
+     vm0.invoke(getStopLocatorRunnable());
+     
+     // now ensure that one of the remaining members became the coordinator
+     WaitCriterion ev = new WaitCriterion() {
+       public boolean done() {
+         return !coord.equals(MembershipManagerHelper.getCoordinator(system));
+       }
+       public String description() {
+         return "expected the coordinator to not be " + coord + " but it is " +
+           MembershipManagerHelper.getCoordinator(system);
+       }
+     };
+     Wait.waitForCriterion(ev, 15 * 1000, 200, false);
+     DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system); 
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator after shutdown of locator was " +
+         newCoord);
+     if (coord.equals(newCoord)) {
+       fail("another member should have become coordinator after the locator was stopped");
+     }
+       
+ 
+     system.disconnect();
+ 
+     SerializableRunnable disconnect =
+       new SerializableRunnable("Disconnect from " + locators) {
+           public void run() {
+             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+             if (sys != null && sys.isConnected()) {
+               sys.disconnect();
+             }
+           }
+         };
+     vm1.invoke(disconnect);
+     vm2.invoke(disconnect);
+ 
+     } finally {
+       vm0.invoke(getStopLocatorRunnable());
+     }
+   }
+ 
+ //  public void testRepeat() throws Exception {
+ //    for (int i=0; i<10; i++) {
+ //      System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> run #"+i);
+ //      testLocatorBecomesCoordinator();
+ //      tearDown();
+ //      setUp();
+ //    }
+ //  }
+   /**
+    * Tests starting one locator in a remote VM and having multiple
+    * members of the distributed system join it.  This ensures that
+    * members start up okay, and that handling of a stopped locator
+    * is correct.  It then restarts the locator to demonstrate that
+    * it can connect to and function as the group coordinator
+    */
+   public void testLocatorBecomesCoordinator() throws Exception {
+     disconnectAllFromDS();
+     final String expected = "java.net.ConnectException";
+     final String addExpected = 
+       "<ExpectedException action=add>" + expected + "</ExpectedException>";
+     final String removeExpected = 
+       "<ExpectedException action=remove>" + expected + "</ExpectedException>";
+ 
+     Host host = Host.getHost(0);
+     VM vm0 = host.getVM(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+ 
+     final int port =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     final String locators = NetworkUtils.getServerHostName(host) + "[" + port + "]";
+     
+     vm0.invoke(getStartSBLocatorRunnable(port, getUniqueName()+"1"));
+     try {
+ 
+     final Properties props = new Properties();
+     props.setProperty("mcast-port", "0");
+     props.setProperty("locators", locators);
+     props.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+     SerializableRunnable connect =
+       new SerializableRunnable("Connect to " + locators) {
+           public void run() {
+             //System.setProperty("p2p.joinTimeout", "5000");
+             DistributedSystem sys = getSystem(props);
+             sys.getLogWriter().info(addExpected);
+           }
+         };
+     vm1.invoke(connect);
+     vm2.invoke(connect);
+ 
+     system = (InternalDistributedSystem)getSystem(props);
+ 
+     final DistributedMember coord = MembershipManagerHelper.getCoordinator(system);
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator before termination of locator is " + coord);
+ 
+     vm0.invoke(getStopLocatorRunnable());
+     
+     // now ensure that one of the remaining members became the coordinator
+     WaitCriterion ev = new WaitCriterion() {
+       public boolean done() {
+         return !coord.equals(MembershipManagerHelper.getCoordinator(system));
+       }
+       public String description() {
+         return "expected the coordinator to be " + coord + " but it is " +
+           MembershipManagerHelper.getCoordinator(system);
+       }
+     };
+     Wait.waitForCriterion(ev, 15000, 200, true);
+     DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system); 
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator after shutdown of locator was " +
+         newCoord);
+     if (newCoord == null || coord.equals(newCoord)) {
+       fail("another member should have become coordinator after the locator was stopped: "
+           + newCoord);
+     }
+       
+ 
+     // restart the locator to demonstrate reconnection & make disconnects faster
+     // it should also regain the role of coordinator, so we check to make sure
+     // that the coordinator has changed
+     vm0.invoke(getStartSBLocatorRunnable(port, getUniqueName()+"2"));
+     
+     final DistributedMember tempCoord = newCoord;
+     ev = new WaitCriterion() {
+       public boolean done() {
+         return !tempCoord.equals(MembershipManagerHelper.getCoordinator(system));
+       }
+       public String description() {
+         return null;
+       }
+     };
+     Wait.waitForCriterion(ev, 5000, 200, true);
+     
+     system.disconnect();
+     LogWriter bgexecLogger =
+       new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+     bgexecLogger.info(removeExpected);
+ 
+     SerializableRunnable disconnect =
+       new SerializableRunnable("Disconnect from " + locators) {
+           public void run() {
+             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+             if (sys != null && sys.isConnected()) {
+               sys.disconnect();
+             }
+             // connectExceptions occur during disconnect, so we need the
+             // expectedexception hint to be in effect until this point
+             LogWriter bLogger =
+               new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
+             bLogger.info(removeExpected);
+           }
+         };
+     vm1.invoke(disconnect);
+     vm2.invoke(disconnect);
+     vm0.invoke(getStopLocatorRunnable());
+     } finally {
+       vm0.invoke(getStopLocatorRunnable());
+     }
+ 
+   }
+ 
+   
+   /** set a short locator refresh rate */
+   public static void setShortRefreshWait() {
+     System.setProperty("p2p.gossipRefreshRate", "2000");
+   }
+   
+   /** remove shortened locator refresh rate */
+   public static void resetRefreshWait() {
+     System.getProperties().remove("p2p.gossipRefreshRate");
+   }
+   
+   public static boolean isSystemConnected() {
+     DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+     if (sys != null && sys.isConnected()) {
+       return true;
+     }
+     return false;
+   }
+   
+ 
+   static boolean beforeFailureNotificationReceived;
+   static boolean afterFailureNotificationReceived;
+ 
+ 
+   /**
+    * Tests starting multiple locators in multiple VMs.
+    */
+   public void testMultipleLocators() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm0 = host.getVM(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM vm3 = host.getVM(3);
+ 
+     int[] freeTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = freeTCPPorts[0];
+     this.port1 = port1;
+     final int port2 = freeTCPPorts[1];
+     this.port2 = port2;
+     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
+     final String host0 = NetworkUtils.getServerHostName(host); 
+     final String locators = host0 + "[" + port1 + "]," +
+                             host0 + "[" + port2 + "]";
+ 
+     final Properties dsProps = new Properties();
+     dsProps.setProperty("locators", locators);
+     dsProps.setProperty("mcast-port", "0");
+     dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ //    dsProps.setProperty("log-level", "finest");
+     final String uniqueName = getUniqueName();
+ 
+     vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
+       public void run() {
+         File logFile = new File("");
+         try {
+           Locator.startLocatorAndDS(port1, logFile, dsProps);
+         } catch (IOException ex) {
+           com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port1, ex);
+         }
+       }
+     });
+     try {
+ 
+       //try { Thread.currentThread().sleep(4000); } catch (InterruptedException ie) { }
+ 
+       vm3.invoke(new SerializableRunnable("Start locator on " + port2) {
+         public void run() {
+           File logFile = new File("");
+           try {
+             Locator.startLocatorAndDS(port2, logFile, dsProps);
+ 
+           } catch (IOException ex) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port2, ex);
+           }
+         }
+       });
+       try {
+ 
+         SerializableRunnable connect =
+           new SerializableRunnable("Connect to " + locators) {
+           public void run() {
+             Properties props = new Properties();
+             props.setProperty("mcast-port", "0");
+             props.setProperty("locators", locators);
+             DistributedSystem.connect(props);
+           }
+         };
+         vm1.invoke(connect);
+         vm2.invoke(connect);
+ 
+         Properties props = new Properties();
+         props.setProperty("mcast-port", "0");
+         props.setProperty("locators", locators);
+ 
+         system = (InternalDistributedSystem)DistributedSystem.connect(props);
+ 
+         WaitCriterion ev = new WaitCriterion() {
+           public boolean done() {
+             try {
+               return system.getDM().getViewMembers().size() >= 3;
+             }
+             catch (Exception e) {
+               e.printStackTrace();
+               fail("unexpected exception");
+             }
+             return false; // NOTREACHED
+           }
+           public String description() {
+             return null;
+           }
+         };
+         Wait.waitForCriterion(ev, 10 * 1000, 200, true);
+ 
+         // three applications plus
+         assertEquals(5, system.getDM().getViewMembers().size());
+ 
+         system.disconnect();
+ 
+         SerializableRunnable disconnect =
+           new SerializableRunnable("Disconnect from " + locators) {
+           public void run() {
+             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+             if (sys != null && sys.isConnected()) {
+               sys.disconnect();
+             }
+           }
+         };
+         vm1.invoke(disconnect);
+         vm2.invoke(disconnect);
+ 
+       } finally {
+         vm3.invoke(getStopLocatorRunnable());
+       }
+     } finally {
+       vm0.invoke(getStopLocatorRunnable());
+     }
+   }
+   
+   /**
+    * Tests starting multiple locators in multiple VMs.
+    */
+   public void testMultipleMcastLocators() throws Exception {
+     disconnectAllFromDS();
+     IgnoredException.addIgnoredException("Could not stop  Distribution Locator"); // shutdown timing issue in InternalLocator
+     Host host = Host.getHost(0);
+     VM vm0 = host.getVM(0);
+     VM vm1 = host.getVM(1);
+     VM vm2 = host.getVM(2);
+     VM vm3 = host.getVM(3);
+ 
+     final int[] freeTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+     final int port1 = freeTCPPorts[0];
+     this.port1 = port1;
+     final int port2 = freeTCPPorts[1];
+     this.port2 = port2;
+     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
+     final int mcastport = AvailablePort.getRandomAvailablePort(AvailablePort.MULTICAST);
+     
+     final String host0 = NetworkUtils.getServerHostName(host); 
+     final String locators = host0 + "[" + port1 + "]," +
+                             host0 + "[" + port2 + "]";
+     final String uniqueName = getUniqueName();
+     
+     vm0.invoke(new SerializableRunnable("Start locator on " + port1) {
+         public void run() {
+           File logFile = new File("");
+           try {
+             Properties props = new Properties();
+             props.setProperty("mcast-port", String.valueOf(mcastport));
+             props.setProperty("locators", locators);
+             props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
+             props.setProperty("mcast-ttl", "0");
+             props.setProperty("enable-network-partition-detection", "true");
+             props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+ 
+             Locator.startLocatorAndDS(port1, logFile, null, props);
+           }
+           catch (IOException ex) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port1, ex);
+           }
+         }
+       });
+     vm3.invoke(new SerializableRunnable("Start locator on " + port2) {
+         public void run() {
+           File logFile = new File("");
+           try {
+             Properties props = new Properties();
+             props.setProperty("mcast-port", String.valueOf(mcastport));
+             props.setProperty("locators", locators);
+             props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
+             props.setProperty("mcast-ttl", "0");
+             props.setProperty("enable-network-partition-detection", "true");
+             props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+             Locator.startLocatorAndDS(port2, logFile, null, props);
+           }
+           catch (IOException ex) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port2, ex);
+           }
+         }
+       });
+ 
+     SerializableRunnable connect =
+       new SerializableRunnable("Connect to " + locators) {
+           public void run() {
+             Properties props = new Properties();
+             props.setProperty("mcast-port", String.valueOf(mcastport));
+             props.setProperty("locators", locators);
+             props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
+             props.setProperty("mcast-ttl", "0");
+             props.setProperty("enable-network-partition-detection", "true");
+             DistributedSystem.connect(props);
+           }
+         };
+     try {
+       vm1.invoke(connect);
+       vm2.invoke(connect);
+ 
+       Properties props = new Properties();
+       props.setProperty("mcast-port", String.valueOf(mcastport));
+       props.setProperty("locators", locators);
+       props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
+       props.setProperty("mcast-ttl", "0");
+       props.setProperty("enable-network-partition-detection", "true");
+ 
+       system = (InternalDistributedSystem)DistributedSystem.connect(props);
+       WaitCriterion ev = new WaitCriterion() {
+         public boolean done() {
+           try {
+             return system.getDM().getViewMembers().size() == 5;
+           }
+           catch (Exception e) {
+             com.gemstone.gemfire.test.dunit.Assert.fail("unexpected exception", e);
+           }
+           return false; // NOTREACHED
+         }
+         public String description() {
+           return "waiting for 5 members - have " + system.getDM().getViewMembers().size();
+         }
+       };
+       Wait.waitForCriterion(ev, WAIT2_MS, 200, true);
+       system.disconnect();
+ 
+       SerializableRunnable disconnect =
+         new SerializableRunnable("Disconnect from " + locators) {
+             public void run() {
+               DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+               if (sys != null && sys.isConnected()) {
+                 sys.disconnect();
+               }
+             }
+           };
+       vm1.invoke(disconnect);
+       vm2.invoke(disconnect);
+     }
+     finally {
+       SerializableRunnable stop = getStopLocatorRunnable();
+       vm0.invoke(stop);
+       vm3.invoke(stop);
+       if (system != null) {
+         system.disconnect();
+       }
+     }
+   }
+ 
+ 
+   /**
+    * Tests that a VM can connect to a locator that is hosted in its
+    * own VM.
+    */
+   public void testConnectToOwnLocator() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+ 
+     port1 =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     File logFile = new File("");
+     Locator locator = Locator.startLocator(port1, logFile);
+     try {
+ 
+     final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
+ 
+     Properties props = new Properties();
+     props.setProperty("mcast-port", "0");
+     props.setProperty("locators", locators);
+     props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+     system = (InternalDistributedSystem)DistributedSystem.connect(props);
+     system.disconnect();
+     } finally {
+     locator.stop();
+     }
+   }
+ 
+   /**
+    * Tests that a VM cannot connect if the locator has a different
+    * enable-network-partition-detection setting
+    */
+   public void testLocatorForcesDetection() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     VM vm1 = host.getVM(1);
+     Locator locator = null;
+     
+     try {
+       port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+       DistributedTestUtils.deleteLocatorStateFile(port1);
+       final String locators = NetworkUtils.getServerHostName(host) + "[" + port1 + "]";
+       final Properties properties = new Properties();
+       properties.put("mcast-port", "0");
+       properties.put("locators", locators);
+       properties.put(DistributionConfig.ENABLE_NETWORK_PARTITION_DETECTION_NAME, "true");
+       properties.put("disable-auto-reconnect", "true");
+       properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+       File logFile = new File("");
+       locator = Locator.startLocatorAndDS(port1, logFile, properties);
+   
+       final Properties properties2 = new Properties();
+       properties2.put("mcast-port", "0");
+       properties2.put("locators", locators);
+       properties2.put(DistributionConfig.ENABLE_NETWORK_PARTITION_DETECTION_NAME, "false");
+       properties2.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+       properties2.put("disable-auto-reconnect", "true");
+       
+       vm1.invoke(new SerializableRunnable("try to connect") {
+         public void run() {
+           DistributedSystem s = null;
+           try {
+             s = DistributedSystem.connect(properties2);
+             boolean enabled = ((InternalDistributedSystem)s).getConfig().getEnableNetworkPartitionDetection();
+             s.disconnect();
+             if (!enabled) {
+               fail("should not have been able to connect with different enable-network-partition-detection settings");
+             }
+           }
+           catch (GemFireConfigException e) {
+             fail("should have been able to connect and have enable-network-partion-detection enabled");
+           }
+         }
+       });
+       
+       locator.stop();
+       
+       // now start the locator with enable-network-partition-detection=false
+       logFile = new File("");
+       locator = Locator.startLocatorAndDS(port1, logFile , properties2);
+   
+       vm1.invoke(new SerializableRunnable("try to connect") {
+         public void run() {
+           DistributedSystem s = null;
+           try {
+             s = DistributedSystem.connect(properties);
+             s.disconnect();
+             fail("should not have been able to connect with different enable-network-partition-detection settings");
+           }
+           catch (GemFireConfigException e) {
+             // passed
+           }
+         }
+       });
+       
+       locator.stop();
+       locator = null;
+     }
+     finally {
+       if (locator != null) {
+         locator.stop();
+       }
+     }
+   }
+ 
+   /**
+    * Tests that a single VM can NOT host multiple locators
+    */
+   public void testHostingMultipleLocators() throws Exception {
+     disconnectAllFromDS();
+     Host host = Host.getHost(0);
+     //VM vm = host.getVM(0);
+     //VM vm1 = host.getVM(1);
+ 
+     port1 =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     File logFile1 = new File("");
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     Locator locator1 = Locator.startLocator(port1, logFile1);
+     
+     try {
+ 
+     int port2 =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     File logFile2 = new File("");
+ 
+     DistributedTestUtils.deleteLocatorStateFile(port2);
+     
+     try {
+       Locator locator2 = Locator.startLocator(port2, logFile2);
+       fail("expected second locator start to fail.");
+     } catch (IllegalStateException expected) {
+     }
+ 
+     final String host0 = NetworkUtils.getServerHostName(host);
+     final String locators = host0 + "[" + port1 + "]," +
+                             host0 + "[" + port2 + "]";
+ 
+     SerializableRunnable connect =
+       new SerializableRunnable("Connect to " + locators) {
+           public void run() {
+             Properties props = new Properties();
+             props.setProperty("mcast-port", "0");
+             props.setProperty("locators", locators);
+             props.setProperty("log-level", LogWriterUtils.getDUnitLogLevel());
+             DistributedSystem.connect(props);
+           }
+         };
+     connect.run();
+     //vm1.invoke(connect);
+ 
+     SerializableRunnable disconnect =
+       new SerializableRunnable("Disconnect from " + locators) {
+           public void run() {
+             DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+             if (sys != null && sys.isConnected()) {
+               sys.disconnect();
+             }
+           }
+         };
+ 
+     disconnect.run();
+     //vm1.invoke(disconnect);
+ 
+     } finally {
+     locator1.stop();
+     }
+   }
+ 
+   /**
+    * Tests starting, stopping, and restarting a locator.  See bug
+    * 32856.
+    *
+    * @since 4.1
+    */
+   public void testRestartLocator() throws Exception {
+     disconnectAllFromDS();
+     port1 =
+       AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+     DistributedTestUtils.deleteLocatorStateFile(port1);
+     File logFile = new File("");
+     File stateFile = new File("locator"+port1+"state.dat");
+     VM vm0 = Host.getHost(0).getVM(0);
+     final Properties p = new Properties();
+     p.setProperty(DistributionConfig.LOCATORS_NAME, Host.getHost(0).getHostName() + "["+port1+"]");
+     p.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+     p.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
+     if (stateFile.exists()) {
+       stateFile.delete();
+     }
+ 
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Starting locator");
+     Locator locator = Locator.startLocatorAndDS(port1, logFile, p);
+     try {
+     
+     SerializableRunnable connect =
+       new SerializableRunnable("Connect to locator on port " + port1) {
+           public void run() {
+             DistributedSystem.connect(p);
+           }
+         };
+     vm0.invoke(connect);
+     
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Stopping locator");
+     locator.stop();
+     
+     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("Starting locator");
+     locator = Locator.startLocatorAndDS(port1, logFile, p);
+     
+     vm0.invoke(new SerializableRunnable("disconnect") {
+       public void run() {
+         DistributedSystem.connect(p).disconnect();
+       }
+     });
+     
+     } finally {
+     locator.stop();
+     }
+ 
+   }
+   
+   /** return the distributed member id for the ds on this vm */
+   public static DistributedMember getDistributedMember(Properties props) {
+     props.put("name", "vm_"+VM.getCurrentVMNum());
+     DistributedSystem sys = DistributedSystem.connect(props);
+     sys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+     return DistributedSystem.connect(props).getDistributedMember();
+   }
+   
+   /** find a running locator and return its distributed member id */
+   public static DistributedMember getLocatorDistributedMember() {
+     return (Locator.getLocators().iterator().next())
+       .getDistributedSystem().getDistributedMember();
+   }
+   
+   /** find the lead member and return its id */
+   public static DistributedMember getLeadMember() {
+     DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+     return MembershipManagerHelper.getLeadMember(sys);
+   }
+ 
+   private SerializableRunnable getStopLocatorRunnable() {
+     return new SerializableRunnable("stop locator") {
+       public void run() {
+         MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
+         Locator loc = Locator.getLocator();
+         if (loc != null) {
+           loc.stop();
+           assertFalse(Locator.hasLocator());
+         }
+       }
+     };
+   }
+   
+   private SerializableRunnable getStartSBLocatorRunnable(final int port, final String name) {
+     return new SerializableRunnable("Start locator on port " + port) {
+       public void run() {
+         File logFile = new File("");
+         try {
+           System.setProperty(InternalLocator.LOCATORS_PREFERRED_AS_COORDINATORS, "true");
+           System.setProperty("p2p.joinTimeout", "1000");
+           Properties locProps = new Properties();
+           locProps.put("mcast-port", "0");
+           locProps.put("log-level", LogWriterUtils.getDUnitLogLevel());
+           Locator.startLocatorAndDS(port, logFile, locProps);
+         } catch (IOException ex) {
+           com.gemstone.gemfire.test.dunit.Assert.fail("While starting locator on port " + port, ex);
+         }
+         finally {
+           System.getProperties().remove(InternalLocator.LOCATORS_PREFERRED_AS_COORDINATORS);
+           System.getProperties().remove("p2p.joinTimeout");
+         }
+       }
+     };
+   }
+   
+   protected void nukeJChannel(DistributedSystem sys) {
+     sys.getLogWriter().info("<ExpectedException action=add>service failure</ExpectedException>");
+     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ConnectException</ExpectedException>");
+     sys.getLogWriter().info("<ExpectedException action=add>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+     try {
+       MembershipManagerHelper.crashDistributedSystem(sys);
+     }
+     catch (DistributedSystemDisconnectedException se) {
+       // it's okay for the system to already be shut down
+     }
+     sys.getLogWriter().info("<ExpectedException action=remove>service failure</ExpectedException>");
+     sys.getLogWriter().info("<ExpectedException action=remove>com.gemstone.gemfire.ForcedDisconnectException</ExpectedException>");
+   }
+ 
+   
+   //New test hook which blocks before closing channel.
+   class TestHook implements MembershipTestHook {
+ 
+     volatile boolean unboundedWait = true;
+     @Override
+     public void beforeMembershipFailure(String reason, Throwable cause) {
+       System.out.println("Inside TestHook.beforeMembershipFailure with " + cause);
+       long giveUp = System.currentTimeMillis() + 30000;
+       if (cause instanceof ForcedDisconnectException) {
+         while (unboundedWait && System.currentTimeMillis() < giveUp) {
+           Wait.pause(1000);
+         }
+       } else {
+         cause.printStackTrace();
+       }
+     }
+ 
+     @Override
+     public void afterMembershipFailure(String reason, Throwable cause) {
+     }
+ 
+     public void reset() {
+       unboundedWait = false;
+     }
+ 
+   }
+   class MyMembershipListener implements MembershipListener {
+     boolean quorumLostInvoked;
+     List<String> suspectReasons = new ArrayList<>(50);
+     
+     public void memberJoined(InternalDistributedMember id) {  }
+     public void memberDeparted(InternalDistributedMember id, boolean crashed) { }
+     public void memberSuspect(InternalDistributedMember id,
+         InternalDistributedMember whoSuspected, String reason) {
+       suspectReasons.add(reason);
+     }
+     public void quorumLost(Set<InternalDistributedMember> failures,
+         List<InternalDistributedMember> remaining) {
+       quorumLostInvoked = true;
+       com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("quorumLost invoked in test code");
+     }
+   }
+   
+   
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
index 0000000,0606387..b69f82e
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
@@@ -1,0 -1,188 +1,188 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.fail;
+ 
+ import java.io.IOException;
+ import java.nio.ByteBuffer;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.ChunkValueWrapper;
+ import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.Flushable;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
+ import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
+ import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class ChunkValueWrapperJUnitTest {
+ 
+   private static ChunkValueWrapper createChunkValueWrapper(byte[] bytes, boolean isSerialized) {
 -    Chunk c = (Chunk)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false, null);
++    ObjectChunk c = (ObjectChunk)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false);
+     return new ChunkValueWrapper(c);
+   }
+ 
+   @Before
+   public void setUp() throws Exception {
 -    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+   }
+ 
+   @Test
+   public void testIsSerialized() {
+     assertEquals(true, createChunkValueWrapper(new byte[16], true).isSerialized());
+     assertEquals(false, createChunkValueWrapper(new byte[16], false).isSerialized());
+   }
+   
+   @Test
+   public void testGetUserBits() {
+     assertEquals((byte)1, createChunkValueWrapper(new byte[16], true).getUserBits());
+     assertEquals((byte)0, createChunkValueWrapper(new byte[16], false).getUserBits());
+   }
+   
+   @Test
+   public void testGetLength() {
+     assertEquals(32, createChunkValueWrapper(new byte[32], true).getLength());
+     assertEquals(17, createChunkValueWrapper(new byte[17], false).getLength());
+   }
+   
+   @Test
+   public void testGetBytesAsString() {
+     assertEquals("byte[0, 0, 0, 0, 0, 0, 0, 0]", createChunkValueWrapper(new byte[8], false).getBytesAsString());
+   }
+   
+   @Test
+   public void testSendTo() throws IOException {
+     final ByteBuffer bb = ByteBuffer.allocateDirect(18);
+     bb.limit(8);
+     ChunkValueWrapper vw = createChunkValueWrapper(new byte[]{1,2,3,4,5,6,7,8}, false);
+     vw.sendTo(bb, new Flushable() {
+       @Override
+       public void flush() throws IOException {
+         fail("should not have been called");
+       }
+ 
+       @Override
+       public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException {
+         fail("should not have been called");
+       }
+     });
+     assertEquals(8, bb.position());
+     bb.flip();
+     assertEquals(1, bb.get());
+     assertEquals(2, bb.get());
+     assertEquals(3, bb.get());
+     assertEquals(4, bb.get());
+     assertEquals(5, bb.get());
+     assertEquals(6, bb.get());
+     assertEquals(7, bb.get());
+     assertEquals(8, bb.get());
+     
+     bb.clear();
+     bb.limit(8);
+     vw = createChunkValueWrapper(new byte[]{1,2,3,4,5,6,7,8,9}, false);
+     final int[] flushCalls = new int[1];
+     vw.sendTo(bb, new Flushable() {
+       @Override
+       public void flush() throws IOException {
+         if (flushCalls[0] != 0) {
+           fail("expected flush to only be called once");
+         }
+         flushCalls[0]++;
+         assertEquals(8, bb.position());
+         for (int i=0; i < 8; i++) {
+           assertEquals(i+1, bb.get(i));
+         }
+         bb.clear();
+         bb.limit(8);
+       }
+ 
+       @Override
+       public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException {
+         fail("should not have been called");
+       }
+     });
+     assertEquals(1, bb.position());
+     bb.flip();
+     assertEquals(9, bb.get());
+     
+     bb.clear();
+     bb.limit(8);
+     flushCalls[0] = 0;
+     vw = createChunkValueWrapper(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, false);
+     vw.sendTo(bb, new Flushable() {
+       @Override
+       public void flush() throws IOException {
+         if (flushCalls[0] > 1) {
+           fail("expected flush to only be called twice");
+         }
+         assertEquals(8, bb.position());
+         for (int i=0; i < 8; i++) {
+           assertEquals((flushCalls[0]*8)+i+1, bb.get(i));
+         }
+         flushCalls[0]++;
+         bb.clear();
+         bb.limit(8);
+       }
+ 
+       @Override
+       public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException {
+         fail("should not have been called");
+       }
+     });
+     assertEquals(1, bb.position());
+     bb.flip();
+     assertEquals(17, bb.get());
+     
+     // now test with a chunk that will not fit in bb.
+     bb.clear();
+     flushCalls[0] = 0;
+     bb.put((byte) 0);
+     vw = createChunkValueWrapper(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}, false);
+     vw.sendTo(bb, new Flushable() {
+       @Override
+       public void flush() throws IOException {
+         fail("should not have been called");
+       }
+ 
+       @Override
+       public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException {
+         flushCalls[0]++;
+         assertEquals(1, bb.position());
+         bb.flip();
+         assertEquals(0, bb.get());
+         assertEquals(19, chunkbb.remaining());
+         for (int i=1; i <= 19; i++) {
+           assertEquals(i, chunkbb.get());
+         }
+       }
+     });
+     assertEquals(1, flushCalls[0]);
+   }
+ }


[082/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
index 0000000,2092508..b6d8c49
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
@@@ -1,0 -1,12975 +1,12975 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import static com.gemstone.gemfire.internal.offheap.annotations.OffHeapIdentifier.*;
+ 
+ import java.io.DataInputStream;
+ import java.io.DataOutputStream;
+ import java.io.File;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
+ import java.util.AbstractSet;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.EnumSet;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Hashtable;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.NoSuchElementException;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.ExecutionException;
+ import java.util.concurrent.Future;
+ import java.util.concurrent.RejectedExecutionException;
+ import java.util.concurrent.Semaphore;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.concurrent.locks.Lock;
+ import java.util.concurrent.locks.ReentrantLock;
+ import java.util.regex.Pattern;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelCriterion;
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.CopyHelper;
+ import com.gemstone.gemfire.DataSerializable;
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.DeltaSerializationException;
+ import com.gemstone.gemfire.InternalGemFireError;
+ import com.gemstone.gemfire.InternalGemFireException;
+ import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.admin.internal.SystemMemberCacheEventProcessor;
+ import com.gemstone.gemfire.cache.AttributesMutator;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.cache.CacheEvent;
+ import com.gemstone.gemfire.cache.CacheException;
+ import com.gemstone.gemfire.cache.CacheListener;
+ import com.gemstone.gemfire.cache.CacheLoader;
+ import com.gemstone.gemfire.cache.CacheLoaderException;
+ import com.gemstone.gemfire.cache.CacheRuntimeException;
+ import com.gemstone.gemfire.cache.CacheStatistics;
+ import com.gemstone.gemfire.cache.CacheWriter;
+ import com.gemstone.gemfire.cache.CacheWriterException;
+ import com.gemstone.gemfire.cache.CustomExpiry;
+ import com.gemstone.gemfire.cache.DataPolicy;
+ import com.gemstone.gemfire.cache.DiskAccessException;
+ import com.gemstone.gemfire.cache.DiskStoreFactory;
+ import com.gemstone.gemfire.cache.DiskWriteAttributes;
+ import com.gemstone.gemfire.cache.DiskWriteAttributesFactory;
+ import com.gemstone.gemfire.cache.EntryDestroyedException;
+ import com.gemstone.gemfire.cache.EntryExistsException;
+ import com.gemstone.gemfire.cache.EntryNotFoundException;
+ import com.gemstone.gemfire.cache.EvictionAttributes;
+ import com.gemstone.gemfire.cache.ExpirationAttributes;
+ import com.gemstone.gemfire.cache.FailedSynchronizationException;
+ import com.gemstone.gemfire.cache.InterestRegistrationEvent;
+ import com.gemstone.gemfire.cache.InterestResultPolicy;
+ import com.gemstone.gemfire.cache.LoaderHelper;
+ import com.gemstone.gemfire.cache.LowMemoryException;
+ import com.gemstone.gemfire.cache.Operation;
+ import com.gemstone.gemfire.cache.PartitionedRegionStorageException;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionAttributes;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.RegionEvent;
+ import com.gemstone.gemfire.cache.RegionExistsException;
+ import com.gemstone.gemfire.cache.RegionMembershipListener;
+ import com.gemstone.gemfire.cache.RegionReinitializedException;
+ import com.gemstone.gemfire.cache.Scope;
+ import com.gemstone.gemfire.cache.StatisticsDisabledException;
+ import com.gemstone.gemfire.cache.TimeoutException;
+ import com.gemstone.gemfire.cache.TransactionException;
+ import com.gemstone.gemfire.cache.TransactionId;
+ import com.gemstone.gemfire.cache.client.PoolManager;
+ import com.gemstone.gemfire.cache.client.ServerOperationException;
+ import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
+ import com.gemstone.gemfire.cache.client.internal.Connection;
+ import com.gemstone.gemfire.cache.client.internal.Endpoint;
+ import com.gemstone.gemfire.cache.client.internal.PoolImpl;
+ import com.gemstone.gemfire.cache.client.internal.ServerRegionProxy;
+ import com.gemstone.gemfire.cache.control.ResourceManager;
+ import com.gemstone.gemfire.cache.execute.Function;
+ import com.gemstone.gemfire.cache.execute.ResultCollector;
+ import com.gemstone.gemfire.cache.hdfs.internal.HDFSBucketRegionQueue;
+ import com.gemstone.gemfire.cache.hdfs.internal.HDFSIntegrationUtil;
+ import com.gemstone.gemfire.cache.hdfs.internal.HoplogListenerForRegion;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSRegionDirector;
+ import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSRegionDirector.HdfsRegionManager;
+ import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+ import com.gemstone.gemfire.cache.query.FunctionDomainException;
+ import com.gemstone.gemfire.cache.query.Index;
+ import com.gemstone.gemfire.cache.query.IndexMaintenanceException;
+ import com.gemstone.gemfire.cache.query.IndexType;
+ import com.gemstone.gemfire.cache.query.MultiIndexCreationException;
+ import com.gemstone.gemfire.cache.query.NameResolutionException;
+ import com.gemstone.gemfire.cache.query.QueryException;
+ import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+ import com.gemstone.gemfire.cache.query.QueryService;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.query.TypeMismatchException;
+ import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
+ import com.gemstone.gemfire.cache.query.internal.DefaultQueryService;
+ import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
+ import com.gemstone.gemfire.cache.query.internal.IndexUpdater;
+ import com.gemstone.gemfire.cache.query.internal.cq.CqService;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexCreationData;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexManager;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexProtocol;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexUtils;
+ import com.gemstone.gemfire.cache.util.ObjectSizer;
+ import com.gemstone.gemfire.cache.wan.GatewaySender;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.DM;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor;
+ import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
+ import com.gemstone.gemfire.distributed.internal.DistributionStats;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.ResourceEvent;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.ClassLoadUtil;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.InternalStatisticsDisabledException;
+ import com.gemstone.gemfire.internal.NanoTimer;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.CacheProfile;
+ import com.gemstone.gemfire.internal.cache.DiskInitFile.DiskRegionFlag;
+ import com.gemstone.gemfire.internal.cache.FilterRoutingInfo.FilterInfo;
+ import com.gemstone.gemfire.internal.cache.InitialImageOperation.GIIStatus;
+ import com.gemstone.gemfire.internal.cache.PutAllPartialResultException.PutAllPartialResult;
+ import com.gemstone.gemfire.internal.cache.control.InternalResourceManager;
+ import com.gemstone.gemfire.internal.cache.control.InternalResourceManager.ResourceType;
+ import com.gemstone.gemfire.internal.cache.control.MemoryEvent;
+ import com.gemstone.gemfire.internal.cache.control.MemoryThresholds;
+ import com.gemstone.gemfire.internal.cache.control.ResourceListener;
+ import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionExecutor;
+ import com.gemstone.gemfire.internal.cache.execute.DistributedRegionFunctionResultSender;
+ import com.gemstone.gemfire.internal.cache.execute.LocalResultCollector;
+ import com.gemstone.gemfire.internal.cache.execute.RegionFunctionContextImpl;
+ import com.gemstone.gemfire.internal.cache.execute.ServerToClientFunctionResultSender;
+ import com.gemstone.gemfire.internal.cache.ha.ThreadIdentifier;
+ import com.gemstone.gemfire.internal.cache.lru.LRUEntry;
+ import com.gemstone.gemfire.internal.cache.partitioned.RedundancyAlreadyMetException;
+ import com.gemstone.gemfire.internal.cache.persistence.DiskExceptionHandler;
+ import com.gemstone.gemfire.internal.cache.persistence.DiskRecoveryStore;
+ import com.gemstone.gemfire.internal.cache.persistence.DiskRegionView;
+ import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberID;
+ import com.gemstone.gemfire.internal.cache.persistence.query.IndexMap;
+ import com.gemstone.gemfire.internal.cache.persistence.query.mock.IndexMapImpl;
+ import com.gemstone.gemfire.internal.cache.tier.InterestType;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientNotifier;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientHealthMonitor;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientTombstoneMessage;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientUpdateMessage;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+ import com.gemstone.gemfire.internal.cache.versions.ConcurrentCacheModificationException;
+ import com.gemstone.gemfire.internal.cache.versions.RegionVersionHolder;
+ import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
+ import com.gemstone.gemfire.internal.cache.versions.VersionSource;
+ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
+ import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventCallbackArgument;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.internal.sequencelog.EntryLogger;
+ import com.gemstone.gemfire.internal.util.concurrent.FutureResult;
+ import com.gemstone.gemfire.internal.util.concurrent.StoppableCountDownLatch;
+ import com.gemstone.gemfire.internal.util.concurrent.StoppableReadWriteLock;
+ import com.gemstone.gemfire.i18n.StringId;
+ 
+ /**
+  * Implementation of a local scoped-region. Note that this class has a different
+  * meaning starting with 3.0. In previous versions, a LocalRegion was the
+  * representation of a region in the VM. Starting with 3.0, a LocalRegion is a
+  * non-distributed region. The subclass DistributedRegion adds distribution
+  * behavior.
+  *
+  * @author Eric Zoerner
+  */
+ @SuppressWarnings("deprecation")
+ public class LocalRegion extends AbstractRegion 
+   implements LoaderHelperFactory, ResourceListener<MemoryEvent>,
+              DiskExceptionHandler, DiskRecoveryStore
+ {
+   private static final Logger logger = LogService.getLogger();
+   
+   /**
+    * Internal interface used to simulate failures when performing entry operations
+    * @author Mitch Thomas
+    * @since 5.7
+    */
+   public interface TestCallable {
+     public void call(LocalRegion r, Operation op, RegionEntry re);
+   }
+ 
+   // view types for iterators
+   public enum IteratorType {
+     KEYS, VALUES, ENTRIES
+   }
+ 
+   // iniitialization level
+   public static final int AFTER_INITIAL_IMAGE = 0;
+ 
+   public static final int BEFORE_INITIAL_IMAGE = 1;
+ 
+   public static final int ANY_INIT = 2;
+ 
+   /**
+    * thread local to indicate that this thread should bypass the initialization
+    * Latch
+    */
+   private static final ThreadLocal initializationThread = new ThreadLocal();
+ 
+   /* thread local to indicate its for persist data convert tool */
+   protected static final ThreadLocal isConversion = new ThreadLocal();
+   
+   // user attributes //
+   private Object regionUserAttribute;
+ 
+   protected Map entryUserAttributes; // @todo darrel: shouldn't this be an
+ 
+   // identity map whose key is a RegionEntry?
+ 
+   private final String regionName;
+ 
+   protected final LocalRegion parentRegion;
+ 
+   // set to true only if isDestroyed is also true
+   // and region is about to be recreated due to reinitialization by loading
+   // of a snapshot, etc.
+   private volatile boolean reinitialized_old = false;
+ 
+   protected volatile boolean isDestroyed = false;
+ 
+   // In case of parallel wan, when a destroy is called on userPR, it waits for
+   // parallelQueue to drain and then destroys paralleQueue. In this time if
+   // operation like put happens on userPR then it will keep on building parallel
+   // queue increasing time of userPR to get destroyed.this volatile boolean will
+   // block such put operation by throwing RegionDestroyedException
+   protected volatile boolean isDestroyedForParallelWAN = false;
+ 
+   // set to true after snapshot is loaded, to help get initial image
+   // make sure this is the right incarnation of this region
+   private volatile boolean reinitialized_new = false;
+ 
+   /** Lock used to prevent multiple concurrent destroy region operations */
+   private Semaphore destroyLock;
+ 
+   //guarded by regionExpiryLock.
+   private RegionTTLExpiryTask regionTTLExpiryTask = null;
+   //guarded by regionExpiryLock.
+   private RegionIdleExpiryTask regionIdleExpiryTask = null;
+   
+   private final Object regionExpiryLock = new Object();
+   // guarded by regionExpiryLock. Keeps track of how many txs are writing to this region.
+   private int txRefCount;
+ 
+   private final ConcurrentHashMap<RegionEntry, EntryExpiryTask> entryExpiryTasks = new ConcurrentHashMap<RegionEntry, EntryExpiryTask>();
+ 
+   /**
+    * Set to true after an invalidate region expiration so we don't get multiple
+    * expirations
+    */
+   volatile boolean regionInvalid = false;
+ 
+   public final RegionMap entries;
+ 
+   /**
+    * Set to true if this region supports transaction else false.
+    */
+   private final boolean supportsTX;
+ 
+   /** tracks threadID->seqno information for this region */
+   protected EventTracker eventTracker;
+   
+   /** tracks region-level version information for members.  See
+    * https://wiki.gemstone.com/display/gfe70/Consistency+in+Replicated+Regions+and+WAN
+    */
+   private RegionVersionVector versionVector;
+ 
+   private static final Pattern[] QUERY_PATTERNS = new Pattern[] {
+       Pattern.compile("^\\(*select .*", Pattern.CASE_INSENSITIVE
+           | Pattern.UNICODE_CASE | Pattern.DOTALL),
+       Pattern.compile("^import .*", Pattern.CASE_INSENSITIVE
+           | Pattern.UNICODE_CASE | Pattern.DOTALL) };
+ 
+ 
+   public static final String EXPIRY_MS_PROPERTY = "gemfire.EXPIRY_UNITS_MS";
+   
+   /**
+    * Used by unit tests to set expiry to milliseconds instead of the default
+    * seconds. Used in ExpiryTask.
+    *
+    * @since 5.0
+    */
+   final boolean EXPIRY_UNITS_MS;
+ 
+   // Indicates that the entries are in fact initialized. It turns out
+   // you can't trust the assignment of a volatile (as indicated above)
+   // to mean that the the thing being assigned is fully formed, only
+   // those things *before* the assignment are fully formed. mthomas 10/02/2005
+   private volatile boolean entriesInitialized;
+ 
+   /**
+    * contains Regions themselves // marked volatile to make sure it is fully
+    * initialized before being // accessed; (actually should be final)
+    */
+   protected volatile ConcurrentMap subregions;
+ 
+   private final Object subregionsLock = new Object();
+ 
+   // Used for synchronizzing access to client Cqs
+ //  private final Object clientCqsSync = new Object();
+ 
+   /**
+    * Prevents access to this region until it is done initializing, except for
+    * some special initializing operations such as replying to create region
+    * messages In JDK 1.5 we will use java.util.concurrent.CountDownLatch instead
+    * of com.gemstone.gemfire.internal.util.CountDownLatch.
+    */
+   protected final StoppableCountDownLatch initializationLatchBeforeGetInitialImage;
+ 
+   protected final StoppableCountDownLatch initializationLatchAfterGetInitialImage;
+ 
+   /**
+    * Used to hold off cache listener events until the afterRegionCreate is
+    * called
+    *
+    * @since 5.0
+    */
+   private final StoppableCountDownLatch afterRegionCreateEventLatch;
+ 
+   /**
+    * Set to true the first time isInitialized returns true.
+    */
+   private volatile boolean initialized = false; // added for bug 30223
+ 
+   /** Used for accessing region data on disk */
+   private final DiskRegion diskRegion;
+   
+   /**
+    * Used by transactions to suspend entry expiration while a transaction is in
+    * progress on a region. This field is only initialized if expiration is
+    * configured and transactions are possible.
+    */
+   private volatile StoppableReadWriteLock txExpirationLock;
+ 
+   /**
+    * Used for serializing netSearch and netLoad on a per key basis.
+    * CM <Object, Future>
+    */
+   protected final ConcurrentMap getFutures = new ConcurrentHashMap();
+ 
+   /*
+    * Asif: This boolean needs to be made true if the test needs to receive a
+    * synchronous callback just after clear on map is done. Its visibility is
+    * default so that only tests present in com.gemstone.gemfire.internal.cache
+    * will be able to see it
+    */
+   public static boolean ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false;
+ 
+   /**
+    * A flag used to indicate that this Region is being used as an administrative
+    * Region, holding meta-data for a PartitionedRegion
+    */
+   final private boolean isUsedForPartitionedRegionAdmin;
+ 
+   final private boolean isUsedForPartitionedRegionBucket;
+ 
+   final private boolean isUsedForMetaRegion;
+   
+   final private boolean isMetaRegionWithTransactions;
+   
+   final private boolean isUsedForSerialGatewaySenderQueue;
+   
+   final private boolean isUsedForParallelGatewaySenderQueue;
+   
+   final private AbstractGatewaySender serialGatewaySender;
+ 
+   /**
+    * The factory used to create the LoaderHelper when a loader is invoked
+    */
+   protected final LoaderHelperFactory loaderHelperFactory;
+ 
+   /**
+    * Allow for different cacheperfstats locations... primarily for PartitionedRegions
+    */
+   private final CachePerfStats cachePerfStats;
+   private final boolean hasOwnStats; 
+ 
+ 
+   private final ImageState imageState;
+   /**
+    * Register interest count to track if any register interest is in progress for
+    * this region. This count will be incremented when register interest starts
+    * and decremented when register interest finishes.
+    * @guarded.By {@link #imageState}
+    */
+   private int riCnt = 0; /*
+                           * since always written while holding an exclusive write lock
+                           * and only read while holding a read lock
+                           * it does not need to be atomic or
+                           * protected by any other sync.
+                           */
+ 
+ 
+   /**
+    * Map of subregion full paths to serial numbers. These are subregions that
+    * were destroyed when this region was destroyed. This map remains null until
+    * this region is destroyed.
+    */
+   private volatile HashMap destroyedSubregionSerialNumbers;
+ 
+   /**
+    * This boolean is true when a member who has this region is running low on memory.
+    * It is used to reject region operations.
+    */
+   public final AtomicBoolean memoryThresholdReached = new AtomicBoolean(false);
+ 
+   // Lock for updating PR MetaData on client side 
+   public final Lock clientMetaDataLock = new ReentrantLock();
+   
+   
+   protected HdfsRegionManager hdfsManager;
+   protected HoplogListenerForRegion hoplogListener;
+ 
+   /**
+    * There seem to be cases where a region can be created and yet the
+    * distributed system is not yet in place...
+    *
+    * @author jpenney
+    *
+    */
+   protected class Stopper extends CancelCriterion {
+ 
+     @Override
+     public String cancelInProgress() {
+       // ---
+       // This grossness is necessary because there are instances where the
+       // region can exist without having a cache (XML creation)
+       checkFailure();
+       Cache c = LocalRegion.this.getCache();
+       if (c == null) {
+         return LocalizedStrings.LocalRegion_THE_CACHE_IS_NOT_AVAILABLE.toLocalizedString();
+       }
+       // --- end of grossness
+       return c.getCancelCriterion().cancelInProgress();
+     }
+ 
+     /* (non-Javadoc)
+      * @see com.gemstone.gemfire.CancelCriterion#generateCancelledException(java.lang.Throwable)
+      */
+     @Override
+     public RuntimeException generateCancelledException(Throwable e) {
+       // ---
+       // This grossness is necessary because there are instances where the
+       // region can exist without having a cache (XML creation)
+       checkFailure();
+       Cache c = LocalRegion.this.getCache();
+       if (c == null) {
+         return new CacheClosedException("No cache", e);
+       }
+       // --- end of grossness
+       return c.getCancelCriterion().generateCancelledException(e);
+     }
+ 
+   }
+ 
+   protected final CancelCriterion stopper = createStopper();
+ 
+   protected CancelCriterion createStopper() {
+     return new Stopper();
+   }
+ 
+   private final TestCallable testCallable;
+ 
+   /**
+    * ThreadLocal used to set the current region being initialized.
+    * 
+    * Currently used by the OpLog layer to initialize the
+    * {@link KeyWithRegionContext} if required.
+    */
+   private final static ThreadLocal<LocalRegion> initializingRegion =
+     new ThreadLocal<LocalRegion>();
+ 
+   /**
+    * Set to true if the region contains keys implementing
+    * {@link KeyWithRegionContext} that require setting up of region specific
+    * context after deserialization or recovery from disk.
+    */
+   private boolean keyRequiresRegionContext;
+ 
+   /**
+    * Get the current initializing region as set in the ThreadLocal.
+    * 
+    * Note that this value is cleared after the initialization of LocalRegion is
+    * done so is valid only for the duration of region creation and
+    * initialization.
+    */
+   public static LocalRegion getInitializingRegion() {
+     return initializingRegion.get();
+   }
+ 
+   /**
+    * Return true if the keys of this region implement
+    * {@link KeyWithRegionContext} that require region specific context
+    * initialization after deserialization or recovery from disk.
+    * 
+    * Currently used by SQLFabric for the optimized
+    * <code>CompactCompositeRegionKey</code> that points to the raw row bytes and
+    * so requires a handle to table schema for interpretation of those bytes.
+    */
+   public final boolean keyRequiresRegionContext() {
+     return this.keyRequiresRegionContext;
+   }
+ 
+   /**
+    * Set the {@link #keyRequiresRegionContext} flag to given value.
+    */
+   public final void setKeyRequiresRegionContext(boolean v) {
+     this.keyRequiresRegionContext = v;
+   }
+ 
+   public CancelCriterion getCancelCriterion() {
+     return this.stopper;
+   }
+ 
+   ////////////////// Public Methods ///////////////////////////////////////////
+ 
+   static String calcFullPath(String regionName, LocalRegion parentRegion) {
+     StringBuilder buf = null;
+     if (parentRegion == null) {
+       buf = new StringBuilder(regionName.length() + 1);
+     }
+     else {
+       String parentFull = parentRegion.getFullPath();
+       buf = new StringBuilder(parentFull.length() + regionName.length() + 1);
+       buf.append(parentFull);
+     }
+     buf.append(SEPARATOR).append(regionName);
+     return buf.toString();
+   }
+ 
+   /**
+    * Creates new region
+    */
+   protected LocalRegion(String regionName, RegionAttributes attrs,
+       LocalRegion parentRegion, GemFireCacheImpl cache,
+       InternalRegionArguments internalRegionArgs) throws DiskAccessException {
+     super(cache, attrs,regionName, internalRegionArgs);
+     // Initialized here (and defers to parent) to fix GEODE-128
+     this.EXPIRY_UNITS_MS = parentRegion != null ? parentRegion.EXPIRY_UNITS_MS : Boolean.getBoolean(EXPIRY_MS_PROPERTY);
+ 
+     Assert.assertTrue(regionName != null, "regionName must not be null");
+     this.sharedDataView = buildDataView();
+     this.regionName = regionName;
+     this.parentRegion = parentRegion;
+     this.fullPath = calcFullPath(regionName, parentRegion);
+ 
+     String myName = getFullPath();
+     if (internalRegionArgs.getPartitionedRegion() != null) {
+       myName = internalRegionArgs.getPartitionedRegion().getFullPath();
+     }
+     this.offHeap = attrs.getOffHeap() || Boolean.getBoolean(myName+":OFF_HEAP");
+     if (getOffHeap()) {
+       if (cache.getOffHeapStore() == null) {
+         throw new IllegalStateException(LocalizedStrings.
+             LocalRegion_THE_REGION_0_WAS_CONFIGURED_TO_USE_OFF_HEAP_MEMORY_BUT_OFF_HEAP_NOT_CONFIGURED.toLocalizedString(myName));
+       }
+     }
+     
+     this.initializationLatchBeforeGetInitialImage = new StoppableCountDownLatch(this.stopper, 1);
+     this.initializationLatchAfterGetInitialImage = new StoppableCountDownLatch(this.stopper, 1);
+     this.afterRegionCreateEventLatch = new StoppableCountDownLatch(this.stopper, 1);
+ 
+     // set the user-attribute object upfront for SQLFabric
+     if (internalRegionArgs.getUserAttribute() != null) {
+       setUserAttribute(internalRegionArgs.getUserAttribute());
+     }
+     setKeyRequiresRegionContext(internalRegionArgs.keyRequiresRegionContext());
+     initializingRegion.set(this);
+ 
+     if (internalRegionArgs.getCachePerfStatsHolder() != null) {
+       this.hasOwnStats = false;
+       this.cachePerfStats = internalRegionArgs.getCachePerfStatsHolder()
+           .getCachePerfStats();
+     }
+     else {
+       if (attrs.getPartitionAttributes() != null || isInternalRegion()
+           || internalRegionArgs.isUsedForMetaRegion()) {
+         this.hasOwnStats = false;
+         this.cachePerfStats = cache.getCachePerfStats();
+       }
+       else {
+         this.hasOwnStats = true;
+         this.cachePerfStats = new RegionPerfStats(cache, cache.getCachePerfStats(), regionName);
+       }
+     }
+ 
+     this.hdfsManager = initHDFSManager();
+     this.dsi = findDiskStore(attrs, internalRegionArgs);
+     this.diskRegion = createDiskRegion(internalRegionArgs);
+     this.entries = createRegionMap(internalRegionArgs);
+     this.entriesInitialized = true;
+     this.subregions = new ConcurrentHashMap();
+     // we only need a destroy lock if this is a root
+     if (parentRegion == null) {
+       initRoot();
+     }
+     if (internalRegionArgs.getLoaderHelperFactory() != null) {
+       this.loaderHelperFactory = internalRegionArgs.getLoaderHelperFactory();
+     }
+     else {
+       this.loaderHelperFactory = this;
+     }
+ 
+     this.isUsedForPartitionedRegionAdmin = internalRegionArgs
+         .isUsedForPartitionedRegionAdmin();
+     this.isUsedForPartitionedRegionBucket = internalRegionArgs
+         .isUsedForPartitionedRegionBucket();
+     this.isUsedForMetaRegion = internalRegionArgs
+         .isUsedForMetaRegion();
+     this.isMetaRegionWithTransactions = internalRegionArgs.isMetaRegionWithTransactions();
+     this.isUsedForSerialGatewaySenderQueue = internalRegionArgs.isUsedForSerialGatewaySenderQueue();
+     this.isUsedForParallelGatewaySenderQueue = internalRegionArgs.isUsedForParallelGatewaySenderQueue();
+     this.serialGatewaySender = internalRegionArgs.getSerialGatewaySender();
+     
+     if (!isUsedForMetaRegion && !isUsedForPartitionedRegionAdmin
+         && !isUsedForPartitionedRegionBucket
+         && !isUsedForSerialGatewaySenderQueue
+         && !isUsedForParallelGatewaySenderQueue) {
+       this.filterProfile = new FilterProfile(this);
+     }
+     
+     // initialize client to server proxy
+     this.srp = (this.getPoolName() != null)
+       ? new ServerRegionProxy(this)
+       : null;
+     this.imageState =
+       new UnsharedImageState(this.srp != null,
+                              getDataPolicy().withReplication() || getDataPolicy().isPreloaded(),
+                              getAttributes().getDataPolicy().withPersistence(),
+                              this.stopper);
+ 
+     createEventTracker();
+ 
+     // prevent internal regions from participating in a TX, bug 38709
+     this.supportsTX = !isSecret() && !isUsedForPartitionedRegionAdmin()
+         && !isUsedForMetaRegion() || isMetaRegionWithTransactions();
+ 
+     this.testCallable = internalRegionArgs.getTestCallable();
+     
+   }
+ 
+   private HdfsRegionManager initHDFSManager() {
+     HdfsRegionManager hdfsMgr = null;
+     if (this.getHDFSStoreName() != null) {
+       this.hoplogListener = new HoplogListenerForRegion();
+       HDFSRegionDirector.getInstance().setCache(cache);
+       hdfsMgr = HDFSRegionDirector.getInstance().manageRegion(this, 
+           this.getHDFSStoreName(), hoplogListener);
+     }
+     return hdfsMgr;
+   }
+ 
+   private RegionMap createRegionMap(InternalRegionArguments internalRegionArgs) {
+     RegionMap result = null;
+ 	if ((internalRegionArgs.isReadWriteHDFSRegion()) && this.diskRegion != null) {
+       this.diskRegion.setEntriesMapIncompatible(true);
+     }
+     if (this.diskRegion != null) {
+       result = this.diskRegion.useExistingRegionMap(this);
+     }
+     if (result == null) {
+       RegionMap.Attributes ma = new RegionMap.Attributes();
+       ma.statisticsEnabled = this.statisticsEnabled;
+       ma.loadFactor = this.loadFactor;
+       ma.initialCapacity = this.initialCapacity;
+       ma.concurrencyLevel = this.concurrencyLevel;
+       result = RegionMapFactory.createVM(this, ma, internalRegionArgs);
+     }
+     return result;
+   }
+   
+   protected InternalDataView buildDataView() {
+     return new LocalRegionDataView();
+   }
+ 
+   /**
+    * initialize the event tracker.  Not all region implementations want or
+    * need one of these. Regions that require one should reimplement this method
+    * and create one like so:
+    * <code><pre>
+    *     this.eventTracker = new EventTracker(this.cache);
+    *     this.eventTracker.start();
+    * </pre></code>
+    */
+   void createEventTracker() {
+     // if LocalRegion is changed to have an event tracker, then the initialize()
+     // method should be changed to set it to "initialized" state when the
+     // region finishes initialization
+   }
+   
+   
+   /**
+    * Test method for getting the event tracker.
+    * 
+    * this method is for testing only.  Other region classes may track events using
+    * different mechanisms than EventTrackers
+    */
+   protected EventTracker getEventTracker() {
+     return this.eventTracker;
+   }
+   
+   /** returns the regions version-vector */
+   public RegionVersionVector getVersionVector() {
+     return this.versionVector;
+   }
+   
+   /** returns object used to guard the size() operation during tombstone removal */
+   public Object getSizeGuard() {
+     if (!this.concurrencyChecksEnabled) {
+       return new Object();
+     } else {
+       return this.fullPath; // avoids creating another sync object - could be anything unique to this region
+     }
+   }
+   
+   /** initializes a new version vector for this region */
+   protected void createVersionVector() {
+     
+     this.versionVector = RegionVersionVector.create(getVersionMember(), this);
+     
+     if (dataPolicy.withPersistence()) {
+       //copy the versions that we have recovered from disk into
+       //the version vector.
+       RegionVersionVector diskVector = this.diskRegion.getRegionVersionVector();
+       this.versionVector.recordVersions(diskVector.getCloneForTransmission());
+     } else if (!dataPolicy.withStorage()) {
+       // version vectors are currently only necessary in empty regions for
+       // tracking canonical member IDs
+       this.versionVector.turnOffRecordingForEmptyRegion();
+     }
+     if (this.srp != null) {
+       this.versionVector.setIsClientVector();
+     }
+     this.cache.getDistributionManager().addMembershipListener(this.versionVector);
+   }
+   
+   @Override
+   protected void updateEntryExpiryPossible()
+   {
+     super.updateEntryExpiryPossible();
+     if (!isEntryExpiryPossible()) {
+       // since expiration is no longer possible cleanup the tasks
+       cancelAllEntryExpiryTasks();
+     }
+   }
+ 
+   public IndexUpdater getIndexUpdater() {
+     return this.entries.getIndexUpdater();
+   }
+ 
+   boolean isCacheClosing()
+   {
+     return this.cache.isClosed();
+   }
+ 
+   public RegionEntry getRegionEntry(Object key) {
+     return this.entries.getEntry(key);
+   }
+   
+   /**
+    * Test hook - returns the version stamp for an entry in the form of a
+    * version tag
+    * @param key
+    * @return the entry version information
+    */
+   public VersionTag getVersionTag(Object key) {
+     Region.Entry entry = getEntry(key, true);
+     VersionTag tag = null;
+     if (entry != null && entry instanceof EntrySnapshot) {
+       tag = ((EntrySnapshot)entry).getVersionTag();
+     } else if (entry != null && entry instanceof NonTXEntry) {
+       tag = ((NonTXEntry)entry).getRegionEntry().getVersionStamp().asVersionTag();
+     }
+     return tag;
+   }
+   
+   /** removes any destroyed entries from the region and clear the destroyedKeys
+    * assert: Caller must be holding writeLock on is
+    */
+   private void destroyEntriesAndClearDestroyedKeysSet() {
+     ImageState is = getImageState();
+     Iterator iter = is.getDestroyedEntries();
+     while (iter.hasNext()) {
+       Object key = iter.next();
+       // destroy the entry which has value Token.DESTROYED
+       // If it is Token.DESTROYED then only destroy it.
+       this.entries.removeIfDestroyed(key); // fixes bug 41957
+     }
+   }
+ 
+   /**
+    * @since 5.7
+    */
+   protected final ServerRegionProxy srp;
+ 
+   private final InternalDataView sharedDataView;
+ 
+   public final ServerRegionProxy getServerProxy() {
+     return this.srp;
+   }
+   
+   public final boolean hasServerProxy() {
+     return this.srp != null;
+   }
+ 
+   /** Returns true if the ExpiryTask is currently allowed to expire. */
+   protected boolean isExpirationAllowed(ExpiryTask expiry)
+   {
+     return true;
+   }
+ 
+   void performExpiryTimeout(ExpiryTask p_task) throws CacheException
+   {
+     if (p_task != null) {
+       p_task.basicPerformTimeout(false);
+     }
+   }
+ 
+   private void initRoot()
+   {
+     this.destroyLock = new Semaphore(1);
+   }
+ 
+   public void handleMarker() {
+     
+     RegionEventImpl event = new RegionEventImpl(this,
+         Operation.MARKER, null, false, getMyId(),
+         false /* generate EventID */);
+ 
+     dispatchListenerEvent(EnumListenerEvent.AFTER_REGION_LIVE, event);
+   }
+ 
+   public AttributesMutator getAttributesMutator()
+   {
+     checkReadiness();
+     return this;
+   }
+ 
+   public Region createSubregion(String subregionName,
+       RegionAttributes regionAttributes) throws RegionExistsException,
+       TimeoutException
+   {
+     try {
+       return createSubregion(subregionName, regionAttributes,
+           new InternalRegionArguments().setDestroyLockFlag(true)
+               .setRecreateFlag(false));
+     }
+     catch (IOException e) {
+       // only happens when loading a snapshot, not here
+       InternalGemFireError assErr = new InternalGemFireError(LocalizedStrings.LocalRegion_UNEXPECTED_EXCEPTION.toLocalizedString());
+       assErr.initCause(e);
+       throw assErr;
+ 
+     }
+     catch (ClassNotFoundException e) {
+       // only happens when loading a snapshot, not here
+       InternalGemFireError assErr = new InternalGemFireError(LocalizedStrings.LocalRegion_UNEXPECTED_EXCEPTION.toLocalizedString());
+       assErr.initCause(e);
+       throw assErr;
+ 
+     }
+   }
+ 
+   /**
+    * Returns the member id of my distributed system
+    *
+    * @since 5.0
+    */
+   @Override
+   protected InternalDistributedMember getMyId()
+   {
+     return this.cache.getMyId();
+   }
+   
+   public VersionSource getVersionMember()
+   {
+     if(dataPolicy.withPersistence()) {
+       return getDiskStore().getDiskStoreID();
+     } else {
+       return this.cache.getMyId();
+     }
+   }
+ 
+   public Region createSubregion(String subregionName,
+       RegionAttributes attrs,
+       InternalRegionArguments internalRegionArgs) throws RegionExistsException,
+       TimeoutException, IOException, ClassNotFoundException
+   {
+     checkReadiness();
+     LocalRegion newRegion = null;
+     RegionAttributes regionAttributes = attrs;
+     attrs = cache.invokeRegionBefore(this, subregionName, attrs, internalRegionArgs);
+     final InputStream snapshotInputStream = internalRegionArgs
+         .getSnapshotInputStream();
+     final boolean getDestroyLock = internalRegionArgs.getDestroyLockFlag();
+     final InternalDistributedMember imageTarget = internalRegionArgs
+         .getImageTarget();
+     try {
+       if (getDestroyLock)
+         acquireDestroyLock();
+       LocalRegion existing = null;
+       try {
+         if (isDestroyed()) {
+           if (this.reinitialized_old) {
+             throw new RegionReinitializedException(toString(), getFullPath());
+           }
+           throw new RegionDestroyedException(toString(), getFullPath());
+         }
+         validateRegionName(subregionName);
+ 
+         validateSubregionAttributes(regionAttributes);
+         String regionPath = calcFullPath(subregionName, this);
+ 
+         // lock down the subregionsLock
+         // to prevent other threads from adding a region to it in toRegion
+         // but don't wait on initialization while synchronized (distributed
+         // deadlock)
+         synchronized (this.subregionsLock) {
+           
+           existing = (LocalRegion)this.subregions.get(subregionName);
+ 
+           if (existing == null) {
+             // create the async queue for HDFS if required. 
+             HDFSIntegrationUtil.createAndAddAsyncQueue(regionPath,
+                 regionAttributes, this.cache);
+             regionAttributes = cache.setEvictionAttributesForLargeRegion(
+                 regionAttributes);
+             if (regionAttributes.getScope().isDistributed()
+                 && internalRegionArgs.isUsedForPartitionedRegionBucket()) {
+               final PartitionedRegion pr = internalRegionArgs
+                   .getPartitionedRegion();
+               internalRegionArgs.setIndexUpdater(pr.getIndexUpdater());
+               internalRegionArgs.setUserAttribute(pr.getUserAttribute());
+               internalRegionArgs.setKeyRequiresRegionContext(pr
+                   .keyRequiresRegionContext());
+               if (pr.isShadowPR()) {
+                 if (!pr.isShadowPRForHDFS()) {
+                     newRegion = new BucketRegionQueue(subregionName, regionAttributes,
+                       this, this.cache, internalRegionArgs);
+                 }
+                 else {
+                    newRegion = new HDFSBucketRegionQueue(subregionName, regionAttributes,
+                       this, this.cache, internalRegionArgs);
+                 }
+                 
+               } else {
+                 newRegion = new BucketRegion(subregionName, regionAttributes,
+                     this, this.cache, internalRegionArgs);  
+               }
+             }
+             else if (regionAttributes.getPartitionAttributes() != null) {
+               newRegion = new PartitionedRegion(subregionName,
+                   regionAttributes, this, this.cache,  internalRegionArgs);
+             }
+             else {
+               boolean local = regionAttributes.getScope().isLocal();
+               newRegion = local ? new LocalRegion(subregionName,
+                   regionAttributes, this, this.cache, internalRegionArgs)
+                   : new DistributedRegion(subregionName, regionAttributes,
+                       this, this.cache, internalRegionArgs);
+             }
+             Object o = this.subregions.putIfAbsent(subregionName, newRegion);
+ 
+             Assert.assertTrue(o == null);
+ 
+             Assert.assertTrue(!newRegion.isInitialized());
+ 
+             //
+             if (logger.isDebugEnabled()) {
+               logger.debug("Subregion created: {}", newRegion.getFullPath());
+             }
+             if (snapshotInputStream != null || imageTarget != null
+                 || internalRegionArgs.getRecreateFlag()) {
+               this.cache.regionReinitialized(newRegion); // fix for bug 33534
+             }
+ 
+           } // endif: existing == null
+         } // end synchronization
+       }
+       finally {
+         if (getDestroyLock)
+           releaseDestroyLock();
+       }
+       
+       //Fix for bug 42127 - moved to outside of the destroy lock.
+       if (existing != null) {
+         // now outside of synchronization we must wait for appropriate
+         // initialization on existing region before returning a reference to
+         // it
+         existing.waitOnInitialization();
+         // fix for bug 32570
+         throw new RegionExistsException(existing);
+       }
+ 
+       
+       boolean success = false;
+       try {
+         newRegion.checkReadiness();
+         this.cache.setRegionByPath(newRegion.getFullPath(), newRegion);
+         if (regionAttributes instanceof UserSpecifiedRegionAttributes){
+           internalRegionArgs.setIndexes((
+             (UserSpecifiedRegionAttributes)regionAttributes).getIndexes());  
+         }
+         newRegion.initialize(snapshotInputStream, imageTarget, internalRegionArgs); // releases initialization Latches
+         //register the region with resource manager to get memory events
+         if(!newRegion.isInternalRegion()){
+           if (!newRegion.isDestroyed) {
+             cache.getResourceManager().addResourceListener(ResourceType.MEMORY, newRegion);
+             
+             if (!newRegion.getOffHeap()) {
+               newRegion.initialCriticalMembers(cache.getResourceManager().getHeapMonitor().getState().isCritical(), cache
+                   .getResourceAdvisor().adviseCritialMembers());
+             } else {
+               newRegion.initialCriticalMembers(cache.getResourceManager().getHeapMonitor().getState().isCritical()
+                   || cache.getResourceManager().getOffHeapMonitor().getState().isCritical(), cache.getResourceAdvisor()
+                   .adviseCritialMembers());
+             }
+ 
+             // synchronization would be done on ManagementAdapter.regionOpLock
+             // instead of destroyLock in LocalRegion? ManagementAdapter is one
+             // of the Resource Event listeners            
+             
+             InternalDistributedSystem system = this.cache
+                 .getDistributedSystem();
+             system.handleResourceEvent(ResourceEvent.REGION_CREATE, newRegion);
+           }
+         }
+         success = true;
+       } catch (CancelException | RegionDestroyedException | RedundancyAlreadyMetException e) {
+         // don't print a call stack
+         throw e;
+       } catch (final RuntimeException validationException) {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.LocalRegion_INITIALIZATION_FAILED_FOR_REGION_0,
+             getFullPath()), validationException);
+         throw validationException;
+       }
+       finally {
+         if (!success) {
+           this.cache.setRegionByPath(newRegion.getFullPath(), null);
+           initializationFailed(newRegion);
+           cache.getResourceManager(false).removeResourceListener(newRegion);
+         }
+       }
+ 
+       newRegion.postCreateRegion();
+     }
+     finally {
+       // make sure region initialization latch is open regardless
+       // before returning;
+       // if the latch is not open at this point, then an exception must
+       // have occurred
+       if (newRegion != null && !newRegion.isInitialized()) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("Region initialize latch is closed, Error must have occurred");
+         }
+       }
+     }
+ 
+     cache.invokeRegionAfter(newRegion);
+     return newRegion;
+   }
+ 
+   public final void create(Object key, Object value, Object aCallbackArgument)
+       throws TimeoutException, EntryExistsException, CacheWriterException {
+     long startPut = CachePerfStats.getStatTime();
+     EntryEventImpl event = newCreateEntryEvent(key, value, aCallbackArgument);
+     validatedCreate(event, startPut);
+     // TODO OFFHEAP: validatedCreate calls freeOffHeapResources
+   }
+ 
+   public final void validatedCreate(EntryEventImpl event, long startPut)
+       throws TimeoutException, EntryExistsException, CacheWriterException {
+ 
+     try {
+       if (event.getEventId() == null && generateEventID()) {
+         event.setNewEventId(cache.getDistributedSystem());
+       }
+       assert event.isFetchFromHDFS() : "validatedPut() should have been called";
+       // Fix for 42448 - Only make create with null a local invalidate for
+       // normal regions. Otherwise, it will become a distributed invalidate.
+       if (getDataPolicy() == DataPolicy.NORMAL) {
+         event.setLocalInvalid(true);
+       }
+       discoverJTA();
+       if (!basicPut(event, true, // ifNew
+           false, // ifOld
+           null, // expectedOldValue
+           true // requireOldValue TODO txMerge why is oldValue required for
+                // create? I think so that the EntryExistsException will have it.
+       )) {
+         throw new EntryExistsException(event.getKey().toString(),
+             event.getOldValue());
+       } else {
+         if (!getDataView().isDeferredStats()) {
+           getCachePerfStats().endPut(startPut, false);
+         }
+       }
+     } finally {
+ 
+       event.release();
+ 
+     }
+   }
+ 
+   // split into a separate newCreateEntryEvent since SQLFabric may need to
+   // manipulate event before doing the put (e.g. posDup flag)
+   public final EntryEventImpl newCreateEntryEvent(Object key, Object value,
+       Object aCallbackArgument) {
+ 
+     validateArguments(key, value, aCallbackArgument);
+     checkReadiness();
+     checkForLimitedOrNoAccess();
+ 
+     return EntryEventImpl.create(this, Operation.CREATE, key,
+         value, aCallbackArgument, false, getMyId())
+         /* to distinguish genuine create */.setCreate(true);
+   }
+ 
+   /**
+    * The default Region implementation will generate EvenTID in the EntryEvent
+    * object. This method is overridden in special Region objects like HARegion
+    * or SingleWriteSingleReadRegionQueue.SingleReadWriteMetaRegion to return
+    * false as the event propagation from those regions do not need EventID
+    * objects
+    *
+    * <p>author Asif
+    * @return boolean indicating whether to generate eventID or not
+    */
+   @Override
+   public boolean generateEventID()
+   {     
+     return !(isUsedForPartitionedRegionAdmin()
+         || isUsedForPartitionedRegionBucket() );
+   }
+ 
+   public final Object destroy(Object key, Object aCallbackArgument)
+       throws TimeoutException, EntryNotFoundException, CacheWriterException {
+     EntryEventImpl event = newDestroyEntryEvent(key, aCallbackArgument);
+     return validatedDestroy(key, event);
+     // TODO OFFHEAP: validatedDestroy calls freeOffHeapResources
+   }
+ 
+   /**
+    * Destroys entry without performing validations. Call this after validating
+    * key, callback arg, and runtime state.
+    */
+   public Object validatedDestroy(Object key, EntryEventImpl event)
+       throws TimeoutException, EntryNotFoundException, CacheWriterException
+  {
+     try {
+       if (event.getEventId() == null && generateEventID()) {
+         event.setNewEventId(cache.getDistributedSystem());
+       }
+       basicDestroy(event, true, // cacheWrite
+           null); // expectedOldValue
+       if (event.isOldValueOffHeap()) {
+         return null;
+       } else {
+         return handleNotAvailable(event.getOldValue());
+       }
+     } finally {
+       event.release();
+     }
+   }
+ 
+   // split into a separate newDestroyEntryEvent since SQLFabric may need to
+   // manipulate event before doing the put (e.g. posDup flag)
+   public final EntryEventImpl newDestroyEntryEvent(Object key,
+       Object aCallbackArgument) {
+     validateKey(key);
+     validateCallbackArg(aCallbackArgument);
+     checkReadiness();
+     checkForLimitedOrNoAccess();
+ 
+     return EntryEventImpl.create(this, Operation.DESTROY, key,
+         null/* newValue */, aCallbackArgument, false, getMyId());
+   }
+ 
+   public void destroyRegion(Object aCallbackArgument)
+       throws CacheWriterException, TimeoutException
+   {
+     getDataView().checkSupportsRegionDestroy();
+     checkForLimitedOrNoAccess();
+ 
+     RegionEventImpl event = new RegionEventImpl(this, Operation.REGION_DESTROY,
+         aCallbackArgument, false, getMyId(), generateEventID());
+     basicDestroyRegion(event, true);
+   }
+ 
+   public InternalDataView getDataView() {
+     final TXStateInterface tx = getTXState();
+     if (tx == null) {
+       return this.sharedDataView;
+     }
+     return tx;
+   }
+ 
+   /**
+    * Fetch the de-serialized value from non-transactional state.
+    * @param keyInfo to which the value is associated
+    * @param updateStats true if the entry stats should be updated.
+    * @param disableCopyOnRead if true then disable copy on read
+    * @param preferCD true if the preferred result form is CachedDeserializable
+    * @param clientEvent client's event, if any (for version tag retrieval)
+    * @param returnTombstones whether destroyed entries should be returned
+    * @param retainResult if true then the result may be a retained off-heap reference
+    * @return the value for the given key
+    */
+   public final Object getDeserializedValue(RegionEntry re, final KeyInfo keyInfo, final boolean updateStats, boolean disableCopyOnRead, 
+   boolean preferCD, EntryEventImpl clientEvent, boolean returnTombstones, boolean allowReadFromHDFS, boolean retainResult) {
+     if (this.diskRegion != null) {
+       this.diskRegion.setClearCountReference();
+     }
+     try {
+       if (re == null) {
+         if (allowReadFromHDFS) {
+           re = this.entries.getEntry(keyInfo.getKey());
+         } else {
+           re = this.entries.getOperationalEntryInVM(keyInfo.getKey());
+         }
+       }
+       //skip updating the stats if the value is null
+       // TODO - We need to clean up the callers of the this class so that we can
+       // update the statistics here, where it would make more sense.
+       if (re == null) {
+         return null;
+       }
+       final Object value;
+       if (clientEvent != null && re.getVersionStamp() != null) {
+         // defer the lruUpdateCallback to prevent a deadlock (see bug 51121).
+         final boolean disabled = this.entries.disableLruUpdateCallback();
+         try {
+         synchronized(re) { // bug #51059 value & version must be obtained atomically
+           clientEvent.setVersionTag(re.getVersionStamp().asVersionTag());
+           value = getDeserialized(re, updateStats, disableCopyOnRead, preferCD, retainResult);
+         }
+         } finally {
+           if (disabled) {
+             this.entries.enableLruUpdateCallback();
+           }
+           try {
+             this.entries.lruUpdateCallback();
+           }catch( DiskAccessException dae) {
+             this.handleDiskAccessException(dae);
+             throw dae;
+           }
+         }
+       } else {
+         value = getDeserialized(re, updateStats, disableCopyOnRead, preferCD, retainResult);
+       }
+       if (logger.isTraceEnabled() && !(this instanceof HARegion)) {
+         logger.trace("getDeserializedValue for {} returning version: {} returnTombstones: {} value: {}",
+             keyInfo.getKey(), (re.getVersionStamp()==null? "null" : re.getVersionStamp().asVersionTag()), returnTombstones, value);
+       }
+       return value;
+     }
+     finally {
+       if (this.diskRegion != null) {
+         this.diskRegion.removeClearCountReference();
+       }
+     }
+   }
+ 
+   /**
+    *
+    * @param re
+    * @param updateStats
+    * @param disableCopyOnRead if true then do not make a copy on read
+    * @param preferCD true if the preferred result form is CachedDeserializable
+    * @param retainResult if true then the result may be a retained off-heap reference
+    * @return the value found, which can be
+    *  <ul>
+    *    <li> null if the value was removed from the region entry
+    *    <li>Token.INVALID if the value of the region entry is invalid
+    *    <li>Token.LOCAL_INVALID if the value of the region entry is local invalid
+    *  </ul>
+    */
+   @Retained
+   protected final Object getDeserialized(RegionEntry re, boolean updateStats, boolean disableCopyOnRead, boolean preferCD, boolean retainResult) {
+     assert !retainResult || preferCD;
+     try {
+       @Retained Object v = null;
+       try {
+         if (retainResult) {
+           v = re.getValueRetain(this);
+         } else {
+           v = re.getValue(this);
+         }
+       } catch(DiskAccessException dae) {
+         this.handleDiskAccessException(dae);
+         throw dae;
+       }
+   
+       //skip updating the stats if the value is null
+       if (v == null) {
+         return null;
+       }
+       if (v instanceof CachedDeserializable) {
+         if (!preferCD) {
+           if (isCopyOnRead()) {
+             if (disableCopyOnRead) {
+               v = ((CachedDeserializable)v).getDeserializedForReading();
+             } else {
+               v = ((CachedDeserializable)v).getDeserializedWritableCopy(this, re);
+             }
+           } else {
+             v = ((CachedDeserializable)v).getDeserializedValue(this, re);
+           }
+         }
+       }
+       else if (!disableCopyOnRead) {
+           v = conditionalCopy(v);
+       }
+   
+       if (updateStats) {
+         updateStatsForGet(re, v != null && !Token.isInvalid(v));
+       }
+       return v;
+     } catch(IllegalArgumentException i) {
+       IllegalArgumentException iae = new IllegalArgumentException(LocalizedStrings.DONT_RELEASE.toLocalizedString("Error while deserializing value for key="+re.getKey()));
+       iae.initCause(i);
+       throw iae;
+     }
+   }
+   
+   @Override
+   public Object get(Object key, Object aCallbackArgument,
+       boolean generateCallbacks, EntryEventImpl clientEvent) throws TimeoutException, CacheLoaderException
+   {
+     Object result = get(key, aCallbackArgument, generateCallbacks, false, false, null, clientEvent, false, true/*allowReadFromHDFS*/);
+     if (Token.isInvalid(result)) {
+       result = null;
+     }
+     return result;
+   }
+   
+   /*
+    * @see BucketRegion#getSerialized(KeyInfo, boolean, boolean)
+    */
+   public Object get(Object key, Object aCallbackArgument,
+ 	      boolean generateCallbacks, boolean disableCopyOnRead, boolean preferCD,
+ 	      ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones, boolean allowReadFromHDFS) throws TimeoutException, CacheLoaderException {
+ 	  return get(key, aCallbackArgument,
+ 		      generateCallbacks, disableCopyOnRead, preferCD,requestingClient, clientEvent, returnTombstones, false, allowReadFromHDFS, false);
+   }
+   
+   /**
+    * The result of this operation may be an off-heap reference that the caller must release
+    */
+   @Retained
+   public Object getRetained(Object key, Object aCallbackArgument,
+       boolean generateCallbacks, boolean disableCopyOnRead,
+       ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones) throws TimeoutException, CacheLoaderException {
+     return getRetained(key, aCallbackArgument,
+               generateCallbacks, disableCopyOnRead, requestingClient, clientEvent, returnTombstones, false);
+   }
+ 
+   /**
+    * The result of this operation may be an off-heap reference that the caller must release.
+    * @param opScopeIsLocal if true then just check local storage for a value; if false then try to find the value if it is not local
+    */
+   @Retained
+   public Object getRetained(Object key, Object aCallbackArgument,
+       boolean generateCallbacks, boolean disableCopyOnRead,
+       ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones, boolean opScopeIsLocal) throws TimeoutException, CacheLoaderException {
+     return get(key, aCallbackArgument, generateCallbacks, disableCopyOnRead, true, requestingClient, clientEvent, returnTombstones, opScopeIsLocal, true, false);
+   }
+   /**
+    * @param opScopeIsLocal if true then just check local storage for a value; if false then try to find the value if it is not local
+    * @param retainResult if true then the result may be a retained off-heap reference.
+    */
+   public Object get(Object key, Object aCallbackArgument,
+       boolean generateCallbacks, boolean disableCopyOnRead, boolean preferCD,
+       ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones, 
+ 	  boolean opScopeIsLocal, boolean allowReadFromHDFS, boolean retainResult) throws TimeoutException, CacheLoaderException
+   {
+     assert !retainResult || preferCD;
+     validateKey(key);
+     validateCallbackArg(aCallbackArgument);
+     checkReadiness();
+     checkForNoAccess();
+     discoverJTA();
+     CachePerfStats stats = getCachePerfStats();
+     long start = stats.startGet();
+     boolean isMiss = true;
+     try {
+       KeyInfo keyInfo = getKeyInfo(key, aCallbackArgument);
+       Object value = getDataView().getDeserializedValue(keyInfo, this, true, disableCopyOnRead, preferCD, clientEvent, returnTombstones, allowReadFromHDFS, retainResult);
+       final boolean isCreate = value == null;
+       isMiss = value == null || Token.isInvalid(value)
+           || (!returnTombstones && value == Token.TOMBSTONE);
+       // Note: if the value was Token.DESTROYED then getDeserialized
+       // returns null so we don't need the following in the above expression:
+       // || (isRegInterestInProgress() && Token.isDestroyed(value))
+       // because (value == null) will be true in this case.
+       if (isMiss) {
+         // to fix bug 51509 raise the precedence of opScopeIsLocal
+         // if scope is local and there is no loader, then
+         // don't go further to try and get value
+         if (!opScopeIsLocal
+             && ((getScope().isDistributed() && !isHDFSRegion())
+                 || hasServerProxy()
+                 || basicGetLoader() != null)) { 
+           // serialize search/load threads if not in txn
+           // TODO OFFHEAP OPTIMIZE: findObject can be enhanced to use the retainResult flag
+           value = getDataView().findObject(keyInfo,
+               this, isCreate, generateCallbacks, value, disableCopyOnRead,
+               preferCD, requestingClient, clientEvent, returnTombstones, false/*allowReadFromHDFS*/);
+           if (!returnTombstones && value == Token.TOMBSTONE) {
+             value = null;
+           }
+         }
+         else { // local scope with no loader, still might need to update stats
+           if (isCreate) {
+             recordMiss(null, key);
+           }
+           value = null;
+         }
+       }
+       return value;
+     }
+     finally {
+       stats.endGet(start, isMiss);
+     }
+   }
+ 
+   /**
+    * Update region and potentially entry stats for the miss case 
+    * @param re optional region entry, fetched if null
+    * @param key the key used to fetch the region entry
+    */
+   final public void recordMiss(final RegionEntry re, Object key) {
+     final RegionEntry e;
+     if (re == null && !isTX() && !isHDFSRegion()) {
+       e = basicGetEntry(key);
+     } else {
+       e = re;
+     }
+     updateStatsForGet(e, false);
+   }
+ 
+   /**
+    * @return true if this region has been configured for HDFS persistence
+    */
+   public boolean isHDFSRegion() {
+     return false;
+   }
+ 
+   /**
+    * @return true if this region is configured to read and write data from HDFS
+    */
+   public boolean isHDFSReadWriteRegion() {
+     return false;
+   }
+ 
+   /**
+    * @return true if this region is configured to only write to HDFS
+    */
+   protected boolean isHDFSWriteOnly() {
+     return false;
+   }
+ 
+   /**
+    * FOR TESTING ONLY
+    */
+   public HoplogListenerForRegion getHoplogListener() {
+     return hoplogListener;
+   }
+   
+   /**
+    * FOR TESTING ONLY
+    */
+   public HdfsRegionManager getHdfsRegionManager() {
+     return hdfsManager;
+   }
+   
+   /**
+    * optimized to only allow one thread to do a search/load, other threads wait
+    * on a future
+    *
+    * @param keyInfo
+    * @param p_isCreate
+    *                true if call found no entry; false if updating an existing
+    *                entry
+    * @param generateCallbacks
+    * @param p_localValue
+    *                the value retrieved from the region for this object.
+    * @param disableCopyOnRead if true then do not make a copy
+    * @param preferCD true if the preferred result form is CachedDeserializable
+    * @param clientEvent the client event, if any
+    * @param returnTombstones whether to return tombstones
+    */
+   @Retained
+   Object nonTxnFindObject(KeyInfo keyInfo, boolean p_isCreate,
+       boolean generateCallbacks, Object p_localValue, boolean disableCopyOnRead, boolean preferCD,
+       ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones, boolean allowReadFromHDFS) 
+       throws TimeoutException, CacheLoaderException
+   {
+     final Object key = keyInfo.getKey();
+   
+     Object localValue = p_localValue;
+     boolean isCreate = p_isCreate;
+     Object[] valueAndVersion = null;
+     @Retained Object result = null;
+     FutureResult thisFuture = new FutureResult(this.stopper);
+     Future otherFuture = (Future)this.getFutures.putIfAbsent(keyInfo.getKey(), thisFuture);
+     // only one thread can get their future into the map for this key at a time
+     if (otherFuture != null) {
+       try {
+         valueAndVersion = (Object[])otherFuture.get();
+         if (valueAndVersion != null) {
+           result = valueAndVersion[0];
+           if (clientEvent != null) {
+             clientEvent.setVersionTag((VersionTag)valueAndVersion[1]);
+           }
+           if (!preferCD && result instanceof CachedDeserializable) {
+             CachedDeserializable cd = (CachedDeserializable)result;
+             // fix for bug 43023
+             if (!disableCopyOnRead && isCopyOnRead()) {
+               result = cd.getDeserializedWritableCopy(null, null);
+             } else {
+               result = cd.getDeserializedForReading();
+             }
+            
+           } else if (!disableCopyOnRead) {
+             result = conditionalCopy(result);
+           }
+           //For sqlf since the deserialized value is nothing but chunk
+           // before returning the found value increase its use count
 -          if(GemFireCacheImpl.sqlfSystem() && result instanceof Chunk) {
 -            if(!((Chunk)result).retain()) {
++          if(GemFireCacheImpl.sqlfSystem() && result instanceof ObjectChunk) {
++            if(!((ObjectChunk)result).retain()) {
+               return null;
+             }
+           }
+           // what was a miss is now a hit
+           RegionEntry re = null;
+           if (isCreate) {
+             re = basicGetEntry(keyInfo.getKey());
+             updateStatsForGet(re, true);
+           }
+           return result;
+         }
+         // if value == null, try our own search/load
+       }
+       catch (InterruptedException e) {
+         Thread.currentThread().interrupt();
+         // TODO check a CancelCriterion here?
+         return null;
+       }
+       catch (ExecutionException e) {
+         // unexpected since there is no background thread
+         InternalGemFireError err = new InternalGemFireError(LocalizedStrings.LocalRegion_UNEXPECTED_EXCEPTION.toLocalizedString());
+         err.initCause(err);
+         throw err;
+       }
+     }
+     // didn't find a future, do one more probe for the entry to catch a race
+     // condition where the future was just removed by another thread
+     try {
+       boolean partitioned = this.getDataPolicy().withPartitioning();
+       if (!partitioned) {
+         localValue = getDeserializedValue(null, keyInfo, isCreate, disableCopyOnRead, preferCD, clientEvent, false, false/*allowReadFromHDFS*/, false);
+ 
+         // stats have now been updated
+         if (localValue != null && !Token.isInvalid(localValue)) {
+           result = localValue;
+           return result;
+         }
+         isCreate = localValue == null;
+         result = findObjectInSystem(keyInfo, isCreate, null, generateCallbacks,
+             localValue, disableCopyOnRead, preferCD, requestingClient, clientEvent, returnTombstones, false/*allowReadFromHDFS*/);
+ 
+       } else {
+         
+         // This code was moved from PartitionedRegion.nonTxnFindObject().  That method has been removed.
+         // For PRs we don't want to deserialize the value and we can't use findObjectInSystem because
+         // it can invoke code that is transactional.
+         result = getSharedDataView().findObject(keyInfo, this, true/*isCreate*/, generateCallbacks,
+             localValue, disableCopyOnRead, preferCD, null, null, false, allowReadFromHDFS);
+         // TODO why are we not passing the client event or returnTombstones in the above invokation?
+       }
+ 
+       if (result == null && localValue != null) {
+         if (localValue != Token.TOMBSTONE || returnTombstones) {
+           result = localValue;
+         }
+       }
+       // findObjectInSystem does not call conditionalCopy
+     }
+     finally {
+       if (result != null) {
+         VersionTag tag = (clientEvent==null)? null : clientEvent.getVersionTag();
+         thisFuture.set(new Object[]{result, tag});
+       } else {
+         thisFuture.set(null);
+       }
+       this.getFutures.remove(keyInfo.getKey());
+     }
+     if (!disableCopyOnRead) {
+       result = conditionalCopy(result);
+     }
+     return result;
+   }
+ 
+   /**
+    * Returns true if get should give a copy; false if a reference.
+    *
+    * @since 4.0
+    */
+   protected boolean isCopyOnRead()
+   {
+     return this.compressor == null
+       && this.cache.isCopyOnRead()
+       && ! this.isUsedForPartitionedRegionAdmin
+       && ! this.isUsedForMetaRegion
+       && ! getOffHeap()
+       && ! isSecret();
+   }
+ 
+   /**
+    * Makes a copy, if copy-on-get is enabled, of the specified object.
+    *
+    * @since 4.0
+    */
+   protected Object conditionalCopy(Object o)
+   {
+     if (isCopyOnRead() && !Token.isInvalid(o)) {
+       return CopyHelper.copy(o);
+     }
+     else {
+       return o;
+     }
+   }
+ 
+   private final String fullPath;
+ 
+   public String getFullPath()
+   {
+     return this.fullPath;
+   }
+ 
+   //   public String getFullPath() {
+   //     // work way up to root region, prepending
+   //     // the region names to a buffer
+   //     StringBuffer buf = new StringBuffer(SEPARATOR);
+   //     Assert.assertTrue(this.regionName != null);
+   //     buf.append(this.regionName);
+   //     LocalRegion r = this;
+   //     while ((r = r.parentRegion) != null) {
+   //       buf.insert(0, r.regionName);
+   //       buf.insert(0, SEPARATOR_CHAR);
+   //     }
+   //     return buf.toString();
+   //   }
+ 
+   public Region getParentRegion()
+   {
+     //checkReadiness();
+     return this.parentRegion;
+   }
+ 
+   public Region getSubregion(String path)
+   {
+     checkReadiness();
+     return getSubregion(path, false);
+   }
+ 
+   public void invalidateRegion(Object aCallbackArgument)
+       throws TimeoutException
+   {
+     getDataView().checkSupportsRegionInvalidate();
+     validateCallbackArg(aCallbackArgument);
+     checkReadiness();
+     checkForLimitedOrNoAccess();
+     RegionEventImpl event = new RegionEventImpl(this, Operation.REGION_INVALIDATE,
+       aCallbackArgument, false, getMyId(), generateEventID());
+ 
+     basicInvalidateRegion(event);
+   }
+ 
+   public Object put(Object key, Object value, Object aCallbackArgument)
+       throws TimeoutException, CacheWriterException {
+     long startPut = CachePerfStats.getStatTime();
+     EntryEventImpl event = newUpdateEntryEvent(key, value, aCallbackArgument);
+      //Since Sqlfire directly calls validatedPut, the freeing is done in
+     // validatedPut
+      return validatedPut(event, startPut);
+      // TODO OFFHEAP: validatedPut calls freeOffHeapResources
+     
+   }
+ 
+   public final Object validatedPut(EntryEventImpl event, long startPut)
+       throws TimeoutException, CacheWriterException {
+ 
+     try {
+       if (event.getEventId() == null && generateEventID()) {
+         event.setNewEventId(cache.getDistributedSystem());
+       }
+       Object oldValue = null;
+       // Sqlf changes begin
+       // see #40294.
+ 
+       // Rahul: this has to be an update.
+       // so executing it as an update.
+       boolean forceUpdateForDelta = event.hasDelta();
+       // Sqlf Changes end.
+       if (basicPut(event, false, // ifNew
+           forceUpdateForDelta, // ifOld
+           null, // expectedOldValue
+           false // requireOldValue
+       )) {
+         if (!event.isOldValueOffHeap()) {
+           // don't copy it to heap just to return from put.
+           // TODO: come up with a better way to do this.
+           oldValue = event.getOldValue();
+         }
+         if (!getDataView().isDeferredStats()) {
+           getCachePerfStats().endPut(startPut, false);
+         }
+       }
+       return handleNotAvailable(oldValue);
+     } finally {
+       event.release();
+     }
+   }
+ 
+   // split into a separate newUpdateEntryEvent since SQLFabric may need to
+   // manipulate event before doing the put (e.g. posDup flag)
+   public final EntryEventImpl newUpdateEntryEvent(Object key, Object value,
+       Object aCallbackArgument) {
+ 
+     validateArguments(key, value, aCallbackArgument);
+     if (value == null) {
+       throw new NullPointerException(LocalizedStrings
+           .LocalRegion_VALUE_MUST_NOT_BE_NULL.toLocalizedString());
+     }
+     checkReadiness();
+     checkForLimitedOrNoAccess();
+     discoverJTA();
+ 
+     // This used to call the constructor which took the old value. It
+     // was modified to call the other EntryEventImpl constructor so that
+     // an id will be generated by default. Null was passed in anyway.
+     //   generate EventID
+     final EntryEventImpl event = EntryEventImpl.create(
+         this, Operation.UPDATE, key,
+         value, aCallbackArgument, false, getMyId());
+     boolean eventReturned = false;
+     try {
+     extractDeltaIntoEvent(value, event);
+     eventReturned = true;
+     return event;
+     } finally {
+       if (!eventReturned) event.release();
+     }
+   }
+   /**
+    * Creates an EntryEventImpl that is optimized to not fetch data from HDFS.
+    * This is meant to be used by PUT dml from GemFireXD.
+    */
+   public final EntryEventImpl newPutEntryEvent(Object key, Object value,
+       Object aCallbackArgument) {
+     EntryEventImpl ev = newUpdateEntryEvent(key, value, aCallbackArgument);
+     ev.setFetchFromHDFS(false);
+     ev.setPutDML(true);
+     return ev;
+   }
+   private void extractDeltaIntoEvent(Object value, EntryEventImpl event) {
+     // 1. Check for DS-level delta property.
+     // 2. Default value for operation type is UPDATE, so no need to check that here.
+     // 3. Check if it has server region proxy. 
+     //    We do not have a handle to event in PutOpImpl to check if we have 
+     //    delta bytes calculated already. So no need to calculate it here.
+     // 4. Check if value is instanceof com.gemstone.gemfire.Delta
+     // 5. Check if Region in PR with redundantCopies > 0. Set extractDelta.
+     // 6. Check if Region has peers. Set extractDelta.
+     // 7. Check if it has any delta proxies attached to it. Set extractDelta.
+     // 8. If extractDelta is set, check if it has delta.
+     // 9. If delta is found, extract it and set it into the event.
+     // 10. If any exception is caught while invoking the delta callbacks, throw it back.
+     // 11. Wrap any checked exception in InternalGemFireException before throwing it.
+     try {
+       boolean extractDelta = false;
+       // How costly is this if check?
+       if (this.getSystem().getConfig().getDeltaPropagation()
+           && value instanceof com.gemstone.gemfire.Delta) {
+         if (!this.hasServerProxy()) {
+           if ((this instanceof PartitionedRegion)) {
+             if (((PartitionedRegion)this).getRedundantCopies() > 0) {
+               extractDelta = true;
+             } else {
+               InternalDistributedMember ids = (InternalDistributedMember)PartitionRegionHelper
+                   .getPrimaryMemberForKey(this, event.getKey());
+               if (ids != null) {
+                 if (this.getSystem().getMemberId().equals(ids.getId())) {
+                   extractDelta = hasAdjunctRecipientsNeedingDelta(event);
+                 } else {
+                   extractDelta = true;
+                 }
+               } else {
+                 extractDelta = true;
+               }
+             }
+           } else if ((this instanceof DistributedRegion)
+               && !((DistributedRegion)this).scope.isDistributedNoAck()
+               && ((DistributedRegion)this).getCacheDistributionAdvisor()
+                   .adviseCacheOp().size() > 0) {
+             extractDelta = true;
+           }
+           if (!extractDelta && ClientHealthMonitor.getInstance() != null) {
+             extractDelta = ClientHealthMonitor.getInstance().hasDeltaClients();
+           }
+         } else if (HandShake.isDeltaEnabledOnServer()) {
+           // This is a client region
+           extractDelta = true;
+         }
+         if (extractDelta && ((com.gemstone.gemfire.Delta)value).hasDelta()) {
+           HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+           long start = DistributionStats.getStatTime();
+           try {
+             ((com.gemstone.gemfire.Delta)value).toDelta(hdos);
+           } catch (RuntimeException re) {
+             throw re;
+           } catch (Exception e) {
+             throw new DeltaSerializationException(
+                 LocalizedStrings.DistributionManager_CAUGHT_EXCEPTION_WHILE_SENDING_DELTA
+                     .toLocalizedString(), e);
+           }
+           event.setDeltaBytes(hdos.toByteArray());
+           this.getCachePerfStats().endDeltaPrepared(start);
+         }
+       }
+     } catch (RuntimeException re) {
+       throw re;
+     } catch (Exception e) {
+       throw new InternalGemFireException(e);
+     }
+   }
+ 
+   @SuppressWarnings("unchecked")
+   private boolean hasAdjunctRecipientsNeedingDelta(EntryEventImpl event) {
+     PartitionedRegion pr = ((PartitionedRegion)this);
+     BucketRegion br = null;
+     FilterRoutingInfo filterRouting = null;
+     Set twoMessages = Collections.EMPTY_SET;
+     Set adjunctRecipients = Collections.EMPTY_SET;
+     Set cacheservers = null;
+ 
+     int bId = event.getKeyInfo().getBucketId();
+     try {
+       br = pr.dataStore.getInitializedBucketForId(event.getKey(), bId);
+     } catch (ForceReattemptException fre) {
+       return true;
+     }
+     Set<InternalDistributedMember> recipients = br.getCacheDistributionAdvisor().adviseUpdate(event);
+     twoMessages = br.getBucketAdvisor().adviseRequiresTwoMessages();
+     CacheDistributionAdvisor cda = pr.getCacheDistributionAdvisor();
+     filterRouting = cda.adviseFilterRouting(event, recipients);
+     adjunctRecipients = br.getAdjunctReceivers(event, recipients, twoMessages, filterRouting);
+     cacheservers = cda.adviseCacheServers();
+     return !Collections.disjoint(adjunctRecipients, cacheservers);
+   }
+ 
+   public Region.Entry getEntry(Object key)
+   {
+     validateKey(key);
+     checkReadiness();
+     checkForNoAccess();
+     discoverJTA();
+     return getDataView().getEntry(getKeyInfo(key), this, false);
+   }
+ 
+   /** internally we often need to get an entry whether it is a tombstone or not */
+   public Region.Entry getEntry(Object key, boolean allowTombstones) {
+     return getDataView().getEntry(getKeyInfo(key), this, allowTombstones);
+   }
+ 
+   /**
+    * Just like getEntry but also updates the stats that get would have depending
+    * on a flag. See bug 42410. Also skips discovering JTA
+    * 
+    * @param key
+    * @return the entry if it exists; otherwise null.
+    */
+   public Entry accessEntry(Object key, boolean updateStats) {
+     validateKey(key);
+     checkReadiness();
+     checkForNoAccess();
+     if(updateStats) {
+       return getDataView().accessEntry(getKeyInfo(key), this);
+     } else {
+       return getDataView().getEntry(getKeyInfo(key), this, false);
+     }
+   }
+ 
+   protected boolean includeHDFSResults() {
+     return isUsedForPartitionedRegionBucket() 
+         && isHDFSReadWriteRegion() 
+         && getPartitionedRegion().includeHDFSResults();
+   }
+   
+ 
+   /** a fast estimate of total number of entries locally in the region */
+   public long getEstimatedLocalSize() {
+     RegionMap rm;
+     if (!this.isDestroyed) {
+       long size;
+       if (isHDFSReadWriteRegion() && this.initialized) {
+         // this size is not used by HDFS region iterators
+         // fixes bug 49239
+         return 0;
+       }
+       // if region has not been initialized yet, then get the estimate from
+       // disk region's recovery map if available
+       if (!this.initialized && this.diskRegion != null
+           && (rm = this.diskRegion.getRecoveredEntryMap()) != null
+           && (size = rm.size()) > 0) {
+         return size;
+       }
+       if ((rm = getRegionMap()) != null) {
+         return rm.size();
+       }
+     }
+     return 0;
+   }
+     /**
+    * @param keyInfo
+    * @param access
+    *          true if caller wants last accessed time updated
+    * @param allowTombstones whether an entry with a TOMBSTONE value can be returned
+    * @return TODO
+    */
+   protected Region.Entry nonTXGetEntry(KeyInfo keyInfo, boolean access, boolean allowTombstones) {
+     final Object key = keyInfo.getKey();
+     RegionEntry re = this.entries.getEntry(key);
+     boolean miss = (re == null || re.isDestroyedOrRemoved());
+     if (access) {
+       updateStatsForGet(re, !miss);
+     }
+     if (re == null) {
+       return null;
+     }
+     if (re.isTombstone()) {
+       if (!allowTombstones) {
+         return null;
+       } // else return an entry (client GII / putAll results)
+     } else if (miss) {
+       return null;
+     }
+ 
+     Region.Entry ren = new NonTXEntry(re);
+     //long start=0, end=0;
+     //start = System.currentTimeMillis();
+     //end = System.currentTimeMillis();
+     //System.out.println("getEntry: " + (end-start));
+     return ren;
+   }
+ 
+   /**
+    * @return boolean
+    */
+   protected boolean isClosed()
+   {
+     return this.cache.isClosed();
+   }
+ 
+   /**
+    * Returns true if this region is or has been closed or destroyed.
+    * Note that unlike {@link #isDestroyed()} this method will not
+    * return true if the cache is closing but has not yet started closing
+    * this region.
+    */
+   public boolean isThisRegionBeingClosedOrDestroyed() {
+     return this.isDestroyed;
+   }
+   
+   /** returns true if this region has been destroyed */
+   public boolean isDestroyed()
+   {
+     if (isClosed()) {
+       return true; // for bug 42328
+     }
+     boolean isTraceEnabled = logger.isTraceEnabled();
+     //    boolean result = false;
+     if (this.isDestroyed) {
+       if (isTraceEnabled) {
+         logger.trace("isDestroyed: true, this.isDestroyed: {}", getFullPath());
+       }
+       return true;
+     }
+     //    if (!isInitialized()) { // don't return true if still initializing
+     //      if (finestEnabled) {
+     //        log.finest("isDestroyed: false, not initialized: " + getFullPath());
+     //      }
+     //      return false;
+     //    }
+     // @todo we could check parents here if we want this to be more accurate,
+     // and the isDestroyed field could be made volatile as well.
+     // if (this.parentRegion != null) return this.parentRegion.isDestroyed();
+     if (isTraceEnabled) {
+       logger.trace("isDestroyed: false : {}", getFullPath());
+     }
+     return false;
+   }
+ 
+   /** a variant of subregions() that does not perform a readiness check */
+   protected Set basicSubregions(boolean recursive) {
+     return new SubregionsSet(recursive);
+   }
+   
+   public Set subregions(boolean recursive) {
+     checkReadiness();
+     return new SubregionsSet(recursive);
+   }
+ 
+   public Set entries(boolean recursive) {
+     checkReadiness();
+     checkForNoAccess();
+     return basicEntries(recursive);
+   }
+ 
+   /** Returns set of entries without performing validation checks. */
+   public Set basicEntries(boolean recursive) {
+     return new EntriesSet(this, recursive, IteratorType.ENTRIES, false);
+   }
+ 
+   /**
+    * Flavor of keys that will not do repeatable read
+    * @since 5.5
+    */
+   public Set testHookKeys()
+   {
+     checkReadiness();
+     checkForNoAccess();
+     return new EntriesSet(this, false, IteratorType.KEYS,
+         false /* dontRememberReads */, false /* skipTxCheckInIteration */,
+         false /* allowTombstones */);
+   }
+ 
+   public Set keys()
+   {
+     checkReadiness();
+     checkForNoAccess();
+     return new EntriesSet(this, false, IteratorType.KEYS, false);
+   }
+ 
+   /**
+    * return a set of the keys in this region
+    * @param allowTombstones whether destroyed entries should be included
+    * @return the keys
+    */
+   public Set keySet(boolean allowTombstones) {
+     checkReadiness();
+     checkForNoAccess();
+     return new EntriesSet(this, false, IteratorType.KEYS, allowTombstones);
+   }
+ 
+   public Collection values()
+   {
+     checkReadiness();
+     checkForNoAccess();
+     return new EntriesSet(this, false, IteratorType.VALUES, false);
+   }
+ 
+   public Object getUserAttribute()
+   {
+     return this.regionUserAttribute;
+   }
+ 
+   public void setUserAttribute(Object value)
+   {
+     checkReadiness();
+     this.regionUserAttribute = value;
+   }
+ 
+   public boolean containsKey(Object key)
+   {
+     checkReadiness();
+     checkForNoAccess();
+     return getDataView().containsKey(getKeyInfo(key), this);
+   }
+ 
+   public boolean containsTombstone(Object key)
+   {
+     checkReadiness();
+     checkForNoAccess();
+     if (!this.concurrencyChecksEnabled) {
+       return false;
+     } else {
+       try {
+         Entry entry = getDataView().getEntry(getKeyInfo(key), this, true);
+         if (entry == null) {
+           return false;
+         } else {
+           return (entry.getValue() == Token.TOMBSTONE);
+         }
+       } catch (EntryDestroyedException e) {
+         return true;
+       }
+     }
+   }
+ 
+   protected boolean nonTXContainsKey(KeyInfo keyInfo) {
+     boolean contains = getRegionMap().containsKey(keyInfo.getKey());
+     if (contains && this.imageState.isClient()) {
+       // fix for bug #40871 - concurrent RI causes containsKey for destroyed entry
+       // to return true
+       RegionEntry re = this.entries.getEntry(keyInfo.getKey());
+       // TODO:KIRK:OK if (re == null || Token.isRemoved(re.getValueInVM(this))) {
+       if (re == null || re.isDestroyedOrRemoved()) {
+         contains = false;
+       }
+     }
+     return contains;
+   }
+ 
+   public boolean containsValueForKey(Object key)
+   {
+     discoverJTA();
+     return getDataView().containsValueForKey(getKeyInfo(key), this);
+   }
+ 
+   /**
+    * @param keyInfo
+    * @return TODO
+    */
+   protected boolean nonTXContainsValueForKey(KeyInfo keyInfo) {
+     checkReadiness();
+     checkForNoAccess();
+     if (this.diskRegion != null) {
+       this.diskRegion.setClearCountReference();
+     }
+     try {
+       RegionEntry entry = this.entries.getEntry(keyInfo.getKey());
+       boolean result = entry != null;
+       if (result) {
+         ReferenceCountHelper.skipRefCountTracking();
+         Object val = entry.getTransformedValue(); // no need to decompress since we only want to know if we have an existing value 
+         if (val instanceof StoredObject) {
+           OffHeapHelper.release(val);
+           ReferenceCountHelper.unskipRefCountTracking();
+           return true;
+         }
+         ReferenceCountHelper.unskipRefCountTracking();
+         // No need to to check CachedDeserializable because of Bruce's fix in r30960 for bug 42162. See bug 42732.
+         // this works because INVALID and LOCAL_INVALID will never be faulted out of mem
+         // If val is NOT_AVAILABLE that means we have a valid value on disk.
+         result = !Token.isInvalidOrRemoved(val);
+       }
+       return result;
+     }
+     finally {
+       if (this.diskRegion != null) {
+         this.diskRegion.removeClearCountReference();
+       }
+     }
+   }
+ 
+   public RegionAttributes getAttributes()
+   {
+     // to fix bug 35134 allow attribute access on closed regions
+     //checkReadiness();
+     return this;
+   }
+ 
+   public String getName()
+   {
+     return this.regionName;
+   }
+ 
+   /**
+    * Convenience method to get region name for logging/exception messages.
+    * if this region is an instanceof bucket region, it returns the
+    * bucket region name
+    * @return name of the region or the owning partitioned region
+    */
+   public String getDisplayName() {
+     if (this.isUsedForPartitionedRegionBucket()) {
+       r

<TRUNCATED>


[059/100] [abbrv] incubator-geode git commit: GEODE-831: unit test FreeListManager

Posted by ud...@apache.org.
GEODE-831: unit test FreeListManager

* moved state from SimpleMemoryAllocatorImpl to FreeListManager
* refactored and cleaned up release/free code
* Removed ChunkType and ChunkFactory. They were no longer used by GemFire and complicated the code
* removed BATCH_SIZE; it was an expirement that was not longer used
* combined Chunk and GemFireChunk to the new ObjectChunk class


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/9899940b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/9899940b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/9899940b

Branch: refs/heads/feature/GEODE-870
Commit: 9899940bbbe9e6a123b62269884dd852f1a70ac0
Parents: 01c0a2c
Author: Darrel Schneider <ds...@pivotal.io>
Authored: Fri Jan 22 11:42:35 2016 -0800
Committer: Darrel Schneider <ds...@pivotal.io>
Committed: Fri Feb 19 13:38:57 2016 -0800

----------------------------------------------------------------------
 .../internal/GetOperationContextImpl.java       |   6 +-
 .../query/internal/index/AbstractIndex.java     |   8 +-
 .../query/internal/index/DummyQRegion.java      |  14 +-
 .../cache/query/internal/index/HashIndex.java   |   6 +-
 .../internal/cache/AbstractRegionEntry.java     |  16 +-
 .../internal/cache/AbstractRegionMap.java       |   4 +-
 .../cache/BytesAndBitsForCompactor.java         |   8 +-
 .../gemfire/internal/cache/DiskEntry.java       |  20 +-
 .../internal/cache/DistributedRegion.java       |   6 +-
 .../gemfire/internal/cache/EntryEventImpl.java  |  52 +-
 .../gemfire/internal/cache/LocalRegion.java     |   6 +-
 .../internal/cache/PartitionedRegion.java       |   2 +-
 .../internal/cache/tier/sockets/Part.java       |  20 +-
 .../cache/wan/GatewaySenderEventImpl.java       |  14 +-
 .../offheap/AddressableMemoryChunk.java         |  29 +
 .../offheap/AddressableMemoryChunkFactory.java  |  27 +
 .../gemfire/internal/offheap/Chunk.java         | 792 ----------------
 .../gemfire/internal/offheap/ChunkFactory.java  |  51 -
 .../gemfire/internal/offheap/ChunkType.java     |  30 -
 .../internal/offheap/ChunkWithHeapForm.java     |  40 -
 .../gemfire/internal/offheap/Fragment.java      |  12 +-
 .../internal/offheap/FreeListManager.java       | 427 +++++----
 .../gemfire/internal/offheap/GemFireChunk.java  |  47 -
 .../internal/offheap/GemFireChunkFactory.java   |  52 --
 .../internal/offheap/GemFireChunkSlice.java     |  44 -
 .../internal/offheap/MemoryAllocator.java       |   6 +-
 .../gemfire/internal/offheap/MemoryBlock.java   |   1 -
 .../internal/offheap/MemoryBlockNode.java       |  22 +-
 .../gemfire/internal/offheap/ObjectChunk.java   | 737 +++++++++++++++
 .../internal/offheap/ObjectChunkSlice.java      |  44 +
 .../offheap/ObjectChunkWithHeapForm.java        |  40 +
 .../offheap/OffHeapCachedDeserializable.java    |   2 +-
 .../offheap/OffHeapRegionEntryHelper.java       |  22 +-
 .../offheap/SimpleMemoryAllocatorImpl.java      | 250 ++---
 .../internal/offheap/SyncChunkStack.java        |  12 +-
 .../internal/offheap/UnsafeMemoryChunk.java     |  16 +-
 .../internal/tcp/ByteBufferInputStream.java     |  10 +-
 .../tcp/ImmutableByteBufferInputStream.java     |   4 +-
 .../gemfire/internal/util/BlobHelper.java       |   4 +-
 .../gemfire/pdx/internal/PdxInputStream.java    |   4 +-
 .../cache/ChunkValueWrapperJUnitTest.java       |   6 +-
 .../cache/OldValueImporterTestBase.java         |  18 +-
 .../offheap/ChunkWithHeapFormJUnitTest.java     |  64 --
 .../internal/offheap/FragmentJUnitTest.java     |  56 +-
 .../internal/offheap/FreeListManagerTest.java   | 797 ++++++++++++++++
 .../offheap/FreeListOffHeapRegionJUnitTest.java |   2 +-
 .../offheap/GemFireChunkFactoryJUnitTest.java   | 129 ---
 .../internal/offheap/GemFireChunkJUnitTest.java | 921 -------------------
 .../offheap/GemFireChunkSliceJUnitTest.java     |  72 --
 .../offheap/LifecycleListenerJUnitTest.java     |  10 +-
 .../internal/offheap/ObjectChunkJUnitTest.java  | 902 ++++++++++++++++++
 .../offheap/ObjectChunkSliceJUnitTest.java      |  72 ++
 .../ObjectChunkWithHeapFormJUnitTest.java       |  64 ++
 .../offheap/OffHeapHelperJUnitTest.java         |   4 +-
 .../internal/offheap/OffHeapRegionBase.java     |  20 +-
 .../OffHeapRegionEntryHelperJUnitTest.java      |  48 +-
 .../offheap/OffHeapStorageJUnitTest.java        |   4 +-
 .../offheap/OffHeapValidationJUnitTest.java     |   4 +-
 .../OffHeapWriteObjectAsByteArrayJUnitTest.java |   8 +-
 .../OldFreeListOffHeapRegionJUnitTest.java      |   2 +-
 ...moryAllocatorFillPatternIntegrationTest.java |  10 +-
 ...mpleMemoryAllocatorFillPatternJUnitTest.java |  18 +-
 .../offheap/SimpleMemoryAllocatorJUnitTest.java | 170 ++--
 .../internal/offheap/StoredObjectTestSuite.java |   7 +-
 .../offheap/SyncChunkStackJUnitTest.java        |  38 +-
 .../offheap/UnsafeMemoryChunkJUnitTest.java     |   2 +-
 .../OffHeapByteBufferByteSourceJUnitTest.java   |   8 +-
 .../gemfire/pdx/OffHeapByteSourceJUnitTest.java |  10 +-
 68 files changed, 3356 insertions(+), 3017 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
index d973cd7..11d9248 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
@@ -18,7 +18,7 @@ package com.gemstone.gemfire.cache.operations.internal;
 
 import com.gemstone.gemfire.SerializationException;
 import com.gemstone.gemfire.cache.operations.GetOperationContext;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.Releasable;
 import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
@@ -70,7 +70,7 @@ public class GetOperationContextImpl extends GetOperationContext implements Rele
 
   private void checkForReleasedOffHeapValue(Object v) {
     // Note that we only care about Chunk (instead of all StoredObject) because it is the only one using a refcount
-    if (this.released && v instanceof Chunk) {
+    if (this.released && v instanceof ObjectChunk) {
       throw new IllegalStateException("Attempt to access off-heap value after the OperationContext callback returned.");
     }
   }
@@ -116,7 +116,7 @@ public class GetOperationContextImpl extends GetOperationContext implements Rele
     // our value (since this context did not retain it)
     // but we do make sure that any future attempt to access
     // the off-heap value fails.
-    if (super.getValue() instanceof Chunk) {
+    if (super.getValue() instanceof ObjectChunk) {
       this.released = true;
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
index 83a77fd..aab99cb 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/AbstractIndex.java
@@ -75,7 +75,7 @@ import com.gemstone.gemfire.internal.cache.RegionEntry;
 import com.gemstone.gemfire.internal.cache.persistence.query.CloseableIterator;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Released;
 import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 import com.gemstone.gemfire.pdx.PdxInstance;
@@ -1477,9 +1477,9 @@ public abstract class AbstractIndex implements IndexProtocol
         valueInIndex = verifyAndGetPdxDomainObject(value);
       } else{
         @Released Object val = re.getValueInVM(context.getPartitionedRegion());
-        Chunk valToFree = null;
-        if (val instanceof Chunk) {
-          valToFree = (Chunk)val;
+        ObjectChunk valToFree = null;
+        if (val instanceof ObjectChunk) {
+          valToFree = (ObjectChunk)val;
         }
         try {
         if (val instanceof CachedDeserializable) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
index 3577e38..bde948d 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
@@ -41,7 +41,7 @@ import com.gemstone.gemfire.internal.cache.LocalRegion;
 import com.gemstone.gemfire.internal.cache.RegionEntry;
 import com.gemstone.gemfire.internal.cache.RegionEntryContext;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Released;
 import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 
@@ -134,8 +134,8 @@ public class DummyQRegion extends QRegion {
     }
     valueInList.clear();
     Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
-    if (val instanceof Chunk) {
-      @Retained @Released Chunk ohval = (Chunk) val;
+    if (val instanceof ObjectChunk) {
+      @Retained @Released ObjectChunk ohval = (ObjectChunk) val;
       try {
         // TODO OFFHEAP: val may be off-heap PdxInstance
         val = ohval.getDeserializedValue(getRegion(), this.entry);
@@ -155,8 +155,8 @@ public class DummyQRegion extends QRegion {
       valueInArray = new  Object[1];      
     }   
     Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
-    if (val instanceof Chunk) {      
-      @Retained @Released Chunk ohval = (Chunk) val;
+    if (val instanceof ObjectChunk) {      
+      @Retained @Released ObjectChunk ohval = (ObjectChunk) val;
       try {
         // TODO OFFHEAP: val may be off-heap PdxInstance
         val = ohval.getDeserializedValue(getRegion(), this.entry);
@@ -178,8 +178,8 @@ public class DummyQRegion extends QRegion {
     }
     values.clear();
     Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
-    if (val instanceof Chunk) {
-      @Retained @Released Chunk ohval = (Chunk) val;
+    if (val instanceof ObjectChunk) {
+      @Retained @Released ObjectChunk ohval = (ObjectChunk) val;
       try {
         // TODO OFFHEAP: val may be off-heap PdxInstance
         val = ohval.getDeserializedValue(getRegion(), this.entry);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
index 465c038..a30a264 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
@@ -79,7 +79,7 @@ import com.gemstone.gemfire.internal.cache.Token;
 import com.gemstone.gemfire.internal.cache.persistence.query.CloseableIterator;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Released;
 import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 import com.gemstone.gemfire.pdx.internal.PdxString;
@@ -876,8 +876,8 @@ public class HashIndex extends AbstractIndex {
     if (this.indexOnValues) {
       Object o = entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
       try {
-        if (o instanceof Chunk) {
-          Chunk ohval = (Chunk) o;
+        if (o instanceof ObjectChunk) {
+          ObjectChunk ohval = (ObjectChunk) o;
           try {
             o = ohval.getDeserializedForReading();
           } finally {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
index dd33b15..558ea37 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
@@ -61,9 +61,9 @@ import com.gemstone.gemfire.internal.lang.StringUtils;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
-import com.gemstone.gemfire.internal.offheap.Chunk;
-import com.gemstone.gemfire.internal.offheap.ChunkWithHeapForm;
-import com.gemstone.gemfire.internal.offheap.GemFireChunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunkWithHeapForm;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.MemoryAllocator;
 import com.gemstone.gemfire.internal.offheap.OffHeapCachedDeserializable;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
@@ -1311,9 +1311,9 @@ public abstract class AbstractRegionEntry implements RegionEntry,
           }
           return prepareValueForCache(r, heapValue, event, isEntryUpdate);
         }
-        if (val instanceof Chunk) {
+        if (val instanceof ObjectChunk) {
           // if the reused guy has a refcount then need to inc it
-          if (!((Chunk)val).retain()) {
+          if (!((ObjectChunk)val).retain()) {
             throw new IllegalStateException("Could not use an off heap value because it was freed");
           }
         }
@@ -1346,10 +1346,10 @@ public abstract class AbstractRegionEntry implements RegionEntry,
         boolean isCompressed = compressedData != data;
         ReferenceCountHelper.setReferenceCountOwner(this);
         MemoryAllocator ma = SimpleMemoryAllocatorImpl.getAllocator(); // fix for bug 47875
-        val = ma.allocateAndInitialize(compressedData, isSerialized, isCompressed, GemFireChunk.TYPE); // TODO:KIRK:48068 race happens right after this line
+        val = ma.allocateAndInitialize(compressedData, isSerialized, isCompressed); // TODO:KIRK:48068 race happens right after this line
         ReferenceCountHelper.setReferenceCountOwner(null);
-        if (val instanceof GemFireChunk) {
-          val = new com.gemstone.gemfire.internal.offheap.ChunkWithHeapForm((GemFireChunk)val, data);
+        if (val instanceof ObjectChunk) {
+          val = new ObjectChunkWithHeapForm((ObjectChunk)val, data);
         }
 //        if (val instanceof Chunk && r instanceof LocalRegion) {
 //          Chunk c = (Chunk) val;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
index 6fe60ce..699de2f 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionMap.java
@@ -75,7 +75,7 @@ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.OffHeapRegionEntryHelper;
 import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
@@ -955,7 +955,7 @@ public abstract class AbstractRegionMap implements RegionMap {
                   ((ListOfDeltas)oldValue).apply(event);
                   Object preparedNewValue =oldRe.prepareValueForCache(owner,
                       event.getNewValueAsOffHeapDeserializedOrRaw(), true);
-                  if(preparedNewValue instanceof Chunk) {
+                  if(preparedNewValue instanceof ObjectChunk) {
                     event.setNewValue(preparedNewValue);
                   }
                   oldRe.setValue(owner, preparedNewValue, event);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
index 3a3b5a1..cc358f5 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
@@ -16,7 +16,7 @@
  */
 package com.gemstone.gemfire.internal.cache;
 
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 
 /**
@@ -36,7 +36,7 @@ public class BytesAndBitsForCompactor {
    * The dataChunk field is unretained so it can only be used while the RegionEntry is still synced.
    * When done with the dataChunk, null it out if you want to reuse the byte[] later.
    */
-  private @Unretained Chunk dataChunk;
+  private @Unretained ObjectChunk dataChunk;
   private  byte[] data;
   private  byte userBits=0;
   // length of the data present in the byte array 
@@ -56,7 +56,7 @@ public class BytesAndBitsForCompactor {
   }
 
   
-  public final Chunk getDataChunk() {
+  public final ObjectChunk getDataChunk() {
     return this.dataChunk;
   }
   public final byte[] getBytes() {
@@ -87,7 +87,7 @@ public class BytesAndBitsForCompactor {
     this.validLength = validLength;    
     this.isReusable = isReusable;
   }
-  public void setChunkData(Chunk c, byte userBits) {
+  public void setChunkData(ObjectChunk c, byte userBits) {
     this.dataChunk = c;
     this.userBits = userBits;
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
index c855cca..327279b 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
@@ -40,7 +40,7 @@ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
 import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
 import com.gemstone.gemfire.internal.offheap.Releasable;
@@ -208,8 +208,8 @@ public interface DiskEntry extends RegionEntry {
     static Object getValueOnDiskOrBuffer(DiskEntry entry, DiskRegion dr, RegionEntryContext context) {
       @Released Object v = getOffHeapValueOnDiskOrBuffer(entry, dr, context);
       if (v instanceof CachedDeserializable) {
-        if (v instanceof Chunk) {
-          @Released Chunk ohv = (Chunk) v;
+        if (v instanceof ObjectChunk) {
+          @Released ObjectChunk ohv = (ObjectChunk) v;
           try {
             v = ohv.getDeserializedValue(null, null);
             if (v == ohv) {
@@ -688,8 +688,8 @@ public interface DiskEntry extends RegionEntry {
      * Note that this class is only used with uncompressed chunks.
      */
     public static class ChunkValueWrapper implements ValueWrapper {
-      private final @Unretained Chunk chunk;
-      public ChunkValueWrapper(Chunk c) {
+      private final @Unretained ObjectChunk chunk;
+      public ChunkValueWrapper(ObjectChunk c) {
         assert !c.isCompressed();
         this.chunk = c;
       }
@@ -722,7 +722,7 @@ public interface DiskEntry extends RegionEntry {
             return;
           }
         }
-        final long bbAddress = Chunk.getDirectByteBufferAddress(bb);
+        final long bbAddress = ObjectChunk.getDirectByteBufferAddress(bb);
         if (bbAddress != 0L) {
           int bytesRemaining = maxOffset;
           int availableSpace = bb.remaining();
@@ -782,8 +782,8 @@ public interface DiskEntry extends RegionEntry {
         byte[] bytes;
         if (value instanceof CachedDeserializable) {
           CachedDeserializable proxy = (CachedDeserializable)value;
-          if (proxy instanceof Chunk) {
-            return new ChunkValueWrapper((Chunk) proxy);
+          if (proxy instanceof ObjectChunk) {
+            return new ChunkValueWrapper((ObjectChunk) proxy);
           }
           if (proxy instanceof StoredObject) {
             StoredObject ohproxy = (StoredObject) proxy;
@@ -833,8 +833,8 @@ public interface DiskEntry extends RegionEntry {
           // We don't do this for the delta case because getRawNewValue returns delta
           // and we want to write the entire new value to disk.
           rawValue = event.getRawNewValue();
-          if (rawValue instanceof Chunk) {
-            return new ChunkValueWrapper((Chunk) rawValue);
+          if (rawValue instanceof ObjectChunk) {
+            return new ChunkValueWrapper((ObjectChunk) rawValue);
           }
         }
         if (event.getCachedSerializedNewValue() != null) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
index f3e730a..021eba6 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/DistributedRegion.java
@@ -121,7 +121,7 @@ import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewa
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.annotations.Released;
 import com.gemstone.gemfire.internal.offheap.annotations.Retained;
@@ -2549,8 +2549,8 @@ public class DistributedRegion extends LocalRegion implements
     }
     //For SQLFire , we need to increment the use count so that returned
     //object has use count 2
-    if( incrementUseCountForSqlf && result instanceof Chunk) {
-      ((Chunk)result).retain();
+    if( incrementUseCountForSqlf && result instanceof ObjectChunk) {
+      ((ObjectChunk)result).retain();
     }
     return result;
     } finally {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
index c731721..6c58790 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/EntryEventImpl.java
@@ -73,7 +73,7 @@ import com.gemstone.gemfire.internal.lang.StringUtils;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.OffHeapRegionEntryHelper;
 import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
@@ -930,9 +930,9 @@ public class EntryEventImpl
     if (this.offHeapOk) {
       OffHeapHelper.releaseAndTrackOwner(this.newValue, this);
     }
-    if (v instanceof Chunk) {
+    if (v instanceof ObjectChunk) {
       ReferenceCountHelper.setReferenceCountOwner(this);
-      if (!((Chunk) v).retain()) {
+      if (!((ObjectChunk) v).retain()) {
         ReferenceCountHelper.setReferenceCountOwner(null);
         this.newValue = null;
         return;
@@ -946,13 +946,13 @@ public class EntryEventImpl
    * Returns true if this event has a reference to an off-heap new or old value.
    */
   public boolean hasOffHeapValue() {
-    return (this.newValue instanceof Chunk) || (this.oldValue instanceof Chunk);
+    return (this.newValue instanceof ObjectChunk) || (this.oldValue instanceof ObjectChunk);
   }
   
   @Unretained
   protected final Object basicGetNewValue() {
     Object result = this.newValue;
-    if (!this.offHeapOk && result instanceof Chunk) {
+    if (!this.offHeapOk && result instanceof ObjectChunk) {
       //this.region.getCache().getLogger().info("DEBUG new value already freed " + System.identityHashCode(result));
       throw new IllegalStateException("Attempt to access off heap value after the EntryEvent was released.");
     }
@@ -992,7 +992,7 @@ public class EntryEventImpl
     @Released final Object curOldValue = this.oldValue;
     if (v == curOldValue) return;
     if (this.offHeapOk) {
-      if (curOldValue instanceof Chunk) {
+      if (curOldValue instanceof ObjectChunk) {
         if (ReferenceCountHelper.trackReferenceCounts()) {
           OffHeapHelper.releaseAndTrackOwner(curOldValue, new OldValueOwner());
         } else {
@@ -1008,17 +1008,17 @@ public class EntryEventImpl
   private void retainAndSetOldValue(@Retained(ENTRY_EVENT_OLD_VALUE) Object v) {
     if (v == this.oldValue) return;
     
-    if (v instanceof Chunk) {
+    if (v instanceof ObjectChunk) {
       if (ReferenceCountHelper.trackReferenceCounts()) {
         ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
-        boolean couldNotRetain = (!((Chunk) v).retain());
+        boolean couldNotRetain = (!((ObjectChunk) v).retain());
         ReferenceCountHelper.setReferenceCountOwner(null);
         if (couldNotRetain) {
           this.oldValue = null;
           return;
         }
       } else {
-        if (!((Chunk) v).retain()) {
+        if (!((ObjectChunk) v).retain()) {
           this.oldValue = null;
           return;
         }
@@ -1031,7 +1031,7 @@ public class EntryEventImpl
   private Object basicGetOldValue() {
     @Unretained(ENTRY_EVENT_OLD_VALUE)
     Object result = this.oldValue;
-    if (!this.offHeapOk && result instanceof Chunk) {
+    if (!this.offHeapOk && result instanceof ObjectChunk) {
       //this.region.getCache().getLogger().info("DEBUG old value already freed " + System.identityHashCode(result));
       throw new IllegalStateException("Attempt to access off heap value after the EntryEvent was released.");
     }
@@ -1360,7 +1360,7 @@ public class EntryEventImpl
       @Unretained(ENTRY_EVENT_NEW_VALUE)
       final StoredObject so = (StoredObject) nv;
       final boolean isSerialized = so.isSerialized();
-      if (nv instanceof Chunk) {
+      if (nv instanceof ObjectChunk) {
         if (importer.isUnretainedNewReferenceOk()) {
           importer.importNewObject(nv, isSerialized);
         } else {
@@ -1447,7 +1447,7 @@ public class EntryEventImpl
     if (ov instanceof StoredObject) {
       final StoredObject so = (StoredObject) ov;
       final boolean isSerialized = so.isSerialized();
-      if (ov instanceof Chunk) {
+      if (ov instanceof ObjectChunk) {
         if (importer.isUnretainedOldReferenceOk()) {
           importer.importOldObject(ov, isSerialized);
         } else {
@@ -1869,8 +1869,8 @@ public class EntryEventImpl
     Object preparedV = reentry.prepareValueForCache(this.region, v, this, this.hasDelta());
     if (preparedV != v) {
       v = preparedV;
-      if (v instanceof Chunk) {
-        if (!((Chunk) v).isCompressed()) { // fix bug 52109
+      if (v instanceof ObjectChunk) {
+        if (!((ObjectChunk) v).isCompressed()) { // fix bug 52109
           // If we put it off heap and it is not compressed then remember that value.
           // Otherwise we want to remember the decompressed value in the event.
           basicSetNewValue(v);
@@ -1931,8 +1931,8 @@ public class EntryEventImpl
       success = true;
     }
     } finally {
-      if (!success && reentry instanceof OffHeapRegionEntry && v instanceof Chunk) {
-        OffHeapRegionEntryHelper.releaseEntry((OffHeapRegionEntry)reentry, (Chunk)v);
+      if (!success && reentry instanceof OffHeapRegionEntry && v instanceof ObjectChunk) {
+        OffHeapRegionEntryHelper.releaseEntry((OffHeapRegionEntry)reentry, (ObjectChunk)v);
       }      
     }
     if (logger.isTraceEnabled()) {
@@ -2232,7 +2232,7 @@ public class EntryEventImpl
    * If a PdxInstance is returned then it will have an unretained reference
    * to Chunk's off-heap address.
    */
-  public static @Unretained Object deserializeChunk(Chunk bytes) {
+  public static @Unretained Object deserializeChunk(ObjectChunk bytes) {
     if (bytes == null)
       return null;
     try {
@@ -2881,7 +2881,7 @@ public class EntryEventImpl
     private final byte[] serializedValue;
     
     SerializedCacheValueImpl(EntryEventImpl event, Region r, RegionEntry re, @Unretained CachedDeserializable cd, byte[] serializedBytes) {
-      if (cd instanceof Chunk) {
+      if (cd instanceof ObjectChunk) {
         this.event = event;
       } else {
         this.event = null;
@@ -3060,14 +3060,14 @@ public class EntryEventImpl
     Object nv = basicGetNewValue();
     this.offHeapOk = false;
     
-    if (ov instanceof Chunk) {
+    if (ov instanceof ObjectChunk) {
       //this.region.getCache().getLogger().info("DEBUG freeing ref to old value on " + System.identityHashCode(ov));
       if (ReferenceCountHelper.trackReferenceCounts()) {
         ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
-        ((Chunk) ov).release();
+        ((ObjectChunk) ov).release();
         ReferenceCountHelper.setReferenceCountOwner(null);
       } else {
-        ((Chunk) ov).release();
+        ((ObjectChunk) ov).release();
       }
     }
     OffHeapHelper.releaseAndTrackOwner(nv, this);
@@ -3078,7 +3078,7 @@ public class EntryEventImpl
    * Once this is called on an event it does not need to have release called.
    */
   public void disallowOffHeapValues() {
-    if (this.newValue instanceof Chunk || this.oldValue instanceof Chunk) {
+    if (this.newValue instanceof ObjectChunk || this.oldValue instanceof ObjectChunk) {
       throw new IllegalStateException("This event does not support off-heap values");
     }
     this.offHeapOk = false;
@@ -3092,7 +3092,7 @@ public class EntryEventImpl
   @Released({ENTRY_EVENT_NEW_VALUE, ENTRY_EVENT_OLD_VALUE})
   public void copyOffHeapToHeap() {
     Object ov = basicGetOldValue();
-    if (ov instanceof Chunk) {
+    if (ov instanceof ObjectChunk) {
       if (ReferenceCountHelper.trackReferenceCounts()) {
         ReferenceCountHelper.setReferenceCountOwner(new OldValueOwner());
         this.oldValue = OffHeapHelper.copyAndReleaseIfNeeded(ov);
@@ -3102,19 +3102,19 @@ public class EntryEventImpl
       }
     }
     Object nv = basicGetNewValue();
-    if (nv instanceof Chunk) {
+    if (nv instanceof ObjectChunk) {
       ReferenceCountHelper.setReferenceCountOwner(this);
       this.newValue = OffHeapHelper.copyAndReleaseIfNeeded(nv);
       ReferenceCountHelper.setReferenceCountOwner(null);
     }
-    if (this.newValue instanceof Chunk || this.oldValue instanceof Chunk) {
+    if (this.newValue instanceof ObjectChunk || this.oldValue instanceof ObjectChunk) {
       throw new IllegalStateException("event's old/new value still off-heap after calling copyOffHeapToHeap");
     }
     this.offHeapOk = false;
   }
 
   public boolean isOldValueOffHeap() {
-    return this.oldValue instanceof Chunk;
+    return this.oldValue instanceof ObjectChunk;
   }
   public final boolean isFetchFromHDFS() {
     return fetchFromHDFS;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
index 2092508..b6d8c49 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/LocalRegion.java
@@ -203,7 +203,7 @@ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
 import com.gemstone.gemfire.internal.offheap.StoredObject;
@@ -1587,8 +1587,8 @@ public class LocalRegion extends AbstractRegion
           }
           //For sqlf since the deserialized value is nothing but chunk
           // before returning the found value increase its use count
-          if(GemFireCacheImpl.sqlfSystem() && result instanceof Chunk) {
-            if(!((Chunk)result).retain()) {
+          if(GemFireCacheImpl.sqlfSystem() && result instanceof ObjectChunk) {
+            if(!((ObjectChunk)result).retain()) {
               return null;
             }
           }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
index b145a91..541c453 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java
@@ -252,7 +252,7 @@ import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 import com.gemstone.gemfire.internal.sequencelog.RegionLogger;
 import com.gemstone.gemfire.internal.util.TransformUtils;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
index f5f6326..c681621 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
@@ -18,7 +18,7 @@ package com.gemstone.gemfire.internal.cache.tier.sockets;
 
 import com.gemstone.gemfire.internal.*;
 import com.gemstone.gemfire.internal.cache.CachedDeserializable;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.DataAsAddress;
 import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
@@ -131,7 +131,7 @@ public class Part {
     if (so instanceof DataAsAddress) {
       this.part = ((DataAsAddress)so).getRawBytes();
     } else {
-      this.part = (Chunk)so;
+      this.part = (ObjectChunk)so;
     }
   }
   public byte getTypeCode() {
@@ -146,8 +146,8 @@ public class Part {
       return 0;
     } else if (this.part instanceof byte[]) {
       return ((byte[])this.part).length;
-    } else if (this.part instanceof Chunk) {
-      return ((Chunk) this.part).getValueSizeInBytes();
+    } else if (this.part instanceof ObjectChunk) {
+      return ((ObjectChunk) this.part).getValueSizeInBytes();
     } else {
       return ((HeapDataOutputStream)this.part).size();
     }
@@ -289,8 +289,8 @@ public class Part {
       if (this.part instanceof byte[]) {
         byte[] bytes = (byte[])this.part;
         out.write(bytes, 0, bytes.length);
-      } else if (this.part instanceof Chunk) {
-        Chunk c = (Chunk) this.part;
+      } else if (this.part instanceof ObjectChunk) {
+        ObjectChunk c = (ObjectChunk) this.part;
         ByteBuffer cbb = c.createDirectByteBuffer();
         if (cbb != null) {
           HeapDataOutputStream.writeByteBufferToStream(out,  buf, cbb);
@@ -322,8 +322,8 @@ public class Part {
     if (getLength() > 0) {
       if (this.part instanceof byte[]) {
         buf.put((byte[])this.part);
-      } else if (this.part instanceof Chunk) {
-        Chunk c = (Chunk) this.part;
+      } else if (this.part instanceof ObjectChunk) {
+        ObjectChunk c = (ObjectChunk) this.part;
         ByteBuffer bb = c.createDirectByteBuffer();
         if (bb != null) {
           buf.put(bb);
@@ -372,10 +372,10 @@ public class Part {
           }
           buf.clear();
         }
-      } else if (this.part instanceof Chunk) {
+      } else if (this.part instanceof ObjectChunk) {
         // instead of copying the Chunk to buf try to create a direct ByteBuffer and
         // just write it directly to the socket channel.
-        Chunk c = (Chunk) this.part;
+        ObjectChunk c = (ObjectChunk) this.part;
         ByteBuffer bb = c.createDirectByteBuffer();
         if (bb != null) {
           while (bb.remaining() > 0) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
index 4df8f35..e19d7bf 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
@@ -50,8 +50,8 @@ import com.gemstone.gemfire.internal.cache.WrappedCallbackArgument;
 import com.gemstone.gemfire.internal.cache.lru.Sizeable;
 import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerHelper;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
-import com.gemstone.gemfire.internal.offheap.Chunk;
-import com.gemstone.gemfire.internal.offheap.ChunkWithHeapForm;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunkWithHeapForm;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
 import com.gemstone.gemfire.internal.offheap.Releasable;
@@ -549,11 +549,11 @@ public class GatewaySenderEventImpl implements
     Object result = this.value;
     if (result == null) {
       result = this.valueObj;
-      if (result instanceof Chunk) {
+      if (result instanceof ObjectChunk) {
         if (this.valueObjReleased) {
           result = null;
         } else {
-          Chunk ohref = (Chunk) result;
+          ObjectChunk ohref = (ObjectChunk) result;
           if (!ohref.retain()) {
             result = null;
           } else if (this.valueObjReleased) {
@@ -947,8 +947,8 @@ public class GatewaySenderEventImpl implements
 //    if (so != null  && !event.hasDelta()) {
       // Since GatewaySenderEventImpl instances can live for a long time in the gateway region queue
       // we do not want the StoredObject to be one that keeps the heap form cached.
-      if (so instanceof ChunkWithHeapForm) {
-        so = ((ChunkWithHeapForm) so).getChunkWithoutHeapForm(); // fixes 51999
+      if (so instanceof ObjectChunkWithHeapForm) {
+        so = ((ObjectChunkWithHeapForm) so).getChunkWithoutHeapForm(); // fixes 51999
       }
       this.valueObj = so;
       if (!so.isSerialized()) {
@@ -1260,7 +1260,7 @@ public class GatewaySenderEventImpl implements
           return this;
         }
       }
-      if (v instanceof Chunk) {
+      if (v instanceof ObjectChunk) {
         try {
           return makeCopy();
         } catch (IllegalStateException ex) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java
new file mode 100644
index 0000000..7916e1f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunk.java
@@ -0,0 +1,29 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+/**
+ * A memory chunk that also has an address of its memory.
+ */
+public interface AddressableMemoryChunk extends MemoryChunk {
+
+  /**
+   * Return the address of the memory of this chunk.
+   */
+  public long getMemoryAddress();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java
new file mode 100644
index 0000000..fa2dd78
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryChunkFactory.java
@@ -0,0 +1,27 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+/**
+ * Used to create AddressableMemoryChunk instances.
+ */
+public interface AddressableMemoryChunkFactory {
+  /** Create and return an AddressableMemoryChunk.
+   * @throws OutOfMemoryError if the create fails
+   */
+  public AddressableMemoryChunk create(int size);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Chunk.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Chunk.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Chunk.java
deleted file mode 100644
index 4d1252d..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Chunk.java
+++ /dev/null
@@ -1,792 +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 com.gemstone.gemfire.internal.offheap;
-
-import java.io.DataOutput;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.internal.DSCODE;
-import com.gemstone.gemfire.internal.HeapDataOutputStream;
-import com.gemstone.gemfire.internal.InternalDataSerializer;
-import com.gemstone.gemfire.internal.cache.EntryEventImpl;
-import com.gemstone.gemfire.internal.cache.RegionEntry;
-import com.gemstone.gemfire.internal.cache.RegionEntryContext;
-import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
-
-/**
-   * Note: this class has a natural ordering that is inconsistent with equals.
-   * Instances of this class should have a short lifetime. We do not store references
-   * to it in the cache. Instead the memoryAddress is stored in a primitive field in
-   * the cache and if used it will then, if needed, create an instance of this class.
-   */
-  public abstract class Chunk extends OffHeapCachedDeserializable implements Comparable<Chunk>, MemoryBlock {
-    /**
-     * The unsafe memory address of the first byte of this chunk
-     */
-    private final long memoryAddress;
-    
-    /**
-     * The useCount, chunkSize, dataSizeDelta, isSerialized, and isCompressed
-     * are all stored in off heap memory in a HEADER. This saves heap memory
-     * by using off heap.
-     */
-    public final static int OFF_HEAP_HEADER_SIZE = 4 + 4;
-    /**
-     * We need to smallest chunk to at least have enough room for a hdr
-     * and for an off heap ref (which is a long).
-     */
-    public final static int MIN_CHUNK_SIZE = OFF_HEAP_HEADER_SIZE + 8;
-    /**
-     * int field.
-     * The number of bytes in this chunk.
-     */
-    private final static int CHUNK_SIZE_OFFSET = 0;
-    /**
-     * Volatile int field
-     * The upper two bits are used for the isSerialized
-     * and isCompressed flags.
-     * The next three bits are used to encode the SRC_TYPE enum.
-     * The lower 3 bits of the most significant byte contains a magic number to help us detect
-     * if we are changing the ref count of an object that has been released.
-     * The next byte contains the dataSizeDelta.
-     * The number of bytes of logical data in this chunk.
-     * Since the number of bytes of logical data is always <= chunkSize
-     * and since chunkSize never changes, we have dataSize be
-     * a delta whose max value would be HUGE_MULTIPLE-1.
-     * The lower two bytes contains the use count.
-     */
-    final static int REF_COUNT_OFFSET = 4;
-    /**
-     * The upper two bits are used for the isSerialized
-     * and isCompressed flags.
-     */
-    final static int IS_SERIALIZED_BIT =    0x80000000;
-    final static int IS_COMPRESSED_BIT =    0x40000000;
-    final static int SRC_TYPE_MASK = 0x38000000;
-    final static int SRC_TYPE_SHIFT = 16/*refCount*/+8/*dataSize*/+3/*magicSize*/;
-    final static int MAGIC_MASK = 0x07000000;
-    final static int MAGIC_NUMBER = 0x05000000;
-    final static int DATA_SIZE_DELTA_MASK = 0x00ff0000;
-    final static int DATA_SIZE_SHIFT = 16;
-    final static int REF_COUNT_MASK =       0x0000ffff;
-    final static int MAX_REF_COUNT = 0xFFFF;
-    final static long FILL_PATTERN = 0x3c3c3c3c3c3c3c3cL;
-    final static byte FILL_BYTE = 0x3c;
-    
-    // The 8 bits reserved for SRC_TYPE are basically no longer used.
-    // So we could free up these 8 bits for some other use or we could
-    // keep them for future extensions.
-    // If we ever want to allocate other "types" into a chunk of off-heap
-    // memory then the SRC_TYPE would be the way to go.
-    // For example we may want to allocate the memory for the off-heap
-    // RegionEntry in off-heap memory without it being of type GFE.
-    // When it is of type GFE then it either needs to be the bytes
-    // of a byte array or it needs to be a serialized java object.
-    // For the RegionEntry we may want all the primitive fields of
-    // the entry at certain offsets in the off-heap memory so we could
-    // access them directly in native byte format (i.e. no serialization).
-    // Note that for every SRC_TYPE we should have a ChunkType subclass.
-    public final static int SRC_TYPE_UNUSED0 = 0 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_UNUSED1 = 1 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_UNUSED2 = 2 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_UNUSED3 = 3 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_GFE = 4 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_UNUSED5 = 5 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_UNUSED6 = 6 << SRC_TYPE_SHIFT;
-    public final static int SRC_TYPE_UNUSED7 = 7 << SRC_TYPE_SHIFT;
-    
-    protected Chunk(long memoryAddress, int chunkSize, ChunkType chunkType) {
-      SimpleMemoryAllocatorImpl.validateAddressAndSize(memoryAddress, chunkSize);
-      this.memoryAddress = memoryAddress;
-      setSize(chunkSize);
-      UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, MAGIC_NUMBER|chunkType.getSrcType());
-    }
-    public void readyForFree() {
-      UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0);
-    }
-    public void readyForAllocation(ChunkType chunkType) {
-      if (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0, MAGIC_NUMBER|chunkType.getSrcType())) {
-        throw new IllegalStateException("Expected 0 but found " + Integer.toHexString(UnsafeMemoryChunk.readAbsoluteIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET)));
-      }
-    }
-    /**
-     * Should only be used by FakeChunk subclass
-     */
-    protected Chunk() {
-      this.memoryAddress = 0L;
-    }
-    
-    /**
-     * Used to create a Chunk given an existing, already allocated,
-     * memoryAddress. The off heap header has already been initialized.
-     */
-    protected Chunk(long memoryAddress) {
-      SimpleMemoryAllocatorImpl.validateAddress(memoryAddress);
-      this.memoryAddress = memoryAddress;
-    }
-    
-    protected Chunk(Chunk chunk) {
-      this.memoryAddress = chunk.memoryAddress;
-    }
-    
-    /**
-     * Throw an exception if this chunk is not allocated
-     */
-    public void checkIsAllocated() {
-      int originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
-      if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
-        throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
-      }
-    }
-    
-    public void incSize(int inc) {
-      setSize(getSize()+inc);
-    }
-    
-    protected void beforeReturningToAllocator() {
-      
-    }
-
-    @Override
-    public int getSize() {
-      return getSize(this.memoryAddress);
-    }
-
-    public void setSize(int size) {
-      setSize(this.memoryAddress, size);
-    }
-
-    public long getMemoryAddress() {
-      return this.memoryAddress;
-    }
-    
-    public int getDataSize() {
-      /*int dataSizeDelta = UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET);
-      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
-      dataSizeDelta >>= DATA_SIZE_SHIFT;
-      return getSize() - dataSizeDelta;*/
-      return getDataSize(this.memoryAddress);
-    }
-    
-    protected static int getDataSize(long memoryAdress) {
-      int dataSizeDelta = UnsafeMemoryChunk.readAbsoluteInt(memoryAdress+REF_COUNT_OFFSET);
-      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
-      dataSizeDelta >>= DATA_SIZE_SHIFT;
-      return getSize(memoryAdress) - dataSizeDelta;
-    }
-    
-    protected long getBaseDataAddress() {
-      return this.memoryAddress+OFF_HEAP_HEADER_SIZE;
-    }
-    protected int getBaseDataOffset() {
-      return 0;
-    }
-    
-    /**
-     * Creates and returns a direct ByteBuffer that contains the contents of this Chunk.
-     * Note that the returned ByteBuffer has a reference to this chunk's
-     * off-heap address so it can only be used while this Chunk is retained.
-     * @return the created direct byte buffer or null if it could not be created.
-     */
-    @Unretained
-    public ByteBuffer createDirectByteBuffer() {
-      return basicCreateDirectByteBuffer(getBaseDataAddress(), getDataSize());
-    }
-    @Override
-    public void sendTo(DataOutput out) throws IOException {
-      if (!this.isCompressed() && out instanceof HeapDataOutputStream) {
-        ByteBuffer bb = createDirectByteBuffer();
-        if (bb != null) {
-          HeapDataOutputStream hdos = (HeapDataOutputStream) out;
-          if (this.isSerialized()) {
-            hdos.write(bb);
-          } else {
-            hdos.writeByte(DSCODE.BYTE_ARRAY);
-            InternalDataSerializer.writeArrayLength(bb.remaining(), hdos);
-            hdos.write(bb);
-          }
-          return;
-        }
-      }
-      super.sendTo(out);
-    }
-    
-    @Override
-    public void sendAsByteArray(DataOutput out) throws IOException {
-      if (!isCompressed() && out instanceof HeapDataOutputStream) {
-        ByteBuffer bb = createDirectByteBuffer();
-        if (bb != null) {
-          HeapDataOutputStream hdos = (HeapDataOutputStream) out;
-          InternalDataSerializer.writeArrayLength(bb.remaining(), hdos);
-          hdos.write(bb);
-          return;
-        }
-      }
-      super.sendAsByteArray(out);
-    }
-       
-    private static volatile Class dbbClass = null;
-    private static volatile Constructor dbbCtor = null;
-    private static volatile boolean dbbCreateFailed = false;
-    
-    /**
-     * @return the created direct byte buffer or null if it could not be created.
-     */
-    private static ByteBuffer basicCreateDirectByteBuffer(long baseDataAddress, int dataSize) {
-      if (dbbCreateFailed) {
-        return null;
-      }
-      Constructor ctor = dbbCtor;
-      if (ctor == null) {
-        Class c = dbbClass;
-        if (c == null) {
-          try {
-            c = Class.forName("java.nio.DirectByteBuffer");
-          } catch (ClassNotFoundException e) {
-            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
-            dbbCreateFailed = true;
-            dbbAddressFailed = true;
-            return null;
-          }
-          dbbClass = c;
-        }
-        try {
-          ctor = c.getDeclaredConstructor(long.class, int.class);
-        } catch (NoSuchMethodException | SecurityException e) {
-          //throw new IllegalStateException("Could not get constructor DirectByteBuffer(long, int)", e);
-          dbbClass = null;
-          dbbCreateFailed = true;
-          return null;
-        }
-        ctor.setAccessible(true);
-        dbbCtor = ctor;
-      }
-      try {
-        return (ByteBuffer)ctor.newInstance(baseDataAddress, dataSize);
-      } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-        //throw new IllegalStateException("Could not create an instance using DirectByteBuffer(long, int)", e);
-        dbbClass = null;
-        dbbCtor = null;
-        dbbCreateFailed = true;
-        return null;
-      }
-    }
-    private static volatile Method dbbAddressMethod = null;
-    private static volatile boolean dbbAddressFailed = false;
-    
-    /**
-     * Returns the address of the Unsafe memory for the first byte of a direct ByteBuffer.
-     * If the buffer is not direct or the address can not be obtained return 0.
-     */
-    public static long getDirectByteBufferAddress(ByteBuffer bb) {
-      if (!bb.isDirect()) {
-        return 0L;
-      }
-      if (dbbAddressFailed) {
-        return 0L;
-      }
-      Method m = dbbAddressMethod;
-      if (m == null) {
-        Class c = dbbClass;
-        if (c == null) {
-          try {
-            c = Class.forName("java.nio.DirectByteBuffer");
-          } catch (ClassNotFoundException e) {
-            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
-            dbbCreateFailed = true;
-            dbbAddressFailed = true;
-            return 0L;
-          }
-          dbbClass = c;
-        }
-        try {
-          m = c.getDeclaredMethod("address");
-        } catch (NoSuchMethodException | SecurityException e) {
-          //throw new IllegalStateException("Could not get method DirectByteBuffer.address()", e);
-          dbbClass = null;
-          dbbAddressFailed = true;
-          return 0L;
-        }
-        m.setAccessible(true);
-        dbbAddressMethod = m;
-      }
-      try {
-        return (Long)m.invoke(bb);
-      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-        //throw new IllegalStateException("Could not create an invoke DirectByteBuffer.address()", e);
-        dbbClass = null;
-        dbbAddressMethod = null;
-        dbbAddressFailed = true;
-        return 0L;
-      }
-    }
-    /**
-     * Returns an address that can be used with unsafe apis to access this chunks memory.
-     * @param offset the offset from this chunk's first byte of the byte the returned address should point to. Must be >= 0.
-     * @param size the number of bytes that will be read using the returned address. Assertion will use this to verify that all the memory accessed belongs to this chunk. Must be > 0.
-     * @return a memory address that can be used with unsafe apis
-     */
-    public long getUnsafeAddress(int offset, int size) {
-      assert offset >= 0 && offset + size <= getDataSize(): "Offset=" + offset + ",size=" + size + ",dataSize=" + getDataSize() + ", chunkSize=" + getSize() + ", but offset + size must be <= " + getDataSize();
-      assert size > 0;
-      long result = getBaseDataAddress() + offset;
-      // validateAddressAndSizeWithinSlab(result, size);
-      return result;
-    }
-    
-    @Override
-    public byte readByte(int offset) {
-      assert offset < getDataSize();
-      return UnsafeMemoryChunk.readAbsoluteByte(getBaseDataAddress() + offset);
-    }
-
-    @Override
-    public void writeByte(int offset, byte value) {
-      assert offset < getDataSize();
-      UnsafeMemoryChunk.writeAbsoluteByte(getBaseDataAddress() + offset, value);
-    }
-
-    @Override
-    public void readBytes(int offset, byte[] bytes) {
-      readBytes(offset, bytes, 0, bytes.length);
-    }
-
-    @Override
-    public void writeBytes(int offset, byte[] bytes) {
-      writeBytes(offset, bytes, 0, bytes.length);
-    }
-
-    public long getAddressForReading(int offset, int size) {
-      //delegate to getUnsafeAddress - as both the methods does return the memory address from given offset
-      return getUnsafeAddress(offset, size);
-    }
-    
-    @Override
-    public void readBytes(int offset, byte[] bytes, int bytesOffset, int size) {
-      assert offset+size <= getDataSize();
-      UnsafeMemoryChunk.readAbsoluteBytes(getBaseDataAddress() + offset, bytes, bytesOffset, size);
-    }
-
-    @Override
-    public void writeBytes(int offset, byte[] bytes, int bytesOffset, int size) {
-      assert offset+size <= getDataSize();
-      UnsafeMemoryChunk.writeAbsoluteBytes(getBaseDataAddress() + offset, bytes, bytesOffset, size);
-    }
-    
-    @Override
-    public void release() {
-      release(this.memoryAddress, true);
-     }
-
-    @Override
-    public int compareTo(Chunk o) {
-      int result = Integer.signum(getSize() - o.getSize());
-      if (result == 0) {
-        // For the same sized chunks we really don't care about their order
-        // but we need compareTo to only return 0 if the two chunks are identical
-        result = Long.signum(getMemoryAddress() - o.getMemoryAddress());
-      }
-      return result;
-    }
-    
-    @Override
-    public boolean equals(Object o) {
-      if (o instanceof Chunk) {
-        return getMemoryAddress() == ((Chunk) o).getMemoryAddress();
-      }
-      return false;
-    }
-    
-    @Override
-    public int hashCode() {
-      long value = this.getMemoryAddress();
-      return (int)(value ^ (value >>> 32));
-    }
-
-    // OffHeapCachedDeserializable methods 
-    
-    @Override
-    public void setSerializedValue(byte[] value) {
-      writeBytes(0, value);
-    }
-    
-    public byte[] getDecompressedBytes(RegionEntryContext context) {
-      byte[] result = getCompressedBytes();
-      long time = context.getCachePerfStats().startDecompression();
-      result = context.getCompressor().decompress(result);
-      context.getCachePerfStats().endDecompression(time);      
-      return result;
-    }
-    
-    /**
-     * Returns the raw possibly compressed bytes of this chunk
-     */
-    public byte[] getCompressedBytes() {
-      byte[] result = new byte[getDataSize()];
-      readBytes(0, result);
-      //debugLog("reading", true);
-      SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
-      return result;
-    }
-    protected byte[] getRawBytes() {
-      byte[] result = getCompressedBytes();
-      // TODO OFFHEAP: change the following to assert !isCompressed();
-      if (isCompressed()) {
-        throw new UnsupportedOperationException();
-      }
-      return result;
-    }
-
-    @Override
-    public byte[] getSerializedValue() {
-      byte [] result = getRawBytes();
-      if (!isSerialized()) {
-        // The object is a byte[]. So we need to make it look like a serialized byte[] in our result
-        result = EntryEventImpl.serialize(result);
-      }
-      return result;
-    }
-    
-    @Override
-    public Object getDeserializedValue(Region r, RegionEntry re) {
-      if (isSerialized()) {
-        // TODO OFFHEAP: debug deserializeChunk
-        return EntryEventImpl.deserialize(getRawBytes());
-        //assert !isCompressed();
-        //return EntryEventImpl.deserializeChunk(this);
-      } else {
-        return getRawBytes();
-      }
-    }
-    
-    /**
-     * We want this to include memory overhead so use getSize() instead of getDataSize().
-     */
-    @Override
-    public int getSizeInBytes() {
-      // Calling getSize includes the off heap header size.
-      // We do not add anything to this since the size of the reference belongs to the region entry size
-      // not the size of this object.
-      return getSize();
-    }
-
-    @Override
-    public int getValueSizeInBytes() {
-      return getDataSize();
-    }
-
-    @Override
-    public void copyBytes(int src, int dst, int size) {
-      throw new UnsupportedOperationException("Implement if used");
-//      assert src+size <= getDataSize();
-//      assert dst+size < getDataSize();
-//      getSlabs()[this.getSlabIdx()].copyBytes(getBaseDataAddress()+src, getBaseDataAddress()+dst, size);
-    }
-
-    @Override
-    public boolean isSerialized() {
-      return (UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET) & IS_SERIALIZED_BIT) != 0;
-    }
-
-    @Override
-    public boolean isCompressed() {
-      return (UnsafeMemoryChunk.readAbsoluteInt(this.memoryAddress+REF_COUNT_OFFSET) & IS_COMPRESSED_BIT) != 0;
-    }
-
-    @Override
-    public boolean retain() {
-      return retain(this.memoryAddress);
-    }
-
-    @Override
-    public int getRefCount() {
-      return getRefCount(this.memoryAddress);
-    }
-
-    public static int getSize(long memAddr) {
-      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
-      return UnsafeMemoryChunk.readAbsoluteInt(memAddr+CHUNK_SIZE_OFFSET);
-    }
-    public static void setSize(long memAddr, int size) {
-      SimpleMemoryAllocatorImpl.validateAddressAndSize(memAddr, size);
-      UnsafeMemoryChunk.writeAbsoluteInt(memAddr+CHUNK_SIZE_OFFSET, size);
-    }
-    public static long getNext(long memAddr) {
-      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
-      return UnsafeMemoryChunk.readAbsoluteLong(memAddr+OFF_HEAP_HEADER_SIZE);
-    }
-    public static void setNext(long memAddr, long next) {
-      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
-      UnsafeMemoryChunk.writeAbsoluteLong(memAddr+OFF_HEAP_HEADER_SIZE, next);
-    }
-    @Override
-    public ChunkType getChunkType() {
-      return SimpleMemoryAllocatorImpl.getAllocator().getChunkFactory().getChunkTypeForAddress(getMemoryAddress());
-    }
-    public static int getSrcTypeOrdinal(long memAddr) {
-      return getSrcType(memAddr) >> SRC_TYPE_SHIFT;
-    }
-    public static int getSrcType(long memAddr) {
-      return getSrcTypeFromRawBits(UnsafeMemoryChunk.readAbsoluteInt(memAddr+REF_COUNT_OFFSET));
-    }
-    public static int getSrcTypeFromRawBits(int rawBits) {
-      return rawBits & SRC_TYPE_MASK;
-    }
-    public static int getSrcTypeOrdinalFromRawBits(int rawBits) {
-      return getSrcTypeFromRawBits(rawBits) >> SRC_TYPE_SHIFT;
-    }
-    
-    /**
-     * Fills the chunk with a repeated byte fill pattern.
-     * @param baseAddress the starting address for a {@link Chunk}.
-     */
-    public static void fill(long baseAddress) {
-      long startAddress = baseAddress + MIN_CHUNK_SIZE;
-      int size = getSize(baseAddress) - MIN_CHUNK_SIZE;
-      
-      UnsafeMemoryChunk.fill(startAddress, size, FILL_BYTE);
-    }
-    
-    /**
-     * Validates that the fill pattern for this chunk has not been disturbed.  This method
-     * assumes the TINY_MULTIPLE is 8 bytes.
-     * @throws IllegalStateException when the pattern has been violated.
-     */
-    public void validateFill() {
-      assert SimpleMemoryAllocatorImpl.TINY_MULTIPLE == 8;
-      
-      long startAddress = getMemoryAddress() + MIN_CHUNK_SIZE;
-      int size = getSize() - MIN_CHUNK_SIZE;
-      
-      for(int i = 0;i < size;i += SimpleMemoryAllocatorImpl.TINY_MULTIPLE) {
-        if(UnsafeMemoryChunk.readAbsoluteLong(startAddress + i) != FILL_PATTERN) {
-          throw new IllegalStateException("Fill pattern violated for chunk " + getMemoryAddress() + " with size " + getSize());
-        }        
-      }
-    }
-
-    public void setSerialized(boolean isSerialized) {
-      if (isSerialized) {
-        int bits;
-        int originalBits;
-        do {
-          originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
-          if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
-            throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
-          }
-          bits = originalBits | IS_SERIALIZED_BIT;
-        } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
-      }
-    }
-    public void setCompressed(boolean isCompressed) {
-      if (isCompressed) {
-        int bits;
-        int originalBits;
-        do {
-          originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
-          if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
-            throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
-          }
-          bits = originalBits | IS_COMPRESSED_BIT;
-        } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
-      }
-    }
-    public void setDataSize(int dataSize) { // KIRK
-      assert dataSize <= getSize();
-      int delta = getSize() - dataSize;
-      assert delta <= (DATA_SIZE_DELTA_MASK >> DATA_SIZE_SHIFT);
-      delta <<= DATA_SIZE_SHIFT;
-      int bits;
-      int originalBits;
-      do {
-        originalBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
-        if ((originalBits&MAGIC_MASK) != MAGIC_NUMBER) {
-          throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(originalBits));
-        }
-        bits = originalBits;
-        bits &= ~DATA_SIZE_DELTA_MASK; // clear the old dataSizeDelta bits
-        bits |= delta; // set the dataSizeDelta bits to the new delta value
-      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, originalBits, bits));
-    }
-    
-    public void initializeUseCount() {
-      int rawBits;
-      do {
-        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET);
-        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
-          throw new IllegalStateException("It looks like this off heap memory was already freed. rawBits=" + Integer.toHexString(rawBits));
-        }
-        int uc = rawBits & REF_COUNT_MASK;
-        if (uc != 0) {
-          throw new IllegalStateException("Expected use count to be zero but it was: " + uc + " rawBits=0x" + Integer.toHexString(rawBits));
-        }
-      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(this.memoryAddress+REF_COUNT_OFFSET, rawBits, rawBits+1));
-    }
-
-    public static int getRefCount(long memAddr) {
-      return UnsafeMemoryChunk.readAbsoluteInt(memAddr+REF_COUNT_OFFSET) & REF_COUNT_MASK;
-    }
-
-    public static boolean retain(long memAddr) {
-      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
-      int uc;
-      int rawBits;
-      int retryCount = 0;
-      do {
-        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET);
-        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
-          // same as uc == 0
-          // TODO MAGIC_NUMBER rethink its use and interaction with compactor fragments
-          return false;
-        }
-        uc = rawBits & REF_COUNT_MASK;
-        if (uc == MAX_REF_COUNT) {
-          throw new IllegalStateException("Maximum use count exceeded. rawBits=" + Integer.toHexString(rawBits));
-        } else if (uc == 0) {
-          return false;
-        }
-        retryCount++;
-        if (retryCount > 1000) {
-          throw new IllegalStateException("tried to write " + (rawBits+1) + " to @" + Long.toHexString(memAddr) + " 1,000 times.");
-        }
-      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET, rawBits, rawBits+1));
-      //debugLog("use inced ref count " + (uc+1) + " @" + Long.toHexString(memAddr), true);
-      if (ReferenceCountHelper.trackReferenceCounts()) {
-        ReferenceCountHelper.refCountChanged(memAddr, false, uc+1);
-      }
-
-      return true;
-    }
-    public static void release(final long memAddr, boolean issueOnReturnCallback) {
-      SimpleMemoryAllocatorImpl.validateAddress(memAddr);
-      int newCount;
-      int rawBits;
-      boolean returnToAllocator;
-      do {
-        returnToAllocator = false;
-        rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET);
-        if ((rawBits&MAGIC_MASK) != MAGIC_NUMBER) {
-          String msg = "It looks like off heap memory @" + Long.toHexString(memAddr) + " was already freed. rawBits=" + Integer.toHexString(rawBits) + " history=" + ReferenceCountHelper.getFreeRefCountInfo(memAddr);
-          //debugLog(msg, true);
-          throw new IllegalStateException(msg);
-        }
-        int curCount = rawBits&REF_COUNT_MASK;
-        if ((curCount) == 0) {
-          //debugLog("too many frees @" + Long.toHexString(memAddr), true);
-          throw new IllegalStateException("Memory has already been freed." + " history=" + ReferenceCountHelper.getFreeRefCountInfo(memAddr) /*+ System.identityHashCode(this)*/);
-        }
-        if (curCount == 1) {
-          newCount = 0; // clear the use count, bits, and the delta size since it will be freed.
-          returnToAllocator = true;
-        } else {
-          newCount = rawBits-1;
-        }
-      } while (!UnsafeMemoryChunk.writeAbsoluteIntVolatile(memAddr+REF_COUNT_OFFSET, rawBits, newCount));
-      //debugLog("free deced ref count " + (newCount&USE_COUNT_MASK) + " @" + Long.toHexString(memAddr), true);
-      if (returnToAllocator ) {
-        /*
-        if(issueOnReturnCallback) {
-         final GemFireCacheImpl.StaticSystemCallbacks sysCb =
-              GemFireCacheImpl.FactoryStatics.systemCallbacks;
-          if(sysCb != null ) {
-            ChunkType ct = SimpleMemoryAllocatorImpl.getAllocator().getChunkFactory().getChunkTypeForRawBits(rawBits);
-            int dataSizeDelta = computeDataSizeDelta(rawBits);
-            sysCb.beforeReturningOffHeapMemoryToAllocator(memAddr, ct, dataSizeDelta);
-          }
-        }
-        */
-       
-        if (ReferenceCountHelper.trackReferenceCounts()) {
-          if (ReferenceCountHelper.trackFreedReferenceCounts()) {
-            ReferenceCountHelper.refCountChanged(memAddr, true, newCount&REF_COUNT_MASK);
-          }
-          ReferenceCountHelper.freeRefCountInfo(memAddr);
-        }
-        
-        // Use fill pattern for free list data integrity check.
-        if(SimpleMemoryAllocatorImpl.getAllocator().validateMemoryWithFill) {
-          fill(memAddr);
-        }
-        
-        SimpleMemoryAllocatorImpl.getAllocator().freeChunk(memAddr);
-      } else {
-        if (ReferenceCountHelper.trackReferenceCounts()) {
-          ReferenceCountHelper.refCountChanged(memAddr, true, newCount&REF_COUNT_MASK);
-        }
-      }
-    }
-    
-    private static int computeDataSizeDelta(int rawBits) {
-      int dataSizeDelta = rawBits;
-      dataSizeDelta &= DATA_SIZE_DELTA_MASK;
-      dataSizeDelta >>= DATA_SIZE_SHIFT;
-      return dataSizeDelta;
-    }
-    
-    @Override
-    public String toString() {
-      return toStringForOffHeapByteSource();
-      // This old impl is not safe because it calls getDeserializedForReading and we have code that call toString that does not inc the refcount.
-      // Also if this Chunk is compressed we don't know how to decompress it.
-      //return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + getMemoryAddress() + " storedObject=" + getDeserializedForReading() + ">";
-    }
-    
-    protected String toStringForOffHeapByteSource() {
-      return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + Long.toHexString(getMemoryAddress()) + ">";
-    }
-    
-    @Override
-    public State getState() {
-      if (getRefCount() > 0) {
-        return State.ALLOCATED;
-      } else {
-        return State.DEALLOCATED;
-      }
-    }
-    @Override
-    public MemoryBlock getNextBlock() {
-      throw new UnsupportedOperationException();
-    }
-    @Override
-    public int getBlockSize() {
-      return getSize();
-    }
-    @Override
-    public int getSlabId() {
-      throw new UnsupportedOperationException();
-    }
-    @Override
-    public int getFreeListId() {
-      return -1;
-    }
-    @Override
-    public String getDataType() {
-      return null;
-    }
-    @Override
-    public Object getDataValue() {
-      return null;
-    }
-    public Chunk slice(int position, int limit) {
-      throw new UnsupportedOperationException();
-    }
-  }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkFactory.java
deleted file mode 100644
index f7d4ba8..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkFactory.java
+++ /dev/null
@@ -1,51 +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 com.gemstone.gemfire.internal.offheap;
-
-
-/**
- * ChunkFactory can be used to create Chunk instances.
- * It can also be used to determine the ChunkType given a Chunk address
- * or the object header bits from an existing Chunk.
- */
-public interface ChunkFactory  {
-  /**
-   * Create a new chunk of the given size and type at the given address.
-   */
-  Chunk newChunk(long address, int chunkSize, ChunkType chunkType);
-  /**
-   * Create a new chunk for a block of memory (identified by address)
-   * that has already been allocated.
-   * The size and type are derived from the existing object header.
-   */
-  Chunk newChunk(long address);
-  /**
-   * Create a new chunk of the given type for a block of memory (identified by address)
-   * that has already been allocated.
-   * The size is derived from the existing object header.
-   */
-  Chunk newChunk(long address, ChunkType chunkType);
-  /**
-   * Given the address of an existing chunk return its ChunkType.
-   */
-  ChunkType getChunkTypeForAddress(long address);
-  /**
-   * Given the rawBits from the object header of an existing chunk
-   * return its ChunkType.
-   */
-  ChunkType getChunkTypeForRawBits(int bits);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkType.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkType.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkType.java
deleted file mode 100644
index e48bb62..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkType.java
+++ /dev/null
@@ -1,30 +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 com.gemstone.gemfire.internal.offheap;
-
-/**
- * Describes the type of data stored in a chunk.
- */
-public interface ChunkType {
-  /**
-   * Returns an int that describes that type of
-   * data stored in the chunk.
-   * Currently the only supported type is
-   * Chunk.SRC_TYPE_GFE.
-   */
-  public int getSrcType();
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapForm.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapForm.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapForm.java
deleted file mode 100644
index d7e65f7..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapForm.java
+++ /dev/null
@@ -1,40 +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 com.gemstone.gemfire.internal.offheap;
-
-/**
- * Used to keep the heapForm around while an operation is still in progress.
- * This allows the operation to access the serialized heap form instead of copying
- * it from offheap. See bug 48135.
- */
-public class ChunkWithHeapForm extends GemFireChunk {
-  private final byte[] heapForm;
-  
-  public ChunkWithHeapForm(GemFireChunk chunk, byte[] heapForm) {
-    super(chunk);
-    this.heapForm = heapForm;
-  }
-
-  @Override
-  protected byte[] getRawBytes() {
-    return this.heapForm;
-  }
-  
-  public Chunk getChunkWithoutHeapForm() {
-    return new GemFireChunk(this);
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
index ef56627..d337cfc 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
@@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
  *
  */
 public class Fragment implements MemoryBlock {
-  private static final byte FILL_BYTE = Chunk.FILL_BYTE;
+  private static final byte FILL_BYTE = ObjectChunk.FILL_BYTE;
   private final long baseAddr;
   private final int size;
   @SuppressWarnings("unused")
@@ -119,11 +119,6 @@ public class Fragment implements MemoryBlock {
   }
 
   @Override
-  public ChunkType getChunkType() {
-    return null;
-  }
-  
-  @Override
   public boolean equals(Object o) {
     if (o instanceof Fragment) {
       return getMemoryAddress() == ((Fragment) o).getMemoryAddress();
@@ -136,4 +131,9 @@ public class Fragment implements MemoryBlock {
     long value = this.getMemoryAddress();
     return (int)(value ^ (value >>> 32));
   }
+  @Override
+  public String toString() {
+    return "Fragment [baseAddr=" + baseAddr + ", size=" + size + ", freeIdx=" + freeIdx + "]";
+  }
+
 }
\ No newline at end of file



[026/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
index f7063bc,0000000..9456f9a
mode 100644,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
@@@ -1,1690 -1,0 +1,1695 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.cache.xmlcache;
 +
 +import java.io.File;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.LinkedHashMap;
 +import java.util.LinkedHashSet;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Map.Entry;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.concurrent.TimeUnit;
 +
 +import javax.naming.Context;
 +
 +import com.gemstone.gemfire.CancelCriterion;
 +import com.gemstone.gemfire.GemFireIOException;
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.Declarable;
 +import com.gemstone.gemfire.cache.DiskStore;
 +import com.gemstone.gemfire.cache.DiskStoreFactory;
 +import com.gemstone.gemfire.cache.DynamicRegionFactory;
 +import com.gemstone.gemfire.cache.GatewayException;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionExistsException;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
 +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueueFactory;
 +import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueFactoryImpl;
 +import com.gemstone.gemfire.cache.client.Pool;
 +import com.gemstone.gemfire.cache.client.PoolFactory;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.client.internal.PoolImpl;
 +import com.gemstone.gemfire.cache.execute.FunctionService;
 +import com.gemstone.gemfire.cache.query.CqAttributes;
 +import com.gemstone.gemfire.cache.query.CqException;
 +import com.gemstone.gemfire.cache.query.CqExistsException;
 +import com.gemstone.gemfire.cache.query.CqQuery;
 +import com.gemstone.gemfire.cache.query.CqServiceStatistics;
 +import com.gemstone.gemfire.cache.query.Index;
 +import com.gemstone.gemfire.cache.query.IndexExistsException;
 +import com.gemstone.gemfire.cache.query.IndexInvalidException;
 +import com.gemstone.gemfire.cache.query.IndexNameConflictException;
 +import com.gemstone.gemfire.cache.query.IndexType;
 +import com.gemstone.gemfire.cache.query.MultiIndexCreationException;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryInvalidException;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.RegionNotFoundException;
 +import com.gemstone.gemfire.cache.query.internal.cq.CqService;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache.snapshot.CacheSnapshotService;
 +import com.gemstone.gemfire.cache.util.GatewayConflictResolver;
 +import com.gemstone.gemfire.cache.wan.GatewayReceiver;
 +import com.gemstone.gemfire.cache.wan.GatewayReceiverFactory;
 +import com.gemstone.gemfire.cache.wan.GatewaySender;
 +import com.gemstone.gemfire.cache.wan.GatewaySenderFactory;
 +import com.gemstone.gemfire.cache.wan.GatewayTransportFilter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.i18n.LogWriterI18n;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.cache.hdfs.HDFSStoreFactory;
 +import com.gemstone.gemfire.cache.hdfs.internal.HDFSIntegrationUtil;
 +import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreCreation;
 +import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreFactoryImpl;
 +import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreImpl;
 +import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 +import com.gemstone.gemfire.internal.cache.CacheConfig;
 +import com.gemstone.gemfire.internal.cache.CacheServerLauncher;
 +import com.gemstone.gemfire.internal.cache.CacheService;
 +import com.gemstone.gemfire.internal.cache.DiskStoreFactoryImpl;
 +import com.gemstone.gemfire.internal.cache.DiskStoreImpl;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.InternalCache;
 +import com.gemstone.gemfire.internal.cache.PoolFactoryImpl;
 +import com.gemstone.gemfire.internal.cache.PoolManagerImpl;
 +import com.gemstone.gemfire.internal.cache.extension.Extensible;
 +import com.gemstone.gemfire.internal.cache.extension.ExtensionPoint;
 +import com.gemstone.gemfire.internal.cache.extension.SimpleExtensionPoint;
 +import com.gemstone.gemfire.internal.cache.ha.HARegionQueue;
 +import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
 +import com.gemstone.gemfire.internal.cache.wan.WANServiceProvider;
 +import com.gemstone.gemfire.internal.cache.wan.InternalGatewaySenderFactory;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.jndi.JNDIInvoker;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.internal.logging.LocalLogWriter;
 +import com.gemstone.gemfire.internal.logging.LogWriterFactory;
 +import com.gemstone.gemfire.pdx.PdxInstance;
 +import com.gemstone.gemfire.pdx.PdxInstanceFactory;
 +import com.gemstone.gemfire.pdx.PdxSerializer;
 +import com.gemstone.gemfire.pdx.internal.TypeRegistry;
 +
 +/**
 + * Represents a {@link Cache} that is created declaratively.  Notice
 + * that it implements the {@link Cache} interface so that this class
 + * must be updated when {@link Cache} is modified.  This class is
 + * public for testing purposes.
 + *
 + * @author David Whitlock
 + *
 + * @since 3.0
 + */
 +public class CacheCreation implements InternalCache {
 +
 +  /** The amount of time to wait for a distributed lock */
 +  private int lockTimeout = GemFireCacheImpl.DEFAULT_LOCK_TIMEOUT;
 +  private boolean hasLockTimeout = false;
 +
 +  /** The duration of a lease on a distributed lock */
 +  private int lockLease = GemFireCacheImpl.DEFAULT_LOCK_LEASE;
 +  private boolean hasLockLease = false;
 +
 +  /** The amount of time to wait for a <code>netSearch</code> */
 +  private int searchTimeout = GemFireCacheImpl.DEFAULT_SEARCH_TIMEOUT;
 +  private boolean hasSearchTimeout = false;
 +
 +  private boolean hasMessageSyncInterval = false;
 +
 +  /** This cache's roots keyed on name */
 +  protected final Map roots = new LinkedHashMap();
 +  
 +  /** Are dynamic regions enabled in this cache? */
 +  private DynamicRegionFactory.Config dynamicRegionFactoryConfig = null;
 +  private boolean hasDynamicRegionFactory = false;
 +
 +  /** Is this a cache server? */
 +  private boolean isServer = false;
 +  private boolean hasServer = false;
 +
 +  /** The bridge servers configured for this cache */
 +  private final List bridgeServers = new ArrayList();
 +  
 +  // Stores the properties used to initialize declarables.
 +  private final Map<Declarable, Properties> declarablePropertiesMap = new HashMap<Declarable, Properties>();
 +  
 +  private Set<GatewaySender> gatewaySenders = new HashSet<GatewaySender>(); 
 +  
 +  private Set<GatewayReceiver> gatewayReceivers = new HashSet<GatewayReceiver>();
 +  
 +  private Set<AsyncEventQueue> asyncEventQueues = new HashSet<AsyncEventQueue>();
 +  
 +  private GatewayConflictResolver gatewayConflictResolver;
 +  
 +  /** The copyOnRead attribute */
 +  private boolean copyOnRead = GemFireCacheImpl.DEFAULT_COPY_ON_READ;
 +  private boolean hasCopyOnRead = false;
 +
 +  /** The CacheTransactionManager representative for this Cache */
 +  protected CacheTransactionManagerCreation txMgrCreation = null;
 +
 +  /** JNDI Context associated with the Gemfire */
 +//  private static Context ctx;
 +
 +  /** The named region attributes associated with this cache */
 +  private final Map namedRegionAttributes = new HashMap();
 +
 +  /** The names of the region attributes in the order in which they
 +   * were added.  Keeping track of this ensures that named region
 +   * attributes are processed in the correct order.  That is, "parent"
 +   * named region attributes will be processed before "children" named
 +   * region attributes. */
 +  protected final List regionAttributesNames = new ArrayList();
 +
 +  /** The named disk store attributes associated with this cache.
 +   * Made this linked so its iteration would be in insert order.
 +   * This is important for unit testing 44914.
 +   */
 +  protected final Map diskStores = new LinkedHashMap();
 +  protected final Map hdfsStores = new LinkedHashMap();
 +  
 +  private final List<File> backups = new ArrayList<File>();
 +
 +  private CacheConfig cacheConfig = new CacheConfig();
 +
 +  /** A logger that is used in debugging */
 +  private InternalLogWriter logWriter =
 +    new LocalLogWriter(InternalLogWriter.ALL_LEVEL, System.out);
 +
 +  private InternalLogWriter securityLogWriter =
 +      LogWriterFactory.toSecurityLogWriter(logWriter);
 +  
 +  /**
 +   * {@link ExtensionPoint} support.
 +   * @since 8.1
 +   */
 +  private SimpleExtensionPoint<Cache> extensionPoint = new SimpleExtensionPoint<Cache>(this, this);
 +
 +  ////////////////////////  Constructors  ////////////////////////
 +
 +  /**
 +   * Creates a new <code>CacheCreation</code> with no root regions
 +   */
 +  public CacheCreation() {
 +    this(false);
 +  }
 +  
 +  /** clear thread locals that may have been set by previous uses of CacheCreation */
 +  public static void clearThreadLocals() {
 +    createInProgress = new ThreadLocal<>();
 +  }
 +
 +  /**
 +   * @param forParsing if true then this creation is used for parsing xml;
 +   *   if false then it is used for generating xml.
 +   * @since 5.7
 +   */
 +  public CacheCreation(boolean forParsing) {
 +    initializeRegionShortcuts();
 +    if (!forParsing) {
 +      createInProgress.set(this.pm);
 +    }
 +  }
 +  /**
 +   * @since 5.7
 +   */
 +  public void startingGenerate() {
 +    createInProgress.set(null);
 +  }
 +  
 +  //////////////////////  Instance Methods  //////////////////////
 +
 +  static final private RegionAttributes defaults = new AttributesFactory().create();
 +    
 +  RegionAttributes getDefaultAttributes() {
 +    return defaults;
 +  }
 +
 +  protected void initializeRegionShortcuts() {
 +    GemFireCacheImpl.initializeRegionShortcuts(this);
 +  }
 +
 +  /**
 +   * Sets the attributes of the root region
 +   *
 +   * @throws RegionExistsException
 +   *         If this cache already contains a region with the same
 +   *         name as <code>root</code>.
 +   */
 +  void addRootRegion(RegionCreation root)
 +    throws RegionExistsException {
 +
 +    String name = root.getName();
 +    RegionCreation existing = (RegionCreation) this.roots.get(name);
 +    if (existing != null) {
 +      throw new RegionExistsException(existing);
 +
 +    } else {
 +      this.roots.put(root.getName(), root);
 +    }
 +  }
 +
 +  public int getLockTimeout() {
 +    return this.lockTimeout;
 +  }
 +
 +  public void setLockTimeout(int seconds) {
 +    this.lockTimeout = seconds;
 +    this.hasLockTimeout = true;
 +  }
 +
 +  boolean hasLockTimeout() {
 +    return this.hasLockTimeout;
 +  }
 +
 +  public int getLockLease() {
 +    return this.lockLease;
 +  }
 +
 +  public void setLockLease(int seconds) {
 +    this.lockLease = seconds;
 +    this.hasLockLease = true;
 +  }
 +
 +  boolean hasLockLease() {
 +    return this.hasLockLease;
 +  }
 +
 +  public int getSearchTimeout() {
 +    return this.searchTimeout;
 +  }
 +
 +  public void setSearchTimeout(int seconds) {
 +    this.searchTimeout = seconds;
 +    this.hasSearchTimeout = true;
 +  }
 +
 +  boolean hasSearchTimeout() {
 +    return this.hasSearchTimeout;
 +  }
 +
 +  public int getMessageSyncInterval()
 +  {
 +    return HARegionQueue.getMessageSyncInterval();
 +  }
 +
 +  public void setMessageSyncInterval(int seconds)
 +  {
 +    if (seconds < 0) {
 +      throw new IllegalArgumentException(LocalizedStrings.CacheCreation_THE_MESSAGESYNCINTERVAL_PROPERTY_FOR_CACHE_CANNOT_BE_NEGATIVE.toLocalizedString());
 +    }
 +    HARegionQueue.setMessageSyncInterval(seconds);
 +    this.hasMessageSyncInterval = true;
 +  }
 +
 +  boolean hasMessageSyncInterval()
 +  {
 +    return this.hasMessageSyncInterval;
 +  }
 +
 +  public Set rootRegions() {
 +    Set regions = new LinkedHashSet();
 +    for (Iterator itr = this.roots.values().iterator(); itr.hasNext();) {
 +      regions.add(itr.next());
 +    }
 +    return Collections.unmodifiableSet(regions);
 +  }
 +
 +  /**
 +   * create diskstore factory
 +   * 
 +   * @since prPersistSprint2
 +   */
 +  public DiskStoreFactory createDiskStoreFactory() {
 +    return new DiskStoreFactoryImpl(this);
 +  }
 +  
 +  /**
 +   * Store the current CacheCreation that is doing a create.
 +   * Used from PoolManager to defer to CacheCreation as a manager of pools.
 +   * @since 5.7
 +   */
 +  private static ThreadLocal createInProgress = new ThreadLocal();
 +
 +  /**
 +   * Returns null if the current thread is not doing a CacheCreation create.
 +   * Otherwise returns the PoolManagerImpl of the CacheCreation of the
 +   * create being invoked.
 +   * @since 5.7
 +   */
 +  public static final PoolManagerImpl getCurrentPoolManager() {
 +    return (PoolManagerImpl)createInProgress.get();
 +  }
 +  
 +  /**
 +   * Fills in the contents of a {@link Cache} based on this creation
 +   * object's state.
 +   *
 +   * @throws TimeoutException
 +   * @throws CacheWriterException
 +   * @throws RegionExistsException
 +   * @throws GatewayException
 +   */
 +  void create(GemFireCacheImpl cache)
 +    throws TimeoutException, CacheWriterException,
 +           GatewayException,
 +           RegionExistsException {
 +    cache.setDeclarativeCacheConfig(cacheConfig);
 +    
 +    if (cache.isClient()) {
 +      throw new IllegalStateException("You must use client-cache in the cache.xml when ClientCacheFactory is used.");
 +    }
 +    if (this.hasLockLease()) {
 +      cache.setLockLease(this.lockLease);
 +    }
 +    if (this.hasLockTimeout()) {
 +      cache.setLockTimeout(this.lockTimeout);
 +    }
 +    if (this.hasSearchTimeout()) {
 +      cache.setSearchTimeout(this.searchTimeout);
 +    }
 +    if (this.hasMessageSyncInterval()) {
 +      cache.setMessageSyncInterval(this.getMessageSyncInterval());
 +    }
 +    if (this.gatewayConflictResolver != null) {
 +      cache.setGatewayConflictResolver(this.gatewayConflictResolver);
 +    }
 +//    if (this.hasCopyOnRead()) {
 +//      cache.setCopyOnRead(this.copyOnRead);
 +//    }
 +    { // create connection pools
 +      Map m = getPools();
 +      if (!m.isEmpty()) {
 +        Iterator it = m.values().iterator();
 +        while (it.hasNext()) {
 +          Pool cp = (Pool)it.next();
 +          PoolFactoryImpl f;
 +          f = (PoolFactoryImpl)PoolManager.createFactory();
 +          f.init(cp);
 +          PoolImpl p = (PoolImpl)f.create(cp.getName());
 +        }
 +      }
 +    }
 +
 +    if (hasResourceManager()) {
 +      // moved this up to fix bug 42128
 +      getResourceManager().configure(cache.getResourceManager());
 +    }
 +    
 +    DiskStoreAttributesCreation pdxRegDSC = initializePdxDiskStore(cache);
 +    
 +    cache.initializePdxRegistry();
 +
 +    for (Iterator iter = this.diskStores.values().iterator(); iter.hasNext();) {
 +      DiskStoreAttributesCreation creation = (DiskStoreAttributesCreation) iter.next();
 +      if (creation != pdxRegDSC) {
 +        createDiskStore(creation, cache);
 +      }
 +    }
 +    
 +    if (this.hasDynamicRegionFactory()) {
 +      DynamicRegionFactory.get().open(this.getDynamicRegionFactoryConfig());
 +    }
 +    if (this.hasServer()) {
 +      cache.setIsServer(this.isServer);
 +    }
 +    if (this.hasCopyOnRead()) {
 +      cache.setCopyOnRead(this.copyOnRead);
 +    }
 +
 +    if (this.txMgrCreation != null &&
 +        this.txMgrCreation.getListeners().length > 0 &&
 +        cache.getCacheTransactionManager()!=null) {
 +      cache.getCacheTransactionManager().initListeners(this.txMgrCreation.getListeners());
 +    }
 +
 +    if (this.txMgrCreation != null &&
 +        cache.getCacheTransactionManager()!=null) {
 +      cache.getCacheTransactionManager().setWriter(this.txMgrCreation.getWriter());
 +    }
 +    
 +    for (GatewaySender senderCreation : this.getGatewaySenders()) {
 +      GatewaySenderFactory factory = (GatewaySenderFactory)cache
 +          .createGatewaySenderFactory();
 +      ((InternalGatewaySenderFactory)factory).configureGatewaySender(senderCreation);
 +      GatewaySender gatewaySender = factory.create(senderCreation.getId(),
 +          senderCreation.getRemoteDSId());
 +      // Start the sender if it is not set to manually start
 +      if (gatewaySender.isManualStart()) {
 +        cache
 +            .getLoggerI18n()
 +            .info(
 +                LocalizedStrings.CacheCreation_0_IS_NOT_BEING_STARTED_SINCE_IT_IS_CONFIGURED_FOR_MANUAL_START,
 +                gatewaySender);
 +      }
 +    }
 +    
 +    for (AsyncEventQueue asyncEventQueueCreation : this.getAsyncEventQueues()) {
 +      AsyncEventQueueFactoryImpl asyncQueueFactory = 
 +        (AsyncEventQueueFactoryImpl) cache.createAsyncEventQueueFactory();
 +      asyncQueueFactory.configureAsyncEventQueue(asyncEventQueueCreation);
 +      
 +      AsyncEventQueue asyncEventQueue = cache.getAsyncEventQueue(asyncEventQueueCreation.getId());
 +//      AsyncEventQueue asyncEventQueue = 
 +//        asyncQueueFactory.create(asyncEventQueueCreation.getId(), asyncEventQueueCreation.getAsyncEventListener());
 +      if (asyncEventQueue == null) {
 +        asyncQueueFactory.create(asyncEventQueueCreation.getId(), asyncEventQueueCreation.getAsyncEventListener());
 +      }
 +    }
 +    
 +    for (GatewayReceiver receiverCreation : this.getGatewayReceivers()) {
 +      GatewayReceiverFactory factory = cache.createGatewayReceiverFactory();
 +      factory.setBindAddress(receiverCreation.getBindAddress());
 +      factory.setMaximumTimeBetweenPings(receiverCreation
 +          .getMaximumTimeBetweenPings());
 +      factory.setStartPort(receiverCreation.getStartPort());
 +      factory.setEndPort(receiverCreation.getEndPort());
 +      factory.setSocketBufferSize(receiverCreation.getSocketBufferSize());
 +      factory.setManualStart(receiverCreation.isManualStart());
 +      for (GatewayTransportFilter filter : receiverCreation
 +          .getGatewayTransportFilters()) {
 +        factory.addGatewayTransportFilter(filter);
 +      }
 +      factory.setHostnameForSenders(receiverCreation.getHost()); 
 +      GatewayReceiver receiver = factory.create();
 +       if (receiver.isManualStart()) {
 +        cache
 +            .getLoggerI18n()
 +            .info(
 +                LocalizedStrings.CacheCreation_0_IS_NOT_BEING_STARTED_SINCE_IT_IS_CONFIGURED_FOR_MANUAL_START,
 +                receiver);
 +      }
 +    }
 +
 +    for(Iterator iter = this.hdfsStores.entrySet().iterator(); iter.hasNext(); ) {
 +      Entry entry = (Entry) iter.next();
 +      HDFSStoreCreation hdfsStoreCreation = (HDFSStoreCreation) entry.getValue();
 +      HDFSStoreFactory storefactory = cache.createHDFSStoreFactory(hdfsStoreCreation);
 +      storefactory.create((String) entry.getKey());
 +    }
 +
 +    cache.initializePdxRegistry();
 +
 +    
 +    for (Iterator iter = this.regionAttributesNames.iterator();
 +         iter.hasNext(); ) {
 +      String id = (String) iter.next();
 +      RegionAttributesCreation creation =
 +        (RegionAttributesCreation) getRegionAttributes(id);
 +      creation.inheritAttributes(cache, false);
 +
 +      // TODO: HDFS: HDFS store/queue will be mapped against region path and not
 +      // the attribute id; don't really understand what this is trying to do
 +      if (creation.getHDFSStoreName() != null)
 +      {
 +        HDFSStoreImpl store = cache.findHDFSStore(creation.getHDFSStoreName());
 +        if(store == null) {
 +          HDFSIntegrationUtil.createDefaultAsyncQueueForHDFS((Cache)cache, creation.getHDFSWriteOnly(), id);
 +        }
 +      }
 +      if (creation.getHDFSStoreName() != null && creation.getPartitionAttributes().getColocatedWith() == null) {
 +        creation.addAsyncEventQueueId(HDFSStoreFactoryImpl.getEventQueueName(id));
 +      }
 +      
 +      RegionAttributes attrs;
 +      // Don't let the RegionAttributesCreation escape to the user
 +      AttributesFactory factory = new AttributesFactory(creation);
 +      attrs = factory.create();
 +
 +      cache.setRegionAttributes(id, attrs);
 +    }
 +
 +    initializeRegions(this.roots, cache);
 +
 +    cache.readyDynamicRegionFactory();
 +
 +    // Create and start the BridgeServers. This code was moved from
 +    // before region initialization to after it to fix bug 33587.
 +    // Create and start the CacheServers after the gateways have been intialized
 +    // to fix bug 39736.
 +
 +    Integer serverPort = CacheServerLauncher.getServerPort();
 +    String serverBindAdd = CacheServerLauncher.getServerBindAddress();
 +    Boolean disableDefaultServer = CacheServerLauncher.disableDefaultServer.get();
 +    startCacheServers(this.getCacheServers(), cache, serverPort, serverBindAdd, disableDefaultServer);
 +    cache.setBackupFiles(this.backups);
 +    cache.addDeclarableProperties(this.declarablePropertiesMap);
 +    runInitializer();
 +    cache.setInitializer(getInitializer(), getInitializerProps());
 +    
 +    // UnitTest CacheXml81Test.testCacheExtension
 +    // Create all extensions
 +    extensionPoint.fireCreate(cache);
 +  }
 +
 +  protected void initializeRegions(Map declarativeRegions, Cache cache) {
 +    Iterator it = declarativeRegions.values().iterator();
 +    while (it.hasNext()) {
 +      RegionCreation r = (RegionCreation)it.next();
 +      r.createRoot(cache);
 +    }
 +  }
 +
 +  /**
 +   * starts declarative cache servers if a server is not running on the port already.
 +   * Also adds a default server to the param declarativeCacheServers if a serverPort is specified.
 +   */
 +  protected void startCacheServers(List declarativeCacheServers, Cache cache, Integer serverPort, String serverBindAdd, Boolean disableDefaultServer) {
- 
++    CacheServerCreation defaultServer = null;
++    
 +    if (declarativeCacheServers.size() > 1
 +        && (serverPort != null || serverBindAdd != null)) {
 +      throw new RuntimeException(
 +          LocalizedStrings.CacheServerLauncher_SERVER_PORT_MORE_THAN_ONE_CACHE_SERVER
 +              .toLocalizedString());
 +    }
 +
 +    if (declarativeCacheServers.isEmpty()
 +        && (serverPort != null || serverBindAdd != null)
 +        && (disableDefaultServer == null || !disableDefaultServer)) {
 +      boolean existingCacheServer = false;
 +
 +      List<CacheServer> cacheServers = cache.getCacheServers();
 +      if (cacheServers != null) {
 +        for(CacheServer cacheServer : cacheServers) {
 +          if (serverPort == cacheServer.getPort()) {
 +            existingCacheServer = true;
 +          }
 +        }
 +      }
 +      
 +      if (!existingCacheServer) {
-         declarativeCacheServers.add(new CacheServerCreation((GemFireCacheImpl)cache, false));
++        defaultServer = new CacheServerCreation((GemFireCacheImpl)cache, false);
++        declarativeCacheServers.add(defaultServer);
 +      }
 +    }
 +    
 +    for (Iterator iter = declarativeCacheServers.iterator(); iter.hasNext();) {
 +      CacheServerCreation declaredCacheServer = (CacheServerCreation)iter.next();
 +
 +      boolean startServer = true;
 +      List<CacheServer> cacheServers = cache.getCacheServers();
 +      if (cacheServers != null) {
 +        for (CacheServer cacheServer : cacheServers) {
 +          if (declaredCacheServer.getPort() == cacheServer.getPort()) {
 +            startServer = false;
 +          }
 +        }
 +      }
 +
 +      if (!startServer) {
 +        continue;
 +      }
 +
 +      CacheServerImpl impl = (CacheServerImpl)cache.addCacheServer();
 +      impl.configureFrom(declaredCacheServer);
++      if (declaredCacheServer == defaultServer) {
++        impl.setIsDefaultServer();
++      }
 +
 +      if (serverPort != null && serverPort != CacheServer.DEFAULT_PORT) {
 +        impl.setPort(serverPort);
 +      }
 +      if (serverBindAdd != null) {
 +        impl.setBindAddress(serverBindAdd.trim());
 +      }
 +      
 +      try {
 +        if (!impl.isRunning())
 +          impl.start();
 +
 +      }
 +      catch (IOException ex) {
 +        throw new GemFireIOException(
 +            LocalizedStrings.CacheCreation_WHILE_STARTING_CACHE_SERVER_0
 +                .toLocalizedString(impl), ex);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Returns a description of the disk store used by the pdx registry.
 +   */
 +  protected DiskStoreAttributesCreation initializePdxDiskStore(GemFireCacheImpl cache) {
 +    // to fix bug 44271 create the disk store used by the pdx registry first.
 +    // If it is using the default disk store we need to create it now.
 +    // If the cache has a pool then no need to create disk store.
 +    DiskStoreAttributesCreation pdxRegDSC = null;
 +    if (TypeRegistry.mayNeedDiskStore(cache)) {
 +      String pdxRegDsName = cache.getPdxDiskStore();
 +      if (pdxRegDsName == null) {
 +        pdxRegDsName = DiskStoreFactory.DEFAULT_DISK_STORE_NAME;
 +      }
 +      // make sure pdxRegDSC gets set to fix for bug 44914
 +      pdxRegDSC = (DiskStoreAttributesCreation)this.diskStores.get(pdxRegDsName);
 +      if (pdxRegDSC == null) {
 +        if (pdxRegDsName.equals(DiskStoreFactory.DEFAULT_DISK_STORE_NAME)) {
 +          // need to create default disk store
 +          cache.getOrCreateDefaultDiskStore();
 +        }
 +      } else {
 +        createDiskStore(pdxRegDSC, cache);
 +      }
 +    }
 +    return pdxRegDSC;
 +  }
 +  
 +  protected void createDiskStore(DiskStoreAttributesCreation creation, GemFireCacheImpl cache) {
 +    // Don't let the DiskStoreAttributesCreation escape to the user
 +    DiskStoreFactory factory = cache.createDiskStoreFactory(creation);
 +    factory.create(creation.getName());
 +  }
 +
 +  /**
 +   * Returns whether or not this <code>CacheCreation</code> is
 +   * equivalent to another <code>Cache</code>.
 +   */
 +  public boolean sameAs(Cache other) {
 +    boolean sameConfig =
 +      other.getLockLease() == this.getLockLease() &&
 +      other.getLockTimeout() == this.getLockTimeout() &&
 +      other.getSearchTimeout() == this.getSearchTimeout() &&
 +      other.getMessageSyncInterval() == this.getMessageSyncInterval() &&
 +      other.getCopyOnRead() == this.getCopyOnRead() &&
 +      other.isServer() == this.isServer();
 +
 +    if (!sameConfig) {
 +      throw new RuntimeException(LocalizedStrings.CacheCreation_SAMECONFIG.toLocalizedString());
 +
 +    } else {
 +      DynamicRegionFactory.Config drc1 = this.getDynamicRegionFactoryConfig();
 +      if (drc1 != null) {
 +        // we have a dynamic region factory
 +        DynamicRegionFactory.Config drc2 = null;
 +        if (other instanceof CacheCreation) {
 +          drc2 = ((CacheCreation)other).getDynamicRegionFactoryConfig();
 +        } else {
 +          drc2 = DynamicRegionFactory.get().getConfig();
 +        }
 +        if (drc2 == null) {
 +          return false;
 +        }
 +        if (!drc1.equals(drc2)) {
 +          return false;
 +        }
 +      } else {
 +        // we have no dynamic region factory; how about other?
 +        if (other instanceof CacheCreation) {
 +          if (((CacheCreation)other).getDynamicRegionFactoryConfig() != null) {
 +            return false;
 +          }
 +        } else {
 +          // other must be real cache in which case we compare to DynamicRegionFactory
 +          if (DynamicRegionFactory.get().isOpen()) {
 +            return false;
 +          }
 +        }
 +      }
 +
 +      Collection myBridges = this.getCacheServers();
 +      Collection otherBridges = other.getCacheServers();
 +      if (myBridges.size() != otherBridges.size()) {
 +        throw new RuntimeException(LocalizedStrings.CacheCreation_CACHESERVERS_SIZE.toLocalizedString());
 +      }
 +
 +      for (Iterator myIter = myBridges.iterator(); myIter.hasNext(); ) {
 +        CacheServerCreation myBridge =
 +          (CacheServerCreation) myIter.next();
 +        boolean found = false;
 +        for (Iterator otherIter = otherBridges.iterator();
 +             otherIter.hasNext(); ) {
 +          CacheServer otherBridge = (CacheServer) otherIter.next();
 +          if (myBridge.sameAs(otherBridge)) {
 +            found = true;
 +            break;
 +          }
 +        }
 +
 +        if (!found) {
 +          throw new RuntimeException(LocalizedStrings.CacheCreation_CACHE_SERVER_0_NOT_FOUND.toLocalizedString(myBridge));
 +        }
 +      }
 +
 +      { // compare connection pools
 +        Map m1 = getPools();
 +        Map m2 = (other instanceof CacheCreation)
 +          ? ((CacheCreation)other).getPools()
 +          : PoolManager.getAll();
 +        int m1Size = m1.size();
 +        {
 +          // ignore any gateway instances
 +          Iterator it1 = m1.values().iterator();
 +          while (it1.hasNext()) {
 +            Pool cp = (Pool)it1.next();
 +            if (((PoolImpl)cp).isUsedByGateway()) {
 +              m1Size--;
 +            }
 +          }
 +        }
 +        int m2Size = m2.size();
 +        {
 +          // ignore any gateway instances
 +          Iterator it2 = m2.values().iterator();
 +          while (it2.hasNext()) {
 +            Pool cp = (Pool)it2.next();
 +            if (((PoolImpl)cp).isUsedByGateway()) {
 +              m2Size--;
 +            }
 +          }
 +        }
 +        if (m2Size == 1) {
 +          // if it is just the DEFAULT pool then ignore it
 +          Pool p = (Pool)m2.values().iterator().next();
 +          if (p.getName().equals("DEFAULT")) {
 +            m2Size = 0;
 +          }
 +        }
 +        
 +        if (m1Size != m2Size) {
 +          throw new RuntimeException("pool sizes differ m1Size=" + m1Size
 +                                     + " m2Size=" + m2Size
 +                                     + " m1=" + m1.values()
 +                                     + " m2=" + m2.values());
 +        }
 +        
 +        if (m1Size > 0) {
 +          Iterator it1 = m1.values().iterator();
 +          while (it1.hasNext()) {
 +            PoolImpl cp = (PoolImpl)it1.next();
 +            // ignore any gateway instances
 +            if (!(cp).isUsedByGateway()) {
 +              cp.sameAs(m2.get(cp.getName()));
 +            }
 +          }
 +        }
 +      }
 +
 +      // compare disk stores
 +      for (Iterator myIter = diskStores.values().iterator(); myIter.hasNext(); ) {
 +        DiskStoreAttributesCreation dsac = (DiskStoreAttributesCreation)myIter.next();
 +        String name = dsac.getName();
 +        DiskStore ds = other.findDiskStore(name);
 +        if (ds == null) {
 +          getLogger().fine("Disk store " + name+" not found.");
 +          throw new RuntimeException(LocalizedStrings.CacheCreation_DISKSTORE_NOTFOUND_0.toLocalizedString(name));
 +        } else {
 +          if (!dsac.sameAs(ds)) {
 +            getLogger().fine("Attributes for disk store " + name + " do not match");
 +            throw new RuntimeException(LocalizedStrings.CacheCreation_ATTRIBUTES_FOR_DISKSTORE_0_DO_NOT_MATCH.toLocalizedString(name));
 +          }
 +        }
 +      }
 +
 +      Map myNamedAttributes = this.listRegionAttributes();
 +      Map otherNamedAttributes = other.listRegionAttributes();
 +      if (myNamedAttributes.size() != otherNamedAttributes.size()) {
 +        throw new RuntimeException(LocalizedStrings.CacheCreation_NAMEDATTRIBUTES_SIZE.toLocalizedString());
 +      }
 +
 +      for (Iterator myIter = myNamedAttributes.entrySet().iterator();
 +           myIter.hasNext(); ) {
 +        Map.Entry myEntry = (Map.Entry) myIter.next();
 +        String myId = (String) myEntry.getKey();
 +        Assert.assertTrue(myEntry.getValue() instanceof RegionAttributesCreation,
 +                          "Entry value is a " + myEntry.getValue().getClass().getName());
 +        RegionAttributesCreation myAttrs =
 +          (RegionAttributesCreation) myEntry.getValue();
 +        RegionAttributes otherAttrs = other.getRegionAttributes(myId);
 +        if (otherAttrs == null) {
 +          getLogger().fine("No attributes for " + myId);
 +          throw new RuntimeException(LocalizedStrings.CacheCreation_NO_ATTRIBUTES_FOR_0.toLocalizedString(myId));
 +
 +        } else {
 +          if (!myAttrs.sameAs(otherAttrs)) {
 +            getLogger().fine("Attributes for " + myId +
 +                             " do not match");
 +            throw new RuntimeException(LocalizedStrings.CacheCreation_ATTRIBUTES_FOR_0_DO_NOT_MATCH.toLocalizedString(myId));
 +          }
 +        }
 +      }
 +
 +      Collection myRoots = this.roots.values();
 +      Collection otherRoots = other.rootRegions();
 +      if (myRoots.size() != otherRoots.size()) {
 +        throw new RuntimeException(LocalizedStrings.CacheCreation_ROOTS_SIZE.toLocalizedString());
 +      }
 +      Iterator it = myRoots.iterator();
 +      while (it.hasNext()) {
 +        RegionCreation r = (RegionCreation)it.next();
 +        Region r2 = other.getRegion(r.getName());
 +        if (r2 == null) {
 +          throw new RuntimeException(LocalizedStrings.CacheCreation_NO_ROOT_0.toLocalizedString(r.getName()));
 +        } else if (!r.sameAs(r2)) {
 +          throw new RuntimeException(LocalizedStrings.CacheCreation_REGIONS_DIFFER.toLocalizedString());
 +        }
 +      }
 +
 +      // If both have a listener, make sure they are equal.
 +      if (getCacheTransactionManager() != null) {
 +        // Currently the GemFireCache always has a CacheTransactionManager,
 +        // whereas that is not true for CacheTransactionManagerCreation.
 +
 +        List otherTxListeners =
 +          Arrays.asList(other.getCacheTransactionManager().getListeners());
 +        List thisTxListeners =
 +          Arrays.asList(getCacheTransactionManager().getListeners());
 +
 +        if (!thisTxListeners.equals(otherTxListeners)) {
 +          throw new RuntimeException(LocalizedStrings.CacheCreation_TXLISTENER.toLocalizedString());
 +        }
 +      }
 +    }
 +
 +    if (hasResourceManager()) {
 +      getResourceManager().sameAs(other.getResourceManager());
 +    }
 +
 +    return true;
 +  }
 +
 +  //////////  Inherited methods that don't do anything  //////////
 +
 +  public void close() {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  public void close(boolean keepalive) {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +//  public Region createRootRegion(RegionAttributes aRegionAttributes)
 +//    throws RegionExistsException, TimeoutException  {
 +//
 +//    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +//  }
 +
 +  // see Cache.isReconnecting()
 +  public boolean isReconnecting() {
 +    throw new UnsupportedOperationException();
 +  }
 +
 +  // see Cache.waitUntilReconnected(long, TimeUnit)
 +  public boolean waitUntilReconnected(long time, TimeUnit units) throws InterruptedException {
 +    throw new UnsupportedOperationException();
 +  }
 +  
 +  // see Cache.stopReconnecting()
 +  public void stopReconnecting() {
 +    throw new UnsupportedOperationException();
 +  }
 +  
 +  // see Cache.getReconnectedCache()
 +  public Cache getReconnectedCache() {
 +    throw new UnsupportedOperationException();
 +  }
 +  
 +  public LogWriter getLogger() {
 +    return this.logWriter;
 +  }
 +
 +  public LogWriter getSecurityLogger() {
 +    return this.securityLogWriter;
 +  }
 +
 +  public LogWriterI18n getLoggerI18n() {
 +    return this.logWriter.convertToLogWriterI18n();
 +  }
 +  
 +  public LogWriterI18n getSecurityLoggerI18n() {
 +    return this.securityLogWriter.convertToLogWriterI18n();
 +  }
 +  
 +  public DistributedSystem getDistributedSystem() {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  public boolean isClosed(){
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  public String getName() {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +  
 +  public CancelCriterion getCancelCriterion() {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  public com.gemstone.gemfire.cache.query.QueryService getQueryService() {
 +    return queryService;
 +  }
 +    
 +  /**
 +   * @since 6.5
 +   */
 +  public <K,V> RegionFactory<K,V> createRegionFactory(RegionShortcut atts) {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +  /**
 +   * @since 6.5
 +   */
 +  public <K,V> RegionFactory<K,V> createRegionFactory() {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +  /**
 +   * @since 6.5
 +   */
 +  public <K,V> RegionFactory<K,V> createRegionFactory(String regionAttributesId) {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +  /**
 +   * @since 6.5
 +   */
 +  public <K,V> RegionFactory<K,V> createRegionFactory(RegionAttributes<K,V> regionAttributes) {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  public Region createVMRegion(String name, RegionAttributes attrs) throws RegionExistsException, TimeoutException {
 +    return createRegion(name, attrs);
 +  }
 +  public Region createRegion(String name, RegionAttributes attrs) throws RegionExistsException, TimeoutException {
 +    if (attrs instanceof RegionAttributesCreation) {
 +      ((RegionAttributesCreation) attrs).inheritAttributes(this);
 +      ((RegionAttributesCreation) attrs).prepareForValidation();
 +    }
 +    AttributesFactory.validateAttributes(attrs);
 +    RegionCreation region = new RegionCreation(this, name, null);
 +    region.setAttributes(attrs);
 +    this.addRootRegion(region);
 +    return region;
 +  }
 +  public Region createRegion(String name, String refid) throws RegionExistsException, TimeoutException {
 +    RegionCreation region = new RegionCreation(this, name, refid);
 +    this.addRootRegion(region);
 +    return region;
 +  }
 +
 +  public Region getRegion(String path) {
 +    if (path.indexOf('/') != -1) {
 +      throw new UnsupportedOperationException();
 +    }
 +    return (Region)this.roots.get(path);
 +  }
 +
 +  public CacheServer addCacheServer() {
 +    return addCacheServer(false);
 +  }
 +  
 +  public CacheServer addCacheServer(boolean isGatewayReceiver) {
 +    CacheServer bridge = new CacheServerCreation(this, false);
 +    this.bridgeServers.add(bridge);
 +    return bridge;
 +  }
 +
 +  public void addDeclarableProperties(final Declarable declarable, final Properties properties) {
 +    this.declarablePropertiesMap.put(declarable, properties);
 +  }
 +  
 +  public List getCacheServers() {
 +    return this.bridgeServers;
 +  }
 +  
 +  public GatewaySender addGatewaySender(GatewaySender sender){
 +    this.gatewaySenders.add(sender);
 +    return sender;
 +  }
 +  
 +  public GatewayReceiver addGatewayReceiver(GatewayReceiver receiver){
 +    this.gatewayReceivers.add(receiver);
 +    return receiver;
 +  }
 +  
 +  public AsyncEventQueue addAsyncEventQueue(AsyncEventQueue asyncEventQueue) {
 +    this.asyncEventQueues.add(asyncEventQueue);
 +    return asyncEventQueue;
 +  }
 +  
 +  public Set<GatewaySender> getGatewaySenders(){
 +    Set<GatewaySender> tempSet = new HashSet<GatewaySender>();
 +    for (GatewaySender sender : this.gatewaySenders) {
 +      if (!((AbstractGatewaySender)sender).isForInternalUse()) {
 +        tempSet.add(sender);
 +      }
 +    }
 +    return tempSet;
 +  }
 +  
 +  public GatewaySender getGatewaySender(String Id) {
 +    for (GatewaySender sender : this.gatewaySenders) {
 +      if (sender.getId().equals(Id)) {
 +        return sender;
 +      }
 +    }
 +    return null;
 +  }
 +  
 +//  public GatewayReceiver addGatewayReceiver(){
 +//    GatewayReceiverCreation receiver = new GatewayReceiverCreation();
 +//    this.gatewayReceivers.add(receiver);
 +//    return receiver;
 +//  }
 +//  
 +  public Set<GatewayReceiver>  getGatewayReceivers(){
 +    return this.gatewayReceivers;
 +  }
 +  
 +  public Set<AsyncEventQueue> getAsyncEventQueues() {
 +    return this.asyncEventQueues;
 +  }
 +  
 +  public AsyncEventQueue getAsyncEventQueue(String id) {
 +    for (AsyncEventQueue asyncEventQueue : this.asyncEventQueues) {
 +      if (asyncEventQueue.getId().equals(id)) {
 +        return asyncEventQueue;
 +      }
 +    }
 +    return null;
 +  }
 +
 +  public void setIsServer(boolean isServer) {
 +    this.isServer = isServer;
 +    this.hasServer = true;
 +  }
 +
 +  public boolean isServer() {
 +	if (!this.isServer) {  
 +	  return (this.bridgeServers.size() > 0);
 +	}
 +	else {
 +	  return true;	
 +	}
 +  }
 +
 +  boolean hasServer() {
 +    return this.hasServer;
 +  }
 +
 +  public void setDynamicRegionFactoryConfig(DynamicRegionFactory.Config v) {
 +    this.dynamicRegionFactoryConfig = v;
 +    this.hasDynamicRegionFactory = true;
 +  }
 +
 +  boolean hasDynamicRegionFactory() {
 +    return this.hasDynamicRegionFactory;
 +  }
 +
 +  public DynamicRegionFactory.Config getDynamicRegionFactoryConfig() {
 +    return this.dynamicRegionFactoryConfig;
 +  }
 +  
 +  public CacheTransactionManager getCacheTransactionManager() {
 +    return this.txMgrCreation;
 +  }
 +
 +  /**
 +   * Implementation of {@link Cache#setCopyOnRead}
 +   * @since 4.0
 +   */
 +  public void setCopyOnRead(boolean copyOnRead) {
 +    this.copyOnRead = copyOnRead;
 +    this.hasCopyOnRead = true;
 +  }
 +
 +  /**
 +   * Implementation of {@link Cache#getCopyOnRead}
 +   * @since 4.0
 +   */
 +  public boolean getCopyOnRead() {
 +    return this.copyOnRead;
 +  }
 +
 +  boolean hasCopyOnRead() {
 +    return this.hasCopyOnRead;
 +  }
 +
 +  /**
 +   * Adds a CacheTransactionManagerCreation for this Cache (really just a
 +   * placeholder since a CacheTransactionManager is really a Cache singleton)
 +   * @since 4.0
 +   * @see GemFireCacheImpl
 +   */
 +  public void
 +    addCacheTransactionManagerCreation(CacheTransactionManagerCreation txm) {
 +    this.txMgrCreation = txm;
 +  }
 +
 +/**
 + * @return Context jndi context associated with the Cache.
 + */
 +  public Context getJNDIContext() {
 +    return JNDIInvoker.getJNDIContext();
 +  }
 +  
 +  // It's not used
 +  public DiskStore findDiskStore(String storeName) {
 +    String s = storeName;
 +    if (s == null) {
 +      s = GemFireCacheImpl.getDefaultDiskStoreName();
 +    }
 +    return (DiskStore)this.diskStores.get(s);
 +  }
 +  public void addDiskStore(DiskStore ds) {
 +    this.diskStores.put(ds.getName(), ds);
 +  }
 +
 +  /**
 +   * Returns the DiskStore list
 +   *
 +   * @since prPersistSprint2
 +   */
 +  public Collection<DiskStoreImpl> listDiskStores() {
 +    return this.diskStores.values();
 +  }
 +  
 +  public void setDiskStore(String name, DiskStoreAttributesCreation dsac) {
 +//    Assert.assertTrue(ds instanceof DiskStoreAttributesCreation,
 +//                      "Attributes are a " + ds.getClass().getName());
 +    this.diskStores.put(name, dsac);
 +  }
 +
 +  public RegionAttributes getRegionAttributes(String id) {
 +    return (RegionAttributes) this.namedRegionAttributes.get(id);
 +  }
 +
 +  public void setRegionAttributes(String id, RegionAttributes attrs) {
 +    RegionAttributes a = attrs;
 +    if (!(a instanceof RegionAttributesCreation)) {
 +      a = new RegionAttributesCreation(this, a, false);
 +    }
 +    this.namedRegionAttributes.put(id, a);
 +    this.regionAttributesNames.add(id);
 +  }
 +
 +  public Map listRegionAttributes() {
 +    return Collections.unmodifiableMap(this.namedRegionAttributes);
 +  }
 +
 +  public void loadCacheXml(InputStream is)
 +    throws TimeoutException, CacheWriterException,
 +           RegionExistsException {
 +
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  public void readyForEvents() {
 +    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +  }
 +
 +  private final PoolManagerImpl pm = new PoolManagerImpl(false);
 +  private volatile FunctionServiceCreation functionServiceCreation;
 +
 +  public Map getPools() {
 +    return this.pm.getMap();
 +  }
 +
 +  public PoolFactory createPoolFactory() {
 +    return (new PoolFactoryImpl(this.pm)).setStartDisabled(true);
 +  }
 +
 +  public Pool findPool(String name) {
 +    return this.pm.find(name);
 +  }
 +  
 +  public void setFunctionServiceCreation(FunctionServiceCreation f) {
 +    this.functionServiceCreation = f;
 +  }
 +  public FunctionServiceCreation getFunctionServiceCreation() {
 +    return this.functionServiceCreation;
 +  }
 +
 +  private volatile boolean hasResourceManager = false;
 +  private volatile ResourceManagerCreation resourceManagerCreation;
 +  public void setResourceManagerCreation(ResourceManagerCreation rmc) {
 +    this.hasResourceManager = true;
 +    this.resourceManagerCreation = rmc;
 +  }
 +  public ResourceManagerCreation getResourceManager() {
 +    return this.resourceManagerCreation;
 +  }
 +  public boolean hasResourceManager() {
 +    return this.hasResourceManager;
 +  }
 +  
 +  private volatile boolean hasSerializerRegistration = false;
 +  private volatile SerializerCreation serializerCreation;
 +  public void setSerializerCreation(SerializerCreation sc) {
 +    this.hasSerializerRegistration = true;
 +    this.serializerCreation = sc;
 +  }
 +  public SerializerCreation getSerializerCreation() {
 +    return this.serializerCreation;
 +  }
 +  public boolean hasSerializerCreation() {
 +    return this.hasSerializerRegistration;
 +  }
 +  public FunctionService getFunctionService(){
 +    throw new UnsupportedOperationException();
 +  }
 +
 +  public void addBackup(File backup) {
 +    this.backups.add(backup);
 +  }
 +  
 +  public List<File> getBackupFiles() {
 +    return Collections.unmodifiableList(this.backups);
 +  }
 +  
 +  public GatewaySenderFactory createGatewaySenderFactory(){
 +    return WANServiceProvider.createGatewaySenderFactory(this);
 +  }
 +  
 +  public GatewayReceiverFactory createGatewayReceiverFactory() {
 +    return WANServiceProvider.createGatewayReceiverFactory(this);
 +  }
 +  
 +  public AsyncEventQueueFactory createAsyncEventQueueFactory() {
 +    return new AsyncEventQueueFactoryImpl(this);
 +  }
 +
 +  public void setPdxReadSerialized(boolean readSerialized) {
 +    cacheConfig.setPdxReadSerialized(readSerialized);
 +  }
 +  public void setPdxIgnoreUnreadFields(boolean ignore) {
 +    cacheConfig.setPdxIgnoreUnreadFields(ignore);
 +  }
 +
 + public void setPdxSerializer(PdxSerializer serializer) {
 +   cacheConfig.setPdxSerializer(serializer);
 + }
 +
 + public void setPdxDiskStore(String diskStore) {
 +   cacheConfig.setPdxDiskStore(diskStore);
 + }
 +
 + public void setPdxPersistent(boolean persistent) {
 +   cacheConfig.setPdxPersistent(persistent);
 + }
 +  
 +  /**
 +   * Returns whether PdxInstance is preferred for PDX types instead of Java object.
 +   * @see com.gemstone.gemfire.cache.CacheFactory#setPdxReadSerialized(boolean)
 +   *
 +   * @since 6.6
 +   */
 +  public boolean getPdxReadSerialized() {
 +     return cacheConfig.isPdxReadSerialized();
 +  }
 +
 +  public PdxSerializer getPdxSerializer() {
 +    return cacheConfig.getPdxSerializer();
 +  }
 +
 +  public String getPdxDiskStore() {
 +    return cacheConfig.getPdxDiskStore();
 +  }
 +
 +  public boolean getPdxPersistent() {
 +    return cacheConfig.isPdxPersistent();
 +  }
 +  public boolean getPdxIgnoreUnreadFields() {
 +    return cacheConfig.getPdxIgnoreUnreadFields();
 +  }
 +
 +
 +  public CacheConfig getCacheConfig() {
 +    return cacheConfig;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache.Cache#getMembers()
 +   */
 +  public Set<DistributedMember> getMembers() {
 +    return Collections.EMPTY_SET;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache.Cache#getAdminMembers()
 +   */
 +  public Set<DistributedMember> getAdminMembers() {
 +    return Collections.EMPTY_SET;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see com.gemstone.gemfire.cache.Cache#getMembers(com.gemstone.gemfire.cache.Region)
 +   */
 +  public Set<DistributedMember> getMembers(Region r) {
 +    return Collections.EMPTY_SET;
 +  }
 +
 +  private Declarable initializer = null;
 +  private Properties initializerProps = null;
 +  
 +  public Declarable getInitializer() {
 +    return this.initializer;
 +  }
 +  public Properties getInitializerProps() {
 +    return this.initializerProps;
 +  }
 +  
 +  public void setInitializer(Declarable d, Properties props) {
 +    this.initializer = d;
 +    this.initializerProps = props;
 +  }
 +  
 +  protected void runInitializer() {
 +    if (getInitializer() != null) {
 +      getInitializer().init(getInitializerProps());
 +    }
 +  }
 +
 +  public void setGatewayConflictResolver(GatewayConflictResolver g) {
 +    this.gatewayConflictResolver = g;
 +  }
 +
 +  public GatewayConflictResolver getGatewayConflictResolver() {
 +    return this.gatewayConflictResolver;
 +  }
 +    
 +  public PdxInstanceFactory createPdxInstanceFactory(String className) {
 +    throw new UnsupportedOperationException();
 +  }
 +  public PdxInstanceFactory createPdxInstanceFactory(String className, boolean b) {
 +    throw new UnsupportedOperationException();
 +  }
 +  public PdxInstance createPdxEnum(String className, String enumName, int enumOrdinal) {
 +    throw new UnsupportedOperationException();
 +  }
 +  
 +  public CacheSnapshotService getSnapshotService() {
 +    throw new UnsupportedOperationException();
 +  }
 +
 +  /**
 +   * @see Extensible#getExtensionPoint()
 +   * @since 8.1
 +   */
 +  @Override
 +  public ExtensionPoint<Cache> getExtensionPoint() {
 +    return extensionPoint;
 +  }
 +  
 +  @Override
 +  public Collection<HDFSStoreImpl> getHDFSStores() {
 +    return this.hdfsStores.values();
 +  }
 +
 +  public void addHDFSStore(String name, HDFSStoreCreation hs) {
 +    this.hdfsStores.put(name, hs);
 +  }
 +
 +  
 +
 +  @Override
 +  public DistributedMember getMyId() {
 +    return null;
 +  }
 +
 +  @Override
 +  public Collection<DiskStoreImpl> listDiskStoresIncludingDefault() {
 +    return null;
 +  }
 +
 +  @Override
 +  public Collection<DiskStoreImpl> listDiskStoresIncludingRegionOwned() {
 +    return null;
 +  }
 +
 +  @Override
 +  public CqService getCqService() {
 +    return null;
 +  }
 +
 +  public QueryService queryService = new com.gemstone.gemfire.cache.query.QueryService() {
 +
 +    private Map<String, List> indexes = new HashMap<String, List>();
 +    
 +    @Override
 +    public Query newQuery(String queryString) {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public Index createHashIndex(String indexName, String indexedExpression,
 +        String regionPath) throws IndexInvalidException,
 +        IndexNameConflictException, IndexExistsException,
 +        RegionNotFoundException, UnsupportedOperationException {
 +      return createHashIndex(indexName, indexedExpression, regionPath, "");
 +    }
 +
 +    @Override
 +    public Index createHashIndex(String indexName, String indexedExpression,
 +        String regionPath, String imports) throws IndexInvalidException,
 +        IndexNameConflictException, IndexExistsException,
 +        RegionNotFoundException, UnsupportedOperationException {
 +      return createIndex(indexName, IndexType.HASH, indexedExpression, regionPath, imports);
 +    }
 +
 +    @Override
 +    public Index createIndex(String indexName, IndexType indexType,
 +        String indexedExpression, String fromClause)
 +        throws IndexInvalidException, IndexNameConflictException,
 +        IndexExistsException, RegionNotFoundException,
 +        UnsupportedOperationException {
 +      return createIndex(indexName, indexType, indexedExpression, fromClause, "");
 +    }
 +
 +    @Override
 +    /** 
 +     * Due to not having the full implementation to determine region names etc
 +     * this implementation will only match a single region with no alias at this time
 +     */
 +    public Index createIndex(String indexName, IndexType indexType,
 +        String indexedExpression, String fromClause, String imports)
 +        throws IndexInvalidException, IndexNameConflictException,
 +        IndexExistsException, RegionNotFoundException,
 +        UnsupportedOperationException {
 +      IndexCreationData indexData = new IndexCreationData(indexName);
 +      indexData.setFunctionalIndexData(fromClause, indexedExpression, imports);
 +      indexData.setIndexType(indexType.toString());
 +      List indexesForRegion = indexes.get(fromClause);
 +      if (indexesForRegion == null) {
 +        indexesForRegion = new ArrayList();
 +        indexes.put(fromClause, indexesForRegion);
 +      }
 +      indexesForRegion.add(indexData);
 +      return indexData;
 +    }
 +
 +    @Override
 +    public Index createIndex(String indexName, String indexedExpression,
 +        String regionPath) throws IndexInvalidException,
 +        IndexNameConflictException, IndexExistsException,
 +        RegionNotFoundException, UnsupportedOperationException {
 +      return createIndex(indexName, indexedExpression, regionPath, "");
 +    }
 +
 +    @Override
 +    public Index createIndex(String indexName, String indexedExpression,
 +        String regionPath, String imports) throws IndexInvalidException,
 +        IndexNameConflictException, IndexExistsException,
 +        RegionNotFoundException, UnsupportedOperationException {
 +       return createIndex(indexName, IndexType.FUNCTIONAL, indexedExpression, regionPath, imports);
 +
 +    }
 +
 +    @Override
 +    public Index createKeyIndex(String indexName, String indexedExpression,
 +        String regionPath) throws IndexInvalidException,
 +        IndexNameConflictException, IndexExistsException,
 +        RegionNotFoundException, UnsupportedOperationException {
 +      return createIndex(indexName, IndexType.PRIMARY_KEY, indexedExpression, regionPath, "");
 +
 +    }
 +
 +    @Override
 +    public Index getIndex(Region<?, ?> region, String indexName) {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public Collection<Index> getIndexes() {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public Collection<Index> getIndexes(Region<?, ?> region) {
 +      return indexes.get(region.getFullPath());
 +    }
 +
 +    @Override
 +    public Collection<Index> getIndexes(Region<?, ?> region,
 +        IndexType indexType) {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void removeIndex(Index index) {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());        
 +    }
 +
 +    @Override
 +    public void removeIndexes() {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());        
 +    }
 +
 +    @Override
 +    public void removeIndexes(Region<?, ?> region) {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());        
 +    }
 +
 +    @Override
 +    public CqQuery newCq(String queryString, CqAttributes cqAttr)
 +        throws QueryInvalidException, CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public CqQuery newCq(String queryString, CqAttributes cqAttr,
 +        boolean isDurable) throws QueryInvalidException, CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public CqQuery newCq(String name, String queryString, CqAttributes cqAttr)
 +        throws QueryInvalidException, CqExistsException, CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public CqQuery newCq(String name, String queryString,
 +        CqAttributes cqAttr, boolean isDurable) throws QueryInvalidException,
 +        CqExistsException, CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void closeCqs() {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());        
 +    }
 +
 +    @Override
 +    public CqQuery[] getCqs() {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public CqQuery[] getCqs(String regionName) throws CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public CqQuery getCq(String cqName) {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void executeCqs() throws CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void stopCqs() throws CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void executeCqs(String regionName) throws CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void stopCqs(String regionName) throws CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public List<String> getAllDurableCqsFromServer() throws CqException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public CqServiceStatistics getCqStatistics() {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +
 +    @Override
 +    public void defineKeyIndex(String indexName, String indexedExpression,
 +        String fromClause) throws RegionNotFoundException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void defineHashIndex(String indexName, String indexedExpression,
 +        String regionPath) throws RegionNotFoundException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void defineHashIndex(String indexName, String indexedExpression,
 +        String regionPath, String imports) throws RegionNotFoundException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void defineIndex(String indexName, String indexedExpression,
 +        String regionPath) throws RegionNotFoundException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public void defineIndex(String indexName, String indexedExpression,
 +        String regionPath, String imports) throws RegionNotFoundException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public List<Index> createDefinedIndexes() throws MultiIndexCreationException {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +
 +    @Override
 +    public boolean clearDefinedIndexes() {
 +      throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
 +    }
 +    
 +  };
 +
 +  @Override
 +  public <T extends CacheService> T getService(Class<T> clazz) {
 +    throw new UnsupportedOperationException();
 +  }
 +}


[085/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
index 0000000,3a3b5a1..cc358f5
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/BytesAndBitsForCompactor.java
@@@ -1,0 -1,94 +1,94 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ /**
+  * Used to fetch a record's raw bytes and user bits.
+  * The actual data length in byte array may be less than
+  * the size of the byte array itself. An integer field contains
+  * the valid length. This class is used exclusively by the Oplog Compactor
+  * for rolling the entries. The reason for this class is to reuse the
+  * underlying byte array for rolling multiple entries there by
+  * reducing the garbage.
+  * @author Asif 
+  * @since 5.5
+  */
+ public class BytesAndBitsForCompactor {
+   /**
+    * If dataChunk is set then ignore the "data" and "validLength" fields.
+    * The dataChunk field is unretained so it can only be used while the RegionEntry is still synced.
+    * When done with the dataChunk, null it out if you want to reuse the byte[] later.
+    */
 -  private @Unretained Chunk dataChunk;
++  private @Unretained ObjectChunk dataChunk;
+   private  byte[] data;
+   private  byte userBits=0;
+   // length of the data present in the byte array 
+   private  int validLength;
+   private static final byte[] INIT_FOR_WRAPPER = new byte[0];
+   // boolean indicating if the object can be reused.
+   // Typically if the data stores the reference of a value byte [] directly
+   // from the RegionEntry than this byte array cannot be reused for
+   //storing another entry's data 
+   private boolean isReusable ;
+ 
+   public BytesAndBitsForCompactor() {
+     this.data = INIT_FOR_WRAPPER;
+     //this.userBits = userBits;
+     this.validLength = INIT_FOR_WRAPPER.length;
+     this.isReusable = true;
+   }
+ 
+   
 -  public final Chunk getDataChunk() {
++  public final ObjectChunk getDataChunk() {
+     return this.dataChunk;
+   }
+   public final byte[] getBytes() {
+     return this.data;
+   }
+   public final byte getBits() {
+     return this.userBits;
+   }
+   
+   public final int getValidLength() {
+     return this.validLength;
+   }
+   
+   public boolean isReusable() {
+     return this.isReusable;
+   }
+   
+   /**
+    * 
+    * @param data byte array storing the data 
+    * @param userBits byte with appropriate bits set
+    * @param validLength  The number of bytes representing the data , starting from 0 as offset
+    * @param isReusable true if this object is safe for reuse as a data holder
+    */
+   public void setData(byte[] data, byte userBits, int validLength, boolean isReusable) {
+     this.data = data;
+     this.userBits = userBits;
+     this.validLength = validLength;    
+     this.isReusable = isReusable;
+   }
 -  public void setChunkData(Chunk c, byte userBits) {
++  public void setChunkData(ObjectChunk c, byte userBits) {
+     this.dataChunk = c;
+     this.userBits = userBits;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
index 0000000,c855cca..327279b
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/DiskEntry.java
@@@ -1,0 -1,2028 +1,2028 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import java.io.IOException;
+ import java.nio.ByteBuffer;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.cache.DiskAccessException;
+ import com.gemstone.gemfire.distributed.internal.DM;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.ByteArrayDataInput;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.ValueWrapper;
+ import com.gemstone.gemfire.internal.cache.DiskStoreImpl.AsyncDiskEntry;
+ import com.gemstone.gemfire.internal.cache.lru.EnableLRU;
+ import com.gemstone.gemfire.internal.cache.lru.LRUClockNode;
+ import com.gemstone.gemfire.internal.cache.lru.LRUEntry;
+ import com.gemstone.gemfire.internal.cache.persistence.BytesAndBits;
+ import com.gemstone.gemfire.internal.cache.persistence.DiskRecoveryStore;
+ import com.gemstone.gemfire.internal.cache.persistence.DiskRegionView;
+ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
+ import com.gemstone.gemfire.internal.offheap.Releasable;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ import com.gemstone.gemfire.internal.util.BlobHelper;
+ 
+ /**
+  * Represents an entry in an {@link RegionMap} whose value may be
+  * stored on disk.  This interface provides accessor and mutator
+  * methods for a disk entry's state.  This allows us to abstract all
+  * of the interesting behavior into a {@linkplain DiskEntry.Helper
+  * helper class} that we only need to implement once.
+  *
+  * <P>
+  *
+  * Each <code>DiskEntry</code> has a unique <code>id</code> that is
+  * used by the {@link DiskRegion} to identify the key/value pair.
+  * Before the disk entry is written to disk, the value of the
+  * <code>id</code> is {@link DiskRegion#INVALID_ID invalid}.  Once the
+  * object has been written to disk, the <code>id</code> is a positive
+  * number.  If the value is {@linkplain Helper#update updated}, then the
+  * <code>id</code> is negated to signify that the value on disk is
+  * dirty.
+  *
+  * @see DiskRegion
+  *
+  * @author David Whitlock
+  *
+  * @since 3.2
+  */
+ public interface DiskEntry extends RegionEntry {
+   /**
+    * Sets the value with a {@link RegionEntryContext}.
+    * @param context the value's context.
+    * @param value an entry value.
+    */
+   public void setValueWithContext(RegionEntryContext context,Object value);
+   
+   /**
+    * In some cases we need to do something just before we drop the value
+    * from a DiskEntry that is being moved (i.e. overflowed) to disk.
+    * @param context
+    */
+   public void handleValueOverflow(RegionEntryContext context);
+   
+   /**
+    * In some cases we need to do something just after we unset the value
+    * from a DiskEntry that has been moved (i.e. overflowed) to disk.
+    * @param context
+    */
+   public void afterValueOverflow(RegionEntryContext context);
+ 
+   /**
+    * Returns true if the DiskEntry value is equal to {@link Token#DESTROYED}, {@link Token#REMOVED_PHASE1}, or {@link Token#REMOVED_PHASE2}.
+    */
+   public boolean isRemovedFromDisk();
+   
+   /**
+    * Returns the id of this <code>DiskEntry</code>
+    */
+   public DiskId getDiskId();
+ 
+   public void _removePhase1();
+   
+   public int updateAsyncEntrySize(EnableLRU capacityController);
+   
+   public DiskEntry getPrev();
+   public DiskEntry getNext();
+   public void setPrev(DiskEntry v);
+   public void setNext(DiskEntry v);
+ 
+   /**
+    * Used as the entry value if it was invalidated.
+    */
+   public static final byte[] INVALID_BYTES = new byte[0];
+   /**
+    * Used as the entry value if it was locally invalidated.
+    */
+   public static final byte[] LOCAL_INVALID_BYTES = new byte[0];
+   /**
+    * Used as the entry value if it was tombstone.
+    */
+   public static final byte[] TOMBSTONE_BYTES = new byte[0];
+     
+   ///////////////////////  Inner Classes  //////////////////////
+ 
+   /**
+    * A Helper class for performing functions common to all
+    * <code>DiskEntry</code>s. 
+    */
+   public static class Helper {
+     private static final Logger logger = LogService.getLogger();
+ 
+     /**
+      * Testing purpose only
+      * Get the value of an entry that is on disk without faulting
+      * it in and without looking in the io buffer.
+      * @since 3.2.1
+      */
+     static Object getValueOnDisk(DiskEntry entry, DiskRegion dr) {
+       DiskId id = entry.getDiskId();
+       if (id == null) {
+         return null;
+       }
+       dr.acquireReadLock();
+       try {
+       synchronized (id) {
+         if (id == null
+             || (dr.isBackup() && id.getKeyId() == DiskRegion.INVALID_ID)
+             || (!entry.isValueNull() && id.needsToBeWritten() && !EntryBits.isRecoveredFromDisk(id.getUserBits()))/*fix for bug 41942*/) {
+           return null;
+         }
+ 
+         return dr.getNoBuffer(id);
+       }
+       } finally {
+         dr.releaseReadLock();
+       }
+     }
+     
+     /**
+      * Get the serialized value directly from disk.  Returned object may be
+      * a {@link CachedDeserializable}.  Goes straight to disk without faulting
+      * into memory.  Only looks at the disk storage, not at heap storage.
+      * @param entry the entry used to identify the value to fetch
+      * @param dr the persistent storage from which to fetch the value
+      * @return either null, byte array, or CacheDeserializable
+      * @since gemfire57_hotfix
+      */
+     public static Object getSerializedValueOnDisk(
+         DiskEntry entry, DiskRegion dr) {
+       DiskId did = entry.getDiskId();
+       if (did == null) {
+         return null;
+       }
+       dr.acquireReadLock();
+       try {
+       synchronized (did) {
+         if (did == null
+             || (dr.isBackup() && did.getKeyId() == DiskRegion.INVALID_ID)) {
+           return null;
+         } else if (!entry.isValueNull() && did.needsToBeWritten() && !EntryBits.isRecoveredFromDisk(did.getUserBits())/*fix for bug 41942*/) {
+           return null;
+         }
+         return dr.getSerializedData(did);
+       }
+       } finally {
+         dr.releaseReadLock();
+       }
+     }
+ 
+     
+     /**
+      * Get the value of an entry that is on disk without
+      * faulting it in . It checks for the presence in the buffer also.
+      * This method is used for concurrent map operations, SQLFabric and CQ processing
+      * 
+      * @throws DiskAccessException
+      * @since 5.1
+      */
+     static Object getValueOnDiskOrBuffer(DiskEntry entry, DiskRegion dr, RegionEntryContext context) {
+       @Released Object v = getOffHeapValueOnDiskOrBuffer(entry, dr, context);
+       if (v instanceof CachedDeserializable) {
 -        if (v instanceof Chunk) {
 -          @Released Chunk ohv = (Chunk) v;
++        if (v instanceof ObjectChunk) {
++          @Released ObjectChunk ohv = (ObjectChunk) v;
+           try {
+             v = ohv.getDeserializedValue(null, null);
+             if (v == ohv) {
+               throw new IllegalStateException("sqlf tried to use getValueOnDiskOrBuffer");
+             }
+           } finally {
+             ohv.release(); // OFFHEAP the offheap ref is decremented here
+           }
+         } else {
+           v = ((CachedDeserializable)v).getDeserializedValue(null, null);
+         }
+       }
+       return v;
+     }
+     
+     @Retained
+     static Object getOffHeapValueOnDiskOrBuffer(DiskEntry entry, DiskRegion dr, RegionEntryContext context) {
+       DiskId did = entry.getDiskId();
+       Object syncObj = did;
+       if (syncObj == null) {
+         syncObj = entry;
+       }
+       if (syncObj == did) {
+         dr.acquireReadLock();
+       }
+       try {
+         synchronized (syncObj) {
+           if (did != null && did.isPendingAsync()) {
+             @Retained Object v = entry._getValueRetain(context, true); // TODO:KIRK:OK Rusty had Object v = entry.getValueWithContext(context);
+             if (Token.isRemovedFromDisk(v)) {
+               v = null;
+             }
+             return v;
+           }
+           if (did == null
+               || ( dr.isBackup() && did.getKeyId() == DiskRegion.INVALID_ID)
+               || (!entry.isValueNull() && did.needsToBeWritten() && !EntryBits.isRecoveredFromDisk(did.getUserBits()))/*fix for bug 41942*/) {
+             return null;
+           }
+ 
+           return dr.getSerializedData(did);
+         }
+       } finally {
+         if (syncObj == did) {
+           dr.releaseReadLock();
+         }
+       }
+     }
+       
+     /**
+      * Returns false if the entry is INVALID (or LOCAL_INVALID). Determines this
+      * without faulting in the value from disk.
+      * 
+      * @since 3.2.1
+      */
+     /* TODO prpersist - Do we need this method? It was added by the sqlf merge
+     static boolean isValid(DiskEntry entry, DiskRegion dr) {
+       synchronized (entry) {
+         if (entry.isRecovered()) {
+           // We have a recovered entry whose value is still on disk.
+           // So take a peek at it without faulting it in.
+           //long id = entry.getDiskId().getKeyId();
+           //entry.getDiskId().setKeyId(-id);
+           byte bits = dr.getBits(entry.getDiskId());
+           //TODO Asif:Check if resetting is needed
+           return !EntryBits.isInvalid(bits) && !EntryBits.isLocalInvalid(bits);
+         }
+       }
+     }*/
+ 
+     static boolean isOverflowedToDisk(DiskEntry de, DiskRegion dr, DistributedRegion.DiskPosition dp,RegionEntryContext context) {
+       Object v = null;
+       DiskId did;
+       synchronized (de) {
+         did = de.getDiskId();
+       }
+       Object syncObj = did;
+       if (syncObj == null) {
+         syncObj = de;
+       }
+       if (syncObj == did) {
+         dr.acquireReadLock();
+       }
+       try {
+       synchronized (syncObj) {
+         if (de.isValueNull()) {
+           if (did == null) {
+             synchronized (de) {
+               did = de.getDiskId();
+             }
+             assert did != null;
+             return isOverflowedToDisk(de, dr, dp, context);
+           } else {
+             dp.setPosition(did.getOplogId(), did.getOffsetInOplog());
+             return true;
+           }
+         } else {
+           return false;
+         }
+       }
+       } finally {
+         if (syncObj == did) {
+           dr.releaseReadLock();
+         }
+       }
+     }
+     
+     /**
+      * Get the value of an entry that is on disk without faulting
+      * it in.
+      * @since 3.2.1
+      */
+     static boolean fillInValue(DiskEntry de, InitialImageOperation.Entry entry,
+                                DiskRegion dr, DM mgr, ByteArrayDataInput in, RegionEntryContext context) {
+       @Retained @Released Object v = null;
+       DiskId did;
+       synchronized (de) {
+         did = de.getDiskId();
+       }
+       Object syncObj = did;
+       if (syncObj == null) {
+         syncObj = de;
+       }
+       if (syncObj == did) {
+         dr.acquireReadLock();
+       }
+       try {
+       synchronized (syncObj) {
+         entry.setLastModified(mgr, de.getLastModified());
+                               
+         ReferenceCountHelper.setReferenceCountOwner(entry);
+         v = de._getValueRetain(context, true); // OFFHEAP copied to heap entry; todo allow entry to refer to offheap since it will be copied to network.
+         ReferenceCountHelper.setReferenceCountOwner(null);
+         if (v == null) {
+           if (did == null) {
+             // fix for bug 41449
+             synchronized (de) {
+               did = de.getDiskId();
+             }
+             assert did != null;
+             // do recursive call to get readLock on did
+             return fillInValue(de, entry, dr, mgr, in, context);
+           }
+           if (logger.isDebugEnabled()) {
+             logger.debug("DiskEntry.Helper.fillInValue, key={}; getting value from disk, disk id={}", entry.key, did);
+           }
+           BytesAndBits bb  = null;
+           try {
+             bb = dr.getBytesAndBits(did, false);
+           }catch(DiskAccessException dae){
+             return false;
+           }
+           if (EntryBits.isInvalid(bb.getBits())) {
+             entry.setInvalid();
+           }
+           else if (EntryBits.isLocalInvalid(bb.getBits())) {
+             entry.setLocalInvalid();
+           }
+           else if (EntryBits.isTombstone(bb.getBits())) {
+             entry.setTombstone();
+           }
+           else {
+             entry.value = bb.getBytes();
+             entry.setSerialized(EntryBits.isSerialized(bb.getBits()));
+           }
+           return true;
+         }
+       }
+       } finally {
+         if (syncObj == did) {
+           dr.releaseReadLock();
+         }
+       }
+       final boolean isEagerDeserialize = entry.isEagerDeserialize();
+       if (isEagerDeserialize) {
+         entry.clearEagerDeserialize();
+       }
+       if (Token.isRemovedFromDisk(v)) {
+         // fix for bug 31757
+         return false;
+       } else if (v instanceof CachedDeserializable) {
+         try {
+           if (v instanceof StoredObject && !((StoredObject) v).isSerialized()) {
+             entry.setSerialized(false);
+             entry.value = ((StoredObject) v).getDeserializedForReading();
+             
+             //For SQLFire we prefer eager deserialized
+ //            if(v instanceof ByteSource) {
+ //              entry.setEagerDeserialize();
+ //            }
+           } else {
+             // don't serialize here if it is not already serialized
+             
+             Object tmp = ((CachedDeserializable)v).getValue();
+           //For SQLFire we prefer eager deserialized
+ //            if(v instanceof ByteSource) {
+ //              entry.setEagerDeserialize();
+ //            }
+             if (tmp instanceof byte[]) {
+               byte[] bb = (byte[])tmp;
+               entry.value = bb;
+               entry.setSerialized(true);
+             }
+             else if (isEagerDeserialize && tmp instanceof byte[][]) {
+               // optimize for byte[][] since it will need to be eagerly deserialized
+               // for SQLFabric
+               entry.value = tmp;
+               entry.setEagerDeserialize();
+               entry.setSerialized(true);
+             }
+             else {
+               try {
+                 HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+                 BlobHelper.serializeTo(tmp, hdos);
+                 hdos.trim();
+                 entry.value = hdos;
+                 entry.setSerialized(true);
+               } catch (IOException e) {
+                 RuntimeException e2 = new IllegalArgumentException(LocalizedStrings.DiskEntry_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString());
+                 e2.initCause(e);
+                 throw e2;
+               }
+             }
+           }
+         } finally {
+           // If v == entry.value then v is assumed to be an OffHeapByteSource
+           // and release() will be called on v after the bytes have been read from
+           // off-heap.
+           if (v != entry.value) {
+             OffHeapHelper.releaseWithNoTracking(v);
+           }
+         }
+       }
+       else if (v instanceof byte[]) {
+         entry.value = v;
+         entry.setSerialized(false);
+       }
+       else if (isEagerDeserialize && v instanceof byte[][]) {
+         // optimize for byte[][] since it will need to be eagerly deserialized
+         // for SQLFabric
+         entry.value = v;
+         entry.setEagerDeserialize();
+       }
+       else if (v == Token.INVALID) {
+         entry.setInvalid();
+       }
+       else if (v == Token.LOCAL_INVALID) {
+         // fix for bug 31107
+         entry.setLocalInvalid();
+       } else if (v == Token.TOMBSTONE) {
+         entry.setTombstone();
+       }
+       else {
+         Object preparedValue = v;
+         if (preparedValue != null) {
+           preparedValue = AbstractRegionEntry.prepareValueForGII(preparedValue);
+           if (preparedValue == null) {
+             return false;
+           }
+         }
+       if (CachedDeserializableFactory.preferObject()) {
+         entry.value = preparedValue;
+         entry.setEagerDeserialize();
+       }
+       else {
+         try {
+           HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+           BlobHelper.serializeTo(preparedValue, hdos);
+           hdos.trim();
+           entry.value = hdos;
+           entry.setSerialized(true);
+         } catch (IOException e) {
+           RuntimeException e2 = new IllegalArgumentException(LocalizedStrings.DiskEntry_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString());
+           e2.initCause(e);
+           throw e2;
+         }
+       }
+       }
+       return true;
+     }
+ 
+     /**
+      * Used to initialize a new disk entry
+      */
+     static void initialize(DiskEntry entry, DiskRecoveryStore r, Object newValue) {
+       DiskRegionView drv = null;
+       if (r instanceof LocalRegion) {
+         drv = ((LocalRegion)r).getDiskRegion();
+       } else if (r instanceof DiskRegionView) {
+         drv = (DiskRegionView)r;
+       }
+       if (drv == null) {
+         throw new IllegalArgumentException(LocalizedStrings.DiskEntry_DISK_REGION_IS_NULL.toLocalizedString());
+       }
+ 
+       if (newValue == null || Token.isRemovedFromDisk(newValue)) {
+         // it is not in vm and it is not on disk
+         DiskId did = entry.getDiskId();
+         if (did != null) {
+           did.setKeyId(DiskRegion.INVALID_ID);
+         }
+       }
+       else if (newValue instanceof RecoveredEntry) {
+         // Set the id directly, the value will also be set if RECOVER_VALUES
+         RecoveredEntry re = (RecoveredEntry)newValue;
+         DiskId did = entry.getDiskId();
+         did.setOplogId(re.getOplogId());
+         did.setOffsetInOplog(re.getOffsetInOplog());
+         did.setKeyId(re.getRecoveredKeyId());
+         did.setUserBits(re.getUserBits());
+         did.setValueLength(re.getValueLength());
+         if (re.getRecoveredKeyId() < 0) {
+           drv.incNumOverflowOnDisk(1L);
+           drv.incNumOverflowBytesOnDisk(did.getValueLength());
+           incrementBucketStats(r, 0/*InVM*/, 1/*OnDisk*/, did.getValueLength());
+         }
+         else {
+           entry.setValueWithContext(drv, entry.prepareValueForCache((RegionEntryContext) r,
+               re.getValue(), false));
+           drv.incNumEntriesInVM(1L);
+           incrementBucketStats(r, 1/*InVM*/, 0/*OnDisk*/, 0);
+         }
+       }
+       else {
+         DiskId did = entry.getDiskId();
+         if (did != null) {
+           did.setKeyId(DiskRegion.INVALID_ID);
+         }
+         drv.incNumEntriesInVM(1L);
+         incrementBucketStats(r, 1/*InVM*/, 0/*OnDisk*/, 0);
+       }
+     }
+     
+     private static final ValueWrapper INVALID_VW = new ByteArrayValueWrapper(true, INVALID_BYTES);
+     private static final ValueWrapper LOCAL_INVALID_VW = new ByteArrayValueWrapper(true, LOCAL_INVALID_BYTES);
+     private static final ValueWrapper TOMBSTONE_VW = new ByteArrayValueWrapper(true, TOMBSTONE_BYTES);
+     
+     public static interface ValueWrapper {
+       public boolean isSerialized();
+       public int getLength();
+       public byte getUserBits();
+       public void sendTo(ByteBuffer bb, Flushable flushable) throws IOException;
+       public String getBytesAsString();
+     }
+     public static interface Flushable {
+       public void flush() throws IOException;
+ 
+       public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException;
+     }
+     public static class ByteArrayValueWrapper implements ValueWrapper {
+       public final boolean isSerializedObject;
+       public final byte[] bytes;
+       
+      public ByteArrayValueWrapper(boolean isSerializedObject, byte[] bytes) {
+         this.isSerializedObject = isSerializedObject;
+         this.bytes = bytes;
+       }
+ 
+       @Override
+       public boolean isSerialized() {
+         return this.isSerializedObject;
+       }
+ 
+       @Override
+       public int getLength() {
+         return (this.bytes != null) ? this.bytes.length : 0;
+       }
+ 
+       private boolean isInvalidToken() {
+         return this == INVALID_VW;
+       }
+ 
+       private boolean isLocalInvalidToken() {
+         return this == LOCAL_INVALID_VW;
+       }
+ 
+       private boolean isTombstoneToken() {
+         return this == TOMBSTONE_VW;
+       }
+ 
+       @Override
+       public byte getUserBits() {
+         byte userBits = 0x0;
+         if (isSerialized()) {
+           if (isTombstoneToken()) {
+             userBits = EntryBits.setTombstone(userBits, true);
+           } else if (isInvalidToken()) {
+             userBits = EntryBits.setInvalid(userBits, true);
+           } else if (isLocalInvalidToken()) {
+             userBits = EntryBits.setLocalInvalid(userBits, true);
+           } else {
+             if (this.bytes == null) {
+               throw new IllegalStateException("userBits==1 and value is null");
+             } else if (this.bytes.length == 0) {
+               throw new IllegalStateException("userBits==1 and value is zero length");
+             }
+             userBits = EntryBits.setSerialized(userBits, true);
+           }
+         }
+         return userBits;
+       }
+ 
+       @Override
+       public void sendTo(ByteBuffer bb, Flushable flushable) throws IOException {
+         int offset = 0;
+         final int maxOffset = getLength();
+         while (offset < maxOffset) {
+           int bytesThisTime = maxOffset - offset;
+           boolean needsFlush = false;
+           if (bytesThisTime > bb.remaining()) {
+             needsFlush = true;
+             bytesThisTime = bb.remaining();
+           }
+           bb.put(this.bytes, offset, bytesThisTime);
+           offset += bytesThisTime;
+           if (needsFlush) {
+             flushable.flush();
+           }
+         }
+       }
+ 
+       @Override
+       public String getBytesAsString() {
+         if (this.bytes == null) {
+           return "null";
+         }
+         StringBuffer sb = new StringBuffer();
+         int len = getLength();
+         for (int i = 0; i < len; i++) {
+           sb.append(this.bytes[i]).append(", ");
+         }
+         return sb.toString();
+       }
+     }
+     
+     /**
+      * This class is a bit of a hack used by the compactor.
+      * For the compactor always copies to a byte[] so
+      * this class is just a simple wrapper.
+      * It is possible that the length of the byte array is greater
+      * than the actual length of the wrapped data.
+      * At the time we create this we are all done with isSerialized
+      * and userBits so those methods are not supported.
+      */
+     public static class CompactorValueWrapper extends ByteArrayValueWrapper {
+       private final int length;
+       
+       public CompactorValueWrapper(byte[] bytes, int length) {
+         super(false, bytes);
+         this.length = length;
+       }
+       
+       @Override
+       public boolean isSerialized() {
+         throw new UnsupportedOperationException();
+       }
+ 
+       @Override
+       public int getLength() {
+         return this.length;
+       }
+ 
+       @Override
+       public byte getUserBits() {
+         throw new UnsupportedOperationException();
+       }
+     }
+     
+     /**
+      * Note that the Chunk this ValueWrapper is created with
+      * is unretained so it must be used before the owner of
+      * the chunk releases it.
+      * Since the RegionEntry that has the value we are writing to
+      * disk has it retained we are ok as long as this ValueWrapper's
+      * life ends before the RegionEntry sync is released.
+      * Note that this class is only used with uncompressed chunks.
+      */
+     public static class ChunkValueWrapper implements ValueWrapper {
 -      private final @Unretained Chunk chunk;
 -      public ChunkValueWrapper(Chunk c) {
++      private final @Unretained ObjectChunk chunk;
++      public ChunkValueWrapper(ObjectChunk c) {
+         assert !c.isCompressed();
+         this.chunk = c;
+       }
+       @Override
+       public boolean isSerialized() {
+         return this.chunk.isSerialized();
+       }
+       @Override
+       public int getLength() {
+         return this.chunk.getDataSize();
+       }
+       @Override
+       public byte getUserBits() {
+         byte userBits = 0x0;
+         if (isSerialized()) {
+           userBits = EntryBits.setSerialized(userBits, true);
+         }
+         return userBits;
+       }
+       @Override
+       public void sendTo(ByteBuffer bb, Flushable flushable) throws IOException {
+         final int maxOffset = getLength();
+         if (maxOffset == 0) {
+           return;
+         }
+         if (maxOffset > bb.capacity()) {
+           ByteBuffer chunkbb = this.chunk.createDirectByteBuffer();
+           if (chunkbb != null) {
+             flushable.flush(bb, chunkbb);
+             return;
+           }
+         }
 -        final long bbAddress = Chunk.getDirectByteBufferAddress(bb);
++        final long bbAddress = ObjectChunk.getDirectByteBufferAddress(bb);
+         if (bbAddress != 0L) {
+           int bytesRemaining = maxOffset;
+           int availableSpace = bb.remaining();
+           long addrToWrite = bbAddress + bb.position();
+           long addrToRead = this.chunk.getAddressForReading(0, maxOffset);
+           if (bytesRemaining > availableSpace) {
+             do {
+               UnsafeMemoryChunk.copyMemory(addrToRead, addrToWrite, availableSpace);
+               bb.position(bb.position()+availableSpace);
+               addrToRead += availableSpace;
+               bytesRemaining -= availableSpace;
+               flushable.flush();
+               addrToWrite = bbAddress + bb.position();
+               availableSpace = bb.remaining();
+             } while (bytesRemaining > availableSpace);
+           }
+           UnsafeMemoryChunk.copyMemory(addrToRead, addrToWrite, bytesRemaining);
+           bb.position(bb.position()+bytesRemaining);
+         } else {
+           long addr = this.chunk.getAddressForReading(0, maxOffset);
+           final long endAddr = addr + maxOffset;
+           while (addr != endAddr) {
+             bb.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
+             addr++;
+             if (!bb.hasRemaining()) {
+               flushable.flush();
+             }
+           }
+         }
+       }
+       @Override
+       public String getBytesAsString() {
+         return this.chunk.getStringForm();
+       }
+     }
+ 
+     public static ValueWrapper createValueWrapper(Object value, EntryEventImpl event) {
+       if (value == Token.INVALID) {
+         // even though it is not serialized we say it is because
+         // bytes will never be an empty array when it is serialized
+         // so that gives us a way to specify the invalid value
+         // given a byte array and a boolean flag.
+         return INVALID_VW;
+       }
+       else if (value == Token.LOCAL_INVALID) {
+         // even though it is not serialized we say it is because
+         // bytes will never be an empty array when it is serialized
+         // so that gives us a way to specify the local-invalid value
+         // given a byte array and a boolean flag.
+         return LOCAL_INVALID_VW;
+       }
+       else if (value == Token.TOMBSTONE) {
+         return TOMBSTONE_VW;
+       }
+       else {
+         boolean isSerializedObject = true;
+         byte[] bytes;
+         if (value instanceof CachedDeserializable) {
+           CachedDeserializable proxy = (CachedDeserializable)value;
 -          if (proxy instanceof Chunk) {
 -            return new ChunkValueWrapper((Chunk) proxy);
++          if (proxy instanceof ObjectChunk) {
++            return new ChunkValueWrapper((ObjectChunk) proxy);
+           }
+           if (proxy instanceof StoredObject) {
+             StoredObject ohproxy = (StoredObject) proxy;
+             isSerializedObject = ohproxy.isSerialized();
+             if (isSerializedObject) {
+               bytes = ohproxy.getSerializedValue();
+             } else {
+               bytes = (byte[]) ohproxy.getDeserializedForReading();
+             }
+           } else {
+             bytes = proxy.getSerializedValue();
+           }
+           if (event != null && isSerializedObject) {
+             event.setCachedSerializedNewValue(bytes);
+           }
+         }
+         else if (value instanceof byte[]) {
+           isSerializedObject = false;
+           bytes = (byte[])value;
+         }
+         else {
+           Assert.assertTrue(!Token.isRemovedFromDisk(value));
+           if (event != null && event.getCachedSerializedNewValue() != null) {
+             bytes = event.getCachedSerializedNewValue();
+           } else {
+             bytes = EntryEventImpl.serialize(value);
+             if (bytes.length == 0) {
+               throw new IllegalStateException("serializing <" + value + "> produced empty byte array");
+             }
+             if (event != null) {
+               event.setCachedSerializedNewValue(bytes);
+             }
+           }
+         }
+         return new ByteArrayValueWrapper(isSerializedObject, bytes);
+       }
+     }
+     public static ValueWrapper createValueWrapperFromEntry(DiskEntry entry, LocalRegion region, EntryEventImpl event) {
+       if (event != null) {
+         // For off-heap it should be faster to pass a reference to the
+         // StoredObject instead of using the cached byte[] (unless it is also compressed).
+         // Since NIO is used if the chunk of memory is large we can write it
+         // to the file with using the off-heap memory with no extra copying.
+         // So we give preference to getRawNewValue over getCachedSerializedNewValue
+         Object rawValue = null;
+         if (!event.hasDelta()) {
+           // We don't do this for the delta case because getRawNewValue returns delta
+           // and we want to write the entire new value to disk.
+           rawValue = event.getRawNewValue();
 -          if (rawValue instanceof Chunk) {
 -            return new ChunkValueWrapper((Chunk) rawValue);
++          if (rawValue instanceof ObjectChunk) {
++            return new ChunkValueWrapper((ObjectChunk) rawValue);
+           }
+         }
+         if (event.getCachedSerializedNewValue() != null) {
+           return new ByteArrayValueWrapper(true, event.getCachedSerializedNewValue());
+         }
+         if (rawValue != null) {
+           return createValueWrapper(rawValue, event);
+         }
+       }
+       // TODO OFFHEAP: No need to retain since we hold the sync on entry but we need a flavor of _getValue that will decompress
+       @Retained Object value = entry._getValueRetain(region, true);
+       try {
+         return createValueWrapper(value, event);
+       } finally {
+         OffHeapHelper.release(value);
+       }
+     }
+     
+     private static void writeToDisk(DiskEntry entry, LocalRegion region, boolean async) throws RegionClearedException {
+       writeToDisk(entry, region, async, null);
+     }
+ 
+     /**
+      * Writes the key/value object stored in the given entry to disk
+      * @throws RegionClearedException
+      * 
+      * @see DiskRegion#put
+      */
+     private static void writeToDisk(DiskEntry entry, LocalRegion region, boolean async, EntryEventImpl event) throws RegionClearedException {
+       writeBytesToDisk(entry, region, async, createValueWrapperFromEntry(entry, region, event));
+     }
+     
+     private static void writeBytesToDisk(DiskEntry entry, LocalRegion region, boolean async, ValueWrapper vw) throws RegionClearedException {
+       // @todo does the following unmark need to be called when an async
+       // write is scheduled or is it ok for doAsyncFlush to do it?
+       entry.getDiskId().unmarkForWriting();
+       region.getDiskRegion().put(entry, region, vw, async);
+     }
+ 
+     public static void update(DiskEntry entry, LocalRegion region, Object newValue) throws RegionClearedException {
+       update(entry, region, newValue, null);
+     }
+     /**
+      * Updates the value of the disk entry with a new value. This allows us to
+      * free up disk space in the non-backup case.
+      * 
+      * @throws RegionClearedException
+      */
+     public static void update(DiskEntry entry, LocalRegion region, Object newValue, EntryEventImpl event) throws RegionClearedException {
+       DiskRegion dr = region.getDiskRegion();
+       if (newValue == null) {
+         throw new NullPointerException(LocalizedStrings.DiskEntry_ENTRYS_VALUE_SHOULD_NOT_BE_NULL.toLocalizedString());
+       }
+       
+       //If we have concurrency checks enabled for a persistent region, we need
+       //to add an entry to the async queue for every update to maintain the RVV
+       boolean maintainRVV = region.concurrencyChecksEnabled && dr.isBackup();
+       
+       Token oldValue = null;
+       int oldValueLength = 0;
+       boolean scheduleAsync = false;
+       boolean callRemoveFromDisk = false;
+       DiskId did = entry.getDiskId();
+       VersionTag tag = null;
+       Object syncObj = did;
+       if (syncObj == null) {
+         syncObj = entry;
+       }
+       if (syncObj == did) {
+         dr.acquireReadLock();
+       }
+       try {
+       synchronized (syncObj) {
+         oldValue = entry.getValueAsToken();
+         if (Token.isRemovedFromDisk(newValue)) {
+           if (dr.isBackup()) {
+             dr.testIsRecoveredAndClear(did); // fixes bug 41409
+           }
+           RuntimeException rte = null;
+           try {
+             if (!Token.isRemovedFromDisk(oldValue)) {
+               // removeFromDisk takes care of oldValueLength
+               if (dr.isSync()) {
+                 removeFromDisk(entry, region, false);
+               } else {
+                 callRemoveFromDisk = true; // do it outside the sync
+               }
+             }
+           } catch (RuntimeException e) {
+             rte = e;
+             throw e;
+           }
+           finally {
+             if (rte != null && (rte instanceof CacheClosedException)) {
+              // 47616: not to set the value to be removedFromDisk since it failed to persist
+             } else {
+               // Asif Ensure that the value is rightly set despite clear so
+               // that it can be distributed correctly
+               entry.setValueWithContext(region, newValue); // OFFHEAP newValue was already preparedForCache
+             }
+           }
+         }
+         else if (newValue instanceof RecoveredEntry) {
+           // Now that oplog creates are immediately put in cache
+           // a later oplog modify will get us here
+           RecoveredEntry re = (RecoveredEntry)newValue;
+           long oldKeyId = did.getKeyId();
+           long oldOplogId = did.getOplogId();
+           long newOplogId = re.getOplogId();
+           if (newOplogId != oldOplogId) {
+             did.setOplogId(newOplogId);
+             re.setOplogId(oldOplogId); // so caller knows oldoplog id
+           }
+           did.setOffsetInOplog(re.getOffsetInOplog());
+           // id already set
+           did.setUserBits(re.getUserBits());
+           oldValueLength = did.getValueLength();
+           did.setValueLength(re.getValueLength());
+           // The following undo and then do fixes bug 41849
+           // First, undo the stats done for the previous recovered value
+           if (oldKeyId < 0) {
+             dr.incNumOverflowOnDisk(-1L);
+             dr.incNumOverflowBytesOnDisk(-oldValueLength);
+             incrementBucketStats(region, 0/*InVM*/, -1/*OnDisk*/, -oldValueLength);
+           } else {
+             dr.incNumEntriesInVM(-1L);
+             incrementBucketStats(region, -1/*InVM*/, 0/*OnDisk*/, 0);
+           }
+           // Second, do the stats done for the current recovered value
+           if (re.getRecoveredKeyId() < 0) {
+             if (!entry.isValueNull()) {
+               try {
+                 entry.handleValueOverflow(region);
+                 entry.setValueWithContext(region, null); // fixes bug 41119
+               }finally {
+                 entry.afterValueOverflow(region);
+               }
+               
+             }
+             dr.incNumOverflowOnDisk(1L);
+             dr.incNumOverflowBytesOnDisk(did.getValueLength());
+             incrementBucketStats(region, 0/*InVM*/, 1/*OnDisk*/,
+                                  did.getValueLength());
+           } else {
+             entry.setValueWithContext(region, entry.prepareValueForCache(region, re.getValue(), false));
+             dr.incNumEntriesInVM(1L);
+             incrementBucketStats(region, 1/*InVM*/, 0/*OnDisk*/, 0);
+           }
+         }
+         else {
+           //The new value in the entry needs to be set after the disk writing 
+           // has succeeded. If not , for GemFireXD , it is possible that other thread
+           // may pick this transient value from region entry ( which for 
+           //offheap will eventually be released ) as index key, 
+           //given that this operation is bound to fail in case of
+           //disk access exception.
+           
+           //entry.setValueWithContext(region, newValue); // OFFHEAP newValue already prepared
+           
+           if(did != null && did.isPendingAsync()) {
+             //if the entry was not yet written to disk, we didn't update
+             //the bytes on disk.
+             oldValueLength = 0;
+           } else {
+             oldValueLength = getValueLength(did);
+           }
+           
+           if (dr.isBackup()) {
+             dr.testIsRecoveredAndClear(did); // fixes bug 41409
+             if (dr.isSync()) {
+               //In case of compression the value is being set first 
+               // because atleast for now , GemFireXD does not support compression
+               // if and when it does support, this needs to be taken care of else
+               // we risk Bug 48965
+               if (AbstractRegionEntry.isCompressible(dr, newValue)) {
+                 entry.setValueWithContext(region, newValue); // OFFHEAP newValue already prepared
+                 
+                 // newValue is prepared and compressed. We can't write compressed values to disk.
+                 writeToDisk(entry, region, false, event);
+               } else {
+                 writeBytesToDisk(entry, region, false, createValueWrapper(newValue, event));
+                 entry.setValueWithContext(region, newValue); // OFFHEAP newValue already prepared
+               }
+               
+             } else if (did.isPendingAsync() && !maintainRVV) {
+               entry.setValueWithContext(region, newValue); // OFFHEAP newValue already prepared
+               
+               // nothing needs to be done except
+               // fixing up LRU stats
+               // @todo fixup LRU stats if needed
+               // I'm not sure anything needs to be done here.
+               // If we have overflow and it decided to evict this entry
+               // how do we handle that case when we are async?
+               // Seems like the eviction code needs to leave the value
+               // in memory until the pendingAsync is done.
+             } else {
+               //if the entry is not async, we need to schedule it
+               //for regions with concurrency checks enabled, we add an entry
+               //to the queue for every entry.
+               scheduleAsync = true;
+               did.setPendingAsync(true);
+               VersionStamp stamp = entry.getVersionStamp();
+               if(stamp != null) {
+                 tag = stamp.asVersionTag();
+               }
+               entry.setValueWithContext(region, newValue); 
+             }
+           } else if (did != null) {
+             entry.setValueWithContext(region, newValue); // OFFHEAP newValue already prepared
+             
+             // Mark the id as needing to be written
+             // The disk remove that this section used to do caused bug 30961
+             // @todo this seems wrong. How does leaving it on disk fix the bug?
+             did.markForWriting();
+             //did.setValueSerializedSize(0);
+           }else {
+             entry.setValueWithContext(region, newValue);
+           }
+           
+           if (Token.isRemovedFromDisk(oldValue)) {
+             // Note we now initialize entries removed and then set their
+             // value once we find no existing entry.
+             // So this is the normal path for a brand new entry.
+             dr.incNumEntriesInVM(1L);
+             incrementBucketStats(region, 1/*InVM*/, 0/*OnDisk*/, 0);
+           }
+         }
+         if (entry instanceof LRUEntry) {
+           LRUEntry le = (LRUEntry)entry;
+           boolean wasEvicted = le.testEvicted();
+           le.unsetEvicted();
+           if (!Token.isRemovedFromDisk(newValue)) {
+             if (oldValue == null
+                 // added null check for bug 41759
+                 || wasEvicted && did != null && did.isPendingAsync()) {
+               // Note we do not append this entry because that will be
+               // done by lruEntryUpdate
+               dr.incNumEntriesInVM(1L);
+               dr.incNumOverflowOnDisk(-1L);
+               dr.incNumOverflowBytesOnDisk(-oldValueLength);
+               incrementBucketStats(region, 1/*InVM*/, -1/*OnDisk*/, -oldValueLength);
+             }
+           }
+         }
+       }
+       } finally {
+         if (syncObj == did) {
+           dr.releaseReadLock();
+         }
+       }
+       if (callRemoveFromDisk) {
+         removeFromDisk(entry, region, false, oldValue == null, false);
+       } else if (scheduleAsync && did.isPendingAsync()) {
+         // this needs to be done outside the above sync
+         scheduleAsyncWrite(new AsyncDiskEntry(region, entry, tag));
+       }
+     }
+ 
+     private static int getValueLength(DiskId did) {
+       int result = 0;
+       if (did != null) {
+         synchronized (did) {
+           result = did.getValueLength();
+         }
+       }
+       return result;
+     }
+ 
+     public static void updateRecoveredEntry(PlaceHolderDiskRegion drv,
+                                               DiskEntry entry,
+                                               RecoveredEntry newValue,RegionEntryContext context)
+     {
+       if (newValue == null) {
+         throw new NullPointerException(LocalizedStrings.DiskEntry_ENTRYS_VALUE_SHOULD_NOT_BE_NULL.toLocalizedString());
+       }
+       DiskId did = entry.getDiskId();
+       synchronized (did) {
+         boolean oldValueWasNull = entry.isValueNull();
+         int oldValueLength = did.getValueLength();
+         // Now that oplog creates are immediately put in cache
+         // a later oplog modify will get us here
+         long oldOplogId = did.getOplogId();
+         long newOplogId = newValue.getOplogId();
+         if (newOplogId != oldOplogId) {
+           did.setOplogId(newOplogId);
+           newValue.setOplogId(oldOplogId); // so caller knows oldoplog id
+         }
+         did.setOffsetInOplog(newValue.getOffsetInOplog());
+         // id already set
+         did.setUserBits(newValue.getUserBits());
+         did.setValueLength(newValue.getValueLength());
+         if (newValue.getRecoveredKeyId() >= 0) {
+           entry.setValueWithContext(context, entry.prepareValueForCache(drv, newValue.getValue(), 
+               false));
+         } else {
+           if (!oldValueWasNull) {
+             try {
+               entry.handleValueOverflow(context);
+               entry.setValueWithContext(context,null); // fixes bug 41119
+             }finally {
+               entry.afterValueOverflow(context);
+             }
+           }
+         }
+         if (entry instanceof LRUEntry) {
+           LRUEntry le = (LRUEntry)entry;
+           assert !le.testEvicted();
+           // we don't allow eviction during recovery
+           if (oldValueWasNull) {
+             // Note we do not append this entry because that will be
+             // done by lruEntryUpdate
+             drv.incNumEntriesInVM(1L);
+             drv.incNumOverflowOnDisk(-1L);
+             drv.incNumOverflowBytesOnDisk(-oldValueLength);
+             //No need to call incrementBucketStats here because we don't have
+             //a real bucket region, this is during recovery from disk.
+           }
+         }
+       }
+     }
+ 
+     public static Object getValueInVMOrDiskWithoutFaultIn(DiskEntry entry, LocalRegion region) {
+       Object result = OffHeapHelper.copyAndReleaseIfNeeded(getValueOffHeapOrDiskWithoutFaultIn(entry, region));
+       if (result instanceof CachedDeserializable) {
+         result = ((CachedDeserializable)result).getDeserializedValue(null, null);
+       }
+       if (result instanceof StoredObject) {
+         ((StoredObject) result).release();
+         throw new IllegalStateException("sqlf tried to use getValueInVMOrDiskWithoutFaultIn");
+       }
+       return result;
+     }
+     
+     @Retained
+     public static Object getValueOffHeapOrDiskWithoutFaultIn(DiskEntry entry, LocalRegion region) {
+       @Retained Object v = entry._getValueRetain(region, true); // TODO:KIRK:OK Object v = entry.getValueWithContext(region);
+       if (v == null || Token.isRemovedFromDisk(v)
+           && !region.isIndexCreationThread()) {
+         synchronized (entry) {
+           v = entry._getValueRetain(region, true); // TODO:KIRK:OK v = entry.getValueWithContext(region);
+           if (v == null) {
+             v = Helper.getOffHeapValueOnDiskOrBuffer(entry, region.getDiskRegion(),region);
+           }
+         }
+       }
+       if (Token.isRemovedFromDisk(v)) {
+         // fix for bug 31800
+         v = null;
+ //      } else if (v instanceof ByteSource) {
+ //        // If the ByteSource contains a Delta or ListOfDelta then we want to deserialize it
+ //        Object deserVal = ((CachedDeserializable)v).getDeserializedForReading();
+ //        if (deserVal != v) {
+ //          OffHeapHelper.release(v);
+ //          v = deserVal;
+ //        }
+       }
+       return v;
+     }
+ 
+     /**
+      * 
+      * @param entry
+      * @param region
+      * @return Value
+      * @throws DiskAccessException
+      */
+     public static Object faultInValue(DiskEntry entry, LocalRegion region) {
+       return faultInValue(entry, region, false);
+     }
+     @Retained
+     public static Object faultInValueRetain(DiskEntry entry, LocalRegion region) {
+       return faultInValue(entry, region, true);
+     }
+     /**
+      * @param retainResult if true then the result may be a retained off-heap reference
+      */
+     @Retained
+     private static Object faultInValue(DiskEntry entry, LocalRegion region, boolean retainResult)
+     {
+       DiskRegion dr = region.getDiskRegion();
+       @Retained Object v = entry._getValueRetain(region, true); // TODO:KIRK:OK Object v = entry.getValueWithContext(region);
+       boolean lruFaultedIn = false;
+       boolean done = false;
+       try {
+       //Asif: If the entry is instance of LRU then DidkRegion cannot be null.
+       //Since SqlFabric is accessing this method direcly & it passes the owning region,
+       //if the region happens to be persistent PR type, the owning region passed is PR,
+       // but it will have DiskRegion as null. SqlFabric takes care of passing owning region
+       // as BucketRegion in case of Overflow type entry. This is fix for Bug # 41804
+       if ( entry instanceof LRUEntry && !dr.isSync() ) {
+         synchronized (entry) {
+           DiskId did = entry.getDiskId();
+           if (did != null && did.isPendingAsync()) {
+             done = true;
+             // See if it is pending async because of a faultOut.
+             // If so then if we are not a backup then we can unschedule the pending async.
+             // In either case we need to do the lruFaultIn logic.
+             boolean evicted = ((LRUEntry)entry).testEvicted();
+             if (evicted) {
+               if (!dr.isBackup()) {
+                 // @todo do we also need a bit that tells us if it is in the async queue?
+                 // Seems like we could end up adding it to the queue multiple times.
+                 did.setPendingAsync(false);
+               }
+               // since it was evicted fix the stats here
+               dr.incNumEntriesInVM(1L);
+               dr.incNumOverflowOnDisk(-1L);
+               // no need to dec overflowBytesOnDisk because it was not inced in this case.
+               incrementBucketStats(region, 1/*InVM*/, -1/*OnDisk*/, 0);
+             }
+             lruEntryFaultIn((LRUEntry) entry, region);
+             lruFaultedIn = true;
+           }
+         }
+       }
+       if (!done
+           && (v == null || Token.isRemovedFromDisk(v) && !region.isIndexCreationThread())) {
+         synchronized (entry) {
+           v = entry._getValueRetain(region, true); // TODO:KIRK:OK v = entry.getValueWithContext(region);
+           if (v == null) {
+             v = readValueFromDisk(entry, region);
+             if (entry instanceof LRUEntry) {
+               if (v != null && !Token.isInvalid(v)) {
+                 lruEntryFaultIn((LRUEntry) entry, region);
+                        
+                 lruFaultedIn = true;
+               }
+             }
+           }
+         }
+       }
+       } finally {
+         if (!retainResult) {
+           v = OffHeapHelper.copyAndReleaseIfNeeded(v);
+           // At this point v should be either a heap object
+         }
+       }
+       if (Token.isRemoved(v)) {
+         // fix for bug 31800
+         v = null;
+       } else {
+         ((RegionEntry)entry).setRecentlyUsed();
+       }
+       if (lruFaultedIn) {
+        lruUpdateCallback(region);
+       }
+       return v; // OFFHEAP: the value ends up being returned by RegionEntry.getValue
+     }
+     
+     public static void recoverValue(DiskEntry entry, long oplogId, DiskRecoveryStore recoveryStore, ByteArrayDataInput in) {
+       boolean lruFaultedIn = false;
+       synchronized (entry) {
+         if (entry.isValueNull()) {
+           DiskId did = entry.getDiskId();
+           if (did != null) {
+             Object value = null;
+             DiskRecoveryStore region = recoveryStore;
+             DiskRegionView dr = region.getDiskRegionView();
+             dr.acquireReadLock();
+             try {
+               synchronized (did) {
+                 // don't read if the oplog has changed.
+                 if (oplogId == did.getOplogId()) {
+                   value = getValueFromDisk(dr, did, in);
+                   if (value != null) {
+                     setValueOnFaultIn(value, did, entry, dr, region);
+                   }
+                 }
+               }
+             } finally {
+               dr.releaseReadLock();
+             }
+             if (entry instanceof LRUEntry) {
+               if (value != null && !Token.isInvalid(value)) {
+                 lruEntryFaultIn((LRUEntry) entry, recoveryStore);
+                 lruFaultedIn = true;
+               }
+             }
+           }
+         }
+       }
+       if (lruFaultedIn) {
+         lruUpdateCallback(recoveryStore);
+       }
+     }
+     
+     /**
+      *  Caller must have "did" synced.
+      */
+     private static Object getValueFromDisk(DiskRegionView dr, DiskId did, ByteArrayDataInput in) {
+       Object value;
+       if (dr.isBackup() && did.getKeyId() == DiskRegion.INVALID_ID) {
+         // must have been destroyed
+         value = null;
+       } else {
+         if (did.isKeyIdNegative()) {
+           did.setKeyId(- did.getKeyId());
+         }
+         // if a bucket region then create a CachedDeserializable here instead of object
+         value = dr.getRaw(did); // fix bug 40192
+         if (value instanceof BytesAndBits) {
+           BytesAndBits bb = (BytesAndBits)value;
+           if (EntryBits.isInvalid(bb.getBits())) {
+             value = Token.INVALID;
+           } else if (EntryBits.isLocalInvalid(bb.getBits())) {
+             value = Token.LOCAL_INVALID;
+           } else if (EntryBits.isTombstone(bb.getBits())) {
+             value = Token.TOMBSTONE;
+           } else if (EntryBits.isSerialized(bb.getBits())) {
+             value = readSerializedValue(bb.getBytes(), bb.getVersion(), in, false);
+           } else {
+             value = readRawValue(bb.getBytes(), bb.getVersion(), in);
+           }
+         }
+       }
+       return value;
+     }
+     
+     private static void lruUpdateCallback(DiskRecoveryStore recoveryStore) {
+       /* 
+        * Used conditional check to see if
+        * if its a LIFO Enabled,
+        * yes then disable lruUpdateCallback()
+        * and called updateStats()
+        * its keep track of actual entries
+        * present in memory - useful when 
+        * checking capacity constraint
+        */ 
+       try {
+         if (recoveryStore.getEvictionAttributes() != null
+             && recoveryStore.getEvictionAttributes().getAlgorithm().isLIFO()) {
+           ((VMLRURegionMap) recoveryStore.getRegionMap()).updateStats();
+           return;
+         }
+         // this must be done after releasing synchronization
+         recoveryStore.getRegionMap().lruUpdateCallback();
+       }catch( DiskAccessException dae) {
+         recoveryStore.handleDiskAccessException(dae);
+         throw dae;
+       }
+     }
+     
+     private static void lruEntryFaultIn(LRUEntry entry, DiskRecoveryStore recoveryStore) {
+       RegionMap rm = (RegionMap)recoveryStore.getRegionMap();
+       try {
+         rm.lruEntryFaultIn((LRUEntry) entry);
+       }catch(DiskAccessException dae) {
+         recoveryStore.handleDiskAccessException(dae);
+         throw dae;
+       }
+     }
+     
+     /**
+      * Returns the value of this map entry, reading it from disk, if necessary.
+      * Sets the value in the entry.
+      * This is only called by the faultIn code once it has determined that
+      * the value is no longer in memory.
+      * return the result will only be off-heap if the value is a sqlf ByteSource. Otherwise result will be on-heap.
+      * Caller must have "entry" synced.
+      */
+     @Retained
+     private static Object readValueFromDisk(DiskEntry entry, DiskRecoveryStore region) {
+ 
+       DiskRegionView dr = region.getDiskRegionView();
+       DiskId did = entry.getDiskId();
+       if (did == null) {
+         return null;
+       }
+       dr.acquireReadLock();
+       try {
+       synchronized (did) {
+         Object value = getValueFromDisk(dr, did, null);
+         if (value == null) return null;
+         @Unretained Object preparedValue = setValueOnFaultIn(value, did, entry, dr, region);
+         // For Sqlfire we want to return the offheap representation.
+         // So we need to retain it for the caller to release.
+         /*if (preparedValue instanceof ByteSource) {
+           // This is the only case in which we return a retained off-heap ref.
+           ((ByteSource)preparedValue).retain();
+           return preparedValue;
+         } else */{
+           return value;
+         }
+       }
+       } finally {
+         dr.releaseReadLock();
+       }
+     }
+     
+     /**
+      * Caller must have "entry" and "did" synced and "dr" readLocked.
+      * @return the unretained result must be used by the caller before it releases the sync on "entry".
+      */
+     @Unretained
+     private static Object setValueOnFaultIn(Object value, DiskId did, DiskEntry entry, DiskRegionView dr, DiskRecoveryStore region) {
+ //    dr.getOwner().getCache().getLogger().info("DEBUG: faulting in entry with key " + entry.getKey());
+       int bytesOnDisk = getValueLength(did);
+       // Retained by the prepareValueForCache call for the region entry.
+       // NOTE that we return this value unretained because the retain is owned by the region entry not the caller.
+       @Retained Object preparedValue = entry.prepareValueForCache((RegionEntryContext) region, value,
+           false);
+       region.updateSizeOnFaultIn(entry.getKey(), region.calculateValueSize(preparedValue), bytesOnDisk);
+       //did.setValueSerializedSize(0);
+       // I think the following assertion is true but need to run
+       // a regression with it. Reenable this post 6.5
+       //Assert.assertTrue(entry._getValue() == null);
+       entry.setValueWithContext((RegionEntryContext) region, preparedValue);
+       dr.incNumEntriesInVM(1L);
+       dr.incNumOverflowOnDisk(-1L);
+       dr.incNumOverflowBytesOnDisk(-bytesOnDisk);
+       incrementBucketStats(region, 1/*InVM*/, -1/*OnDisk*/, -bytesOnDisk);
+       return preparedValue;
+     }
+ 
+     static Object readSerializedValue(byte[] valueBytes, Version version,
+         ByteArrayDataInput in, boolean forceDeserialize) {
+       if (forceDeserialize) {
+         // deserialize checking for product version change
+         return EntryEventImpl.deserialize(valueBytes, version, in);
+       }
+       else {
+         // TODO: upgrades: is there a case where GemFire values are internal
+         // ones that need to be upgraded transparently; probably messages
+         // being persisted (gateway events?)
+         return CachedDeserializableFactory.create(valueBytes);
+       }
+     }
+ 
+     static Object readRawValue(byte[] valueBytes, Version version,
+         ByteArrayDataInput in) {
+       /*
+       final StaticSystemCallbacks sysCb;
+       if (version != null && (sysCb = GemFireCacheImpl.FactoryStatics
+           .systemCallbacks) != null) {
+         // may need to change serialized shape for SQLFire
+         return sysCb.fromVersion(valueBytes, false, version, in);
+       }
+       else */ {
+         return valueBytes;
+       }
+     }
+ 
+     public static void incrementBucketStats(Object owner,
+                                              int entriesInVmDelta,
+                                              int overflowOnDiskDelta,
+                                              int overflowBytesOnDiskDelta) {
+       if (owner instanceof BucketRegion) {
+         ((BucketRegion)owner).incNumEntriesInVM(entriesInVmDelta);
+         ((BucketRegion)owner).incNumOverflowOnDisk(overflowOnDiskDelta);
+         ((BucketRegion)owner).incNumOverflowBytesOnDisk(overflowBytesOnDiskDelta);
+       } else if (owner instanceof DiskRegionView) {
+         ((DiskRegionView)owner).incNumOverflowBytesOnDisk(overflowBytesOnDiskDelta);
+       }
+     }
+ 
+     /**
+      * Writes the value of this <code>DiskEntry</code> to disk and
+      * <code>null</code> s out the reference to the value to free up VM space.
+      * <p>
+      * Note that if the value had already been written to disk, it is not
+      * written again.
+      * <p>
+      * Caller must synchronize on entry and it is assumed the entry is evicted
+      * 
+      * see #writeToDisk
+      * @throws RegionClearedException
+      */
+     public static int overflowToDisk(DiskEntry entry, LocalRegion region, EnableLRU ccHelper) throws RegionClearedException {
+       {
+         Token entryVal = entry.getValueAsToken();
+         if (entryVal == null || Token.isRemovedFromDisk(entryVal)) {
+           // Note it could be removed token now because
+           // freeAllEntriesOnDisk is not able to sync on entry
+           return 0;
+         }
+       }
+       DiskRegion dr = region.getDiskRegion();
+       final int oldSize = region.calculateRegionEntryValueSize(entry);;
+       //Asif:Get diskID . If it is null, it implies it is
+       // overflow only mode.
+       //long id = entry.getDiskId().getKeyId();
+       DiskId did = entry.getDiskId();
+       if (did == null) {
+         ((LRUEntry)entry).setDelayedDiskId(region);
+         did = entry.getDiskId();
+       }
+       
+       // Notify the SQLFire IndexManager if present
+      /* final IndexUpdater indexUpdater = region.getIndexUpdater();
+       if(indexUpdater != null && dr.isSync()) {
+         indexUpdater.onOverflowToDisk(entry);
+       }*/
+       
+       int change = 0;
+       boolean scheduledAsyncHere = false;
+       dr.acquireReadLock();
+       try {
+       synchronized (did) {
+         // check for a concurrent freeAllEntriesOnDisk
+         if (entry.isRemovedFromDisk()) {
+           return 0;
+         }
+ 
+         //TODO:Asif: Check if we need to overflow even when id is = 0
+         boolean wasAlreadyPendingAsync = did.isPendingAsync();
+         if (did.needsToBeWritten()) {
+           if (dr.isSync()) {
+             writeToDisk(entry, region, false);
+           } else if (!wasAlreadyPendingAsync) {
+             scheduledAsyncHere = true;
+             did.setPendingAsync(true);
+           } else {
+             // it may have been scheduled to be written (isBackup==true)
+             // and now we are faulting it out
+           }
+         }
+ 
+         boolean movedValueToDisk = false; // added for bug 41849
+         
+         // If async then if it does not need to be written (because it already was)
+         // then treat it like the sync case. This fixes bug 41310
+         if (scheduledAsyncHere || wasAlreadyPendingAsync) {
+           // we call _setValue(null) after it is actually written to disk
+           change = entry.updateAsyncEntrySize(ccHelper);
+           // do the stats when it is actually written to disk
+         } else {
+           region.updateSizeOnEvict(entry.getKey(), oldSize);
+           //did.setValueSerializedSize(byteSizeOnDisk);
+           try {
+             entry.handleValueOverflow(region);
+             entry.setValueWithContext(region,null);
+           }finally {
+             entry.afterValueOverflow(region);
+           }
+           movedValueToDisk = true;
+           change = ((LRUClockNode)entry).updateEntrySize(ccHelper);
+         }
+         int valueLength = 0;
+         if (movedValueToDisk) {
+           valueLength = getValueLength(did);
+         }
+         dr.incNumEntriesInVM(-1L);
+         dr.incNumOverflowOnDisk(1L);
+         dr.incNumOverflowBytesOnDisk(valueLength);
+         incrementBucketStats(region, -1/*InVM*/, 1/*OnDisk*/, valueLength);
+       }
+       } finally {
+         dr.releaseReadLock();
+       }
+       if (scheduledAsyncHere && did.isPendingAsync()) {
+         // this needs to be done outside the above sync
+         // the version tag is null here because this method only needs
+         // to write to disk for overflow only regions, which do not need
+         // to maintain an RVV on disk.
+         scheduleAsyncWrite(new AsyncDiskEntry(region, entry, null));
+       }
+       return change;
+     }
+ 
+     private static void scheduleAsyncWrite(AsyncDiskEntry ade) {
+       DiskRegion dr = ade.region.getDiskRegion();
+       dr.scheduleAsyncWrite(ade);
+     }
+ 
+     
+     public static void handleFullAsyncQueue(DiskEntry entry, LocalRegion region, VersionTag tag) {
+       DiskRegion dr = region.getDiskRegion();
+       DiskId did = entry.getDiskId();
+       synchronized (entry) {
+       dr.acquireReadLock();
+       try {
+         synchronized (did) {
+           if (did.isPendingAsync()) {
+             did.setPendingAsync(false);
+             final Token entryVal = entry.getValueAsToken();
+             final int entryValSize = region.calculateRegionEntryValueSize(entry);
+             boolean remove = false;
+             try {
+               if (Token.isRemovedFromDisk(entryVal)) {
+                 // onDisk was already deced so just do the valueLength here
+                 dr.incNumOverflowBytesOnDisk(-did.getValueLength());
+                 incrementBucketStats(region, 0/*InVM*/, 0/*OnDisk*/,
+                                      -did.getValueLength());
+                 dr.remove(region, entry, true, false);
+                 if (dr.isBackup()) {
+                   did.setKeyId(DiskRegion.INVALID_ID); // fix for bug 41340
+                 }
+                 remove = true;
+               } else if (Token.isInvalid(entryVal) && !dr.isBackup()) {
+                 // no need to write invalid to disk if overflow only
+               } else if (entryVal != null) {
+                 writeToDisk(entry, region, true);
+               } else {
+                 //if we have a version tag we need to record the operation
+                 //to update the RVV
+                 if(tag != null) {
+                   DiskEntry.Helper.doAsyncFlush(tag, region);
+                 }
+                 return;
+               }
+               assert !dr.isSync();
+               // Only setValue to null if this was an evict.
+               // We could just be a backup that is writing async.
+               if (!remove
+                   && !Token.isInvalid(entryVal)
+                   && entry instanceof LRUEntry
+                   && ((LRUEntry)entry).testEvicted()) {
+                 // Moved this here to fix bug 40116.
+                 region.updateSizeOnEvict(entry.getKey(), entryValSize);
+                 // note the old size was already accounted for
+                 // onDisk was already inced so just do the valueLength here
+                 dr.incNumOverflowBytesOnDisk(did.getValueLength());
+                 incrementBucketStats(region, 0/*InVM*/, 0/*OnDisk*/,
+                                      did.getValueLength());
+                 try {
+                   entry.handleValueOverflow(region);
+                   entry.setValueWithContext(region,null);
+                 }finally {
+                   entry.afterValueOverflow(region);
+                 }
+               }
+               
+               //See if we the entry we wrote to disk has the same tag
+               //as this entry. If not, write the tag as a conflicting operation.
+               //to update the RVV.
+               VersionStamp stamp = entry.getVersionStamp();
+               if(tag != null && stamp != null 
+                   && (stamp.getMemberID() != tag.getMemberID()
+                     || stamp.getRegionVersion() != tag.getRegionVersion())) {
+                 DiskEntry.Helper.doAsyncFlush(tag, region);
+               }
+             } catch (RegionClearedException ignore) {
+               // no need to do the op since it was clobbered by a region clear
+             }
+           } else {
+             //if we have a version tag we need to record the operation
+             //to update the RVV, even if we don't write the entry
+             if(tag != null) {
+               DiskEntry.Helper.doAsyncFlush(tag, region);
+             }
+           }
+         }
+       } finally {
+         dr.releaseReadLock();
+       }
+       } // sync entry
+     }
+     
+     public static void doAsyncFlush(VersionTag tag, LocalRegion region) {
+       if (region.isThisRegionBeingClosedOrDestroyed()) return;
+       DiskRegion dr = region.getDiskRegion();
+       if (!dr.isBackup()) {
+         return;
+       }
+       assert !dr.isSync();
+       dr.acquireReadLock();
+       try {
+         dr.getDiskStore().putVersionTagOnly(region, tag, true);
+       } finally {
+         dr.releaseReadLock();
+       }
+     }
+     
+     /**
+      * Flush an entry that was previously scheduled to be written to disk.
+      * @param tag 
+      * @since prPersistSprint1
+      */
+     public static void doAsyncFlush(DiskEntry entry, LocalRegion region, VersionTag tag) {
+       if (region.isThisRegionBeingClosedOrDestroyed()) return;
+       DiskRegion dr = region.getDiskRegion();
+       dr.setClearCountReference();
+       synchronized (entry) { // fixes 40116
+         // If I don't sync the entry and this method ends up doing an eviction
+         // thus setting value to null
+         // some other thread is free to fetch the value while the entry is synced
+         // and think it has removed it or replaced it. This results in updateSizeOn*
+         // being called twice for the same value (once when it is evicted and once
+         // when it is removed/updated).
+       try {
+       dr.acquireReadLock();
+       try {
+         DiskId did = entry.getDiskId();
+         synchronized (did) {
+           if (did.isPendingAsync()) {
+             did.setPendingAsync(false);
+             final Token entryVal = entry.getValueAsToken();
+             final int entryValSize = region.calculateRegionEntryValueSize(entry);
+             boolean remove = false;
+             try {
+               if (Token.isRemovedFromDisk(entryVal)) {
+                 if (region.isThisRegionBeingClosedOrDestroyed()) return;
+                 // onDisk was already deced so just do the valueLength here
+                 dr.incNumOverflowBytesOnDisk(-did.getValueLength());
+                 incrementBucketStats(region, 0/*InVM*/, 0/*OnDisk*/,
+                                      -did.getValueLength());
+                 dr.remove(region, entry, true, false);
+                 if (dr.isBackup()) {
+                   did.setKeyId(DiskRegion.INVALID_ID); // fix for bug 41340
+                 }
+                 remove = true;
+               } else if ((Token.isInvalid(entryVal) || entryVal == Token.TOMBSTONE) && !dr.isBackup()) {
+                 // no need to write invalid or tombstones to disk if overflow only
+               } else if (entryVal != null) {
+                 writeToDisk(entry, region, true);
+               } else {
+                 // @todo why would we have a null value here?
+                 // I'm seeing it show up in tests:
+ // java.lang.IllegalArgumentException: Must not serialize  null  in this context.
+ // 	at com.gemstone.gemfire.internal.cache.EntryEventImpl.serialize(EntryEventImpl.java:1024)
+ // 	at com.gemstone.gemfire.internal.cache.DiskEntry$Helper.writeToDisk(DiskEntry.java:351)
+ // 	at com.gemstone.gemfire.internal.cache.DiskEntry$Helper.doAsyncFlush(DiskEntry.java:683)
+ // 	at com.gemstone.gemfire.internal.cache.DiskRegion$FlusherThread.run(DiskRegion.java:1055)
+                 //if we have a version tag we need to record the operation
+                 //to update the RVV
+                 if(tag != null) {
+                   DiskEntry.Helper.doAsyncFlush(tag, region);
+                 }
+                 return;
+               }
+               assert !dr.isSync();
+               // Only setValue to null if this was an evict.
+               // We could just be a backup that is writing async.
+               if (!remove
+                   && !Token.isInvalid(entryVal)
+                   && (entryVal != Token.TOMBSTONE)
+                   && entry instanceof LRUEntry
+                   && ((LRUEntry)entry).testEvicted()) {
+                 // Moved this here to fix bug 40116.
+                 region.updateSizeOnEvict(entry.getKey(), entryValSize);
+                 // note the old size was already accounted for
+                 // onDisk was already inced so just do the valueLength here
+                 dr.incNumOverflowBytesOnDisk(did.getValueLength());
+                 incrementBucketStats(region, 0/*InVM*/, 0/*OnDisk*/,
+                                      did.getValueLength());
+                 try {
+                  entry.handleValueOverflow(region);
+                  entry.setValueWithContext(region,null);
+                 }finally {
+                   entry.afterValueOverflow(region);
+                 }
+               }
+             } catch (RegionClearedException ignore) {
+               // no need to do the op since it was clobbered by a region clear
+             }
+             
+             //See if we the entry we wrote to disk has the same tag
+             //as this entry. If not, write the tag as a conflicting operation.
+             //to update the RVV.
+             VersionStamp stamp = entry.getVersionStamp();
+             if(tag != null && stamp != null 
+                 && (stamp.getMemberID() != tag.getMemberID() 
+                 || stamp.getRegionVersion() != tag.getRegionVersion())) {
+               DiskEntry.Helper.doAsyncFlush(tag, region);
+             }
+           } else {
+             //if we have a version tag we need to record the operation
+             //to update the RVV
+             if(tag != null) {
+               DiskEntry.Helper.doAsyncFlush(tag, region);
+             }
+           }
+         }
+       } finally {
+         dr.releaseReadLock();
+       }
+       } finally {
+         dr.removeClearCountReference();
+       }
+       } // sync entry
+     }
+     
+     /**
+      * Removes the key/value pair in the given entry from disk
+      *
+      * @throws RegionClearedException If the operation is aborted due to a clear 
+      * @see DiskRegion#remove
+      */
+     public static void removeFromDisk(DiskEntry entry, LocalRegion region, boolean isClear) throws RegionClearedException {
+       removeFromDisk(entry, region, true, false, isClear);
+     }
+     private static void removeFromDisk(DiskEntry entry, LocalRegion region,
+                                       boolean checkValue, boolean valueWasNull, boolean isClear) throws RegionClearedException {
+       DiskRegion dr = region.getDiskRegion();
+       
+       //If we have concurrency checks enabled for a persistent region, we need
+       //to add an entry to the async queue for every update to maintain the RVV
+       boolean maintainRVV = region.concurrencyChecksEnabled && dr.isBackup();
+       
+       DiskId did = entry.getDiskId();
+       VersionTag tag = null;
+       Object syncObj = did;
+       if (did == null) {
+         syncObj = entry;
+       }
+       boolean scheduledAsyncHere = false;
+       if (syncObj == did) {
+         dr.acquireReadLock();
+       }
+       try {
+       synchronized (syncObj) { 
+ 
+         if (did == null || (dr.isBackup() && did.getKeyId()== DiskRegion.INVALID_ID)) {
+           // Not on disk yet
+           dr.incNumEntriesInVM(-1L);
+           incrementBucketStats(region, -1/*InVM*/, 0/*OnDisk*/, 0);
+           dr.unscheduleAsyncWrite(did);
+           return;
+         } 
+         //Asif: This will convert the -ve OplogKeyId to positive as part of fixing
+         //Bug # 39989
+         did.unmarkForWriting();
+ 
+         //System.out.println("DEBUG: removeFromDisk doing remove(" + id + ")");
+         int oldValueLength = 0;
+         if (dr.isSync() || isClear) {
+           oldValueLength = did.getValueLength();
+           dr.remove(region, entry, false, isClear);
+           if (dr.isBackup()) {
+             did.setKeyId(DiskRegion.INVALID_ID); // fix for bug 41340
+           }
+           //If this is a clear, we should unschedule the async write for this
+           //entry
+           did.setPendingAsync(false);
+         } else {
+           if (!did.isPendingAsync() || maintainRVV) {
+             scheduledAsyncHere = true;
+             did.setPendingAsync(true);
+             VersionStamp stamp = entry.getVersionStamp();
+             if(stamp != null) {
+               tag = stamp.asVersionTag();
+             }
+           }
+         }
+         if (checkValue) {
+           valueWasNull = entry.isValueNull();
+           entry._removePhase1();
+         }
+         if (valueWasNull) {
+           dr.incNumOverflowOnDisk(-1L);
+           dr.incNumOverflowBytesOnDisk(-oldValueLength);
+           incrementBucketStats(region, 0/*InVM*/, -1/*OnDisk*/, -oldValueLength);
+         }
+         else {
+           dr.incNumEntriesInVM(-1L);
+           incrementBucketStats(region, -1/*InVM*/, 0/*OnDisk*/, 0);
+           if (!dr.isSync()) {
+             // we are going to do an async remove of an entry that is not currently
+             // overflowed to disk so we don't want to count its value length as being
+             // on disk when we finally do the async op. So we clear it here.
+             did.setValueLength(0);
+           }
+         }
+       }
+       } finally {
+         if (syncObj == did) {
+           dr.releaseReadLock();
+         }
+       }
+       if (scheduledAsyncHere && did.isPendingAsync()) {
+         // do this outside the sync
+         scheduleAsyncWrite(new AsyncDiskEntry(region, entry, tag));
+       }
+     }
+ 
+     /**
+      * @param entry
+      * @param region
+      * @param tag
+      */
+     public static void updateVersionOnly(DiskEntry entry, LocalRegion region,
+         VersionTag tag) {
+       DiskRegion dr = region.getDiskRegion();
+       if (!dr.isBackup()) {
+         return;
+       }
+       
+       assert tag != null && tag.getMemberID()!=null;
+       boolean scheduleAsync = false;
+       DiskId did = entry.getDiskId();
+       Object syncObj = did;
+       if (syncObj == null) {
+         syncObj = entry;
+       }
+       if (syncObj == did) {
+         dr.acquireReadLock();
+       }
+       try {
+         synchronized (syncObj) {
+           if (dr.isSync()) {
+             dr.getDiskStore().putVersionTagOnly(region, tag, false);
+           } else {
+             scheduleAsync = true;
+           }
+         }
+       } finally {
+         if (syncObj == did) {
+           dr.releaseReadLock();
+         }
+       }
+       if (scheduleAsync) {
+         // this needs to be done outside the above sync
+         scheduleAsyncWrite(new AsyncDiskEntry(region, tag));
+       }
+     }
+ 
+   }
+ 
+   /**
+    * A marker object for an entry that has been recovered from disk.
+    * It is handled specially when it is placed in a region.
+    */
+   public static class RecoveredEntry {
+ 
+     /** The disk id of the entry being recovered */
+     private final long recoveredKeyId;
+ 
+     /** The value of the recovered entry */
+     private final Object value;
+ 
+     private final long offsetInOplog;
+     private final byte userBits;
+     private final int valueLength;
+ 
+     private long oplogId;
+     private VersionTag tag;
+ 
+     /**
+      * Only for this constructor, the value is not loaded into the region & it is lying
+      * on the oplogs. Since Oplogs rely on DiskId to furnish user bits so as to correctly 
+      * interpret bytes, the userbit needs to be set correctly here.
+      */
+     public RecoveredEntry(long keyId, long oplogId, long offsetInOplog,
+                           byte userBits, int valueLength) {
+       this(-keyId, oplogId, offsetInOplog, userBits, valueLength, null);
+     }
+ 
+     public RecoveredEntry(long keyId, long oplogId, long offsetInOplog,
+                           byte userBits, int valueLength, Object value) {
+       this.recoveredKeyId = keyId;
+       this.value = value;
+       this.oplogId = oplogId;
+       this.offsetInOplog = offsetInOplog;
+       this.userBits = EntryBits.setRecoveredFromDisk(userBits, true);
+       this.valueLength = valueLength;
+     }
+ 
+     /**
+      * Returns the disk id of the entry being recovered
+      */
+     public long getRecoveredKeyId() {
+       return this.recoveredKeyId;
+     }
+     /**
+      * Returns the value of the recovered entry. Note that if the
+      * disk id is < 0 then the value has not been faulted in and
+      * this method will return null.
+      */
+     public Object getValue() {
+       return this.value;
+     }
+     /**
+      * 
+      * @return byte indicating the user bits. The correct value is returned only in the specific case of
+      * entry  recovered from oplog ( & not rolled to Htree) & the RECOVER_VALUES flag is false . In other cases
+      * the exact value is not needed
+      */
+     public byte getUserBits() {
+       return this.userBits;
+     }
+     public int getValueLength() {
+       return this.valueLength;
+     }
+     public long getOffsetInOplog() {
+       return offsetInOplog;
+     }
+     public long getOplogId() {
+       return this.oplogId;
+     }
+ 
+     public void setOplogId(long v) {
+       this.oplogId = v;
+     }
+     public VersionTag getVersionTag() {
+       return this.tag;
+     }
+     public void setVersionTag(VersionTag tag) {
+       this.tag = tag;
+     }
+   }
+ }


[095/100] [abbrv] incubator-geode git commit: GEODE-870: Handling multiple concurrent locator restarts. Elder locator nomination

Posted by ud...@apache.org.
GEODE-870: Handling multiple concurrent locator restarts. Elder locator nomination


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/f7dd4fdf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/f7dd4fdf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/f7dd4fdf

Branch: refs/heads/feature/GEODE-870
Commit: f7dd4fdf4893d0535f259526f214715e79f62ebc
Parents: 80cbc3f
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Wed Feb 10 09:20:09 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 07:26:42 2016 +1100

----------------------------------------------------------------------
 .../gms/messages/ViewRejectMessage.java         |  96 ------
 .../gms/membership/GMSJoinLeaveHelper.java      |  60 ++++
 .../internal/membership/NetView.java            |   5 +
 .../membership/gms/membership/GMSJoinLeave.java | 319 ++++++++++---------
 .../gms/messages/InstallViewMessage.java        |  18 +-
 .../gemstone/gemfire/internal/DSFIDFactory.java |  11 +-
 .../internal/DataSerializableFixedID.java       |   2 -
 .../gemfire/distributed/LocatorDUnitTest.java   | 209 ++++++------
 gradle/rat.gradle                               |   2 +-
 9 files changed, 352 insertions(+), 370 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java
deleted file mode 100755
index e5bf9e2..0000000
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/ViewRejectMessage.java
+++ /dev/null
@@ -1,96 +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 com.gemstone.gemfire.distributed.internal.membership.gms.messages;
-
-import com.gemstone.gemfire.DataSerializer;
-import com.gemstone.gemfire.distributed.internal.DistributionManager;
-import com.gemstone.gemfire.distributed.internal.HighPriorityDistributionMessage;
-import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
-import com.gemstone.gemfire.distributed.internal.membership.NetView;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-public class ViewRejectMessage extends HighPriorityDistributionMessage {
-
-  private int viewId;
-  private NetView rejectedView;
-  private String reason;
-
-  public ViewRejectMessage(InternalDistributedMember recipient, int viewId, NetView rejectedView, String reason) {
-    super();
-    setRecipient(recipient);
-    this.viewId = viewId;
-    this.rejectedView = rejectedView;
-    this.reason = reason;
-  }
-
-  public ViewRejectMessage() {
-    // no-arg constructor for serialization
-  }
-  
-  public int getViewId() {
-    return viewId;
-  }
-  
-  public NetView getRejectedView() {
-    return this.rejectedView;
-  }
-  
-
-  @Override
-  public int getDSFID() {
-    // TODO Auto-generated method stub
-    return VIEW_REJECT_MESSAGE;
-  }
-
-  public String getReason() {
-    return reason;
-  }
-
-  @Override
-  public int getProcessorType() {
-    return 0;
-  }
-
-  @Override
-  public void process(DistributionManager dm) {
-    throw new IllegalStateException("this message is not intended to execute in a thread pool");
-  }
-
-  @Override
-  public void toData(DataOutput out) throws IOException {
-    super.toData(out);
-    out.writeInt(this.viewId);
-    DataSerializer.writeObject(this.rejectedView, out);
-  }
-
-  @Override
-  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
-    super.fromData(in);
-    this.viewId = in.readInt();
-    this.rejectedView = DataSerializer.readObject(in);
-  }
-  
-  @Override
-  public String toString() {
-    String s = getSender() == null? getRecipientsDescription() : ""+getSender();
-    return "ViewRejectMessage("+s+"; "+this.viewId+";  rejectedView="+this.rejectedView +")";
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java
new file mode 100644
index 0000000..b8311bc
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeaveHelper.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.distributed.internal.membership.gms.membership;
+
+import com.gemstone.gemfire.distributed.Locator;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
+import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
+
+public class GMSJoinLeaveHelper {
+  public static boolean isViewCreator() {
+    GMSJoinLeave gmsJoinLeave = getGmsJoinLeave();
+    if (gmsJoinLeave != null) {
+      GMSJoinLeave.ViewCreator viewCreator = gmsJoinLeave.getViewCreator();
+      if (viewCreator != null && !viewCreator.isShutdown()) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    throw new RuntimeException("This should not have happened. There should be a JoinLeave for every DS");
+  }
+
+  private static GMSJoinLeave getGmsJoinLeave() {
+    InternalDistributedSystem distributedSystem = getInternalDistributedSystem();
+    DM dm = distributedSystem.getDM();
+    GMSMembershipManager membershipManager = (GMSMembershipManager) dm.getMembershipManager();
+    Services services = membershipManager.getServices();
+    return (GMSJoinLeave) services.getJoinLeave();
+  }
+
+  public static Integer getViewId() {
+    return getGmsJoinLeave().getView().getViewId();
+  }
+
+  private static InternalDistributedSystem getInternalDistributedSystem() {
+    InternalDistributedSystem distributedSystem = InternalDistributedSystem.getAnyInstance();
+    if (distributedSystem == null) {
+      Locator locator = Locator.getLocator();
+      return (InternalDistributedSystem) locator.getDistributedSystem();
+    } else {
+      return distributedSystem;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
index 40f5f71..af05f82 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
@@ -29,6 +29,7 @@ import java.util.List;
 import java.util.Random;
 import java.util.Set;
 
+import com.gemstone.gemfire.internal.logging.LogService;
 import org.apache.logging.log4j.Logger;
 
 import com.gemstone.gemfire.DataSerializer;
@@ -47,6 +48,9 @@ import com.gemstone.gemfire.internal.Version;
  */
 public class NetView implements DataSerializableFixedID {
 
+  private static final Logger logger = LogService.getLogger();
+
+
   private int viewId;
   private List<InternalDistributedMember> members;
   private int[] failureDetectionPorts = new int[10];
@@ -86,6 +90,7 @@ public class NetView implements DataSerializableFixedID {
     crashedMembers = Collections.emptySet();
     this.creator = creator;
     Arrays.fill(failureDetectionPorts, -1);
+
   }
 
   // legacy method for JGMM

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index c7eacfa..b246344 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -259,14 +259,14 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       // unable to contact any of the locators
       if (!this.isJoined && state.hasContactedAJoinedLocator) {
         throw new SystemConnectException("Unable to join the distributed system in "
-           + (System.currentTimeMillis()-startTime) + "ms");
+            + (System.currentTimeMillis() - startTime) + "ms");
       }
 
       return this.isJoined;
     } finally {
       // notify anyone waiting on the address to be completed
       if (this.isJoined) {
-        synchronized(this.localAddress) {
+        synchronized (this.localAddress) {
           this.localAddress.notifyAll();
         }
       }
@@ -277,10 +277,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   /**
    * send a join request and wait for a reply.  Process the reply.
    * This may throw a SystemConnectException or an AuthenticationFailedException
-   * 
+   *
    * @return true if the attempt succeeded, false if it timed out
    */
-  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="WA_NOT_IN_LOOP")
+  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "WA_NOT_IN_LOOP")
   boolean attemptToJoin() {
     SearchState state = searchState;
 
@@ -302,7 +302,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       Thread.currentThread().interrupt();
       return false;
     }
-    
+
     if (response == null) {
       if (!isJoined) {
         logger.debug("received no join response");
@@ -314,13 +314,13 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     joinResponse[0] = null;
     String failReason = response.getRejectionMessage();
     if (failReason != null) {
-      if (failReason.contains("Rejecting the attempt of a member using an older version") 
+      if (failReason.contains("Rejecting the attempt of a member using an older version")
           || failReason.contains("15806")) {
         throw new SystemConnectException(failReason);
       }
       throw new AuthenticationFailedException(failReason);
     }
-    
+
     if (response.getCurrentView() == null) {
       logger.info("received join response with no membership view: {}", response);
       return isJoined;
@@ -328,19 +328,18 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
     if (response.getBecomeCoordinator()) {
       logger.info("I am being told to become the membership coordinator by {}", coord);
-      synchronized(viewInstallationLock) {
+      synchronized (viewInstallationLock) {
         this.currentView = response.getCurrentView();
         becomeCoordinator(null);
       }
       return true;
     }
-    
+
     this.birthViewId = response.getMemberID().getVmViewId();
     this.localAddress.setVmViewId(this.birthViewId);
     GMSMember me = (GMSMember) this.localAddress.getNetMember();
     me.setBirthViewId(birthViewId);
     installView(response.getCurrentView());
-
     return true;
   }
 
@@ -384,7 +383,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
    * this method will enqueue the request for processing in another thread.
    * If this is not the coordinator but the coordinator is known, the message
    * is forwarded to the coordinator.
-   * 
+   *
    * @param incomingRequest
    */
   private void processJoinRequest(JoinRequestMessage incomingRequest) {
@@ -413,12 +412,13 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       return;
     }
 
-    if (!this.localAddress.getNetMember().preferredForCoordinator() && 
-        incomingRequest.getMemberID().getNetMember().preferredForCoordinator()) {
-      JoinResponseMessage m = new JoinResponseMessage(incomingRequest.getMemberID(), currentView, true);
-      services.getMessenger().send(m);
-      return;
-    }
+//      Remove JoinResponseMessage to fix GEODE-870
+//        if (!this.localAddress.getNetMember().preferredForCoordinator() &&
+//            incomingRequest.getMemberID().getNetMember().preferredForCoordinator()){
+//          JoinResponseMessage joinResponseMessage = new JoinResponseMessage(incomingRequest.getMemberID(), currentView, true);
+//          services.getMessenger().send(joinResponseMessage);
+//          return;
+//        }
     recordViewRequest(incomingRequest);
   }
 
@@ -426,7 +426,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
    * Process a Leave request from another member. This may cause this member
    * to become the new membership coordinator. If this is the coordinator
    * a new view will be triggered.
-   * 
+   *
    * @param incomingRequest
    */
   private void processLeaveRequest(LeaveRequestMessage incomingRequest) {
@@ -442,7 +442,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     InternalDistributedMember mbr = incomingRequest.getMemberID();
 
     if (logger.isDebugEnabled()) {
-      logger.debug("JoinLeave.processLeaveRequest invoked.  isCoordinator="+isCoordinator+ "; isStopping="+isStopping 
+      logger.debug("JoinLeave.processLeaveRequest invoked.  isCoordinator="+isCoordinator+ "; isStopping="+isStopping
           +"; cancelInProgress="+ services.getCancelCriterion().isCancelInProgress());
     }
 
@@ -487,7 +487,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
    * Process a Remove request from another member. This may cause this member
    * to become the new membership coordinator. If this is the coordinator
    * a new view will be triggered.
-   * 
+   *
    * @param incomingRequest
    */
   private void processRemoveRequest(RemoveMemberMessage incomingRequest) {
@@ -501,7 +501,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       logger.info("Membership ignoring removal request for " + mbr + " from non-member " + incomingRequest.getSender());
       return;
     }
-    
+
     if (v == null) {
       // not yet a member
       return;
@@ -532,11 +532,11 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         check.addCrashedMembers(removedMembers);
         check.removeAll(removedMembers);
       }
-      synchronized(leftMembers) {
+      synchronized (leftMembers) {
         check.removeAll(leftMembers);
       }
       if (check.getCoordinator().equals(localAddress)) {
-        synchronized(viewInstallationLock) {
+        synchronized (viewInstallationLock) {
           becomeCoordinator(mbr);
         }
       }
@@ -580,17 +580,18 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   void becomeCoordinator() { // package access for unit testing
     becomeCoordinator(null);
   }
- 
+
   public void becomeCoordinatorForTest() {
-    synchronized(viewInstallationLock) {
+    synchronized (viewInstallationLock) {
       becomeCoordinator();
     }
   }
-  
+
   /**
    * Test hook for delaying the creation of new views.
    * This should be invoked before this member becomes coordinator
    * and creates its ViewCreator thread.
+   *
    * @param millis
    */
   public void delayViewCreationForTest(int millis) {
@@ -602,17 +603,17 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
    * be invoked under a synch on viewInstallationLock that was held
    * at the time the decision was made to become coordinator so that
    * the decision is atomic with actually becoming coordinator.
+   *
    * @param oldCoordinator may be null
    */
   private void becomeCoordinator(InternalDistributedMember oldCoordinator) {
-    boolean testing = unitTesting.contains("noRandomViewChange");
 
     assert Thread.holdsLock(viewInstallationLock);
-    
+
     if (isCoordinator) {
       return;
     }
-    
+
     logger.info("This member is becoming the membership coordinator with address {}", localAddress);
     isCoordinator = true;
     if (currentView == null) {
@@ -622,55 +623,59 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       this.localAddress.setVmViewId(0);
       installView(newView);
       isJoined = true;
-      if (viewCreator == null || viewCreator.isShutdown()) {
-        createViewCreator();
-        viewCreator.setDaemon(true);
-        viewCreator.start();
-        startViewBroadcaster();
-      }
+      createAndStartViewCreator(newView);
+      startViewBroadcaster();
     } else {
       // create and send out a new view
-      NetView newView;
-      Set<InternalDistributedMember> leaving = new HashSet<>();
-      Set<InternalDistributedMember> removals;
-      synchronized(viewInstallationLock) {
-        int rand = testing? 0 : NetView.RANDOM.nextInt(10);
-        int viewNumber = currentView.getViewId() + 5 + rand;
-        if (this.localAddress.getVmViewId() < 0) {
-          this.localAddress.setVmViewId(viewNumber);
-        }
-        List<InternalDistributedMember> mbrs = new ArrayList<>(currentView.getMembers());
-        if (!mbrs.contains(localAddress)) {
-          mbrs.add(localAddress);
-        }
-        synchronized(this.removedMembers) {
-          removals = new HashSet<>(this.removedMembers);
-        }
-        synchronized(this.leftMembers) {
-          leaving.addAll(leftMembers);
-        }
-        if (oldCoordinator != null && !removals.contains(oldCoordinator)) {
-          leaving.add(oldCoordinator);
-        }
-        mbrs.removeAll(removals);
-        mbrs.removeAll(leaving);
-        newView = new NetView(this.localAddress, viewNumber, mbrs, leaving,
-            removals);
-        newView.setFailureDetectionPorts(currentView);
-        newView.setFailureDetectionPort(this.localAddress, services.getHealthMonitor().getFailureDetectionPort());
-      }
-      if (viewCreator == null || viewCreator.isShutdown()) {
-        createViewCreator();
-        viewCreator.setInitialView(newView, newView.getNewMembers(), leaving, removals);
-        viewCreator.setDaemon(true);
-        viewCreator.start();
-        startViewBroadcaster();
+      NetView newView = addMemberToNetView(this.currentView, oldCoordinator);
+      createAndStartViewCreator(newView);
+      startViewBroadcaster();
+    }
+  }
+
+  private void createAndStartViewCreator(NetView newView) {
+    if (viewCreator == null || viewCreator.isShutdown()) {
+      viewCreator = new ViewCreator("Geode Membership View Creator", Services.getThreadGroup());
+      if (newView != null) {
+        viewCreator.setInitialView(newView, newView.getNewMembers(), newView.getShutdownMembers(), newView.getCrashedMembers());
       }
+      viewCreator.setDaemon(true);
+      viewCreator.start();
     }
   }
 
-  protected void createViewCreator() {
-    viewCreator = new ViewCreator("Geode Membership View Creator", Services.getThreadGroup());
+  private NetView addMemberToNetView(NetView netView, InternalDistributedMember oldCoordinator) {
+    boolean testing = unitTesting.contains("noRandomViewChange");
+    NetView newView = null;
+    Set<InternalDistributedMember> leaving = new HashSet<>();
+    Set<InternalDistributedMember> removals;
+    synchronized (viewInstallationLock) {
+      int rand = testing ? 0 : NetView.RANDOM.nextInt(10);
+      int viewNumber = currentView.getViewId() + 5 + rand;
+      if (this.localAddress.getVmViewId() < 0) {
+        this.localAddress.setVmViewId(viewNumber);
+      }
+      List<InternalDistributedMember> mbrs = new ArrayList<>(currentView.getMembers());
+      if (!mbrs.contains(localAddress)) {
+        mbrs.add(localAddress);
+      }
+      synchronized (this.removedMembers) {
+        removals = new HashSet<>(this.removedMembers);
+      }
+      synchronized (this.leftMembers) {
+        leaving.addAll(leftMembers);
+      }
+      if (oldCoordinator != null && !removals.contains(oldCoordinator)) {
+        leaving.add(oldCoordinator);
+      }
+      mbrs.removeAll(removals);
+      mbrs.removeAll(leaving);
+      newView = new NetView(this.localAddress, viewNumber, mbrs, leaving,
+          removals);
+      newView.setFailureDetectionPorts(currentView);
+      newView.setFailureDetectionPort(this.localAddress, services.getHealthMonitor().getFailureDetectionPort());
+    }
+    return newView;
   }
 
   private void sendRemoveMessages(List<InternalDistributedMember> removals, List<String> reasons, NetView newView) {
@@ -689,7 +694,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     sendView(view, newMembers, false, this.viewProcessor);
   }
 
-  boolean sendView(NetView view, List<InternalDistributedMember> newMembers, boolean preparing, ViewReplyProcessor rp) {
+  private boolean sendView(NetView view, List<InternalDistributedMember> newMembers, boolean preparing, ViewReplyProcessor viewReplyProcessor) {
 
     int id = view.getViewId();
     InstallViewMessage msg = new InstallViewMessage(view, services.getAuthenticator().getCredentials(this.localAddress), preparing);
@@ -708,6 +713,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     if (preparing) {
       this.preparedView = view;
     } else {
+      if(!localAddress.equals(view.getCoordinator()) && getViewCreator() != null)
+      {
+        stopCoordinatorServices();
+      }
       installView(view);
     }
 
@@ -716,25 +725,25 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       return true;
     }
 
-    StringBuilder s = new StringBuilder();
+    StringBuilder stringBuilder = new StringBuilder();
     int[] ports = view.getFailureDetectionPorts();
     int numMembers = view.size();
-    for (int i=0; i<numMembers; i++) {
+    for (int i = 0; i < numMembers; i++) {
       if (i > 0) {
-        s.append(' ');
+        stringBuilder.append(' ');
       }
-      s.append(ports[i]);
+      stringBuilder.append(ports[i]);
     }
     logger.info((preparing ? "preparing" : "sending") + " new view " + view
-        + "\nfailure detection ports: " + s.toString());
+        + "\nfailure detection ports: " + stringBuilder.toString());
 
     msg.setRecipients(recips);
 
     Set<InternalDistributedMember> pendingLeaves = getPendingRequestIDs(LEAVE_REQUEST_MESSAGE);
     Set<InternalDistributedMember> pendingRemovals = getPendingRequestIDs(REMOVE_MEMBER_REQUEST);
     pendingRemovals.removeAll(view.getCrashedMembers());
-    rp.initialize(id, responders);
-    rp.processPendingRequests(pendingLeaves, pendingRemovals);
+    viewReplyProcessor.initialize(id, responders);
+    viewReplyProcessor.processPendingRequests(pendingLeaves, pendingRemovals);
     services.getMessenger().send(msg);
 
     // only wait for responses during preparation
@@ -745,10 +754,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
       logger.info("finished waiting for responses to view preparation");
 
-      InternalDistributedMember conflictingViewSender = rp.getConflictingViewSender();
-      NetView conflictingView = rp.getConflictingView();
+      InternalDistributedMember conflictingViewSender = viewReplyProcessor.getConflictingViewSender();
+      NetView conflictingView = viewReplyProcessor.getConflictingView();
       if (conflictingView != null) {
-        logger.warn("received a conflicting membership view from " + conflictingViewSender 
+        logger.warn("received a conflicting membership view from " + conflictingViewSender
             + " during preparation: " + conflictingView);
         return false;
       }
@@ -762,7 +771,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     return true;
   }
 
-  private void processViewMessage(InstallViewMessage m) {
+  private void processViewMessage(final InstallViewMessage installViewMessage) {
 
     NetView view = m.getView();
 
@@ -829,9 +838,10 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   }
 
   private TcpClientWrapper tcpClientWrapper = new TcpClientWrapper();
-  
+
   /***
    * testing purpose
+   *
    * @param tcpClientWrapper
    */
   void setTcpClientWrapper(TcpClientWrapper tcpClientWrapper) {
@@ -847,21 +857,21 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     SearchState state = searchState;
 
     assert this.localAddress != null;
-    
+
     // If we've already tried to bootstrap from locators that
     // haven't joined the system (e.g., a collocated locator)
     // then jump to using the membership view to try to find
     // the coordinator
-    if ( !state.hasContactedAJoinedLocator && state.view != null) {
+    if (!state.hasContactedAJoinedLocator && state.view != null) {
       return findCoordinatorFromView();
     }
 
     FindCoordinatorRequest request = new FindCoordinatorRequest(this.localAddress, state.alreadyTried, state.viewId);
     Set<InternalDistributedMember> coordinators = new HashSet<InternalDistributedMember>();
-    
-    long giveUpTime = System.currentTimeMillis() + ((long)services.getConfig().getLocatorWaitTime() * 1000L);
-    
-    int connectTimeout = (int)services.getConfig().getMemberTimeout() * 2;
+
+    long giveUpTime = System.currentTimeMillis() + ((long) services.getConfig().getLocatorWaitTime() * 1000L);
+
+    int connectTimeout = (int) services.getConfig().getMemberTimeout() * 2;
     boolean anyResponses = false;
     boolean flagsSet = false;
 
@@ -869,12 +879,12 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
     state.hasContactedAJoinedLocator = false;
     state.locatorsContacted = 0;
-    
+
     do {
       for (InetSocketAddress addr : locators) {
         try {
           Object o = tcpClientWrapper.sendCoordinatorFindRequest(addr, request, connectTimeout);
-          FindCoordinatorResponse response = (o instanceof FindCoordinatorResponse) ? (FindCoordinatorResponse)o : null;
+          FindCoordinatorResponse response = (o instanceof FindCoordinatorResponse) ? (FindCoordinatorResponse) o : null;
           if (response != null) {
             state.locatorsContacted++;
             if (!state.hasContactedAJoinedLocator &&
@@ -886,7 +896,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
             if (response.getCoordinator() != null) {
               anyResponses = true;
               NetView v = response.getView();
-              int viewId = v == null? -1 : v.getViewId();
+              int viewId = v == null ? -1 : v.getViewId();
               if (viewId > state.viewId) {
                 state.viewId = viewId;
                 state.view = v;
@@ -946,17 +956,17 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     }
     return true;
   }
-  
+
   protected class TcpClientWrapper {
-    protected Object sendCoordinatorFindRequest(InetSocketAddress addr, FindCoordinatorRequest request, int connectTimeout) 
-        throws ClassNotFoundException, IOException{
+    protected Object sendCoordinatorFindRequest(InetSocketAddress addr, FindCoordinatorRequest request, int connectTimeout)
+        throws ClassNotFoundException, IOException {
       return TcpClient.requestToServer(
-          addr.getAddress(), addr.getPort(), request, connectTimeout, 
+          addr.getAddress(), addr.getPort(), request, connectTimeout,
           true);
     }
-  }    
+  }
 
-  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="WA_NOT_IN_LOOP")
+  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "WA_NOT_IN_LOOP")
   boolean findCoordinatorFromView() {
     ArrayList<FindCoordinatorResponse> result;
     SearchState state = searchState;
@@ -1028,8 +1038,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   private void inheritSettingsFromLocator(InetSocketAddress addr, FindCoordinatorResponse response) {
     boolean enabled = response.isNetworkPartitionDetectionEnabled();
     if (!enabled && services.getConfig().isNetworkPartitionDetectionEnabled()) {
-      throw new GemFireConfigException("locator at "+addr 
-          +" does not have network-partition-detection enabled but my configuration has it enabled");
+      throw new GemFireConfigException("locator at " + addr
+          + " does not have network-partition-detection enabled but my configuration has it enabled");
     }
 
     GMSMember mbr = (GMSMember) this.localAddress.getNetMember();
@@ -1040,8 +1050,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     if (response.isUsePreferredCoordinators()) {
       this.quorumRequired = true;
       logger.debug("The locator indicates that all locators should be preferred as coordinators");
-      if (services.getLocator() != null 
-          || Locator.hasLocator() 
+      if (services.getLocator() != null
+          || Locator.hasLocator()
           || !services.getConfig().getDistributionConfig().getStartLocator().isEmpty()
           || localAddress.getVmKind() == DistributionManager.LOCATOR_DM_TYPE) {
         ((GMSMember) localAddress.getNetMember()).setPreferredForCoordinator(true);
@@ -1053,7 +1063,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
   /**
    * receives a JoinResponse holding a membership view or rejection message
-   * 
+   *
    * @param rsp
    */
   private void processJoinResponse(JoinResponseMessage rsp) {
@@ -1062,7 +1072,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       joinResponse.notifyAll();
     }
   }
-  
+
   /**
    * for testing, do not use in any other case as it is not thread safe
    */
@@ -1142,7 +1152,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           return;
         }
       }
-      
+
       if (isJoined && isNetworkPartition(newView, true)) {
         if (quorumRequired) {
           Set<InternalDistributedMember> crashes = newView.getActualCrashedMembers(currentView);
@@ -1150,7 +1160,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           return;
         }
       }
-      
+
       previousView = currentView;
       currentView = newView;
       preparedView = null;
@@ -1160,7 +1170,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       if (!isJoined) {
         logger.debug("notifying join thread");
         isJoined = true;
-        synchronized(joinResponse) {
+        synchronized (joinResponse) {
           joinResponse.notifyAll();
         }
       }
@@ -1179,7 +1189,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         // newer than the view just processed - the senders will have to
         // resend these
         synchronized (viewRequests) {
-          for (Iterator<DistributionMessage> it = viewRequests.iterator(); it.hasNext();) {
+          for (Iterator<DistributionMessage> it = viewRequests.iterator(); it.hasNext(); ) {
             DistributionMessage m = it.next();
             if (m instanceof JoinRequestMessage) {
               it.remove();
@@ -1199,7 +1209,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     synchronized (removedMembers) {
       removeMembersFromCollectionIfNotInView(removedMembers, currentView);
     }
-    synchronized(leftMembers) {
+    synchronized (leftMembers) {
       removeMembersFromCollectionIfNotInView(leftMembers, currentView);
     }
   }
@@ -1208,7 +1218,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     Iterator<InternalDistributedMember> iterator = members.iterator();
     while (iterator.hasNext()) {
       if (!currentView.contains(iterator.next())) {
-          iterator.remove();
+        iterator.remove();
       }
     }
   }
@@ -1216,7 +1226,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   /**
    * Sends a message declaring a network partition to the
    * members of the given view via Messenger
-   * 
+   *
    * @param view
    */
   void sendNetworkPartitionMessage(NetView view) {
@@ -1279,10 +1289,11 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
   private void stopCoordinatorServices() {
     if (viewCreator != null && !viewCreator.isShutdown()) {
+      logger.debug("Shutting down ViewCreator");
       viewCreator.shutdown();
     }
   }
-  
+
   private void startViewBroadcaster() {
     services.getTimer().schedule(new ViewBroadcaster(), VIEW_BROADCAST_INTERVAL, VIEW_BROADCAST_INTERVAL);
   }
@@ -1342,7 +1353,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       stopCoordinatorServices();
       if (view != null) {
         if (view.size() > 1) {
-          List<InternalDistributedMember> coords = view.getPreferredCoordinators(Collections.<InternalDistributedMember> emptySet(), localAddress, 5);
+          List<InternalDistributedMember> coords = view.getPreferredCoordinators(Collections.<InternalDistributedMember>emptySet(), localAddress, 5);
           logger.debug("JoinLeave sending a leave request to {}", coords);
           LeaveRequestMessage m = new LeaveRequestMessage(coords, this.localAddress, "this member is shutting down");
           services.getMessenger().send(m);
@@ -1365,7 +1376,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       processRemoveRequest(msg);
       if (!this.isCoordinator) {
         msg.resetRecipients();
-        msg.setRecipients(v.getPreferredCoordinators(Collections.<InternalDistributedMember> emptySet(), localAddress, 10));
+        msg.setRecipients(v.getPreferredCoordinators(Collections.<InternalDistributedMember>emptySet(), localAddress, 10));
         services.getMessenger().send(msg);
       }
     }
@@ -1373,8 +1384,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
   @Override
   public void memberShutdown(DistributedMember mbr, String reason) {
-    LeaveRequestMessage msg = new LeaveRequestMessage(Collections.singleton(this.localAddress), (InternalDistributedMember)mbr, reason);
-    msg.setSender((InternalDistributedMember)mbr);
+    LeaveRequestMessage msg = new LeaveRequestMessage(Collections.singleton(this.localAddress), (InternalDistributedMember) mbr, reason);
+    msg.setSender((InternalDistributedMember) mbr);
     processLeaveRequest(msg);
   }
 
@@ -1494,11 +1505,11 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
   protected ViewReplyProcessor getPrepareViewReplyProcessor() {
     return prepareProcessor;
   }
-  
-  protected boolean testPrepareProcessorWaiting(){
+
+  protected boolean testPrepareProcessorWaiting() {
     return prepareProcessor.isWaiting();
   }
-  
+
   class ViewReplyProcessor {
     volatile int viewId = -1;
     final Set<InternalDistributedMember> notRepliedYet = new HashSet<>();
@@ -1521,7 +1532,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       pendingRemovals.clear();
     }
 
-    boolean isWaiting(){
+    boolean isWaiting() {
       return waiting;
     }
 
@@ -1620,7 +1631,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           }
         }
       } finally {
-        synchronized(this) {
+        synchronized (this) {
           if (!this.waiting) {
             // if we've set waiting to false due to incoming messages then
             // we've discounted receiving any other responses from the
@@ -1663,7 +1674,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         sendCurrentView();
       }
     }
-    
+
     void sendCurrentView() {
       NetView v = currentView;
       if (v != null) {
@@ -1726,9 +1737,9 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
      * All views should be sent by the ViewCreator thread, so
      * if this member becomes coordinator it may have an initial
      * view to transmit that announces the removal of the former coordinator to
-     * 
+     *
      * @param newView
-     * @param leaving - members leaving in this view
+     * @param leaving  - members leaving in this view
      * @param removals - members crashed in this view
      */
     synchronized void setInitialView(NetView newView, List<InternalDistributedMember> newMembers,
@@ -1752,7 +1763,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         List<InternalDistributedMember> iJoins;
         Set<InternalDistributedMember> iLeaves;
         Set<InternalDistributedMember> iRemoves;
-        synchronized(this) {
+        synchronized (this) {
           iView = initialView;
           iJoins = initialJoins;
           iLeaves = initialLeaving;
@@ -1770,7 +1781,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
      * During initial view processing a prepared view was discovered.
      * This method will extract its new members and create a new
      * initial view containing them.
-     * 
+     *
      * @param v The prepared view
      */
     private void processPreparedView(NetView v) {
@@ -1778,7 +1789,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       if (currentView == null || currentView.getViewId() < v.getViewId()) {
         // we have a prepared view that is newer than the current view
         // form a new View ID
-        int viewId = Math.max(initialView.getViewId(),v.getViewId());
+        int viewId = Math.max(initialView.getViewId(), v.getViewId());
         viewId += 1;
         NetView newView = new NetView(initialView, viewId);
 
@@ -1790,13 +1801,13 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         } else {
           newMembers = v.getMembers();
         }
-        for (InternalDistributedMember newMember: newMembers) {
+        for (InternalDistributedMember newMember : newMembers) {
           newView.add(newMember);
           newView.setFailureDetectionPort(newMember, v.getFailureDetectionPort(newMember));
         }
 
         // use the new view as the initial view
-        synchronized(this) {
+        synchronized (this) {
           setInitialView(newView, newMembers, initialLeaving, initialRemovals);
         }
       }
@@ -1899,7 +1910,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         InternalDistributedMember mbr = null;
         switch (msg.getDSFID()) {
         case JOIN_REQUEST:
-          JoinRequestMessage jmsg = (JoinRequestMessage)msg; 
+          JoinRequestMessage jmsg = (JoinRequestMessage) msg;
           mbr = jmsg.getMemberID();
           int port = jmsg.getFailureDetectionPort();
           // see if an old member ID is being reused. If
@@ -1940,8 +1951,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
               removalReqs.add(mbr);
               removalReasons.add(((RemoveMemberMessage) msg).getReason());
             } else {
-              sendRemoveMessages(Collections.<InternalDistributedMember> singletonList(mbr),
-                  Collections.<String> singletonList(((RemoveMemberMessage) msg).getReason()), currentView);
+              sendRemoveMessages(Collections.<InternalDistributedMember>singletonList(mbr),
+                  Collections.<String>singletonList(((RemoveMemberMessage) msg).getReason()), currentView);
             }
           }
           break;
@@ -1977,7 +1988,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         // be reused in an auto-reconnect and get a new vmViewID
         mbrs.addAll(joinReqs);
         newView = new NetView(localAddress, viewNumber, mbrs, leaveReqs, new HashSet<InternalDistributedMember>(removalReqs));
-        for (InternalDistributedMember mbr: joinReqs) {
+        for (InternalDistributedMember mbr : joinReqs) {
           if (mbrs.contains(mbr)) {
             newView.setFailureDetectionPort(mbr, joinPorts.get(mbr));
           }
@@ -1998,14 +2009,14 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         mbr.setVmViewId(newView.getViewId());
         mbr.getNetMember().setSplitBrainEnabled(services.getConfig().isNetworkPartitionDetectionEnabled());
       }
-      
+
       if (isShutdown()) {
         return;
       }
       // send removal messages before installing the view so we stop
       // getting messages from members that have been kicked out
       sendRemoveMessages(removalReqs, removalReasons, newView);
-      
+
       prepareAndSendView(newView, joinReqs, leaveReqs, newView.getCrashedMembers());
 
       return;
@@ -2078,7 +2089,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           List<InternalDistributedMember> newMembers = conflictingView.getNewMembers();
           if (!newMembers.isEmpty()) {
             logger.info("adding these new members from a conflicting view to the new view: {}", newMembers);
-            for (InternalDistributedMember mbr: newMembers) {
+            for (InternalDistributedMember mbr : newMembers) {
               int port = conflictingView.getFailureDetectionPort(mbr);
               newView.add(mbr);
               newView.setFailureDetectionPort(mbr, port);
@@ -2087,7 +2098,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           }
           // trump the view ID of the conflicting view so mine will be accepted
           if (conflictingView.getViewId() >= newView.getViewId()) {
-            newView = new NetView(newView, conflictingView.getViewId()+1);
+            newView = new NetView(newView, conflictingView.getViewId() + 1);
           }
         }
 
@@ -2105,7 +2116,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           List<InternalDistributedMember> newMembers = new ArrayList<>(newView.getMembers());
           newMembers.removeAll(removalReqs);
           NetView tempView = new NetView(localAddress, newView.getViewId() + 1, newMembers, leaveReqs, removalReqs);
-          for (InternalDistributedMember mbr: newView.getMembers()) {
+          for (InternalDistributedMember mbr : newView.getMembers()) {
             if (tempView.contains(mbr)) {
               tempView.setFailureDetectionPort(mbr, newView.getFailureDetectionPort(mbr));
             }
@@ -2113,12 +2124,12 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           newView = tempView;
           int size = failures.size();
           List<String> reasons = new ArrayList<>(size);
-          for (int i=0; i<size; i++) {
+          for (int i = 0; i < size; i++) {
             reasons.add("Failed to acknowledge a new membership view and then failed tcp/ip connection attempt");
           }
           sendRemoveMessages(failures, reasons, newView);
         }
-        
+
         // if there is no conflicting view then we can count
         // the current state as being prepared.  All members
         // who are going to ack have already done so or passed
@@ -2126,13 +2137,13 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         if (conflictingView == null) {
           prepared = true;
         }
-        
+
       } while (!prepared);
 
       lastConflictingView = null;
 
       sendView(newView, joinReqs);
-      
+
       // after sending a final view we need to stop this thread if
       // the GMS is shutting down
       if (isStopping()) {
@@ -2143,11 +2154,11 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     /**
      * performs health checks on the collection of members, removing any that
      * are found to be healthy
-     * 
-     * @param suspects
+     *
+     * @param mbrs
      */
-    private void removeHealthyMembers(final Set<InternalDistributedMember> suspects) throws InterruptedException {
-      List<Callable<InternalDistributedMember>> checkers = new ArrayList<Callable<InternalDistributedMember>>(suspects.size());
+    private void removeHealthyMembers(final Collection<InternalDistributedMember> mbrs) throws InterruptedException {
+      List<Callable<InternalDistributedMember>> checkers = new ArrayList<Callable<InternalDistributedMember>>(mbrs.size());
 
       Set<InternalDistributedMember> newRemovals = new HashSet<>();
       Set<InternalDistributedMember> newLeaves = new HashSet<>();
@@ -2166,7 +2177,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
           @Override
           public InternalDistributedMember call() throws Exception {
             boolean available = GMSJoinLeave.this.checkIfAvailable(mbr);
-            
+
             synchronized (viewRequests) {
               if (available) {
                 suspects.remove(mbr);
@@ -2218,7 +2229,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
             if(suspects.isEmpty() || newRemovals.containsAll(suspects)) {
               break;
             }
-            
+
             viewRequests.wait(waitTime);
             waitTime = giveUpTime - System.currentTimeMillis();
           }
@@ -2249,22 +2260,22 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
         }
       }
     }
-    
+
     private <T> List<Future<T>> submitAll ( ExecutorService executor, Collection<? extends Callable<T> > tasks ) {
       List<Future<T>> result = new ArrayList<Future<T>>( tasks.size() );
 
-      for ( Callable<T> task : tasks ) {
+      for (Callable<T> task : tasks) {
         result.add(executor.submit(task));
       }
 
       return result;
     }
-    
+
     boolean getTestFlageForRemovalRequest() {
       return testFlagForRemovalRequest;
     }
   }
-  
+
   boolean checkIfAvailable(InternalDistributedMember fmbr) {
  // return the member id if it fails health checks
     logger.info("checking state of member " + fmbr);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage.java
index 91f6918..9e42f1f 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage.java
@@ -30,18 +30,19 @@ import com.gemstone.gemfire.distributed.internal.membership.NetView;
 import com.gemstone.gemfire.internal.InternalDataSerializer;
 
 public class InstallViewMessage extends HighPriorityDistributionMessage {
-
   enum messageType {
     INSTALL, PREPARE, SYNC
   }
   private NetView view;
   private Object credentials;
   private messageType kind;
+  private int previousViewId;
 
   public InstallViewMessage(NetView view, Object credentials) {
     this.view = view;
     this.kind = messageType.INSTALL;
     this.credentials = credentials;
+    this.previousViewId = view.getViewId();
   }
 
   public InstallViewMessage(NetView view, Object credentials, boolean preparing) {
@@ -49,6 +50,13 @@ public class InstallViewMessage extends HighPriorityDistributionMessage {
     this.kind = preparing? messageType.PREPARE : messageType.INSTALL;
     this.credentials = credentials;
   }
+
+  public InstallViewMessage(NetView view, Object credentials, int previousViewId, boolean preparing) {
+    this.view = view;
+    this.kind = preparing? messageType.PREPARE : messageType.INSTALL;
+    this.credentials = credentials;
+    this.previousViewId = previousViewId;
+  }
   
   public InstallViewMessage() {
     // no-arg constructor for serialization
@@ -62,6 +70,10 @@ public class InstallViewMessage extends HighPriorityDistributionMessage {
     return view;
   }
 
+  public int getPreviousViewId() {
+    return previousViewId;
+  }
+
   public Object getCredentials() {
     return credentials;
   }
@@ -83,6 +95,7 @@ public class InstallViewMessage extends HighPriorityDistributionMessage {
   @Override
   public void toData(DataOutput out) throws IOException {
     super.toData(out);
+    out.writeInt(previousViewId);
     out.writeInt(kind.ordinal());
     DataSerializer.writeObject(this.view, out);
     DataSerializer.writeObject(this.credentials, out);
@@ -91,6 +104,7 @@ public class InstallViewMessage extends HighPriorityDistributionMessage {
   @Override
   public void fromData(DataInput in) throws IOException, ClassNotFoundException {
     super.fromData(in);
+    this.previousViewId = in.readInt();
     this.kind = messageType.values()[in.readInt()];
     this.view = DataSerializer.readObject(in);
     this.credentials = DataSerializer.readObject(in);
@@ -98,7 +112,7 @@ public class InstallViewMessage extends HighPriorityDistributionMessage {
 
   @Override
   public String toString() {
-    return "InstallViewMessage(type="+this.kind+"; "+this.view
+    return "InstallViewMessage(type="+this.kind+"; Current ViewID="+view.getViewId()+"; Previous View ID="+previousViewId+"; "+this.view
             +"; cred="+(credentials==null?"null": "not null")
              +")";
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/geode-core/src/main/java/com/gemstone/gemfire/internal/DSFIDFactory.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/DSFIDFactory.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/DSFIDFactory.java
index b77dfdb..67e7c8d 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/DSFIDFactory.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/DSFIDFactory.java
@@ -19,6 +19,7 @@ package com.gemstone.gemfire.internal;
 
 
 
+import com.gemstone.gemfire.distributed.internal.membership.gms.messages.*;
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 
 import java.io.DataInput;
@@ -104,16 +105,6 @@ import com.gemstone.gemfire.distributed.internal.membership.gms.locator.FindCoor
 import com.gemstone.gemfire.distributed.internal.membership.gms.locator.FindCoordinatorResponse;
 import com.gemstone.gemfire.distributed.internal.membership.gms.locator.GetViewRequest;
 import com.gemstone.gemfire.distributed.internal.membership.gms.locator.GetViewResponse;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.InstallViewMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.JoinRequestMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.JoinResponseMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.LeaveRequestMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.HeartbeatRequestMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.HeartbeatMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.NetworkPartitionMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.RemoveMemberMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.SuspectMembersMessage;
-import com.gemstone.gemfire.distributed.internal.membership.gms.messages.ViewAckMessage;
 import com.gemstone.gemfire.distributed.internal.streaming.StreamingOperation.StreamingReplyMessage;
 import com.gemstone.gemfire.internal.admin.ClientMembershipMessage;
 import com.gemstone.gemfire.internal.admin.remote.AddHealthListenerRequest;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
index 22ac457..035ba56 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/DataSerializableFixedID.java
@@ -82,8 +82,6 @@ public interface DataSerializableFixedID extends SerializationVersions {
     case FOO:
       return new FOO(in);
   */
-  public static final short VIEW_REJECT_MESSAGE = -158;
-
   public static final short NETWORK_PARTITION_MESSAGE = -157;
   public static final short SUSPECT_MEMBERS_MESSAGE = -156;
   

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index 2c8a147..a6cfba4 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@ -39,12 +39,21 @@ import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 import com.gemstone.gemfire.distributed.internal.membership.MembershipTestHook;
 import com.gemstone.gemfire.distributed.internal.membership.NetView;
 import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper;
+import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeaveHelper;
 import com.gemstone.gemfire.internal.Assert;
 import com.gemstone.gemfire.internal.AvailablePort;
 import com.gemstone.gemfire.internal.AvailablePortHelper;
 import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 import com.gemstone.gemfire.internal.logging.LocalLogWriter;
 import com.gemstone.gemfire.internal.tcp.Connection;
+import com.gemstone.gemfire.test.dunit.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
 import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
@@ -68,7 +77,7 @@ import com.gemstone.gemfire.test.dunit.WaitCriterion;
 public class LocatorDUnitTest extends DistributedTestCase {
 
   static TestHook hook;
-  
+
   /**
    * Creates a new <code>LocatorDUnitTest</code>
    */
@@ -78,12 +87,12 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
   private static final String WAIT2_MS_NAME = "LocatorDUnitTest.WAIT2_MS";
   private static final int WAIT2_MS_DEFAULT = 5000; // 2000 -- see bug 36470
-  private static final int WAIT2_MS 
+  private static final int WAIT2_MS
       = Integer.getInteger(WAIT2_MS_NAME, WAIT2_MS_DEFAULT).intValue();
-  
+
   private int port1;
   private int port2;
-  
+
   @Override
   public void setUp() throws Exception {
     super.setUp();
@@ -91,7 +100,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     port2 = -1;
     IgnoredException.addIgnoredException("Removing shunned member");
   }
-  
+
   @Override
   protected final void preTearDown() throws Exception {
     if (Locator.hasLocator()) {
@@ -106,7 +115,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       DistributedTestUtils.deleteLocatorStateFile(port2);
     }
   }
-  
+
   ////////  Test Methods
 
   public void testRepeat() throws Exception {
@@ -132,7 +141,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     VM vm1 = host.getVM(1);
     VM vm2 = host.getVM(2);
     VM vm3 = host.getVM(3);
-    
+
     port1 = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
     DistributedTestUtils.deleteLocatorStateFile(port1);
 
@@ -149,7 +158,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     InternalDistributedMember mbr = system.getDistributedMember();
     assertEquals("expected the VM to have NORMAL vmKind",
         DistributionManager.NORMAL_DM_TYPE, system.getDistributedMember().getVmKind());
-    
+
     properties.remove("start-locator");
     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
     properties.put("locators", locators);
@@ -165,12 +174,12 @@ public class LocatorDUnitTest extends DistributedTestCase {
     Cache cache = CacheFactory.create(system);
     Region r = cache.createRegionFactory(RegionShortcut.REPLICATE).create("test region");
     assertNotNull("expected to create a region", r);
-    
+
     // create a lock service and have every vm get a lock
     DistributedLockService service = DistributedLockService.create("test service", system);
     service.becomeLockGrantor();
     service.lock("foo0", 0, 0);
-    
+
     vm1.invoke(new SerializableRunnable("get the lock service and lock something") {
       public void run() {
         final DistributedLockService service = DistributedLockService.create("test service", system);
@@ -187,7 +196,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
     // cause elder failover.  vm1 will become the lock grantor
     system.disconnect();
-    
+
     try {
       vm1.invoke(new SerializableRunnable("ensure grantor failover") {
         public void run() {
@@ -203,12 +212,12 @@ public class LocatorDUnitTest extends DistributedTestCase {
             public String description() {
               return "waiting to become lock grantor after shutting down locator/grantor";
             }
-            
+
           }, DistributionConfig.DEFAULT_MEMBER_TIMEOUT * 2, 1000, true);
           assertTrue(service.isLockGrantor());
         }
       });
-  
+
       properties.put("start-locator", locators);
       properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
       system = (InternalDistributedSystem)DistributedSystem.connect(properties);
@@ -231,7 +240,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       });
 
       assertFalse("should not have become lock grantor", service.isLockGrantor());
-      
+
       // Now demonstrate that a new member can join and use the lock service
       properties.remove("start-locator");
       vm3.invoke(startSystem);
@@ -241,7 +250,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
           service.lock("foo5", 0, 0);
         }
       });
-      
+
     } finally {
       disconnectAllFromDS();
     }
@@ -252,7 +261,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
    * split-brain configuration.  To work around this we have always told customers that they
    * need to stagger the starting of locators.  This test configures two locators to start up
    * simultaneously and shows that they find each other and form a single system.
-   * 
+   *
    * @throws Exception
    */
   public void testStartTwoLocators() throws Exception {
@@ -260,7 +269,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     Host host = Host.getHost(0);
     VM loc1 = host.getVM(1);
     VM loc2 = host.getVM(2);
-    
+
     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
     final int port1 = ports[0];
     this.port1 = port1;
@@ -268,7 +277,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     this.port2 = port2; // for cleanup in tearDown2
     DistributedTestUtils.deleteLocatorStateFile(port1);
     DistributedTestUtils.deleteLocatorStateFile(port2);
-    final String host0 = NetworkUtils.getServerHostName(host); 
+    final String host0 = NetworkUtils.getServerHostName(host);
     final String locators = host0 + "[" + port1 + "]," +
                             host0 + "[" + port2 + "]";
     final Properties properties = new Properties();
@@ -394,16 +403,6 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       Object[] connectArgs = new Object[] { properties };
 
-      SerializableRunnable disconnect =
-          new SerializableRunnable("Disconnect from " + locators) {
-            public void run() {
-              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-              if (sys != null && sys.isConnected()) {
-                sys.disconnect();
-              }
-            }
-          };
-
       assertTrue(MembershipManagerHelper.getLeadMember(sys) == null);
 
       // connect three vms and then watch the lead member selection as they
@@ -426,7 +425,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       assertLeadMember(mem1, sys, 5000);
 
       // after disconnecting the first vm, the second one should become the leader
-      vm1.invoke(disconnect);
+      vm1.invoke(getDisconnectRunnable(locators));
       MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
       assertLeadMember(mem2, sys, 5000);
 
@@ -435,15 +434,15 @@ public class LocatorDUnitTest extends DistributedTestCase {
           "getDistributedMember", connectArgs);
       assertLeadMember(mem2, sys, 5000);
 
-      vm2.invoke(disconnect);
+      vm2.invoke(getDisconnectRunnable(locators));
       MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem2);
       assertLeadMember(mem3, sys, 5000);
 
-      vm1.invoke(disconnect);
+      vm1.invoke(getDisconnectRunnable(locators));
       MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem1);
       assertLeadMember(mem3, sys, 5000);
 
-      vm3.invoke(disconnect);
+      vm3.invoke(getDisconnectRunnable(locators));
       MembershipManagerHelper.getMembershipManager(sys).waitForDeparture(mem3);
       assertLeadMember(null, sys, 5000);
 
@@ -495,13 +494,13 @@ public class LocatorDUnitTest extends DistributedTestCase {
     VM vm2 = host.getVM(2);
     VM locvm = host.getVM(3);
     Locator locator = null;
-    
+
     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
     final int port1 = ports[0];
     this.port1 = port1;
     final int port2 = ports[1];
     DistributedTestUtils.deleteLocatorStateFile(port1, port2);
-    final String host0 = NetworkUtils.getServerHostName(host); 
+    final String host0 = NetworkUtils.getServerHostName(host);
     final String locators = host0 + "[" + port1 + "]," +
                             host0 + "[" + port2 + "]";
     final Properties properties = new Properties();
@@ -513,7 +512,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
 //    properties.put("log-level", "fine");
     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
-    
+
     try {
       final String uname = getUniqueName();
       File logFile = new File("");
@@ -563,7 +562,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       assertTrue("Distributed system should not have disconnected",
           vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
-      
+
       // ensure quorumLost is properly invoked
       DistributionManager dm = (DistributionManager) ((InternalDistributedSystem) sys).getDistributionManager();
       MyMembershipListener listener = new MyMembershipListener();
@@ -628,7 +627,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     VM vm2 = host.getVM(2);
     VM locvm = host.getVM(3);
     Locator locator = null;
-    
+
     final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
     final int port1 = ports[0];
     this.port1 = port1;
@@ -647,7 +646,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     properties.put(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 
     SerializableRunnable stopLocator = getStopLocatorRunnable();
-    
+
     try {
       final String uname = getUniqueName();
       File logFile = new File("");
@@ -702,7 +701,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
-      
+
       assertTrue("Distributed system should not have disconnected",
           locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 
@@ -717,7 +716,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
-      
+
       assertTrue("Distributed system should not have disconnected",
           locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 
@@ -725,7 +724,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       assertEquals("This test sometimes fails.  If the log contains " +
       		"'failed to collect all ACKs' it is a false failure.",
       		mem2, vm2.invoke(() -> LocatorDUnitTest.getLeadMember()));
-      
+
       SerializableRunnable disconnect =
           new SerializableRunnable("Disconnect from " + locators) {
             public void run() {
@@ -738,7 +737,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       // disconnect the first vm and demonstrate that the third vm and the
       // locator notice the failure and exit
-      vm2.invoke(disconnect);
+      vm2.invoke(getDisconnectRunnable(locators));
       locvm.invoke(stopLocator);
     } finally {
       MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
@@ -775,7 +774,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     VM vm2 = host.getVM(2);
     VM locvm = host.getVM(3);
     Locator locator = null;
-    
+
     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
     final int port1 = ports[0];
     this.port1 = port1;
@@ -851,7 +850,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
-      
+
       assertTrue("Distributed system should not have disconnected",
           locvm.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 
@@ -912,7 +911,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     VM vm2 = host.getVM(2);
     VM locvm = host.getVM(3);
     Locator locator = null;
-    
+
     int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2);
     final int port1 = ports[0];
     this.port1 = port1;
@@ -984,7 +983,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       vm1.invoke(expectedException);
       DistributedMember mem2 = (DistributedMember) vm2.invoke(this.getClass(),
           "getDistributedMember", connectArgs);
-      
+
       DistributedMember loc1Mbr = (DistributedMember)locvm.invoke(() -> this.getLocatorDistributedMember());
 
       assertLeadMember(mem1, sys, 5000);
@@ -1000,7 +999,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
       assertTrue("Distributed system should not have disconnected",
           vm1.invoke(() -> LocatorDUnitTest.isSystemConnected()));
-      
+
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
 
@@ -1011,7 +1010,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       
       assertTrue("Distributed system should not have disconnected",
           vm2.invoke(() -> LocatorDUnitTest.isSystemConnected()));
-      
+
       assertEquals(sys.getDistributedMember(),
           MembershipManagerHelper.getCoordinator(sys));
       assertEquals(mem2, MembershipManagerHelper.getLeadMember(sys));
@@ -1155,7 +1154,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
       }
     };
     Wait.waitForCriterion(ev, 15 * 1000, 200, false);
-    DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system); 
+    DistributedMember newCoord = MembershipManagerHelper.getCoordinator(system);
     com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("coordinator after shutdown of locator was " +
         newCoord);
     if (coord.equals(newCoord)) {
@@ -1165,17 +1164,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
     system.disconnect();
 
-    SerializableRunnable disconnect =
-      new SerializableRunnable("Disconnect from " + locators) {
-          public void run() {
-            DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-            if (sys != null && sys.isConnected()) {
-              sys.disconnect();
-            }
-          }
-        };
-    vm1.invoke(disconnect);
-    vm2.invoke(disconnect);
+      vm1.invoke(getDisconnectRunnable(locators));
+      vm2.invoke(getDisconnectRunnable(locators));
 
     } finally {
       vm0.invoke(getStopLocatorRunnable());
@@ -1413,17 +1403,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
 
         system.disconnect();
 
-        SerializableRunnable disconnect =
-            new SerializableRunnable("Disconnect from " + locators) {
-              public void run() {
-                DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-                if (sys != null && sys.isConnected()) {
-                  sys.disconnect();
-                }
-              }
-            };
-        vm1.invoke(disconnect);
-        vm2.invoke(disconnect);
+        vm1.invoke(getDisconnectRunnable(locators));
+        vm2.invoke(getDisconnectRunnable(locators));
 
       } finally {
         vm3.invoke(getStopLocatorRunnable());
@@ -1432,7 +1413,18 @@ public class LocatorDUnitTest extends DistributedTestCase {
       vm0.invoke(getStopLocatorRunnable());
     }
   }
-  
+
+  private SerializableRunnable getDisconnectRunnable(final String locators) {
+    return new SerializableRunnable("Disconnect from " + locators) {
+      public void run() {
+        DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
+        if (sys != null && sys.isConnected()) {
+          sys.disconnect();
+        }
+      }
+    };
+  }
+
   /**
    * Tests starting multiple locators at the same time and ensuring that the locators
    * end up only have 1 master.
@@ -1463,7 +1455,6 @@ public class LocatorDUnitTest extends DistributedTestCase {
     dsProps.setProperty("log-level", "FINE");
     dsProps.setProperty("enable-network-partition-detection", "true");
     dsProps.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
-    final String uniqueName = getUniqueName();
 
     startLocatorSync(vm0, new Object[] { port1, dsProps });
     startLocatorSync(vm1, new Object[] { port2, dsProps });
@@ -1494,7 +1485,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
         WaitCriterion waitCriterion = new WaitCriterion() {
           public boolean done() {
             try {
-              return system.getDM().getViewMembers().size() >= 3;
+              return system.getDM().getViewMembers().size() == 6;
             } catch (Exception e) {
               e.printStackTrace();
               fail("unexpected exception");
@@ -1515,10 +1506,31 @@ public class LocatorDUnitTest extends DistributedTestCase {
         vm1.invoke(getStopLocatorRunnable());
         vm2.invoke(getStopLocatorRunnable());
 
+        waitCriterion = new WaitCriterion() {
+          public boolean done() {
+            try {
+              return system.getDM().getAllHostedLocators().size() == 0;
+            } catch (Exception e) {
+              e.printStackTrace();
+              fail("unexpected exception");
+            }
+            return false; // NOTREACHED
+          }
+
+          public String description() {
+            return null;
+          }
+        };
+        DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
+
         final String newLocators = host0 + "[" + port2 + "]," +
             host0 + "[" + port3 + "]";
         dsProps.setProperty("locators", newLocators);
 
+        assertTrue(vm3.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        //Given the start up order of servers, this server is the elder server
+        assertTrue(vm3.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+
         startLocatorAsync(vm1, new Object[] { port2, dsProps });
         startLocatorAsync(vm2, new Object[] { port3, dsProps });
 
@@ -1539,19 +1551,23 @@ public class LocatorDUnitTest extends DistributedTestCase {
         };
         DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
 
+        int netviewId = vm1.invoke(() -> GMSJoinLeaveHelper.getViewId());
+        assertEquals(netviewId, (int) vm2.invoke(() -> GMSJoinLeaveHelper.getViewId()));
+        assertEquals(netviewId, (int) vm3.invoke(() -> GMSJoinLeaveHelper.getViewId()));
+        assertEquals(netviewId, (int) vm4.invoke(() -> GMSJoinLeaveHelper.getViewId()));
+        assertFalse(vm4.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        //Given the start up order of servers, this server is the elder server
+        assertFalse(vm3.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        if (vm1.invoke(() -> GMSJoinLeaveHelper.isViewCreator())) {
+          assertFalse(vm2.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        } else {
+          assertTrue(vm2.invoke(() -> GMSJoinLeaveHelper.isViewCreator()));
+        }
+
       } finally {
         system.disconnect();
-        SerializableRunnable disconnect =
-            new SerializableRunnable("Disconnect from " + locators) {
-              public void run() {
-                DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-                if (sys != null && sys.isConnected()) {
-                  sys.disconnect();
-                }
-              }
-            };
-        vm3.invoke(disconnect);
-        vm4.invoke(disconnect);
+        vm3.invoke(getDisconnectRunnable(locators));
+        vm4.invoke(getDisconnectRunnable(locators));
         vm2.invoke(getStopLocatorRunnable());
         vm1.invoke(getStopLocatorRunnable());
       }
@@ -1689,17 +1705,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
       Wait.waitForCriterion(ev, WAIT2_MS, 200, true);
       system.disconnect();
 
-      SerializableRunnable disconnect =
-          new SerializableRunnable("Disconnect from " + locators) {
-            public void run() {
-              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-              if (sys != null && sys.isConnected()) {
-                sys.disconnect();
-              }
-            }
-          };
-      vm1.invoke(disconnect);
-      vm2.invoke(disconnect);
+      vm1.invoke(getDisconnectRunnable(locators));
+      vm2.invoke(getDisconnectRunnable(locators));
     } finally {
       SerializableRunnable stop = getStopLocatorRunnable();
       vm0.invoke(stop);
@@ -1858,15 +1865,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
     connect.run();
     //vm1.invoke(connect);
 
-      SerializableRunnable disconnect =
-          new SerializableRunnable("Disconnect from " + locators) {
-            public void run() {
-              DistributedSystem sys = InternalDistributedSystem.getAnyInstance();
-              if (sys != null && sys.isConnected()) {
-                sys.disconnect();
-              }
-            }
-          };
+      SerializableRunnable disconnect = getDisconnectRunnable(locators);
 
       disconnect.run();
       //vm1.invoke(disconnect);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f7dd4fdf/gradle/rat.gradle
----------------------------------------------------------------------
diff --git a/gradle/rat.gradle b/gradle/rat.gradle
index 496b20a..68e04c4 100644
--- a/gradle/rat.gradle
+++ b/gradle/rat.gradle
@@ -61,7 +61,7 @@ rat {
     '**/*.log',
     '**/*.patch',
     '**/*.diff',
-          '**/*.MF',
+    '**/*.MF',
 
     // binary files
     '**/*.cer',


[080/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
index 0000000,dd13f19..bef4bf1
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
@@@ -1,0 -1,1625 +1,1611 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
+ 
+ import java.io.EOFException;
+ import java.io.IOException;
+ import java.io.InterruptedIOException;
+ import java.io.PrintWriter;
+ import java.io.StringWriter;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.Semaphore;
+ import java.util.regex.Pattern;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.CopyException;
+ import com.gemstone.gemfire.InternalGemFireError;
+ import com.gemstone.gemfire.SerializationException;
+ import com.gemstone.gemfire.SystemFailure;
+ import com.gemstone.gemfire.cache.CacheLoaderException;
+ import com.gemstone.gemfire.cache.CacheWriterException;
+ import com.gemstone.gemfire.cache.InterestResultPolicy;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.TransactionException;
+ import com.gemstone.gemfire.cache.persistence.PartitionOfflineException;
+ import com.gemstone.gemfire.cache.query.types.CollectionType;
+ import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
+ import com.gemstone.gemfire.distributed.internal.DistributionStats;
+ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+ import com.gemstone.gemfire.internal.cache.DistributedRegion;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.cache.EntrySnapshot;
+ import com.gemstone.gemfire.internal.cache.EventID;
+ import com.gemstone.gemfire.internal.cache.FindVersionTagOperation;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.LocalRegion.NonTXEntry;
+ import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+ import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
+ import com.gemstone.gemfire.internal.cache.TXManagerImpl;
+ import com.gemstone.gemfire.internal.cache.TXStateProxy;
+ import com.gemstone.gemfire.internal.cache.Token;
+ import com.gemstone.gemfire.internal.cache.tier.CachedRegionHelper;
+ import com.gemstone.gemfire.internal.cache.tier.Command;
+ import com.gemstone.gemfire.internal.cache.tier.InterestType;
+ import com.gemstone.gemfire.internal.cache.tier.MessageType;
+ import com.gemstone.gemfire.internal.cache.versions.VersionStamp;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
+ import com.gemstone.gemfire.internal.sequencelog.EntryLogger;
+ import com.gemstone.gemfire.security.GemFireSecurityException;
+ 
+ /**
+  * @author ashahid
+  *
+  */
+ public abstract class BaseCommand implements Command {
+   protected static final Logger logger = LogService.getLogger();
+ 
+   /**
+    * Whether zipped values are being passed to/from the client. Can be modified
+    * using the system property Message.ZIP_VALUES ? This does not appear to
+    * happen anywhere
+    */
+   protected static final boolean zipValues = false;
+ 
+   protected static final boolean APPLY_RETRIES = Boolean
+       .getBoolean("gemfire.gateway.ApplyRetries");
+ 
+   public static final byte[] OK_BYTES = new byte[]{0};  
+ 
+   public static final int maximumChunkSize = Integer.getInteger(
+       "BridgeServer.MAXIMUM_CHUNK_SIZE", 100).intValue();
+ 
+   /** Maximum number of entries in each chunked response chunk */
+ 
+   /** Whether to suppress logging of IOExceptions */
+   private static boolean suppressIOExceptionLogging = Boolean
+       .getBoolean("gemfire.bridge.suppressIOExceptionLogging");
+ 
+   /**
+    * Maximum number of concurrent incoming client message bytes that a bridge
+    * server will allow. Once a server is working on this number additional
+    * incoming client messages will wait until one of them completes or fails.
+    * The bytes are computed based in the size sent in the incoming msg header.
+    */
+   private static final int MAX_INCOMING_DATA = Integer.getInteger(
+       "BridgeServer.MAX_INCOMING_DATA", -1).intValue();
+ 
+   /**
+    * Maximum number of concurrent incoming client messages that a bridge server
+    * will allow. Once a server is working on this number additional incoming
+    * client messages will wait until one of them completes or fails.
+    */
+   private static final int MAX_INCOMING_MSGS = Integer.getInteger(
+       "BridgeServer.MAX_INCOMING_MSGS", -1).intValue();
+ 
+   private static final Semaphore incomingDataLimiter;
+ 
+   private static final Semaphore incomingMsgLimiter;
+   static {
+     Semaphore tmp;
+     if (MAX_INCOMING_DATA > 0) {
+       // backport requires that this is fair since we inc by values > 1
+       tmp = new Semaphore(MAX_INCOMING_DATA, true);
+     }
+     else {
+       tmp = null;
+     }
+     incomingDataLimiter = tmp;
+     if (MAX_INCOMING_MSGS > 0) {
+       tmp = new Semaphore(MAX_INCOMING_MSGS, false); // unfair for best
+       // performance
+     }
+     else {
+       tmp = null;
+     }
+     incomingMsgLimiter = tmp;
+ 
+   }
+ 
+   final public void execute(Message msg, ServerConnection servConn) {
+     // Read the request and update the statistics
+     long start = DistributionStats.getStatTime();
+     //servConn.resetTransientData();
+     if(EntryLogger.isEnabled() && servConn  != null) {
+       EntryLogger.setSource(servConn.getMembershipID(), "c2s");
+     }
+     boolean shouldMasquerade = shouldMasqueradeForTx(msg, servConn);
+     try {
+       if (shouldMasquerade) {
+         GemFireCacheImpl  cache = (GemFireCacheImpl)servConn.getCache();
+         InternalDistributedMember member = (InternalDistributedMember)servConn.getProxyID().getDistributedMember();
+         TXManagerImpl txMgr = cache.getTxManager();
+         TXStateProxy tx = null;
+         try {
+           tx = txMgr.masqueradeAs(msg, member, false);
+           cmdExecute(msg, servConn, start);
+         } finally {
+           txMgr.unmasquerade(tx);
+         }
+       } else {
+         cmdExecute(msg, servConn, start);
+       }
+       
+     }   
++    catch (TransactionException
++        | CopyException
++        | SerializationException
++        | CacheWriterException
++        | CacheLoaderException
++        | GemFireSecurityException
++        | PartitionOfflineException
++        | MessageTooLargeException e) {
++      handleExceptionNoDisconnect(msg, servConn, e);
++    }
+     catch (EOFException eof) {
+       BaseCommand.handleEOFException(msg, servConn, eof);
+       // TODO:Asif: Check if there is any need for explicitly returning
+       return;
+     }
+     catch (InterruptedIOException e) { // Solaris only
+       BaseCommand.handleInterruptedIOException(msg, servConn, e);
 -      return;
+     }
+     catch (IOException e) {
+       BaseCommand.handleIOException(msg, servConn, e);
 -      return;
+     }
+     catch (DistributedSystemDisconnectedException e) {
+       BaseCommand.handleShutdownException(msg, servConn, e);
 -      return;
 -    }
 -    catch (PartitionOfflineException e) { // fix for bug #42225
 -      handleExceptionNoDisconnect(msg, servConn, e);
 -    }
 -    catch (GemFireSecurityException e) {
 -      handleExceptionNoDisconnect(msg, servConn, e);
+     }
 -    catch (CacheLoaderException e) {
 -      handleExceptionNoDisconnect(msg, servConn, e);
 -    }
 -    catch (CacheWriterException e) {
 -      handleExceptionNoDisconnect(msg, servConn, e);
 -    } catch (SerializationException e) {
 -      handleExceptionNoDisconnect(msg, servConn, e);
 -    } catch (CopyException e) {
 -      handleExceptionNoDisconnect(msg, servConn, e);
 -    } catch (TransactionException e) {
 -      handleExceptionNoDisconnect(msg, servConn, e);
 -    }
 -    
+     catch (VirtualMachineError err) {
+       SystemFailure.initiateFailure(err);
+       // If this ever returns, rethrow the error.  We're poisoned
+       // now, so don't let this thread continue.
+       throw err;
+     }
+     catch (Throwable e) {
+       BaseCommand.handleThrowable(msg, servConn, e);
+     } finally {
+       EntryLogger.clearSource();
+     }
 -    /*
 -     * finally { // Keep track of the fact that a message is no longer being //
 -     * processed. servConn.setNotProcessingMessage();
 -     * servConn.clearRequestMsg(); }
 -     */
+   }
+ 
+   /**
+    * checks to see if this thread needs to masquerade as a transactional thread.
+    * clients after GFE_66 should be able to start a transaction.
+    * @param msg
+    * @param servConn
+    * @return true if thread should masquerade as a transactional thread.
+    */
+   protected boolean shouldMasqueradeForTx(Message msg, ServerConnection servConn) {
+     if (servConn.getClientVersion().compareTo(Version.GFE_66) >= 0
+         && msg.getTransactionId() > TXManagerImpl.NOTX) {
+       return true;
+     }
+     return false;
+   }
+   
+   /**
+    * If an operation is retried then some server may have seen it already.
+    * We cannot apply this operation to the cache without knowing whether a
+    * version tag has already been created for it.  Otherwise caches that have
+    * seen the event already will reject it but others will not, but will have
+    * no version tag with which to perform concurrency checks.
+    * <p>The client event should have the event identifier from the client and
+    * the region affected by the operation.
+    * @param clientEvent
+    */
+   public boolean recoverVersionTagForRetriedOperation(EntryEventImpl clientEvent) {
+     LocalRegion r = clientEvent.getRegion();
+     VersionTag tag =  null;
+     if ((clientEvent.getVersionTag() != null) && (clientEvent.getVersionTag().isGatewayTag())) {
+       tag = r.findVersionTagForGatewayEvent(clientEvent.getEventId());
+     }
+     else {
+       tag = r.findVersionTagForClientEvent(clientEvent.getEventId());
+     }
+     if (tag == null) {
+       if (r instanceof DistributedRegion || r instanceof PartitionedRegion) {
+         // TODO this could be optimized for partitioned regions by sending the key
+         // so that the PR could look at an individual bucket for the event
+         tag = FindVersionTagOperation.findVersionTag(r, clientEvent.getEventId(), false);
+       }
+     }
+     if (tag != null) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("recovered version tag {} for replayed operation {}", tag, clientEvent.getEventId());
+       }
+       clientEvent.setVersionTag(tag);
+     }
+     return (tag != null);
+   }
+   
+   /**
+    * If an operation is retried then some server may have seen it already.
+    * We cannot apply this operation to the cache without knowing whether a
+    * version tag has already been created for it.  Otherwise caches that have
+    * seen the event already will reject it but others will not, but will have
+    * no version tag with which to perform concurrency checks.
+    * <p>The client event should have the event identifier from the client and
+    * the region affected by the operation.
+    */
+   protected VersionTag findVersionTagsForRetriedBulkOp(LocalRegion r, EventID eventID) {
+     VersionTag tag = r.findVersionTagForClientBulkOp(eventID);
+     if(tag != null) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("recovered version tag {} for replayed bulk operation {}", tag, eventID);
+       }
+       return tag;
+     }
+     if (r instanceof DistributedRegion || r instanceof PartitionedRegion) {
+       // TODO this could be optimized for partitioned regions by sending the key
+       // so that the PR could look at an individual bucket for the event
+       tag = FindVersionTagOperation.findVersionTag(r, eventID, true);
+     }
+     if (tag != null) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("recovered version tag {} for replayed bulk operation {}", tag, eventID);
+       }
+     }
+     return tag;
+   }
+ 
+   abstract public void cmdExecute(Message msg, ServerConnection servConn,
+       long start) throws IOException, ClassNotFoundException, InterruptedException;
+ 
+   protected void writeReply(Message origMsg, ServerConnection servConn)
+       throws IOException {
+     Message replyMsg = servConn.getReplyMessage();
+     servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
+     replyMsg.setMessageType(MessageType.REPLY);
+     replyMsg.setNumberOfParts(1);
+     replyMsg.setTransactionId(origMsg.getTransactionId());
+     replyMsg.addBytesPart(OK_BYTES);
+     replyMsg.send(servConn);
+     if (logger.isTraceEnabled()) {
+       logger.trace("{}: rpl tx: {}", servConn.getName(), origMsg.getTransactionId());
+     }
+   }
+   protected void writeReplyWithRefreshMetadata(Message origMsg,
+       ServerConnection servConn, PartitionedRegion pr, byte nwHop) throws IOException {
+     Message replyMsg = servConn.getReplyMessage();
+     servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
+     replyMsg.setMessageType(MessageType.REPLY);
+     replyMsg.setNumberOfParts(1);
+     replyMsg.setTransactionId(origMsg.getTransactionId());
+     replyMsg.addBytesPart(new byte[]{pr.getMetadataVersion().byteValue(), nwHop});
+     replyMsg.send(servConn);
+     pr.getPrStats().incPRMetaDataSentCount();
+     if (logger.isTraceEnabled()) {
+       logger.trace("{}: rpl with REFRESH_METADAT tx: {}", servConn.getName(), origMsg.getTransactionId());
+     }
+   }
+ 
+   private static void handleEOFException(Message msg,
+       ServerConnection servConn, Exception eof) {
+     CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
+     CacheServerStats stats = servConn.getCacheServerStats();
+     boolean potentialModification = servConn.getPotentialModification();
+     if (!crHelper.isShutdown()) {
+       if (potentialModification) {
+         stats.incAbandonedWriteRequests();
+       }
+       else {
+         stats.incAbandonedReadRequests();
+       }
+       if (!suppressIOExceptionLogging) {
+         if (potentialModification) {
+           int transId = (msg != null) ? msg.getTransactionId()
+               : Integer.MIN_VALUE;
+           logger.warn(LocalizedMessage.create(
+             LocalizedStrings.BaseCommand_0_EOFEXCEPTION_DURING_A_WRITE_OPERATION_ON_REGION__1_KEY_2_MESSAGEID_3,
+             new Object[] {servConn.getName(), servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}));
+         }
+         else {
+           logger.debug("EOF exception", eof);
+           logger.info(LocalizedMessage.create(
+             LocalizedStrings.BaseCommand_0_CONNECTION_DISCONNECT_DETECTED_BY_EOF,
+             servConn.getName()));
+         }
+       }
+     }
+     servConn.setFlagProcessMessagesAsFalse();
+   }
+ 
+   private static void handleInterruptedIOException(Message msg,
+       ServerConnection servConn, Exception e) {
+     CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
+     if (!crHelper.isShutdown() && servConn.isOpen()) {
+       if (!suppressIOExceptionLogging) {
+         if (logger.isDebugEnabled())
+           logger.debug("Aborted message due to interrupt: {}", e.getMessage(), e);
+       }
+     }
+     servConn.setFlagProcessMessagesAsFalse();
+   }
+ 
+   private static void handleIOException(Message msg, ServerConnection servConn,
+       Exception e) {
+     CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
+     boolean potentialModification = servConn.getPotentialModification();
+ 
+     if (!crHelper.isShutdown() && servConn.isOpen()) {
+       if (!suppressIOExceptionLogging) {
+         if (potentialModification) {
+           int transId = (msg != null) ? msg.getTransactionId()
+               : Integer.MIN_VALUE;
+           logger.warn(LocalizedMessage.create(
+             LocalizedStrings.BaseCommand_0_UNEXPECTED_IOEXCEPTION_DURING_OPERATION_FOR_REGION_1_KEY_2_MESSID_3,
+             new Object[] {servConn.getName(), servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), e);
+         }
+         else {
+           logger.warn(LocalizedMessage.create(
+             LocalizedStrings.BaseCommand_0_UNEXPECTED_IOEXCEPTION,
+             servConn.getName()), e);
+         }
+       }
+     }
+     servConn.setFlagProcessMessagesAsFalse();
+   }
+ 
+   private static void handleShutdownException(Message msg,
+       ServerConnection servConn, Exception e) {
+     CachedRegionHelper crHelper = servConn.getCachedRegionHelper();
+     boolean potentialModification = servConn.getPotentialModification();
+ 
+     if (!crHelper.isShutdown()) {
+       if (potentialModification) {
+         int transId = (msg != null) ? msg.getTransactionId()
+             : Integer.MIN_VALUE;
+         logger.warn(LocalizedMessage.create(
+           LocalizedStrings.BaseCommand_0_UNEXPECTED_SHUTDOWNEXCEPTION_DURING_OPERATION_ON_REGION_1_KEY_2_MESSAGEID_3,
+           new Object[] {servConn.getName(), servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), e);
+       }
+       else {
+         logger.warn(LocalizedMessage.create(
+           LocalizedStrings.BaseCommand_0_UNEXPECTED_SHUTDOWNEXCEPTION,
+           servConn.getName()),e);
+         }
+     }
+     servConn.setFlagProcessMessagesAsFalse();
+   }
+ 
+   // Handle GemfireSecurityExceptions separately since the connection should not
+   // be terminated (by setting processMessages to false) unlike in
+   // handleThrowable. Fixes bugs #38384 and #39392.
+ //  private static void handleGemfireSecurityException(Message msg,
+ //      ServerConnection servConn, GemFireSecurityException e) {
+ //
+ //    boolean requiresResponse = servConn.getTransientFlag(REQUIRES_RESPONSE);
+ //    boolean responded = servConn.getTransientFlag(RESPONDED);
+ //    boolean requiresChunkedResponse = servConn
+ //        .getTransientFlag(REQUIRES_CHUNKED_RESPONSE);
+ //    boolean potentialModification = servConn.getPotentialModification();
+ //
+ //    try {
+ //      try {
+ //        if (requiresResponse && !responded) {
+ //          if (requiresChunkedResponse) {
+ //            writeChunkedException(msg, e, false, servConn);
+ //          }
+ //          else {
+ //            writeException(msg, e, false, servConn);
+ //          }
+ //          servConn.setAsTrue(RESPONDED);
+ //        }
+ //      }
+ //      finally { // inner try-finally to ensure proper ordering of logging
+ //        if (potentialModification) {
+ //          int transId = (msg != null) ? msg.getTransactionId()
+ //              : Integer.MIN_VALUE;
+ //        }
+ //      }
+ //    }
+ //    catch (IOException ioe) {
+ //      if (logger.isDebugEnabled()) {
+ //        logger.fine(servConn.getName()
+ //            + ": Unexpected IOException writing security exception: ", ioe);
+ //      }
+ //    }
+ //  }
+ 
+   private static void handleExceptionNoDisconnect(Message msg,
+       ServerConnection servConn, Exception e) {
+     boolean requiresResponse = servConn.getTransientFlag(REQUIRES_RESPONSE);
+     boolean responded = servConn.getTransientFlag(RESPONDED);
+     boolean requiresChunkedResponse = servConn
+         .getTransientFlag(REQUIRES_CHUNKED_RESPONSE);
+     boolean potentialModification = servConn.getPotentialModification();
+     boolean wroteExceptionResponse = false;
+ 
+     try {
+       try {
+         if (requiresResponse && !responded) {
+           if (requiresChunkedResponse) {
+             writeChunkedException(msg, e, false, servConn);
+           }
+           else {
+             writeException(msg, e, false, servConn);
+           }
+           wroteExceptionResponse = true;
+           servConn.setAsTrue(RESPONDED);
+         }
+       }
+       finally { // inner try-finally to ensure proper ordering of logging
+         if (potentialModification) {
+           int transId = (msg != null) ? msg.getTransactionId()
+               : Integer.MIN_VALUE;
+           if (!wroteExceptionResponse) {
+             logger.warn(LocalizedMessage.create(
+                 LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION_DURING_OPERATION_ON_REGION_1_KEY_2_MESSAGEID_3,
+                 new Object[] {servConn.getName(),servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), e);
+           } else {
+             if (logger.isDebugEnabled()) {
+               logger.debug("{}: Exception during operation on region: {} key: {} messageId: {}", servConn.getName(),
+                   servConn.getModRegion(), servConn.getModKey(), transId, e);
+             }
+           }
+         }
+         else {
+           if (!wroteExceptionResponse) {
+             logger.warn(LocalizedMessage.create(
+                 LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION,
+                 servConn.getName()), e);
+           } else {
+             if (logger.isDebugEnabled()) {
+               logger.debug("{}: Exception: {}", servConn.getName(), e.getMessage(), e);
+             }
+           }
+         }
+       }
+     }
+     catch (IOException ioe) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Unexpected IOException writing exception: {}", servConn.getName(), ioe.getMessage(), ioe);
+       }
+     }
+   }
+ 
+   private static void handleThrowable(Message msg, ServerConnection servConn,
+       Throwable th) {
+     boolean requiresResponse = servConn.getTransientFlag(REQUIRES_RESPONSE);
+     boolean responded = servConn.getTransientFlag(RESPONDED);
+     boolean requiresChunkedResponse = servConn
+         .getTransientFlag(REQUIRES_CHUNKED_RESPONSE);
+     boolean potentialModification = servConn.getPotentialModification();
+ 
+     try {
+       try {
+         if (th instanceof Error) {
+           logger.fatal(LocalizedMessage.create(LocalizedStrings.BaseCommand_0_UNEXPECTED_ERROR_ON_SERVER,
+               servConn.getName()), th);
+         }
+         if (requiresResponse && !responded) {
+           if (requiresChunkedResponse) {
+             writeChunkedException(msg, th, false, servConn);
+           }
+           else {
+             writeException(msg, th, false, servConn);
+           }
+           servConn.setAsTrue(RESPONDED);
+         }
+       }
+       finally { // inner try-finally to ensure proper ordering of logging
+         if (th instanceof Error) {
+           // log nothing
+         } else if (th instanceof CancelException) {
+           // log nothing
+         } else {
+           if (potentialModification) {
+             int transId = (msg != null) ? msg.getTransactionId()
+                 : Integer.MIN_VALUE;
+             logger.warn(LocalizedMessage.create(
+               LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION_DURING_OPERATION_ON_REGION_1_KEY_2_MESSAGEID_3,
+               new Object[] {servConn.getName(),servConn.getModRegion(), servConn.getModKey(), Integer.valueOf(transId)}), th);
+           }
+           else {
+             logger.warn(LocalizedMessage.create(
+               LocalizedStrings.BaseCommand_0_UNEXPECTED_EXCEPTION,
+               servConn.getName()), th);
+           }
+         }
+       }
+     } catch (IOException ioe) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Unexpected IOException writing exception: {}", servConn.getName(), ioe.getMessage(), ioe);
+       }
+     } finally {
+       servConn.setFlagProcessMessagesAsFalse();
+     }
+   }
+   
+   protected static void writeChunkedException(Message origMsg, Throwable e,
+       boolean isSevere, ServerConnection servConn) throws IOException {
+     writeChunkedException(origMsg, e, isSevere, servConn, servConn.getChunkedResponseMessage());
+   }
+ 
+   protected static void writeChunkedException(Message origMsg, Throwable e,
+       boolean isSevere, ServerConnection servConn, ChunkedMessage originalReponse) throws IOException {
+     writeChunkedException(origMsg, e, isSevere, servConn, originalReponse, 2);
+   }
+ 
+   protected static void writeChunkedException(Message origMsg, Throwable e,
+       boolean isSevere, ServerConnection servConn, ChunkedMessage originalReponse, int numOfParts) throws IOException {
+     ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
+     chunkedResponseMsg.setServerConnection(servConn);
+     if (originalReponse.headerHasBeenSent()) {
+       //chunkedResponseMsg = originalReponse;
+       // fix for bug 35442
+       chunkedResponseMsg.setNumberOfParts(numOfParts);
+       chunkedResponseMsg.setLastChunkAndNumParts(true, numOfParts);
+       chunkedResponseMsg.addObjPart(e); 
+       if (numOfParts == 2) {
+         chunkedResponseMsg.addStringPart(getExceptionTrace(e));
+       }
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending exception chunk while reply in progress: {}", servConn.getName(), e.getMessage(), e);
+       }
+     }
+     else {
+       chunkedResponseMsg.setMessageType(MessageType.EXCEPTION);
+       chunkedResponseMsg.setNumberOfParts(numOfParts);
+       chunkedResponseMsg.setLastChunkAndNumParts(true, numOfParts);
+       chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
+       chunkedResponseMsg.sendHeader();
+       chunkedResponseMsg.addObjPart(e);
+       if (numOfParts == 2) {
+         chunkedResponseMsg.addStringPart(getExceptionTrace(e));
+       }
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending exception chunk: {}", servConn.getName(), e.getMessage(), e);
+       }
+     }
+     chunkedResponseMsg.sendChunk(servConn);
+   }
+ 
+   // Get the exception stacktrace for native clients
+   public static String getExceptionTrace(Throwable ex) {
+     StringWriter sw = new StringWriter();
+     PrintWriter pw = new PrintWriter(sw);
+     ex.printStackTrace(pw);
+     pw.close();
+     return sw.toString();
+   }
+ 
+   protected static void writeException(Message origMsg, Throwable e,
+       boolean isSevere, ServerConnection servConn) throws IOException {
+     writeException(origMsg, MessageType.EXCEPTION, e, isSevere, servConn);
+   }
+ 
+   protected static void writeException(Message origMsg, int msgType, Throwable e,
+       boolean isSevere, ServerConnection servConn) throws IOException {
+     Message errorMsg = servConn.getErrorResponseMessage();
+     errorMsg.setMessageType(msgType);
+     errorMsg.setNumberOfParts(2);
+     errorMsg.setTransactionId(origMsg.getTransactionId());
+     if (isSevere) {
+       String msg = e.getMessage();
+       if (msg == null) {
+         msg = e.toString();
+       }
+       logger.fatal(LocalizedMessage.create(LocalizedStrings.BaseCommand_SEVERE_CACHE_EXCEPTION_0, msg));
+     }
+     errorMsg.addObjPart(e);
+     errorMsg.addStringPart(getExceptionTrace(e));
+     errorMsg.send(servConn);
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Wrote exception: {}", servConn.getName(), e.getMessage(), e);
+     }
++    if (e instanceof MessageTooLargeException) {
++      throw (IOException)e;
++    }
+   }
+ 
+   protected static void writeErrorResponse(Message origMsg, int messageType,
+       ServerConnection servConn) throws IOException {
+     Message errorMsg = servConn.getErrorResponseMessage();
+     errorMsg.setMessageType(messageType);
+     errorMsg.setNumberOfParts(1);
+     errorMsg.setTransactionId(origMsg.getTransactionId());
+     errorMsg
+         .addStringPart(LocalizedStrings.BaseCommand_INVALID_DATA_RECEIVED_PLEASE_SEE_THE_CACHE_SERVER_LOG_FILE_FOR_ADDITIONAL_DETAILS.toLocalizedString());
+     errorMsg.send(servConn);
+   }
+ 
+   protected static void writeErrorResponse(Message origMsg, int messageType,
+       String msg, ServerConnection servConn) throws IOException {
+     Message errorMsg = servConn.getErrorResponseMessage();
+     errorMsg.setMessageType(messageType);
+     errorMsg.setNumberOfParts(1);
+     errorMsg.setTransactionId(origMsg.getTransactionId());
+     errorMsg.addStringPart(msg);
+     errorMsg.send(servConn);
+   }
+ 
+   protected static void writeRegionDestroyedEx(Message msg, String regionName,
+       String title, ServerConnection servConn) throws IOException {
+     String reason = servConn.getName() + ": Region named " + regionName + title;
+     RegionDestroyedException ex = new RegionDestroyedException(reason,
+         regionName);
+     if (servConn.getTransientFlag(REQUIRES_CHUNKED_RESPONSE)) {
+       writeChunkedException(msg, ex, false, servConn);
+     }
+     else {
+       writeException(msg, ex, false, servConn);
+     }
+   }
+ 
+   protected static void writeResponse(Object data, Object callbackArg,
+       Message origMsg, boolean isObject, ServerConnection servConn)
+       throws IOException {
+     Message responseMsg = servConn.getResponseMessage();
+     responseMsg.setMessageType(MessageType.RESPONSE);
+     responseMsg.setTransactionId(origMsg.getTransactionId());
+ 
+     
+     if (callbackArg == null) {
+       responseMsg.setNumberOfParts(1);
+     }
+     else {
+       responseMsg.setNumberOfParts(2);
+     }
+     if (data instanceof byte[]) {
+       responseMsg.addRawPart((byte[])data, isObject);
+     }
+     else {
+       Assert.assertTrue(isObject,
+           "isObject should be true when value is not a byte[]");
+       responseMsg.addObjPart(data, zipValues);
+     }
+     if (callbackArg != null) {
+       responseMsg.addObjPart(callbackArg);
+     }
+     servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
+     responseMsg.send(servConn);
+     origMsg.clearParts();
+   }
+   
+   protected static void writeResponseWithRefreshMetadata(Object data,
+       Object callbackArg, Message origMsg, boolean isObject,
+       ServerConnection servConn, PartitionedRegion pr, byte nwHop) throws IOException {
+     Message responseMsg = servConn.getResponseMessage();
+     responseMsg.setMessageType(MessageType.RESPONSE);
+     responseMsg.setTransactionId(origMsg.getTransactionId());
+ 
+     if (callbackArg == null) {
+       responseMsg.setNumberOfParts(2);
+     }
+     else {
+       responseMsg.setNumberOfParts(3);
+     }
+ 
+     if (data instanceof byte[]) {
+       responseMsg.addRawPart((byte[])data, isObject);
+     }
+     else {
+       Assert.assertTrue(isObject,
+           "isObject should be true when value is not a byte[]");
+       responseMsg.addObjPart(data, zipValues);
+     }
+     if (callbackArg != null) {
+       responseMsg.addObjPart(callbackArg);
+     }
+     responseMsg.addBytesPart(new byte[]{pr.getMetadataVersion().byteValue(),nwHop});
+     servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
+     responseMsg.send(servConn);
+     origMsg.clearParts();
+   }
+ 
+   protected static void writeResponseWithFunctionAttribute(byte[] data,
+       Message origMsg, ServerConnection servConn) throws IOException {
+     Message responseMsg = servConn.getResponseMessage();
+     responseMsg.setMessageType(MessageType.RESPONSE);
+     responseMsg.setTransactionId(origMsg.getTransactionId());
+     responseMsg.setNumberOfParts(1);
+     responseMsg.addBytesPart(data);
+     servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
+     responseMsg.send(servConn);
+     origMsg.clearParts();
+   }
+   
+   static protected void checkForInterrupt(ServerConnection servConn, Exception e) 
+       throws InterruptedException, InterruptedIOException {
+     servConn.getCachedRegionHelper().checkCancelInProgress(e);
+     if (e instanceof InterruptedException) {
+       throw (InterruptedException)e;
+     }
+     if (e instanceof InterruptedIOException) {
+       throw (InterruptedIOException)e;
+     }
+   }
+ 
+   protected static void writeQueryResponseChunk(Object queryResponseChunk,
+       CollectionType collectionType, boolean lastChunk,
+       ServerConnection servConn) throws IOException {
+     ChunkedMessage queryResponseMsg = servConn.getQueryResponseMessage();
+     queryResponseMsg.setNumberOfParts(2);
+     queryResponseMsg.setLastChunk(lastChunk);
+     queryResponseMsg.addObjPart(collectionType, zipValues);
+     queryResponseMsg.addObjPart(queryResponseChunk, zipValues);
+     queryResponseMsg.sendChunk(servConn);
+   }
+ 
+   protected static void writeQueryResponseException(Message origMsg,
+       Throwable e, boolean isSevere, ServerConnection servConn)
+       throws IOException {
+     ChunkedMessage queryResponseMsg = servConn.getQueryResponseMessage();
+     ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
+     if (queryResponseMsg.headerHasBeenSent()) {
+       // fix for bug 35442
+       // This client is expecting 2 parts in this message so send 2 parts
+       queryResponseMsg.setServerConnection(servConn);
+       queryResponseMsg.setNumberOfParts(2);
+       queryResponseMsg.setLastChunkAndNumParts(true, 2);
+       queryResponseMsg.addObjPart(e);
+       queryResponseMsg.addStringPart(getExceptionTrace(e));
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending exception chunk while reply in progress: {}", servConn.getName(), e.getMessage(), e);
+       }
+       queryResponseMsg.sendChunk(servConn);
+     }
+     else {
+       chunkedResponseMsg.setServerConnection(servConn);
+       chunkedResponseMsg.setMessageType(MessageType.EXCEPTION);
+       chunkedResponseMsg.setNumberOfParts(2);
+       chunkedResponseMsg.setLastChunkAndNumParts(true, 2);
+       chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
+       chunkedResponseMsg.sendHeader();
+       chunkedResponseMsg.addObjPart(e);
+       chunkedResponseMsg.addStringPart(getExceptionTrace(e));
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending exception chunk: {}", servConn.getName(), e.getMessage(), e);
+       }
+       chunkedResponseMsg.sendChunk(servConn);
+     }
+   }
+ 
+   protected static void writeChunkedErrorResponse(Message origMsg,
+       int messageType, String message, ServerConnection servConn)
+       throws IOException {
+     // Send chunked response header identifying error message
+     ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
+     if (logger.isDebugEnabled()) {
+       logger.debug(servConn.getName() + ": Sending error message header type: "
+           + messageType + " transaction: " + origMsg.getTransactionId());
+     }
+     chunkedResponseMsg.setMessageType(messageType);
+     chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
+     chunkedResponseMsg.sendHeader();
+ 
+     // Send actual error
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Sending error message chunk: {}", servConn.getName(), message);
+     }
+     chunkedResponseMsg.setNumberOfParts(1);
+     chunkedResponseMsg.setLastChunk(true);
+     chunkedResponseMsg.addStringPart(message);
+     chunkedResponseMsg.sendChunk(servConn);
+   }
+   
+   protected static void writeFunctionResponseException(Message origMsg,
+       int messageType, String message, ServerConnection servConn, Throwable e)
+       throws IOException {
+     ChunkedMessage functionResponseMsg = servConn.getFunctionResponseMessage();
+     ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
+     if (functionResponseMsg.headerHasBeenSent()) {
+       functionResponseMsg.setServerConnection(servConn);
+       functionResponseMsg.setNumberOfParts(2);
+       functionResponseMsg.setLastChunkAndNumParts(true,2);
+       functionResponseMsg.addObjPart(e);
+       functionResponseMsg.addStringPart(getExceptionTrace(e));
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending exception chunk while reply in progress: {}", servConn.getName(), e.getMessage(), e);
+       }
+       functionResponseMsg.sendChunk(servConn);
+     }
+     else {
+       chunkedResponseMsg.setServerConnection(servConn);
+       chunkedResponseMsg.setMessageType(messageType);
+       chunkedResponseMsg.setNumberOfParts(2);
+       chunkedResponseMsg.setLastChunkAndNumParts(true,2);
+       chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
+       chunkedResponseMsg.sendHeader();
+       chunkedResponseMsg.addObjPart(e);
+       chunkedResponseMsg.addStringPart(getExceptionTrace(e));
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending exception chunk: {}", servConn.getName(), e.getMessage(), e);
+       }
+       chunkedResponseMsg.sendChunk(servConn);
+     }
+   }
+   
+   protected static void writeFunctionResponseError(Message origMsg,
+       int messageType, String message, ServerConnection servConn)
+       throws IOException {
+     ChunkedMessage functionResponseMsg = servConn.getFunctionResponseMessage();
+     ChunkedMessage chunkedResponseMsg = servConn.getChunkedResponseMessage();
+     if (functionResponseMsg.headerHasBeenSent()) {
+       functionResponseMsg.setNumberOfParts(1);
+       functionResponseMsg.setLastChunk(true);
+       functionResponseMsg.addStringPart(message);
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending Error chunk while reply in progress: {}", servConn.getName(), message);
+       }
+       functionResponseMsg.sendChunk(servConn);
+     }
+     else {
+       chunkedResponseMsg.setMessageType(messageType);
+       chunkedResponseMsg.setNumberOfParts(1);
+       chunkedResponseMsg.setLastChunk(true);
+       chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
+       chunkedResponseMsg.sendHeader();
+       chunkedResponseMsg.addStringPart(message);
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Sending Error chunk: {}", servConn.getName(), message);
+       }
+       chunkedResponseMsg.sendChunk(servConn);
+     }
+   }
+ 
+   protected static void writeKeySetErrorResponse(Message origMsg,
+       int messageType, String message, ServerConnection servConn)
+       throws IOException {
+     // Send chunked response header identifying error message
+     ChunkedMessage chunkedResponseMsg = servConn.getKeySetResponseMessage();
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Sending error message header type: {} transaction: {}",
+           servConn.getName(), messageType, origMsg.getTransactionId());
+     }
+     chunkedResponseMsg.setMessageType(messageType);
+     chunkedResponseMsg.setTransactionId(origMsg.getTransactionId());
+     chunkedResponseMsg.sendHeader();
+     // Send actual error
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Sending error message chunk: {}", servConn.getName(), message);
+     }
+     chunkedResponseMsg.setNumberOfParts(1);
+     chunkedResponseMsg.setLastChunk(true);
+     chunkedResponseMsg.addStringPart(message);
+     chunkedResponseMsg.sendChunk(servConn);
+   }
+   
+   static Message readRequest(ServerConnection servConn) {
+     Message requestMsg = null;
+     try {
+       requestMsg = servConn.getRequestMessage();
+       requestMsg.recv(servConn, MAX_INCOMING_DATA, incomingDataLimiter,
+           incomingMsgLimiter);
+       return requestMsg;
+     }
+     catch (EOFException eof) {
+       handleEOFException(null, servConn, eof);
+       // TODO:Asif: Check if there is any need for explicitly returning
+ 
+     }
+     catch (InterruptedIOException e) { // Solaris only
+       handleInterruptedIOException(null, servConn, e);
+ 
+     }
+     catch (IOException e) {
+       handleIOException(null, servConn, e);
+ 
+     }
+     catch (DistributedSystemDisconnectedException e) {
+       handleShutdownException(null, servConn, e);
+ 
+     }
+     catch (VirtualMachineError err) {
+       SystemFailure.initiateFailure(err);
+       // If this ever returns, rethrow the error.  We're poisoned
+       // now, so don't let this thread continue.
+       throw err;
+     }
+     catch (Throwable e) {
+       SystemFailure.checkFailure();
+       handleThrowable(null, servConn, e);
+     }
+     return requestMsg;
+   }
+ 
+   protected static void fillAndSendRegisterInterestResponseChunks(
+       LocalRegion region, Object riKey, int interestType,
+       InterestResultPolicy policy, ServerConnection servConn)
+       throws IOException {
+     fillAndSendRegisterInterestResponseChunks(region, riKey, interestType,
+         false, policy, servConn);
+   }
+ 
+   /*
+    * serializeValues is unused for clients < GFE_80
+    */
+   protected static void fillAndSendRegisterInterestResponseChunks(
+       LocalRegion region, Object riKey, int interestType, boolean serializeValues,
+       InterestResultPolicy policy, ServerConnection servConn)
+       throws IOException {
+     // Client is not interested.
+     if (policy.isNone()) {
+       sendRegisterInterestResponseChunk(region, riKey, new ArrayList(), true,
+           servConn);
+       return;
+     }
+     if (policy.isKeysValues()
+         && servConn.getClientVersion().compareTo(Version.GFE_80) >= 0) {
+         handleKeysValuesPolicy(region, riKey, interestType, serializeValues, servConn);
+         return;
+     }
+     if (riKey instanceof List) {
+       handleList(region, (List)riKey, policy, servConn);
+       return;
+     }
+     if (!(riKey instanceof String)) {
+       handleSingleton(region, riKey, policy, servConn);
+       return;
+     }
+ 
+     switch (interestType) {
+     case InterestType.OQL_QUERY:
+       // Not supported yet
+       throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
+     case InterestType.FILTER_CLASS:
+       throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
+       // handleFilter(region, (String)riKey, policy);
+       // break;
+     case InterestType.REGULAR_EXPRESSION: {
+       String regEx = (String)riKey;
+       if (regEx.equals(".*")) {
+         handleAllKeys(region, policy, servConn);
+       }
+       else {
+         handleRegEx(region, regEx, policy, servConn);
+       }
+     }
+       break;
+     case InterestType.KEY:
+       if (riKey.equals("ALL_KEYS")) {
+         handleAllKeys(region, policy, servConn);
+       }
+       else {
+         handleSingleton(region, riKey, policy, servConn);
+       }
+       break;
+     default:
+       throw new InternalGemFireError(LocalizedStrings.BaseCommand_UNKNOWN_INTEREST_TYPE.toLocalizedString());
+     }
+   }
+ 
+   @SuppressWarnings("rawtypes")
+   private static void handleKeysValuesPolicy(LocalRegion region, Object riKey,
+       int interestType, boolean serializeValues, ServerConnection servConn)
+       throws IOException {
+     if (riKey instanceof List) {
+       handleKVList(region, (List)riKey, serializeValues, servConn);
+       return;
+     }
+     if (!(riKey instanceof String)) {
+       handleKVSingleton(region, riKey, serializeValues, servConn);
+       return;
+     }
+ 
+     switch (interestType) {
+     case InterestType.OQL_QUERY:
+       throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
+     case InterestType.FILTER_CLASS:
+       throw new InternalGemFireError(LocalizedStrings.BaseCommand_NOT_YET_SUPPORTED.toLocalizedString());
+     case InterestType.REGULAR_EXPRESSION:
+       String regEx = (String)riKey;
+       if (regEx.equals(".*")) {
+         handleKVAllKeys(region, null, serializeValues, servConn);
+       } else {
+         handleKVAllKeys(region, regEx, serializeValues, servConn);
+       }
+       break;
+     case InterestType.KEY:
+       if (riKey.equals("ALL_KEYS")) {
+         handleKVAllKeys(region, null, serializeValues, servConn);
+       } else {
+         handleKVSingleton(region, riKey, serializeValues, servConn);
+       }
+       break;
+     default:
+       throw new InternalGemFireError(LocalizedStrings.BaseCommand_UNKNOWN_INTEREST_TYPE.toLocalizedString());
+     }
+   }
+ 
+   /**
+    * @param list
+    *                is a List of entry keys
+    */
+   protected static void sendRegisterInterestResponseChunk(Region region,
+       Object riKey, ArrayList list, boolean lastChunk, ServerConnection servConn)
+       throws IOException {
+     ChunkedMessage chunkedResponseMsg = servConn.getRegisterInterestResponseMessage();
+     chunkedResponseMsg.setNumberOfParts(1);
+     chunkedResponseMsg.setLastChunk(lastChunk);
+     chunkedResponseMsg.addObjPart(list, zipValues);
+     String regionName = (region == null) ? " null " : region.getFullPath();
+     if (logger.isDebugEnabled()) {
+       String str = servConn.getName() + ": Sending"
+           + (lastChunk ? " last " : " ")
+           + "register interest response chunk for region: " + regionName
+           + " for keys: " + riKey + " chunk=<" + chunkedResponseMsg + ">";
+       logger.debug(str);
+     }
+ 
+     chunkedResponseMsg.sendChunk(servConn);
+   }
+   
+   /**
+    * Determines whether keys for destroyed entries (tombstones) should be sent
+    * to clients in register-interest results.
+    * 
+    * @param servConn
+    * @param policy
+    * @return true if tombstones should be sent to the client
+    */
+   private static boolean sendTombstonesInRIResults(ServerConnection servConn, InterestResultPolicy policy) {
+     return (policy == InterestResultPolicy.KEYS_VALUES)
+          && (servConn.getClientVersion().compareTo(Version.GFE_80) >= 0);
+   }
+ 
+   /**
+    * Process an interest request involving a list of keys
+    *
+    * @param region
+    *                the region
+    * @param keyList
+    *                the list of keys
+    * @param policy
+    *                the policy
+    * @throws IOException
+    */
+   private static void handleList(LocalRegion region, List keyList,
+       InterestResultPolicy policy, ServerConnection servConn)
+       throws IOException {
+     if (region instanceof PartitionedRegion) {
+       // too bad java doesn't provide another way to do this...
+       handleListPR((PartitionedRegion)region, keyList, policy, servConn);
+       return;
+     }
+     ArrayList newKeyList = new ArrayList(maximumChunkSize);
+     // Handle list of keys
+     if (region != null) {
+       for (Iterator it = keyList.iterator(); it.hasNext();) {
+         Object entryKey = it.next();
+         if (region.containsKey(entryKey)
+             || (sendTombstonesInRIResults(servConn, policy) && region.containsTombstone(entryKey))) {
+           
+           appendInterestResponseKey(region, keyList, entryKey, newKeyList,
+               "list", servConn);
+         }
+       }
+     }
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendRegisterInterestResponseChunk(region, keyList, newKeyList, true,
+         servConn);
+   }
+ 
+   /**
+    * Handles both RR and PR cases
+    */
+   @SuppressWarnings("rawtypes")
+   @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="NP_NULL_PARAM_DEREF", justification="Null value handled in sendNewRegisterInterestResponseChunk()")
+   private static void handleKVSingleton(LocalRegion region, Object entryKey,
+       boolean serializeValues, ServerConnection servConn)
+       throws IOException {
+     VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
+         true, region == null ? true : region.getAttributes()
+             .getConcurrencyChecksEnabled(), serializeValues);
+ 
+     if (region != null) {
+       if (region.containsKey(entryKey) || region.containsTombstone(entryKey)) {
+         EntryEventImpl versionHolder = EntryEventImpl.createVersionTagHolder();
+         ClientProxyMembershipID id = servConn == null ? null : servConn.getProxyID();
+         // From Get70.getValueAndIsObject()
+         Object data = region.get(entryKey, null, true, true, true, id, versionHolder, true, false);
+         VersionTag vt = versionHolder.getVersionTag();
+ 
+         updateValues(values, entryKey, data, vt);
+       }
+     }
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendNewRegisterInterestResponseChunk(region, entryKey, values, true, servConn);
+   }
+ 
+   /**
+    * Process an interest request consisting of a single key
+    *
+    * @param region
+    *                the region
+    * @param entryKey
+    *                the key
+    * @param policy
+    *                the policy
+    * @throws IOException
+    */
+   private static void handleSingleton(LocalRegion region, Object entryKey,
+       InterestResultPolicy policy, ServerConnection servConn)
+       throws IOException {
+     ArrayList keyList = new ArrayList(1);
+     if (region != null) {
+       if (region.containsKey(entryKey) ||
+           (sendTombstonesInRIResults(servConn, policy) && region.containsTombstone(entryKey))) {
+         appendInterestResponseKey(region, entryKey, entryKey, keyList,
+             "individual", servConn);
+       }
+     }
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendRegisterInterestResponseChunk(region, entryKey, keyList, true, servConn);
+   }
+ 
+   /**
+    * Process an interest request of type ALL_KEYS
+    *
+    * @param region
+    *                the region
+    * @param policy
+    *                the policy
+    * @throws IOException
+    */
+   private static void handleAllKeys(LocalRegion region,
+       InterestResultPolicy policy, ServerConnection servConn)
+       throws IOException {
+     ArrayList keyList = new ArrayList(maximumChunkSize);
+     if (region != null) {
+       for (Iterator it = region.keySet(sendTombstonesInRIResults(servConn, policy)).iterator(); it.hasNext();) {
+         appendInterestResponseKey(region, "ALL_KEYS", it.next(), keyList,
+             "ALL_KEYS", servConn);
+       }
+     }
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendRegisterInterestResponseChunk(region, "ALL_KEYS", keyList, true,
+         servConn);
+   }
+ 
+   /**
+    * @param region
+    * @param regex
+    * @param serializeValues
+    * @param servConn
+    * @throws IOException
+    */
+   private static void handleKVAllKeys(LocalRegion region, String regex,
+       boolean serializeValues, ServerConnection servConn) throws IOException {
+ 
+     if (region != null && region instanceof PartitionedRegion) {
+       handleKVKeysPR((PartitionedRegion) region, regex, serializeValues, servConn);
+       return;
+     }
+ 
+     VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
+         true, region == null ? true : region.getAttributes()
+             .getConcurrencyChecksEnabled(), serializeValues);
+ 
+     if (region != null) {
+ 
+       VersionTag versionTag = null;
+       Object data = null;
+ 
+       Pattern keyPattern = null;
+       if (regex != null) {
+         keyPattern = Pattern.compile(regex);
+       }
+ 
+       for (Object key : region.keySet(true)) {
+         EntryEventImpl versionHolder = EntryEventImpl.createVersionTagHolder();
+         if (keyPattern != null) {
+           if (!(key instanceof String)) {
+             // key is not a String, cannot apply regex to this entry
+             continue;
+           }
+           if (!keyPattern.matcher((String) key).matches()) {
+             // key does not match the regex, this entry should not be
+             // returned.
+             continue;
+           }
+         }
+ 
+         ClientProxyMembershipID id = servConn == null ? null : servConn.getProxyID();
+         data = region.get(key, null, true, true, true, id, versionHolder, true, false);
+         versionTag = versionHolder.getVersionTag();
+         updateValues(values, key, data, versionTag);
+ 
+         if (values.size() == maximumChunkSize) {
+           sendNewRegisterInterestResponseChunk(region, regex != null ? regex : "ALL_KEYS", values, false, servConn);
+           values.clear();
+         }
+       } // for
+     } // if
+ 
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendNewRegisterInterestResponseChunk(region, regex != null ? regex : "ALL_KEYS", values, true, servConn);
+   }
+ 
+   private static void handleKVKeysPR(PartitionedRegion region, Object keyInfo,
+       boolean serializeValues, ServerConnection servConn) throws IOException {
+     int id = 0;
+     HashMap<Integer, HashSet> bucketKeys = null;
+ 
+     VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
+         true, region.getConcurrencyChecksEnabled(), serializeValues);
+ 
+     if (keyInfo != null && keyInfo instanceof List) {
+       bucketKeys = new HashMap<Integer, HashSet>();
+       for (Object key : (List) keyInfo) {
+         id = PartitionedRegionHelper.getHashKey(region, null, key, null, null);
+         if (bucketKeys.containsKey(id)) {
+           bucketKeys.get(id).add(key);
+         } else {
+           HashSet<Object> keys = new HashSet<Object>();
+           keys.add(key);
+           bucketKeys.put(id, keys);
+         }
+       }
+       region.fetchEntries(bucketKeys, values, servConn);
+     } else { // keyInfo is a String
+       region.fetchEntries((String)keyInfo, values, servConn);
+     }
+ 
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendNewRegisterInterestResponseChunk(region, keyInfo != null ? keyInfo : "ALL_KEYS", values, true, servConn);
+   }
+ 
+   /**
+    * Copied from Get70.getValueAndIsObject(), except a minor change. (Make the
+    * method static instead of copying it here?)
+    * 
+    * @param value
+    */
+   private static void updateValues(VersionedObjectList values, Object key, Object value, VersionTag versionTag) {
+     boolean isObject = true;
+ 
+     // If the value in the VM is a CachedDeserializable,
+     // get its value. If it is Token.REMOVED, Token.DESTROYED,
+     // Token.INVALID, or Token.LOCAL_INVALID
+     // set it to null. If it is NOT_AVAILABLE, get the value from
+     // disk. If it is already a byte[], set isObject to false.
+     boolean wasInvalid = false;
+     if (value instanceof CachedDeserializable) {
+       value = ((CachedDeserializable)value).getValue();
+     }
+     else if (value == Token.REMOVED_PHASE1 || value == Token.REMOVED_PHASE2 || value == Token.DESTROYED || value == Token.TOMBSTONE) {
+       value = null;
+     }
+     else if (value == Token.INVALID || value == Token.LOCAL_INVALID) {
+       value = null; // fix for bug 35884
+       wasInvalid = true;
+     }
+     else if (value instanceof byte[]) {
+       isObject = false;
+     }
+     boolean keyNotPresent = !wasInvalid && (value == null || value == Token.TOMBSTONE);
+ 
+     if (keyNotPresent) {
+       values.addObjectPartForAbsentKey(key, value, versionTag);
+     } else {
+       values.addObjectPart(key, value, isObject, versionTag);
+     }
+   }
+ 
+   public static void appendNewRegisterInterestResponseChunkFromLocal(LocalRegion region,
+       VersionedObjectList values, Object riKeys, Set keySet, ServerConnection servConn)
+       throws IOException {
+     Object key = null;
+     EntryEventImpl versionHolder = null;
+     ClientProxyMembershipID requestingClient = servConn == null ? null : servConn.getProxyID();
+     for (Iterator it = keySet.iterator(); it.hasNext();) {
+       key = it.next();
+       versionHolder = EntryEventImpl.createVersionTagHolder();
+ 
+       Object value = region.get(key, null, true, true, true, requestingClient, versionHolder, true, false);
+       
+       updateValues(values, key, value, versionHolder.getVersionTag());
+ 
+       if (values.size() == maximumChunkSize) {
+         // Send the chunk and clear the list
+         // values.setKeys(null); // Now we need to send keys too.
+         sendNewRegisterInterestResponseChunk(region, riKeys != null ? riKeys : "ALL_KEYS", values, false, servConn);
+         values.clear();
+       }
+     } // for
+   }
+ 
+   /**
+    * 
+    * @param region
+    * @param values {@link VersionedObjectList}
+    * @param riKeys
+    * @param set set of entries
+    * @param servConn
+    * @throws IOException
+    */
+   public static void appendNewRegisterInterestResponseChunk(LocalRegion region,
+       VersionedObjectList values, Object riKeys, Set set, ServerConnection servConn)
+       throws IOException {
+     for (Iterator<Map.Entry> it = set.iterator(); it.hasNext();) {
+       Map.Entry entry = it.next(); // Region.Entry or Map.Entry
+       if (entry instanceof Region.Entry) { // local entries
+         VersionTag vt = null;
+         Object key = null;
+         Object value = null;
+         if (entry instanceof EntrySnapshot) {
+           vt = ((EntrySnapshot) entry).getVersionTag();
+           key = ((EntrySnapshot) entry).getRegionEntry().getKey();
+           value = ((EntrySnapshot) entry).getRegionEntry().getValue(null);
+           updateValues(values, key, value, vt);
+         } else {
+           VersionStamp vs = ((NonTXEntry)entry).getRegionEntry().getVersionStamp();
+           vt = vs == null ? null : vs.asVersionTag();
+           key = entry.getKey();
+           value = ((NonTXEntry)entry).getRegionEntry()._getValueRetain(region, true);
+           try {
+             updateValues(values, key, value, vt);
+           } finally {
+             // TODO OFFHEAP: in the future we might want to delay this release
+             // until the "values" VersionedObjectList is released.
+             // But for now "updateValues" copies the off-heap value to the heap.
+             OffHeapHelper.release(value);
+           }
+         }
+       } else { // Map.Entry (remote entries)
+         ArrayList list = (ArrayList)entry.getValue();
+         Object value = list.get(0);
+         VersionTag tag = (VersionTag)list.get(1);
+         updateValues(values, entry.getKey(), value, tag);
+       }
+       if (values.size() == maximumChunkSize) {
+         // Send the chunk and clear the list
+         // values.setKeys(null); // Now we need to send keys too.
+         sendNewRegisterInterestResponseChunk(region, riKeys != null ? riKeys : "ALL_KEYS", values, false, servConn);
+         values.clear();
+       }
+     } // for
+   }
+ 
+   public static void sendNewRegisterInterestResponseChunk(LocalRegion region,
+       Object riKey, VersionedObjectList list, boolean lastChunk, ServerConnection servConn)
+       throws IOException {
+     ChunkedMessage chunkedResponseMsg = servConn.getRegisterInterestResponseMessage();
+     chunkedResponseMsg.setNumberOfParts(1);
+     chunkedResponseMsg.setLastChunk(lastChunk);
+     chunkedResponseMsg.addObjPart(list, zipValues);
+     String regionName = (region == null) ? " null " : region.getFullPath();
+     if (logger.isDebugEnabled()) {
+       String str = servConn.getName() + ": Sending"
+           + (lastChunk ? " last " : " ")
+           + "register interest response chunk for region: " + regionName
+           + " for keys: " + riKey + " chunk=<" + chunkedResponseMsg + ">";
+       logger.debug(str);
+     }
+ 
+     chunkedResponseMsg.sendChunk(servConn);
+   }
+ 
+   /**
+    * Process an interest request of type {@link InterestType#REGULAR_EXPRESSION}
+    *
+    * @param region
+    *                the region
+    * @param regex
+    *                the regex
+    * @param policy
+    *                the policy
+    * @throws IOException
+    */
+   private static void handleRegEx(LocalRegion region, String regex,
+       InterestResultPolicy policy, ServerConnection servConn)
+       throws IOException {
+     if (region instanceof PartitionedRegion) {
+       // too bad java doesn't provide another way to do this...
+       handleRegExPR((PartitionedRegion)region, regex, policy, servConn);
+       return;
+     }
+     ArrayList keyList = new ArrayList(maximumChunkSize);
+     // Handle the regex pattern
+     Pattern keyPattern = Pattern.compile(regex);
+     if (region != null) {
+       for (Iterator it = region.keySet(sendTombstonesInRIResults(servConn, policy)).iterator(); it.hasNext();) {
+         Object entryKey = it.next();
+         if (!(entryKey instanceof String)) {
+           // key is not a String, cannot apply regex to this entry
+           continue;
+         }
+         if (!keyPattern.matcher((String)entryKey).matches()) {
+           // key does not match the regex, this entry should not be returned.
+           continue;
+         }
+ 
+         appendInterestResponseKey(region, regex, entryKey, keyList, "regex",
+             servConn);
+       }
+     }
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendRegisterInterestResponseChunk(region, regex, keyList, true, servConn);
+   }
+ 
+   /**
+    * Process an interest request of type {@link InterestType#REGULAR_EXPRESSION}
+    *
+    * @param region
+    *                the region
+    * @param regex
+    *                the regex
+    * @param policy
+    *                the policy
+    * @throws IOException
+    */
+   private static void handleRegExPR(final PartitionedRegion region,
+       final String regex, final InterestResultPolicy policy,
+       final ServerConnection servConn) throws IOException {
+     final ArrayList keyList = new ArrayList(maximumChunkSize);
+     region.getKeysWithRegEx(regex, sendTombstonesInRIResults(servConn, policy), new PartitionedRegion.SetCollector() {
+       public void receiveSet(Set theSet) throws IOException {
+         appendInterestResponseKeys(region, regex, theSet, keyList, "regex",
+             servConn);
+       }
+     });
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendRegisterInterestResponseChunk(region, regex, keyList, true, servConn);
+   }
+ 
+   /**
+    * Process an interest request involving a list of keys
+    *
+    * @param region
+    *                the region
+    * @param keyList
+    *                the list of keys
+    * @param policy
+    *                the policy
+    * @throws IOException
+    */
+   private static void handleListPR(final PartitionedRegion region,
+       final List keyList, final InterestResultPolicy policy,
+       final ServerConnection servConn) throws IOException {
+     final ArrayList newKeyList = new ArrayList(maximumChunkSize);
+     region.getKeysWithList(keyList, sendTombstonesInRIResults(servConn, policy), new PartitionedRegion.SetCollector() {
+       public void receiveSet(Set theSet) throws IOException {
+         appendInterestResponseKeys(region, keyList, theSet, newKeyList, "list",
+             servConn);
+       }
+     });
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendRegisterInterestResponseChunk(region, keyList, newKeyList, true,
+         servConn);
+   }
+ 
+   @SuppressWarnings("rawtypes")
+   private static void handleKVList(final LocalRegion region,
+       final List keyList, boolean serializeValues,
+       final ServerConnection servConn) throws IOException {
+ 
+     if (region != null && region instanceof PartitionedRegion) {
+       handleKVKeysPR((PartitionedRegion)region, keyList, serializeValues, servConn);
+       return;
+     }
+     VersionedObjectList values = new VersionedObjectList(maximumChunkSize,
+         true, region == null ? true : region.getAttributes()
+             .getConcurrencyChecksEnabled(), serializeValues);
+ 
+     // Handle list of keys
+     if (region != null) {
+       VersionTag versionTag = null;
+       Object data = null;
+ 
+       for (Iterator it = keyList.iterator(); it.hasNext();) {
+         Object key = it.next();
+         if (region.containsKey(key) || region.containsTombstone(key)) {
+           EntryEventImpl versionHolder = EntryEventImpl
+               .createVersionTagHolder();
+ 
+           ClientProxyMembershipID id = servConn == null ? null : servConn
+               .getProxyID();
+           data = region.get(key, null, true, true, true, id, versionHolder,
+               true, false);
+           versionTag = versionHolder.getVersionTag();
+           updateValues(values, key, data, versionTag);
+ 
+           if (values.size() == maximumChunkSize) {
+             // Send the chunk and clear the list
+             // values.setKeys(null); // Now we need to send keys too.
+             sendNewRegisterInterestResponseChunk(region, keyList, values, false, servConn);
+             values.clear();
+           }
+         }
+       }
+     }
+     // Send the last chunk (the only chunk for individual and list keys)
+     // always send it back, even if the list is of zero size.
+     sendNewRegisterInterestResponseChunk(region, keyList, values, true, servConn);
+   }
+ 
+   /**
+    * Append an interest response
+    *
+    * @param region
+    *                the region (for debugging)
+    * @param riKey
+    *                the registerInterest "key" (what the client is interested
+    *                in)
+    * @param entryKey
+    *                key we're responding to
+    * @param list
+    *                list to append to
+    * @param kind
+    *                for debugging
+    */
+   private static void appendInterestResponseKey(LocalRegion region,
+       Object riKey, Object entryKey, ArrayList list, String kind,
+       ServerConnection servConn) throws IOException {
+     list.add(entryKey);
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: appendInterestResponseKey <{}>; list size was {}; region: {}",
+           servConn.getName(), entryKey, list.size(), region.getFullPath());
+     }
+     if (list.size() == maximumChunkSize) {
+       // Send the chunk and clear the list
+       sendRegisterInterestResponseChunk(region, riKey, list, false, servConn);
+       list.clear();
+     }
+   }
+ 
+   protected static void appendInterestResponseKeys(LocalRegion region,
+       Object riKey, Collection entryKeys, ArrayList collector, String riDescr,
+       ServerConnection servConn) throws IOException {
+     for (Iterator it = entryKeys.iterator(); it.hasNext();) {
+       appendInterestResponseKey(region, riKey, it.next(), collector, riDescr,
+           servConn);
+     }
+   }
+ }


[004/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionReliabilityTestCase.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionReliabilityTestCase.java
index 2ae8293,0000000..8cc65d3
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionReliabilityTestCase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/RegionReliabilityTestCase.java
@@@ -1,1450 -1,0 +1,1463 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.ByteArrayOutputStream;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.concurrent.locks.Lock;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.AttributesMutator;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.CommitDistributionException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.ExpirationAction;
 +import com.gemstone.gemfire.cache.ExpirationAttributes;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.LossAction;
 +import com.gemstone.gemfire.cache.MembershipAttributes;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAccessException;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDistributionException;
 +import com.gemstone.gemfire.cache.RegionEvent;
 +import com.gemstone.gemfire.cache.RegionMembershipListener;
 +import com.gemstone.gemfire.cache.RegionReinitializedException;
 +import com.gemstone.gemfire.cache.RequiredRoles;
 +import com.gemstone.gemfire.cache.ResumptionAction;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.util.RegionMembershipListenerAdapter;
 +import com.gemstone.gemfire.distributed.Role;
 +import com.gemstone.gemfire.distributed.internal.DM;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalRole;
 +import com.gemstone.gemfire.internal.cache.AbstractRegion;
 +import com.gemstone.gemfire.internal.cache.DistributedCacheOperation;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.TXState;
 +import com.gemstone.gemfire.internal.cache.TXStateInterface;
 +import com.gemstone.gemfire.internal.cache.TXStateProxyImpl;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
++import com.gemstone.gemfire.test.dunit.SerializableRunnableIF;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * Tests region reliability defined by MembershipAttributes.
 + *
 + * @author Kirk Lund
 + * @since 5.0
 + */
 +public abstract class RegionReliabilityTestCase extends ReliabilityTestCase {
 +
 +  public RegionReliabilityTestCase(String name) {
 +    super(name);
 +  }
 +
 +  @Override
 +  protected final void preTearDownCacheTestCase() throws Exception {
 +    DistributedCacheOperation.setBeforePutOutgoing(null);
 +  }
 +
 +  // -------------------------------------------------------------------------
 +  // Configuration and setup methods
 +  // -------------------------------------------------------------------------
 +  
 +  /** Returns scope to execute tests under. */
 +  protected abstract Scope getRegionScope();
 +  
 +  protected InternalDistributedSystem createConnection(String[] roles) {
 +    StringBuffer rolesValue = new StringBuffer();
 +    if (roles != null) {
 +      for (int i = 0; i < roles.length; i++) {
 +        if (i > 0) {
 +          rolesValue.append(",");
 +        }
 +        rolesValue.append(roles[i]);
 +      }
 +    }
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, rolesValue.toString());
 +    return getSystem(config);
 +  }
 +
 +  protected void assertLimitedAccessThrows(Region region) throws Exception {
 +    try {
 +      region.clear();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.create("KEY", "VAL");
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.destroy(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.destroyRegion();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    if (region.getAttributes().getScope().isGlobal()) {
 +      try {
 +        region.becomeLockGrantor();
 +        fail("Should have thrown an RegionAccessException");
 +      } catch (RegionAccessException ex) {
 +        // pass...
 +      }
 +      try {
 +        region.getDistributedLock(new Object());
 +        fail("Should have thrown an RegionAccessException");
 +      } catch (RegionAccessException ex) {
 +        // pass...
 +      }
 +      try {
 +        region.getRegionDistributedLock();
 +        fail("Should have thrown an RegionAccessException");
 +      } catch (RegionAccessException ex) {
 +        // pass...
 +      }
 +    }
 +    try {
 +      region.invalidate(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.invalidateRegion();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.loadSnapshot(new ByteArrayInputStream(new byte[] {}));
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try { // netload TODO: configure CacheLoader in region
 +      region.get("netload");
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try { // netsearch TODO: add 2nd VM that has the object
 +      region.get("netsearch");
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.put(new Object(), new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      Map map = new HashMap();
 +      map.put(new Object(), new Object());
 +      region.putAll(map);
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      Map map = new HashMap();
 +      map.put(new Object(), new Object());
 +      region.putAll(map, "callbackArg");
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.remove(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    if (!region.getAttributes().getScope().isGlobal()) {
 +      CacheTransactionManager tx = region.getCache().getCacheTransactionManager();
 +      tx.begin();
 +      try {
 +        region.put("KEY-tx", "VAL-tx");
 +        fail("Should have thrown an RegionAccessException");
 +      } catch (RegionAccessException ex) {
 +        // pass...
 +      }
 +      tx.rollback();
 +    }
 +  }
 +  
 +  protected void assertNoAccessThrows(Region region) throws Exception {
 +    assertLimitedAccessThrows(region);
 +    try {
 +      region.containsKey(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.containsValue(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.containsValueForKey(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.entries(false);
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.entrySet();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.get(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.getEntry(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.isEmpty();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.keys();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.keySet();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.localDestroy(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.localInvalidate(new Object());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.localInvalidateRegion();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.saveSnapshot(new ByteArrayOutputStream());
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.size();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    try {
 +      region.values();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +    
 +    try {
 +      QueryService qs = region.getCache().getQueryService();
 +      Query query = qs.newQuery(
 +        "(select distinct * from " + region.getFullPath() + ").size");
 +      query.execute();
 +      fail("Should have thrown an RegionAccessException");
 +    } catch (RegionAccessException ex) {
 +      // pass...
 +    }
 +  }
 +  
 +  protected void assertLimitedAccessDoesNotThrow(Region region) throws Exception {
 +    // insert some values for test
 +    Object[] keys = new Object[] {"hip", "hop"};
 +    Object[] values = new Object[] {"clip", "clop"};
 +    for (int i = 0; i < keys.length; i++) {
 +      region.put(keys[i], values[i]);
 +    }
 +
 +    // test the ops that can throw RegionAccessException for LIMITED_ACCESS
 +    region.create("jack", "jill");
 +    region.destroy("jack");
 +    
 +    if (region.getAttributes().getScope().isGlobal()) {
 +      region.becomeLockGrantor();
 +
 +      Lock dlock = region.getDistributedLock(keys[0]);
 +      dlock.lock();
 +      dlock.unlock();
 +      
 +      Lock rlock = region.getRegionDistributedLock();
 +      rlock.lock();
 +      rlock.unlock();
 +    }
 +    
 +    // netload (configured in vm0)
 +    assertEquals("netload", region.get("netload"));
 +    // netsearch (entry exists in vm0)
 +    assertEquals("netsearch", region.get("netsearch"));
 +    
 +    region.invalidate(keys[0]);
 +    region.invalidateRegion();
 +    
 +    ByteArrayOutputStream baos = new ByteArrayOutputStream();
 +    region.saveSnapshot(baos);
 +    region.loadSnapshot(new ByteArrayInputStream(baos.toByteArray()));
 +    
 +    // need to get a new handle to the region...
 +    region = getRootRegion(region.getFullPath());
 +    
 +    region.put(keys[0], values[0]);
 +
 +    Map map = new HashMap();
 +    map.put("mom", "pop");
 +    region.putAll(map);
 +    region.putAll(map, "callbackArg");
 +
 +    QueryService qs = region.getCache().getQueryService();
 +    Query query = qs.newQuery(
 +      "(select distinct * from " + region.getFullPath() + ").size");
 +    query.execute();
 +    
 +    region.remove(keys[0]);
 +
 +    if (!region.getAttributes().getScope().isGlobal()) {
 +      CacheTransactionManager tx = region.getCache().getCacheTransactionManager();
 +      tx.begin();
 +      region.put("KEY-tx", "VAL-tx");
 +      tx.commit();
 +    }
 +    
 +    region.clear();
 +    region.destroyRegion();
 +  }
 +  
 +  protected void assertNoAccessDoesNotThrow(Region region) throws Exception {
 +    // insert some values for test
 +    Object[] keys = new Object[] {"bip", "bam"};
 +    Object[] values = new Object[] {"foo", "bar"};
 +    for (int i = 0; i < keys.length; i++) {
 +      region.put(keys[i], values[i]);
 +    }
 +    
 +    // test the ops that can throw RegionAccessException for NO_ACCESS
 +    region.containsKey(new Object());
 +    region.containsValue(new Object());
 +    region.containsValueForKey(new Object());
 +    region.entries(false);
 +    region.entrySet();
 +    region.get(keys[0]);
 +    region.getEntry(keys[0]);
 +    region.isEmpty();
 +    region.keys();
 +    region.keySet();
 +    region.localDestroy(keys[0]);
 +    region.localInvalidate(keys[1]);
 +    region.localInvalidateRegion();
 +    region.saveSnapshot(new ByteArrayOutputStream());
 +    region.size();
 +    region.values();
 +
 +    QueryService qs = region.getCache().getQueryService();
 +    Query query = qs.newQuery(
 +      "(select distinct * from " + region.getFullPath() + ").size");
 +    query.execute();
 +    
 +    assertLimitedAccessDoesNotThrow(region);
 +  }
 +  
 +  protected void sleep(long millis) {
 +    try {
 +      Thread.sleep(millis);
 +    }
 +    catch (InterruptedException e) {
 +      fail("interrupted");
 +    }
 +  }
 +  
 +  // -------------------------------------------------------------------------
 +  // Tests to be run under every permutation of config options
 +  //   Valid configurations include scope D-ACK, D-NOACK, GLOBAL
 +  // -------------------------------------------------------------------------
 +  
 +  /**
 +   * Tests affect of NO_ACCESS on region operations.
 +   */
 +  public void testNoAccess() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.NO_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    Region region = createRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    // use vm0 for netsearch and netload
 +    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(null);
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        fac.setCacheLoader(new CacheLoader() {
 +          public Object load(LoaderHelper helper) throws CacheLoaderException {
 +            if ("netload".equals(helper.getKey())) {
 +              return "netload";
 +            } else {
 +              return null;
 +            }
 +          }
 +          public void close() {}
 +        });
 +        RegionAttributes attr = fac.create();
 +        Region region = createRootRegion(name, attr);
 +        Object netsearch = "netsearch";
 +        region.put(netsearch, netsearch);
 +      }
 +    });
 +    
 +    // test ops on Region that should throw
 +    assertNoAccessThrows(region);
 +    
 +    // use vm1 to create role
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    Role role = (Role) requiredRolesSet.iterator().next();
 +    assertTrue(RequiredRoles.isRoleInRegionMembership(region, role));
 +    
 +    // retest ops on Region to assert no longer throw    
 +    assertNoAccessDoesNotThrow(region);
 +  }
 +  
 +  private static InternalDistributedMember findDistributedMember() {
 +    DM dm = (
 +      InternalDistributedSystem.getAnyInstance()).getDistributionManager();
 +    return dm.getDistributionManagerId();
 +  }
 +  
 +  /**
 +   * Tests affect of NO_ACCESS on local entry expiration actions.
 +   */
 +  public void testNoAccessWithLocalEntryExpiration() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.NO_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    final Region region = createExpiryRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    // use vm1 to create role
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    // test to make sure expiration is not suspended
 +    region.put("expireMe", "expireMe");
 +    assertTrue(region.size() == 1);
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Close Region") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion(name);
 +        region.close();
 +      }
 +    });
 +    //TODO: waitForMemberTimeout(); ?
 +
 +    // set expiration and sleep
 +    AttributesMutator mutator = region.getAttributesMutator();
 +    mutator.setEntryTimeToLive(
 +      new ExpirationAttributes(1, ExpirationAction.LOCAL_DESTROY));
 +    sleep(200);
 +
 +    // make sure no values were expired
 +    Set entries = ((LocalRegion) region).basicEntries(false);
 +    assertTrue(entries.size() == 1);
 +    
 +    // create region again in vm1
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    waitForEntryDestroy(region, "expireMe");
 +  }
 +  
 +  /**
 +   * Tests affect of NO_ACCESS on local region expiration actions.
 +   */
 +  public void testNoAccessWithLocalRegionExpiration() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.NO_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    final Region region = createExpiryRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    AttributesMutator mutator = region.getAttributesMutator();
 +    mutator.setRegionTimeToLive(
 +      new ExpirationAttributes(1, ExpirationAction.LOCAL_DESTROY));
 +      
 +    // sleep and make sure region does not expire
 +    sleep(200);
 +    assertFalse(region.isDestroyed());
 +    
 +    // create region in vm1
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    waitForRegionDestroy(region);
 +  }
 +  
 +  /**
 +   * Tests affect of LIMITED_ACCESS on region operations.
 +   */
 +  public void testLimitedAccess() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.LIMITED_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    Region region = createRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    // use vm0 for netsearch and netload
 +    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(null);
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        fac.setCacheLoader(new CacheLoader() {
 +          public Object load(LoaderHelper helper) throws CacheLoaderException {
 +            if ("netload".equals(helper.getKey())) {
 +              return "netload";
 +            } else {
 +              return null;
 +            }
 +          }
 +          public void close() {}
 +        });
 +        RegionAttributes attr = fac.create();
 +        Region region = createRootRegion(name, attr);
 +        Object netsearch = "netsearch";
 +        region.put(netsearch, netsearch);
 +      }
 +    });
 +    
 +    // test ops on Region that should throw
 +    assertLimitedAccessThrows(region);
 +    
 +    // this query should not throw
 +    QueryService qs = region.getCache().getQueryService();
 +    Query query = qs.newQuery(
 +      "(select distinct * from " + region.getFullPath() + ").size");
 +    query.execute();
 +    
 +    // use vm1 to create role
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    // retest ops on Region to assert no longer throw    
 +    assertLimitedAccessDoesNotThrow(region);
 +  }
 +  
 +  /**
 +   * Tests affect of LIMITED_ACCESS on local entry expiration actions.
 +   */
 +  public void testLimitedAccessWithLocalEntryExpiration() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.LIMITED_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    final Region region = createExpiryRootRegion(name, attr);
 +     
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    // use vm1 to create role
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    // test to make sure expiration is suspended
 +    region.put("expireMe", "expireMe");
 +    assertTrue(region.size() == 1);
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Close Region") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion(name);
 +        region.close();
 +      }
 +    });
 +    //TODO: waitForMemberTimeout(); ?
 +
 +    // set expiration and sleep
 +    AttributesMutator mutator = region.getAttributesMutator();
 +    mutator.setEntryTimeToLive(
 +      new ExpirationAttributes(1, ExpirationAction.LOCAL_DESTROY));
 +    WaitCriterion wc1 = new WaitCriterion() {
 +      public boolean done() {
 +        return ((LocalRegion) region).basicEntries(false).size() == 0;
 +      }
 +      public String description() {
 +        return "expected zero entries but have " + ((LocalRegion) region).basicEntries(false).size();
 +      }
 +    };
 +    Wait.waitForCriterion(wc1, 30*1000, 10, true);
 +
 +    // create region again
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    region.put("expireMe", "expireMe");
 +    
 +    waitForEntryDestroy(region, "expireMe");
 +    assertTrue(region.size() == 0);
 +  }
 +  
 +  /**
 +   * Tests affect of LIMITED_ACCESS on local region expiration actions.
 +   */
 +  public void testLimitedAccessWithLocalRegionExpiration() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.LIMITED_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    final Region region = createExpiryRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    AttributesMutator mutator = region.getAttributesMutator();
 +    mutator.setRegionTimeToLive(
 +      new ExpirationAttributes(1, ExpirationAction.LOCAL_DESTROY));
 +      
 +    waitForRegionDestroy(region);
 +  }
 +  
 +  /**
 +   * Tests affect of FULL_ACCESS on region operations.
 +   */
 +  public void testFullAccess() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.FULL_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    Region region = createRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    // use vm0 for netsearch and netload
 +    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(null);
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        fac.setCacheLoader(new CacheLoader() {
 +          public Object load(LoaderHelper helper) throws CacheLoaderException {
 +            if ("netload".equals(helper.getKey())) {
 +              return "netload";
 +            } else {
 +              return null;
 +            }
 +          }
 +          public void close() {}
 +        });
 +        RegionAttributes attr = fac.create();
 +        Region region = createRootRegion(name, attr);
 +        Object netsearch = "netsearch";
 +        region.put(netsearch, netsearch);
 +      }
 +    });
 +    
 +    // test ops on Region that should not throw
 +    assertNoAccessDoesNotThrow(region);
 +  }
 +  
 +  /**
 +   * Tests affect of FULL_ACCESS on local entry expiration actions.
 +   */
 +  public void testFullAccessWithLocalEntryExpiration() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    // assign names to 4 vms...
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.FULL_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    final Region region = createExpiryRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    // test to make sure expiration is not suspended
 +    region.put("expireMe", "expireMe");
 +    assertTrue(region.size() == 1);
 +
 +    // set expiration and sleep
 +    AttributesMutator mutator = region.getAttributesMutator();
 +    mutator.setEntryTimeToLive(
 +      new ExpirationAttributes(1, ExpirationAction.LOCAL_DESTROY));
 +
 +    waitForEntryDestroy(region, "expireMe");
 +    assertTrue(region.size() == 0);
 +  }
 +  
 +  public static void waitForRegionDestroy(final Region region) {
 +    WaitCriterion wc = new WaitCriterion() {
 +      public boolean done() {
 +        return region.isDestroyed();
 +      }
 +      public String description() {
 +        return "expected region " + region + " to be destroyed";
 +      }
 +    };
 +    Wait.waitForCriterion(wc, 30*1000, 10, true);
 +  }
 +  
 +  public static void waitForEntryDestroy(final Region region, final Object key) {
 +    WaitCriterion wc = new WaitCriterion() {
 +      public boolean done() {
 +        return region.get(key) == null;
 +      }
 +      public String description() {
 +        return "expected entry " + key + " to not exist but it has the value " + region.get(key);
 +      }
 +    };
 +    Wait.waitForCriterion(wc, 30*1000, 10, true);
 +  }
 +  
 +  /**
 +   * Tests affect of FULL_ACCESS on local region expiration actions.
 +   */
 +  public void testFullAccessWithLocalRegionExpiration() throws Exception {
 +    final String name = this.getUniqueName();
 +    
 +    final String roleA = name+"-A";
 +    
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.FULL_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setStatisticsEnabled(true);
 +    RegionAttributes attr = fac.create();
 +    final Region region = createExpiryRootRegion(name, attr);
 +    
 +    // wait for memberTimeout to expire
 +    waitForMemberTimeout();
 +
 +    AttributesMutator mutator = region.getAttributesMutator();
 +    mutator.setRegionTimeToLive(
 +      new ExpirationAttributes(1, ExpirationAction.LOCAL_DESTROY));
 +      
 +    waitForRegionDestroy(region);
 +  }
 +  
 +  protected static Boolean[] detectedDeparture_testCommitDistributionException = 
 +    { Boolean.FALSE };
 +  public void testCommitDistributionException() throws Exception {
 +    if (getRegionScope().isGlobal()) return; // skip test under Global
 +    if (getRegionScope().isDistributedNoAck()) return; // skip test under DistributedNoAck
 +    
 +    final String name = this.getUniqueName();
 +    final String roleA = name+"-A";
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
 +    
 +    RegionMembershipListener listener = new RegionMembershipListenerAdapter() {
 +      public void afterRemoteRegionDeparture(RegionEvent event) {
 +        synchronized (detectedDeparture_testCommitDistributionException) {
 +          detectedDeparture_testCommitDistributionException[0] = Boolean.TRUE;
 +          detectedDeparture_testCommitDistributionException.notify();
 +        }
 +      }
 +    };
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.NO_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.addCacheListener(listener);
 +    RegionAttributes attr = fac.create();
 +    Region region = createRootRegion(name, attr);
 +    
 +    // use vm1 to create role
 +    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    // define the afterReleaseLocalLocks callback
-     Runnable removeRequiredRole = new SerializableRunnable() {
++    SerializableRunnableIF removeRequiredRole = new SerializableRunnableIF() {
 +      public void run() {
 +        Host.getHost(0).getVM(1).invoke(new SerializableRunnable("Close Region") {
 +          public void run() {
 +            getRootRegion(name).close();
 +          }
 +        });
 +        try {
 +          synchronized (detectedDeparture_testCommitDistributionException) {
 +            while (detectedDeparture_testCommitDistributionException[0] == Boolean.FALSE) {
 +              detectedDeparture_testCommitDistributionException.wait();
 +            }
 +          }
 +        }
 +        catch (InterruptedException e) {fail("interrupted");}
 +      }
 +    };
 +    
 +    // define the add and remove expected exceptions
 +    final String expectedExceptions = 
 +      "com.gemstone.gemfire.internal.cache.CommitReplyException";
 +    SerializableRunnable addExpectedExceptions = 
 +      new CacheSerializableRunnable("addExpectedExceptions") {
 +        public void run2() throws CacheException {
 +          getCache().getLogger().info("<ExpectedException action=add>" + 
 +              expectedExceptions + "</ExpectedException>");
 +        }
 +      };
 +    SerializableRunnable removeExpectedExceptions = 
 +      new CacheSerializableRunnable("removeExpectedExceptions") {
 +        public void run2() throws CacheException {
 +          getCache().getLogger().info("<ExpectedException action=remove>" + 
 +              expectedExceptions + "</ExpectedException>");
 +        }
 +      };
 +
 +    // perform the actual test...
 +      
 +    CacheTransactionManager ctm = cache.getCacheTransactionManager();
 +    ctm.begin();
 +    TXStateInterface txStateProxy = ((TXManagerImpl)ctm).getTXState();
 +    ((TXStateProxyImpl)txStateProxy).forceLocalBootstrap();
 +    TXState txState = (TXState)((TXStateProxyImpl)txStateProxy).getRealDeal(null,null);
-     txState.setBeforeSend(removeRequiredRole);
++    txState.setBeforeSend(() -> {
++      try { 
++        removeRequiredRole.run(); 
++      } catch(Exception e) {
++        throw new RuntimeException(e);
++      }
++    });
 +    
 +    // now start a transaction and commit it
 +    region.put("KEY", "VAL");
 +      
 +    addExpectedExceptions.run();
 +    Host.getHost(0).getVM(1).invoke(addExpectedExceptions);
 +    
 +    try {
 +      ctm.commit();
 +      fail("Should have thrown CommitDistributionException");
 +    }
 +    catch (CommitDistributionException e) {
 +      // pass
 +    }
 +    finally {
 +      removeExpectedExceptions.run();
 +      Host.getHost(0).getVM(1).invoke(removeExpectedExceptions);
 +    }
 +  }
 +  
 +  protected static Boolean[] detectedDeparture_testRegionDistributionException = 
 +    { Boolean.FALSE };
 +  public void testRegionDistributionException() throws Exception {
 +    if (getRegionScope().isDistributedNoAck()) return; // skip test under DistributedNoAck
 +    
 +    final String name = this.getUniqueName();
 +    final String roleA = name+"-A";
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    RegionMembershipListener listener = new RegionMembershipListenerAdapter() {
 +      public void afterRemoteRegionDeparture(RegionEvent event) {
 +        synchronized (detectedDeparture_testRegionDistributionException) {
 +          detectedDeparture_testRegionDistributionException[0] = Boolean.TRUE;
 +          detectedDeparture_testRegionDistributionException.notify();
 +        }
 +      }
 +    };
 +
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.NO_ACCESS, ResumptionAction.NONE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +//    fac.addCacheListener(listener);
 +    RegionAttributes attr = fac.create();
 +    Region region = createRootRegion(name, attr);
 +    
 +    assertTrue(((AbstractRegion)region).requiresReliabilityCheck());
 +    
 +    // use vm1 to create role
 +    CacheSerializableRunnable createRegion = new CacheSerializableRunnable("Create Region") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    };
 +    
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    region.put("DESTROY_ME", "VAL");
 +    region.put("INVALIDATE_ME", "VAL");
 +      
 +    // define the afterReleaseLocalLocks callback
-     Runnable removeRequiredRole = new SerializableRunnable() {
++    SerializableRunnable removeRequiredRole = new SerializableRunnable() {
 +      public void run() {
 +        Host.getHost(0).getVM(1).invoke(new SerializableRunnable("Close Region") {
 +          public void run() {
 +            getRootRegion(name).close();
 +          }
 +        });
 +//        try {
 +//          synchronized (detectedDeparture_testRegionDistributionException) {
 +//            while (detectedDeparture_testRegionDistributionException[0] == Boolean.FALSE) {
 +//              detectedDeparture_testRegionDistributionException.wait();
 +//            }
 +//          }
 +//        }
 +//        catch (InterruptedException e) {}
 +      }
 +    };
-     DistributedCacheOperation.setBeforePutOutgoing(removeRequiredRole);
++    DistributedCacheOperation.setBeforePutOutgoing(() -> {
++     try {
++       removeRequiredRole.run();
++     } catch(Exception e) {
++       throw new RuntimeException(e);
++     }
++    });
 +
 +    Runnable reset = new Runnable() {
 +      public void run() {
 +//        synchronized (detectedDeparture_testRegionDistributionException) {
 +//          detectedDeparture_testRegionDistributionException[0] = Boolean.FALSE;
 +//        }
 +      }
 +    };
 +    
 +    // PUT    
 +    try {
 +      region.put("KEY", "VAL");
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +    
 +    // INVALIDATE
 +    reset.run();
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    try {
 +      region.invalidate("INVALIDATE_ME");
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +    
 +    // DESTROY
 +    reset.run();
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    try {
 +      region.destroy("DESTROY_ME");
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +
 +    // CLEAR
 +    reset.run();
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    try {
 +      region.clear();
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +    
 +    // PUTALL
 +    reset.run();
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    try {
 +      Map putAll = new HashMap();
 +      putAll.put("PUTALL_ME", "VAL");
 +      region.putAll(putAll);
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +    
 +    // INVALIDATE REGION
 +    reset.run();
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    try {
 +      region.invalidateRegion();
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +    
 +    // DESTROY REGION
 +    reset.run();
 +    Host.getHost(0).getVM(1).invoke(createRegion);
 +    try {
 +      region.destroyRegion();
 +      fail("Should have thrown RegionDistributionException");
 +    }
 +    catch (RegionDistributionException e) {
 +      // pass
 +    }
 +  }
 +
 +  public void testReinitialization() throws Exception {
 +    final String name = this.getUniqueName();
 +    final String roleA = name+"-A";
 +    final String[] requiredRoles = {roleA};
 +    Set requiredRolesSet = new HashSet();
 +    for (int i = 0; i < requiredRoles.length; i++) {
 +      requiredRolesSet.add(InternalRole.getRole(requiredRoles[i]));
 +    }
 +    assertEquals(requiredRoles.length, requiredRolesSet.size());
 +
 +    // connect controller to system...
 +    Properties config = new Properties();
 +    config.setProperty(DistributionConfig.ROLES_NAME, "");
 +    getSystem(config);
 +    
 +    getCache();
 +    
 +    // create region in controller...
 +    MembershipAttributes ra = new MembershipAttributes(
 +        requiredRoles, LossAction.NO_ACCESS, ResumptionAction.REINITIALIZE);
 +    AttributesFactory fac = new AttributesFactory();
 +    fac.setMembershipAttributes(ra);
 +    fac.setScope(getRegionScope());
 +    fac.setDataPolicy(DataPolicy.REPLICATE);
 +    RegionAttributes attr = fac.create();
 +    Region region = createRootRegion(name, attr);
 +    
 +    assertTrue(((AbstractRegion)region).requiresReliabilityCheck());
 +    assertFalse(RequiredRoles.checkForRequiredRoles(region).isEmpty());
 +
 +    final String key = "KEY-testReinitialization";
 +    final String val = "VALUE-testReinitialization";
 +    
 +    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("Create Data") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        fac.setDataPolicy(DataPolicy.REPLICATE);
 +        RegionAttributes attr = fac.create();
 +        Region region = createRootRegion(name, attr);
 +        region.put(key, val);
 +      }
 +    });
 +
 +    final Region finalRegion = region;
 +    Thread thread = new Thread(new Runnable() {
 +      public void run() {
 +        try {
 +          RequiredRoles.waitForRequiredRoles(finalRegion, -1);
 +        } 
 +        catch (InterruptedException e) {fail("interrupted");}
 +        catch (RegionReinitializedException e) {}
 +      }
 +    });
 +    thread.start();
 +    
 +    // create role and verify reinitialization took place
 +    Host.getHost(0).getVM(1).invokeAsync(new CacheSerializableRunnable("Create Role") {
 +      public void run2() throws CacheException {
 +        createConnection(new String[] {roleA});
 +        AttributesFactory fac = new AttributesFactory();
 +        fac.setScope(getRegionScope());
 +        RegionAttributes attr = fac.create();
 +        createRootRegion(name, attr);
 +      }
 +    });
 +    
 +    ThreadUtils.join(thread, 30 * 1000);
 +    assertTrue(region.isDestroyed());
 +    try {
 +      region.put("fee", "fi");
 +      fail("Should have thrown RegionReinitializedException");
 +    }
 +    catch(RegionReinitializedException e) {
 +      // pass
 +    }
 +    try {
 +      RequiredRoles.checkForRequiredRoles(region);
 +      fail("Should have thrown RegionReinitializedException");
 +    }
 +    catch(RegionReinitializedException e) {
 +      // pass
 +    }
 +    try {
 +      Role role = (Role) requiredRolesSet.iterator().next();
 +      RequiredRoles.isRoleInRegionMembership(region, role);
 +      fail("Should have thrown RegionReinitializedException");
 +    }
 +    catch(RegionReinitializedException e) {
 +      // pass
 +    }
 +    
 +    region = getRootRegion(name);
 +    assertNotNull(region);
 +    assertTrue(((AbstractRegion)region).requiresReliabilityCheck());
 +    assertTrue(RequiredRoles.checkForRequiredRoles(region).isEmpty());
 +    assertNotNull(region.getEntry(key));
 +    assertEquals(val, region.getEntry(key).getValue());
 +  }
 +  
 +}
 +

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/RemoveAllMultiVmDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/RemoveAllMultiVmDUnitTest.java
index f45c403,0000000..cfd1ce8
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/RemoveAllMultiVmDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/RemoveAllMultiVmDUnitTest.java
@@@ -1,300 -1,0 +1,300 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * RemoveAllMultiVmDUnitTest.java
 + *
 + * Adapted from PutAllMultiVmDUnitTest
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + *
 + * @author  darrel
 + */
 +public class RemoveAllMultiVmDUnitTest extends DistributedTestCase {
 +    
 +    /** Creates a new instance of RemoveAllMultiVmDUnitTest */
 +    public RemoveAllMultiVmDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    static Cache cache;
 +    static Properties props = new Properties();
 +    static Properties propsWork = new Properties();
 +    static DistributedSystem ds = null;
 +    static Region region;
 +    static Region mirroredRegion;
 +    static CacheTransactionManager cacheTxnMgr;
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(RemoveAllMultiVmDUnitTest.class, "createCache");
-       vm1.invoke(RemoveAllMultiVmDUnitTest.class, "createCache");
++      vm0.invoke(() -> RemoveAllMultiVmDUnitTest.createCache());
++      vm1.invoke(() -> RemoveAllMultiVmDUnitTest.createCache());
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(RemoveAllMultiVmDUnitTest.class, "closeCache");
-       vm1.invoke(RemoveAllMultiVmDUnitTest.class, "closeCache");
++      vm0.invoke(() -> RemoveAllMultiVmDUnitTest.closeCache());
++      vm1.invoke(() -> RemoveAllMultiVmDUnitTest.closeCache());
 +      cache = null;
 +      Invoke.invokeInEveryVM(new SerializableRunnable() { public void run() { cache = null; } });
 +    }
 +    
 +    public static void createCache(){
 +        try{
 +            ds = (new RemoveAllMultiVmDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of createCache
 +    
 +    public static void createMirroredRegion(){
 +        try{
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr = factory.create();
 +            mirroredRegion = cache.createRegion("mirrored", attr);
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of createCache
 +    
 +    public static void closeCache(){
 +        try{
 +            //System.out.println("closing cache cache cache cache cache 33333333");
 +            cache.close();
 +            ds.disconnect();
 +            //System.out.println("closed cache cache cache cache cache 44444444");
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of closeCache
 +    
 +    
 +    //tests methods
 +    
 +    public void testLocalRemoveAll(){
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +    
 +      vm0.invoke(new CacheSerializableRunnable("testLocalRemoveAll"){
 +          public void run2() throws CacheException {
 +              int cntr = 0, cntr1 = 0;
 +              for(int i=1; i<6; i++) {
 +                  region.put(Integer.valueOf(i), new String("testLocalRemoveAll"+i));
 +                  cntr++;
 +              }
 +              
 +              int size1 = region.size();
 +              assertEquals(5, size1);
 +              
 +              region.removeAll(Collections.EMPTY_SET);
 +              assertEquals(size1, region.size());
 +              region.removeAll(Collections.singleton(Integer.valueOf(666)));
 +              assertEquals(size1, region.size());
 +              assertEquals(true, region.containsKey(Integer.valueOf(1)));
 +              region.removeAll(Collections.singleton(Integer.valueOf(1)));
 +              assertEquals(false, region.containsKey(Integer.valueOf(1)));
 +              assertEquals(size1-1, region.size());
 +              size1--;
 +              region.removeAll(Arrays.asList(Integer.valueOf(2), Integer.valueOf(3)));
 +              assertEquals(size1-2, region.size());
 +              size1 -= 2;
 +         }
 +      } );
 +    }
 +    
 +    public void testLocalTxRemoveAll(){
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +    
 +      vm0.invoke(new CacheSerializableRunnable("testSimpleRemoveAllTx"){
 +        public void run2() throws CacheException {
 +            cacheTxnMgr = cache.getCacheTransactionManager();
 +            int cntr = 0;
 +            for(int i=1; i<6; i++) {
 +                region.put(Integer.valueOf(i), new String("testLocalTxRemoveAll"+i));
 +                cntr++;
 +            }
 +            
 +            int size1 = region.size();
 +            assertEquals(5, size1);
 +            
 +            cacheTxnMgr.begin();
 +            region.removeAll(Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)));
 +            cacheTxnMgr.rollback();
 +            
 +            assertEquals(size1, region.size());
 +            
 +            cacheTxnMgr.begin();
 +            region.removeAll(Arrays.asList(Integer.valueOf(666), Integer.valueOf(1), Integer.valueOf(2)));
 +            cacheTxnMgr.commit();
 +            
 +            int size2 = region.size();
 +            
 +            assertEquals(size1-2, size2);
 +            assertEquals(true, region.containsKey(Integer.valueOf(3)));
 +            assertEquals(false, region.containsKey(Integer.valueOf(2)));
 +            assertEquals(false, region.containsKey(Integer.valueOf(1)));
 +        }
 +    } );
 +    }
 +
 +    public void testDistributedRemoveAll(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        vm1.invoke(new CacheSerializableRunnable("create mirrored region"){
 +          public void run2() throws CacheException {
 +              createMirroredRegion();
 +          }
 +        });
 +      
 +        vm0.invoke(new CacheSerializableRunnable("testDistributedRemoveAll1"){
 +            public void run2() throws CacheException {
 +                createMirroredRegion();
 +                int cntr = 0, cntr1 = 0;
 +                for(int i=1; i<6; i++) {
 +                  mirroredRegion.put(Integer.valueOf(i), new String("testDistributedRemoveAll"+i));
 +                    cntr++;
 +                }
 +                
 +                int size1 = mirroredRegion.size();
 +                assertEquals(5, size1);
 +                
 +                mirroredRegion.removeAll(Collections.EMPTY_SET);
 +                assertEquals(size1, mirroredRegion.size());
 +                mirroredRegion.removeAll(Collections.singleton(Integer.valueOf(666)));
 +                assertEquals(size1, mirroredRegion.size());
 +                assertEquals(true, mirroredRegion.containsKey(Integer.valueOf(1)));
 +                mirroredRegion.removeAll(Collections.singleton(Integer.valueOf(1)));
 +                assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(1)));
 +                assertEquals(size1-1, mirroredRegion.size());
 +                size1--;
 +                mirroredRegion.removeAll(Arrays.asList(Integer.valueOf(2), Integer.valueOf(3)));
 +                assertEquals(size1-2, mirroredRegion.size());
 +                size1 -= 2;
 +           }
 +        } );
 +        
 +        vm1.invoke(new CacheSerializableRunnable("testDistributedRemoveAllVerifyRemote"){
 +          public void run2() throws CacheException {
 +            assertEquals(true, mirroredRegion.containsKey(Integer.valueOf(5)));
 +            assertEquals(true, mirroredRegion.containsKey(Integer.valueOf(4)));
 +            assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(3)));
 +            assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(2)));
 +            assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(1)));
 +            assertEquals(2, mirroredRegion.size());
 +          }
 +        } );
 +    }
 +    public void testDistributedTxRemoveAll(){
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
 +      
 +      vm1.invoke(new CacheSerializableRunnable("create mirrored region"){
 +        public void run2() throws CacheException {
 +            createMirroredRegion();
 +        }
 +      });
 +    
 +      vm0.invoke(new CacheSerializableRunnable("testDistributedTxRemoveAll1"){
 +          public void run2() throws CacheException {
 +              createMirroredRegion();
 +              int cntr = 0, cntr1 = 0;
 +              for(int i=1; i<6; i++) {
 +                mirroredRegion.put(Integer.valueOf(i), new String("testDistributedTxRemoveAll"+i));
 +                  cntr++;
 +              }
 +              
 +              int size1 = mirroredRegion.size();
 +              assertEquals(5, size1);
 +              cacheTxnMgr = cache.getCacheTransactionManager();
 +              
 +              cacheTxnMgr.begin();
 +             mirroredRegion.removeAll(Collections.EMPTY_SET);
 +             cacheTxnMgr.commit();
 +              assertEquals(size1, mirroredRegion.size());
 +              cacheTxnMgr.begin();
 +              mirroredRegion.removeAll(Collections.singleton(Integer.valueOf(666)));
 +              cacheTxnMgr.commit();
 +              assertEquals(size1, mirroredRegion.size());
 +              assertEquals(true, mirroredRegion.containsKey(Integer.valueOf(1)));
 +              cacheTxnMgr.begin();
 +              mirroredRegion.removeAll(Collections.singleton(Integer.valueOf(1)));
 +              cacheTxnMgr.commit();
 +              assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(1)));
 +              assertEquals(size1-1, mirroredRegion.size());
 +              size1--;
 +              cacheTxnMgr.begin();
 +              mirroredRegion.removeAll(Arrays.asList(Integer.valueOf(2), Integer.valueOf(3)));
 +              cacheTxnMgr.commit();
 +              assertEquals(size1-2, mirroredRegion.size());
 +              size1 -= 2;
 +         }
 +      } );
 +      
 +      vm1.invoke(new CacheSerializableRunnable("testDistributedTxRemoveAllVerifyRemote"){
 +        public void run2() throws CacheException {
 +          assertEquals(true, mirroredRegion.containsKey(Integer.valueOf(5)));
 +          assertEquals(true, mirroredRegion.containsKey(Integer.valueOf(4)));
 +          assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(3)));
 +          assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(2)));
 +          assertEquals(false, mirroredRegion.containsKey(Integer.valueOf(1)));
 +          assertEquals(2, mirroredRegion.size());
 +        }
 +      } );
 +  }
 +     
 +}//end of RemoveAllMultiVmDUnitTest

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/RolePerformanceDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/RolePerformanceDUnitTest.java
index e7c0ba7,0000000..babbf12
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/RolePerformanceDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/RolePerformanceDUnitTest.java
@@@ -1,189 -1,0 +1,188 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +
 +/**
 + * Tests the performance of Regions when Roles are assigned.
 + *
 + * @author Kirk Lund
 + * @since 5.0
 + */
 +public class RolePerformanceDUnitTest extends CacheTestCase {
 +
 +  public RolePerformanceDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  /**
 +   * Compares times required for series of puts with Roles assigned to
 +   * series of puts with no Roles assigned. Scope is D_ACK.
 +   * <p>
 +   * Up to 10 attempts will be made before failing.
 +   */
 +  public void testRolePerformance() {
 +    int maxAttempts = 10;
 +    for (int i = 1; i <= maxAttempts; i++) {
 +      try {
 +        if (i > 1) {
 +          // clean up from previous run
 +          closeCaches();
 +        }
 +        doTestRolePerformance();
 +        break;
 +      }
 +      // only catch assertion failures...
 +      catch (junit.framework.AssertionFailedError e) {
 +        if (i == maxAttempts) {
 +          throw e;
 +        }
 +        else {
 +          LogWriterUtils.getLogWriter().info("testRolePerformance attempt #" + i + 
 +            " failed -- reattempting up to 10x", e);
 +        }
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Implementation of testRolePerformance.
 +   */
 +  private void doTestRolePerformance() {
 +    final String name = this.getUniqueName();
 +
 +    // throw away this run
 +    createConnections(name, false);
 +    createRegions(name);
 +    executeOperations(name);
 +    
 +    closeCaches();
 +    
 +    // first time with no roles
 +    createConnections(name, false);
 +    createRegions(name);
 +    long millisNoRoles = executeOperations(name);
 +    
 +    closeCaches();
 +    
 +    // second time with roles
 +    createConnections(name, true);
 +    createRegions(name);
 +    long millisWithRoles = executeOperations(name);
 +    
 +    long deviation = (long)(millisNoRoles * 0.05); // 5% increase is allowed
 +    long ceiling = millisNoRoles + deviation;
 +
 +    String data = name + " results: millisNoRoles=" + millisNoRoles +
 +      ", millisWithRoles=" + millisWithRoles + ", deviation=" + deviation + 
 +      ", ceiling=" + ceiling;
 +    LogWriterUtils.getLogWriter().info(data);
 +    
 +    assertTrue("millisWithRoles is greater than allowable deviation: " + data,
 +               millisWithRoles <= ceiling);
 +  }
 +  
 +  /**
 +   * Create connection to distributed system in all vms and assign one role
 +   * to each if assignRoles is true.
 +   */
 +  private void createConnections(final String name, final boolean assignRoles) {
 +    final String[][] vmRoles = new String[][] 
 +      {{name+"-A"},{name+"-B"},{name+"-C"},{name+"-D"}};
 +    for (int i = 0; i < vmRoles.length; i++) {
 +      final int vm = i;
 +      Host.getHost(0).getVM(vm).invoke(new SerializableRunnable("Connect") {
 +        public void run() {
 +          Properties config = new Properties();
 +          if (assignRoles) {
 +            config.setProperty(DistributionConfig.ROLES_NAME, vmRoles[vm][0]);
 +          }
 +          getSystem(config);
 +        }
 +      });
 +    }
 +  }
 +  
 +  /**
 +   * Close the cache in all vms.
 +   */
 +  private void closeCaches() { 
 +    for (int i = 0; i < Host.getHost(0).getVMCount(); i++) {
 +      final int vm = i;
 +      Host.getHost(0).getVM(vm).invoke(new CacheSerializableRunnable("Close Cache") {
 +        public void run2() throws CacheException {
 +          closeCache();
 +        }
 +      });
 +    }
 +  }
 +  
 +  /**
 +   * Create the named root region in all vms.
 +   */
 +  private void createRegions(final String name) {
 +    for (int i = 0; i < Host.getHost(0).getVMCount(); i++) {
 +      final int vm = i;
 +      Host.getHost(0).getVM(vm).invoke(new CacheSerializableRunnable("Create Region") {
 +        public void run2() throws CacheException {
 +          AttributesFactory fac = new AttributesFactory();
 +          fac.setScope(Scope.DISTRIBUTED_ACK);
 +          fac.setDataPolicy(DataPolicy.REPLICATE);
 +          RegionAttributes attr = fac.create();
 +          createRootRegion(name, attr);
 +        }
 +      });
 +    }
 +  }
 +  
 +  /**
 +   * Execute operations on the named region in one vm.
 +   */
 +  private long executeOperations(final String name) {
 +    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("Operations") {
 +      public void run2() throws CacheException {
 +        Region region = getRootRegion(name);
 +        long begin = System.currentTimeMillis();
 +        for (int i = 0; i < 1000; i++) {
 +          region.put("KEY-"+i, "VAL-"+i);
 +        }
 +        long finish = System.currentTimeMillis();
 +        timing = finish - begin;
 +      }
 +    });
-     Long timing = (Long) Host.getHost(0).getVM(0).invoke(
-       RolePerformanceDUnitTest.class, "getTiming", new Object[] {});
++    Long timing = (Long) Host.getHost(0).getVM(0).invoke(() -> RolePerformanceDUnitTest.getTiming());
 +    return timing.longValue();
 +  }
 +  protected static transient long timing = -1;
 +  private static Long getTiming() {
 +    return new Long(timing);
 +  }
 +  
 +}
 +


[024/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/Bits.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/Bits.java
index 0000000,0000000..351adbb
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/Bits.java
@@@ -1,0 -1,0 +1,48 @@@
++/*
++ * Copyright (C) 2011 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++import java.io.ByteArrayInputStream;
++import java.io.DataInput;
++import java.io.DataInputStream;
++import java.io.IOException;
++
++public class Bits {
++
++    public static int[] getBits(byte[] mBytes) throws IOException {
++        int bitSize = mBytes.length / 4;
++        int[] bits = new int[bitSize];
++        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(mBytes));
++        for (int i = 0; i < bitSize; i++) {
++            bits[i] = dis.readInt();
++        }
++        return bits;
++    }
++
++    /**
++     * This method might be better described as
++     * "byte array to int array" or "data input to int array"
++     */
++    public static int[] getBits(DataInput dataIn, int byteLength) throws IOException {
++        int bitSize = byteLength / 4;
++        int[] bits = new int[bitSize];
++        for (int i = 0; i < bitSize; i++) {
++            bits[i] = dataIn.readInt();
++        }
++        return bits;
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/CardinalityMergeException.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/CardinalityMergeException.java
index 0000000,0000000..e8ae3be
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/CardinalityMergeException.java
@@@ -1,0 -1,0 +1,26 @@@
++/*
++ * Copyright (C) 2011 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++
++
++@SuppressWarnings("serial")
++public abstract class CardinalityMergeException extends Exception {
++
++    public CardinalityMergeException(String message) {
++        super(message);
++    }
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/HyperLogLog.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/HyperLogLog.java
index 0000000,0000000..7e88198
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/HyperLogLog.java
@@@ -1,0 -1,0 +1,345 @@@
++/*
++ * Copyright (C) 2012 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++import com.gemstone.gemfire.internal.redis.executor.hll.HllExecutor;
++
++import java.io.ByteArrayInputStream;
++import java.io.ByteArrayOutputStream;
++import java.io.DataInput;
++import java.io.DataInputStream;
++import java.io.DataOutput;
++import java.io.DataOutputStream;
++import java.io.Externalizable;
++import java.io.IOException;
++import java.io.ObjectInput;
++import java.io.ObjectOutput;
++import java.io.Serializable;
++
++/**
++ * Java implementation of HyperLogLog (HLL) algorithm from this paper:
++ * <p/>
++ * http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf
++ * <p/>
++ * HLL is an improved version of LogLog that is capable of estimating
++ * the cardinality of a set with accuracy = 1.04/sqrt(m) where
++ * m = 2^b.  So we can control accuracy vs space usage by increasing
++ * or decreasing b.
++ * <p/>
++ * The main benefit of using HLL over LL is that it only requires 64%
++ * of the space that LL does to get the same accuracy.
++ * <p/>
++ * This implementation implements a single counter.  If a large (millions)
++ * number of counters are required you may want to refer to:
++ * <p/>
++ * http://dsiutils.dsi.unimi.it/
++ * <p/>
++ * It has a more complex implementation of HLL that supports multiple counters
++ * in a single object, drastically reducing the java overhead from creating
++ * a large number of objects.
++ * <p/>
++ * This implementation leveraged a javascript implementation that Yammer has
++ * been working on:
++ * <p/>
++ * https://github.com/yammer/probablyjs
++ * <p>
++ * Note that this implementation does not include the long range correction function
++ * defined in the original paper.  Empirical evidence shows that the correction
++ * function causes more harm than good.
++ * </p>
++ * <p/>
++ * <p>
++ * Users have different motivations to use different types of hashing functions.
++ * Rather than try to keep up with all available hash functions and to remove
++ * the concern of causing future binary incompatibilities this class allows clients
++ * to offer the value in hashed int or long form.  This way clients are free
++ * to change their hash function on their own time line.  We recommend using Google's
++ * Guava Murmur3_128 implementation as it provides good performance and speed when
++ * high precision is required.  In our tests the 32bit MurmurHash function included
++ * in this project is faster and produces better results than the 32 bit murmur3
++ * implementation google provides.
++ * </p>
++ */
++public class HyperLogLog implements ICardinality, Serializable {
++
++  private static final long serialVersionUID = -4661220245111112301L;
++  private final RegisterSet registerSet;
++  private final int log2m;
++  private final double alphaMM;
++
++
++  /**
++   * Create a new HyperLogLog instance using the specified standard deviation.
++   *
++   * @param rsd - the relative standard deviation for the counter.
++   *            smaller values create counters that require more space.
++   */
++  public HyperLogLog(double rsd) {
++    this(log2m(rsd));
++  }
++
++  private static int log2m(double rsd) {
++    return (int) (Math.log((1.106 / rsd) * (1.106 / rsd)) / Math.log(2));
++  }
++
++  /**
++   * Create a new HyperLogLog instance.  The log2m parameter defines the accuracy of
++   * the counter.  The larger the log2m the better the accuracy.
++   * <p/>
++   * accuracy = 1.04/sqrt(2^log2m)
++   *
++   * @param log2m - the number of bits to use as the basis for the HLL instance
++   */
++  public HyperLogLog(int log2m) {
++    this(log2m, new RegisterSet(1 << log2m));
++  }
++
++  /**
++   * Creates a new HyperLogLog instance using the given registers.  Used for unmarshalling a serialized
++   * instance and for merging multiple counters together.
++   *
++   * @param registerSet - the initial values for the register set
++   */
++  @Deprecated
++  public HyperLogLog(int log2m, RegisterSet registerSet) {
++    if (log2m < 0 || log2m > 30) {
++      throw new IllegalArgumentException("log2m argument is "
++          + log2m + " and is outside the range [0, 30]");
++    }
++    this.registerSet = registerSet;
++    this.log2m = log2m;
++    int m = 1 << this.log2m;
++
++    alphaMM = getAlphaMM(log2m, m);
++  }
++
++  @Override
++  public boolean offerHashed(long hashedValue) {
++    // j becomes the binary address determined by the first b log2m of x
++    // j will be between 0 and 2^log2m
++    final int j = (int) (hashedValue >>> (Long.SIZE - log2m));
++    final int r = Long.numberOfLeadingZeros((hashedValue << this.log2m) | (1 << (this.log2m - 1)) + 1) + 1;
++    return registerSet.updateIfGreater(j, r);
++  }
++
++  @Override
++  public boolean offerHashed(int hashedValue) {
++    // j becomes the binary address determined by the first b log2m of x
++    // j will be between 0 and 2^log2m
++    final int j = hashedValue >>> (Integer.SIZE - log2m);
++    final int r = Integer.numberOfLeadingZeros((hashedValue << this.log2m) | (1 << (this.log2m - 1)) + 1) + 1;
++    return registerSet.updateIfGreater(j, r);
++  }
++
++  @Override
++  public boolean offer(Object o) {
++    final int x = MurmurHash.hash(o);
++    return offerHashed(x);
++  }
++
++
++  @Override
++  public long cardinality() {
++    double registerSum = 0;
++    int count = registerSet.count;
++    double zeros = 0.0;
++    for (int j = 0; j < registerSet.count; j++) {
++      int val = registerSet.get(j);
++      registerSum += 1.0 / (1 << val);
++      if (val == 0) {
++        zeros++;
++      }
++    }
++
++    double estimate = alphaMM * (1 / registerSum);
++
++    if (estimate <= (5.0 / 2.0) * count) {
++      // Small Range Estimate
++      return Math.round(linearCounting(count, zeros));
++    } else {
++      return Math.round(estimate);
++    }
++  }
++
++  @Override
++  public int sizeof() {
++    return registerSet.size * 4;
++  }
++
++  @Override
++  public byte[] getBytes() throws IOException {
++    ByteArrayOutputStream baos = new ByteArrayOutputStream();
++    DataOutput dos = new DataOutputStream(baos);
++    writeBytes(dos);
++
++    return baos.toByteArray();
++  }
++
++  private void writeBytes(DataOutput serializedByteStream) throws IOException {
++    serializedByteStream.writeInt(log2m);
++    serializedByteStream.writeInt(registerSet.size * 4);
++    for (int x : registerSet.readOnlyBits()) {
++      serializedByteStream.writeInt(x);
++    }
++  }
++
++  /**
++   * Add all the elements of the other set to this set.
++   * <p/>
++   * This operation does not imply a loss of precision.
++   *
++   * @param other A compatible Hyperloglog instance (same log2m)
++   * @throws CardinalityMergeException if other is not compatible
++   */
++  public void addAll(HyperLogLog other) throws CardinalityMergeException {
++    if (this.sizeof() != other.sizeof()) {
++      throw new HyperLogLogMergeException("Cannot merge estimators of different sizes");
++    }
++
++    registerSet.merge(other.registerSet);
++  }
++
++  @Override
++  public ICardinality merge(ICardinality... estimators) throws CardinalityMergeException {
++    HyperLogLog merged = new HyperLogLog(HllExecutor.DEFAULT_HLL_STD_DEV);//new HyperLogLog(log2m, new RegisterSet(this.registerSet.count));
++    merged.addAll(this);
++
++    if (estimators == null) {
++      return merged;
++    }
++
++    for (ICardinality estimator : estimators) {
++      if (!(estimator instanceof HyperLogLog)) {
++        throw new HyperLogLogMergeException("Cannot merge estimators of different class");
++      }
++      HyperLogLog hll = (HyperLogLog) estimator;
++      merged.addAll(hll);
++    }
++
++    return merged;
++  }
++
++  private Object writeReplace() {
++    return new SerializationHolder(this);
++  }
++
++  /**
++   * This class exists to support Externalizable semantics for
++   * HyperLogLog objects without having to expose a public
++   * constructor, public write/read methods, or pretend final
++   * fields aren't final.
++   *
++   * In short, Externalizable allows you to skip some of the more
++   * verbose meta-data default Serializable gets you, but still
++   * includes the class name. In that sense, there is some cost
++   * to this holder object because it has a longer class name. I
++   * imagine people who care about optimizing for that have their
++   * own work-around for long class names in general, or just use
++   * a custom serialization framework. Therefore we make no attempt
++   * to optimize that here (eg. by raising this from an inner class
++   * and giving it an unhelpful name).
++   */
++  private static class SerializationHolder implements Externalizable {
++
++    HyperLogLog hyperLogLogHolder;
++
++    public SerializationHolder(HyperLogLog hyperLogLogHolder) {
++      this.hyperLogLogHolder = hyperLogLogHolder;
++    }
++
++    /**
++     * required for Externalizable
++     */
++    @SuppressWarnings("unused")
++    public SerializationHolder() {
++
++    }
++
++    @Override
++    public void writeExternal(ObjectOutput out) throws IOException {
++      hyperLogLogHolder.writeBytes(out);
++    }
++
++    @Override
++    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
++      hyperLogLogHolder = Builder.build(in);
++    }
++
++    private Object readResolve() {
++      return hyperLogLogHolder;
++    }
++  }
++
++  public static class Builder implements IBuilder<ICardinality>, Serializable {
++
++    private static final long serialVersionUID = -979314356097156719L;
++    private double rsd;
++
++    public Builder(double rsd) {
++      this.rsd = rsd;
++    }
++
++    @Override
++    public HyperLogLog build() {
++      return new HyperLogLog(rsd);
++    }
++
++    @Override
++    public int sizeof() {
++      int log2m = log2m(rsd);
++      int k = 1 << log2m;
++      return RegisterSet.getBits(k) * 4;
++    }
++
++    public static HyperLogLog build(byte[] bytes) throws IOException {
++      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
++      return build(new DataInputStream(bais));
++    }
++
++    public static HyperLogLog build(DataInput serializedByteStream) throws IOException {
++      int log2m = serializedByteStream.readInt();
++      int byteArraySize = serializedByteStream.readInt();
++      return new HyperLogLog(log2m,
++          new RegisterSet(1 << log2m, Bits.getBits(serializedByteStream, byteArraySize)));
++    }
++  }
++
++  @SuppressWarnings("serial")
++  protected static class HyperLogLogMergeException extends CardinalityMergeException {
++
++    public HyperLogLogMergeException(String message) {
++      super(message);
++    }
++  }
++
++  protected static double getAlphaMM(final int p, final int m) {
++    // See the paper.
++    switch (p) {
++    case 4:
++      return 0.673 * m * m;
++    case 5:
++      return 0.697 * m * m;
++    case 6:
++      return 0.709 * m * m;
++    default:
++      return (0.7213 / (1 + 1.079 / m)) * m * m;
++    }
++  }
++
++  protected static double linearCounting(int m, double V) {
++    return m * Math.log(m / V);
++  }
++}


[041/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionStats.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionStats.java
index 28ca380,0000000..6750a54
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionStats.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionStats.java
@@@ -1,2051 -1,0 +1,2065 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.StatisticDescriptor;
 +import com.gemstone.gemfire.Statistics;
 +import com.gemstone.gemfire.StatisticsFactory;
 +import com.gemstone.gemfire.StatisticsType;
 +import com.gemstone.gemfire.StatisticsTypeFactory;
 +import com.gemstone.gemfire.internal.NanoTimer;
 +import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +//import java.io.*;
 +import com.gemstone.gemfire.internal.tcp.Buffers;
 +import com.gemstone.gemfire.internal.util.Breadcrumbs;
 +
 +/**
 + * This class maintains statistics in GemFire about the distribution
 + * manager and distribution in general.
 + *
 + * @author Darrel Schneider
 + * @author Bruce Schuchardt
 + *
 + */
 +public class DistributionStats implements DMStats {
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  public static boolean enableClockStats = false;
 +
 +
 +  //////////////////  Statistic "Id" Fields  //////////////////
 +
 +  private final static StatisticsType type;
 +  private final static int sentMessagesId;
 +  private final static int sentCommitMessagesId;
 +  private final static int commitWaitsId;
 +  private final static int sentMessagesTimeId;
 +  private final static int sentMessagesMaxTimeId;
 +  private final static int broadcastMessagesId;
 +  private final static int broadcastMessagesTimeId;
 +  private final static int receivedMessagesId;
 +  private final static int receivedBytesId;
 +  private final static int sentBytesId;
 +  private final static int processedMessagesId;
 +  private final static int processedMessagesTimeId;
 +  private final static int messageProcessingScheduleTimeId;
 +  private final static int messageChannelTimeId;
++  private final static int udpDispatchRequestTimeId;
 +  private final static int replyMessageTimeId;
 +  private final static int distributeMessageTimeId;
 +  private final static int nodesId;
 +  private final static int overflowQueueSizeId;
 +  private final static int processingThreadsId;
 +  private final static int serialThreadsId;
 +  private final static int waitingThreadsId;
 +  private final static int highPriorityThreadsId;
 +  private final static int partitionedRegionThreadsId;
 +  private final static int functionExecutionThreadsId;
 +  private final static int partitionedRegionThreadJobsId;
 +  private final static int functionExecutionThreadJobsId;
 +  private final static int waitingQueueSizeId;
 +  private final static int overflowQueueThrottleTimeId;
 +  private final static int overflowQueueThrottleCountId;
 +  private final static int highPriorityQueueSizeId;
 +  private final static int highPriorityQueueThrottleTimeId;
 +  private final static int highPriorityQueueThrottleCountId;
 +  private final static int partitionedRegionQueueSizeId;
 +  private final static int partitionedRegionQueueThrottleTimeId;
 +  private final static int partitionedRegionQueueThrottleCountId;
 +  private final static int functionExecutionQueueSizeId;
 +  private final static int functionExecutionQueueThrottleCountId;
 +  private final static int functionExecutionQueueThrottleTimeId;
 +  private final static int serialQueueSizeId;
 +  private final static int serialQueueBytesId;
 +  private final static int serialPooledThreadId;
 +  private final static int serialQueueThrottleTimeId;
 +  private final static int serialQueueThrottleCountId;
 +  private final static int replyWaitsInProgressId;
 +  private final static int replyWaitsCompletedId;
 +  private final static int replyWaitTimeId;
 +  private final static int replyTimeoutsId;
 +  private final static int replyWaitMaxTimeId;
 +  private final static int receiverConnectionsId;
 +  private final static int failedAcceptsId;
 +  private final static int failedConnectsId;
 +  private final static int reconnectAttemptsId;
 +  private final static int lostConnectionLeaseId;
 +  private final static int sharedOrderedSenderConnectionsId;
 +  private final static int sharedUnorderedSenderConnectionsId;
 +  private final static int threadOrderedSenderConnectionsId;
 +  private final static int threadUnorderedSenderConnectionsId;
 +
 +  private final static int syncSocketWritesInProgressId;
 +  private final static int syncSocketWriteTimeId;
 +  private final static int syncSocketWritesId;
 +  private final static int syncSocketWriteBytesId;
 +
 +  private final static int ucastReadsId;
 +  private final static int ucastReadBytesId;
 +  private final static int ucastWritesId;
 +  private final static int ucastWriteBytesId;
 +  private final static int ucastRetransmitsId;
 +
 +  private final static int mcastReadsId;
 +  private final static int mcastReadBytesId;
 +  private final static int mcastWritesId;
 +  private final static int mcastWriteBytesId;
 +  private final static int mcastRetransmitsId;
 +  private final static int mcastRetransmitRequestsId;
 +
 +  private final static int serializationTimeId;
 +  private final static int serializationsId;
 +  private final static int serializedBytesId;
 +
 +  private final static int pdxSerializationsId;
 +  private final static int pdxSerializedBytesId;
 +
 +  private final static int deserializationTimeId;
 +  private final static int deserializationsId;
 +  private final static int deserializedBytesId;
 +  private final static int pdxDeserializationsId;
 +  private final static int pdxDeserializedBytesId;
 +  private final static int pdxInstanceDeserializationsId;
 +  private final static int pdxInstanceDeserializationTimeId;
 +  private final static int pdxInstanceCreationsId;
 +
 +  private final static int msgSerializationTimeId;
 +  private final static int msgDeserializationTimeId;
 +
 +  private final static int batchSendTimeId;
 +  private final static int batchCopyTimeId;
 +  private final static int batchWaitTimeId;
 +  private final static int batchFlushTimeId;
 +
 +  private final static int threadOwnedReceiversId;
 +  private final static int threadOwnedReceiversId2;
 +
 +  private final static int asyncSocketWritesInProgressId;
 +  private final static int asyncSocketWritesId;
 +  private final static int asyncSocketWriteRetriesId;
 +  private final static int asyncSocketWriteTimeId;
 +  private final static int asyncSocketWriteBytesId;
 +
 +  private final static int socketLocksInProgressId;
 +  private final static int socketLocksId;
 +  private final static int socketLockTimeId;
 +
 +  private final static int bufferAcquiresInProgressId;
 +  private final static int bufferAcquiresId;
 +  private final static int bufferAcquireTimeId;
 +
 +  private final static int asyncQueueAddTimeId;
 +  private final static int asyncQueueRemoveTimeId;
 +
 +  private static final int asyncQueuesId;
 +  private static final int asyncQueueFlushesInProgressId;
 +  private static final int asyncQueueFlushesCompletedId;
 +  private static final int asyncQueueFlushTimeId;
 +  private static final int asyncQueueTimeoutExceededId;
 +  private static final int asyncQueueSizeExceededId;
 +  private static final int asyncDistributionTimeoutExceededId;
 +  private static final int asyncQueueSizeId;
 +  private static final int asyncQueuedMsgsId;
 +  private static final int asyncDequeuedMsgsId;
 +  private static final int asyncConflatedMsgsId;
 +
 +  private static final int asyncThreadsId;
 +  private static final int asyncThreadInProgressId;
 +  private static final int asyncThreadCompletedId;
 +  private static final int asyncThreadTimeId;
 +
 +  private static final int receiverDirectBufferSizeId;
 +  private static final int receiverHeapBufferSizeId;
 +  private static final int senderDirectBufferSizeId;
 +  private static final int senderHeapBufferSizeId;
 +
 +  private static final int messagesBeingReceivedId;
 +  private static final int messageBytesBeingReceivedId;
 +
 +  private static final int serialThreadStartsId;
 +  private static final int viewThreadStartsId;
 +  private static final int processingThreadStartsId;
 +  private static final int highPriorityThreadStartsId;
 +  private static final int waitingThreadStartsId;
 +  private static final int partitionedRegionThreadStartsId;
 +  private static final int functionExecutionThreadStartsId;
 +  private static final int serialPooledThreadStartsId;
 +  private static final int TOSentMsgId;
 +
 +  private static final int replyHandoffTimeId;
 +
 +  private final static int viewThreadsId;
 +  private final static int serialThreadJobsId;
 +  private final static int viewProcessorThreadJobsId;
 +  private final static int serialPooledThreadJobsId;
 +  private final static int pooledMessageThreadJobsId;
 +  private final static int highPriorityThreadJobsId;
 +  private final static int waitingPoolThreadJobsId;
 +
 +  private final static int eldersId;
 +  private final static int initialImageMessagesInFlightId;
 +  private final static int initialImageRequestsInProgressId;
 +  
 +  //For GMSHealthMonitor
 +  private final static int heartbeatRequestsSentId;  
 +  private final static int heartbeatRequestsReceivedId;  
 +  private final static int heartbeatsSentId;  
 +  private final static int heartbeatsReceivedId;  
 +  private final static int suspectsSentId;  
 +  private final static int suspectsReceivedId;
 +  private final static int finalCheckRequestsSentId;  
 +  private final static int finalCheckRequestsReceivedId;  
 +  private final static int finalCheckResponsesSentId;  
 +  private final static int finalCheckResponsesReceivedId;  
 +  private final static int tcpFinalCheckRequestsSentId; 
 +  private final static int tcpFinalCheckRequestsReceivedId;  
 +  private final static int tcpFinalCheckResponsesSentId;  
 +  private final static int tcpFinalCheckResponsesReceivedId;
 +  private final static int udpFinalCheckRequestsSentId;
 +  private final static int udpFinalCheckRequestsReceivedId;
 +  private final static int udpFinalCheckResponsesSentId;
 +  private final static int udpFinalCheckResponsesReceivedId;
 +
 +  static {
 +    String statName = "DistributionStats";
 +    String statDescription = "Statistics on the gemfire distribution layer.";
 +
 +    final String sentMessagesDesc = "The number of distribution messages that this GemFire system has sent. This includes broadcastMessages.";
 +    final String sentCommitMessagesDesc = "The number of transaction commit messages that this GemFire system has created to be sent. Note that it is possible for a commit to only create one message even though it will end up being sent to multiple recipients.";
 +    final String commitWaitsDesc = "The number of transaction commits that had to wait for a response before they could complete.";
 +    final String sentMessagesTimeDesc = "The total amount of time this distribution manager has spent sending messages. This includes broadcastMessagesTime.";
 +    final String sentMessagesMaxTimeDesc = "The highest amount of time this distribution manager has spent distributing a single message to the network.";
 +    final String broadcastMessagesDesc = "The number of distribution messages that this GemFire system has broadcast. A broadcast message is one sent to every other manager in the group.";
 +    final String broadcastMessagesTimeDesc = "The total amount of time this distribution manager has spent broadcasting messages. A broadcast message is one sent to every other manager in the group.";
 +    final String receivedMessagesDesc = "The number of distribution messages that this GemFire system has received.";
 +    final String receivedBytesDesc = "The number of distribution message bytes that this GemFire system has received.";
 +    final String sentBytesDesc = "The number of distribution message bytes that this GemFire system has sent.";
 +    final String processedMessagesDesc = "The number of distribution messages that this GemFire system has processed.";
 +    final String processedMessagesTimeDesc = "The amount of time this distribution manager has spent in message.process().";
 +    final String messageProcessingScheduleTimeDesc = "The amount of time this distribution manager has spent dispatching message to processor threads.";
 +    final String overflowQueueSizeDesc = "The number of normal distribution messages currently waiting to be processed.";
 +    final String waitingQueueSizeDesc = "The number of distribution messages currently waiting for some other resource before they can be processed.";
 +    final String overflowQueueThrottleTimeDesc = "The total amount of time, in nanoseconds, spent delayed by the overflow queue throttle.";
 +    final String overflowQueueThrottleCountDesc = "The total number of times a thread was delayed in adding a normal message to the overflow queue.";
 +    final String highPriorityQueueSizeDesc = "The number of high priority distribution messages currently waiting to be processed.";
 +    final String highPriorityQueueThrottleTimeDesc = "The total amount of time, in nanoseconds, spent delayed by the high priority queue throttle.";
 +    final String highPriorityQueueThrottleCountDesc = "The total number of times a thread was delayed in adding a normal message to the high priority queue.";
 +    final String serialQueueSizeDesc = "The number of serial distribution messages currently waiting to be processed.";
 +    final String serialQueueBytesDesc = "The approximate number of bytes consumed by serial distribution messages currently waiting to be processed.";
 +    final String serialPooledThreadDesc = "The number of threads created in the SerialQueuedExecutorPool.";
 +    final String serialQueueThrottleTimeDesc = "The total amount of time, in nanoseconds, spent delayed by the serial queue throttle.";
 +    final String serialQueueThrottleCountDesc = "The total number of times a thread was delayed in adding a ordered message to the serial queue.";
 +    final String serialThreadsDesc = "The number of threads currently processing serial/ordered messages.";
 +    final String processingThreadsDesc = "The number of threads currently processing normal messages.";
 +    final String highPriorityThreadsDesc = "The number of threads currently processing high priority messages.";
 +    final String partitionedRegionThreadsDesc = "The number of threads currently processing partitioned region messages.";
 +    final String functionExecutionThreadsDesc = "The number of threads currently processing function execution messages.";
 +    final String waitingThreadsDesc = "The number of threads currently processing messages that had to wait for a resource.";
 +    final String messageChannelTimeDesc = "The total amount of time received messages spent in the distribution channel";
++    final String udpDispatchRequestTimeDesc = "The total amount of time spent deserializing and dispatching UDP messages in the message-reader thread.";
 +    final String replyMessageTimeDesc = "The amount of time spent processing reply messages. This includes both processedMessagesTime and messageProcessingScheduleTime.";
 +    final String distributeMessageTimeDesc = "The amount of time it takes to prepare a message and send it on the network.  This includes sentMessagesTime.";
 +    final String nodesDesc = "The current number of nodes in this distributed system.";
 +    final String replyWaitsInProgressDesc = "Current number of threads waiting for a reply.";
 +    final String replyWaitsCompletedDesc = "Total number of times waits for a reply have completed.";
 +    final String replyWaitTimeDesc = "Total time spent waiting for a reply to a message.";
 +    final String replyWaitMaxTimeDesc = "Maximum time spent transmitting and then waiting for a reply to a message. See sentMessagesMaxTime for related information";
 +    final String replyTimeoutsDesc =
 +      "Total number of message replies that have timed out.";
 +    final String receiverConnectionsDesc =
 +      "Current number of sockets dedicated to receiving messages.";
 +    final String failedAcceptsDesc =
 +      "Total number of times an accept (receiver creation) of a connect from some other member has failed";
 +    final String failedConnectsDesc =
 +      "Total number of times a connect (sender creation) to some other member has failed.";
 +    final String reconnectAttemptsDesc =
 +      "Total number of times an established connection was lost and a reconnect was attempted.";
 +    final String lostConnectionLeaseDesc =
 +      "Total number of times an unshared sender socket has remained idle long enough that its lease expired.";
 +    final String sharedOrderedSenderConnectionsDesc =
 +      "Current number of shared sockets dedicated to sending ordered messages.";
 +    final String sharedUnorderedSenderConnectionsDesc =
 +      "Current number of shared sockets dedicated to sending unordered messages.";
 +    final String threadOrderedSenderConnectionsDesc =
 +      "Current number of thread sockets dedicated to sending ordered messages.";
 +    final String threadUnorderedSenderConnectionsDesc =
 +      "Current number of thread sockets dedicated to sending unordered messages.";
 +
 +    final String asyncQueuesDesc = "The current number of queues for asynchronous messaging.";
 +    final String asyncQueueFlushesInProgressDesc = "Current number of asynchronous queues being flushed.";
 +    final String asyncQueueFlushesCompletedDesc = "Total number of asynchronous queue flushes completed.";
 +    final String asyncQueueFlushTimeDesc = "Total time spent flushing asynchronous queues.";
 +    final String asyncQueueTimeoutExceededDesc = "Total number of asynchronous queues that have timed out by being blocked for more than async-queue-timeout milliseconds.";
 +    final String asyncQueueSizeExceededDesc = "Total number of asynchronous queues that have exceeded max size.";
 +    final String asyncDistributionTimeoutExceededDesc = "Total number of times the async-distribution-timeout has been exceeded during a socket write.";
 +    final String asyncQueueSizeDesc = "The current size in bytes used for asynchronous queues.";
 +    final String asyncQueuedMsgsDesc = "The total number of queued messages used for asynchronous queues.";
 +    final String asyncDequeuedMsgsDesc = "The total number of queued messages that have been removed from the queue and successfully sent.";
 +    final String asyncConflatedMsgsDesc = "The total number of queued conflated messages used for asynchronous queues.";
 +
 +    final String asyncThreadsDesc = "Total number of asynchronous message queue threads.";
 +    final String asyncThreadInProgressDesc = "Current iterations of work performed by asynchronous message queue threads.";
 +    final String asyncThreadCompletedDesc = "Total number of iterations of work performed by asynchronous message queue threads.";
 +    final String asyncThreadTimeDesc = "Total time spent by asynchronous message queue threads performing iterations.";
 +    final String receiverDirectBufferSizeDesc = "Current number of bytes allocated from direct memory as buffers for incoming messages.";
 +    final String receiverHeapBufferSizeDesc = "Current number of bytes allocated from Java heap memory as buffers for incoming messages.";
 +    final String senderDirectBufferSizeDesc = "Current number of bytes allocated from direct memory as buffers for outgoing messages.";
 +    final String senderHeapBufferSizeDesc = "Current number of bytes allocated from Java heap memory as buffers for outoing messages.";
 +
 +    final String replyHandoffTimeDesc = "Total number of seconds to switch thread contexts from processing thread to application thread.";
 +
 +    final String partitionedRegionThreadJobsDesc = "The number of messages currently being processed by partitioned region threads";
 +    final String functionExecutionThreadJobsDesc = "The number of messages currently being processed by function execution threads";
 +    final String viewThreadsDesc = "The number of threads currently processing view messages.";
 +    final String serialThreadJobsDesc = "The number of messages currently being processed by serial threads.";
 +    final String viewThreadJobsDesc = "The number of messages currently being processed by view threads.";
 +    final String serialPooledThreadJobsDesc = "The number of messages currently being processed by pooled serial processor threads.";
 +    final String processingThreadJobsDesc = "The number of messages currently being processed by pooled message processor threads.";
 +    final String highPriorityThreadJobsDesc = "The number of messages currently being processed by high priority processor threads.";
 +    final String waitingThreadJobsDesc = "The number of messages currently being processed by waiting pooly processor threads.";
 +
 +    final String eldersDesc = "Current number of system elders hosted in this member.";
 +    final String initialImageMessagesInFlightDesc = "The number of messages with initial image data sent from this member that have not yet been acknowledged.";
 +    final String initialImageRequestsInProgressDesc = "The number of initial images this member is currently receiving.";
 +
 +    //For GMSHealthMonitor
 +    final String heartbeatRequestsSentDesc = "Heartbeat request messages that this member has sent.";
 +    final String heartbeatRequestsReceivedDesc = "Heartbeat request messages that this member has received.";
 +    
 +    final String heartbeatsSentDesc = "Heartbeat messages that this member has sent.";
 +    final String heartbeatsReceivedDesc = "Heartbeat messages that this member has received.";
 +    
 +    final String suspectsSentDesc = "Suspect member messages that this member has sent.";
 +    final String suspectsReceivedDesc = "Suspect member messages that this member has received.";
 +    
 +    final String finalCheckRequestsSentDesc = "Final check requests that this member has sent.";
 +    final String finalCheckRequestsReceivedDesc = "Final check requests that this member has received.";
 +    
 +    final String finalCheckResponsesSentDesc = "Final check responses that this member has sent.";
 +    final String finalCheckResponsesReceivedDesc = "Final check responses that this member has received.";    
 +    
 +    final String tcpFinalCheckRequestsSentDesc = "TCP final check requests that this member has sent.";
 +    final String tcpFinalCheckRequestsReceivedDesc = "TCP final check requests that this member has received.";
 +    
 +    final String tcpFinalCheckResponsesSentDesc = "TCP final check responses that this member has sent.";
 +    final String tcpFinalCheckResponsesReceivedDesc = "TCP final check responses that this member has received.";
 +
 +    final String udpFinalCheckRequestsSentDesc = "UDP final check requests that this member has sent.";
 +    final String udpFinalCheckRequestsReceivedDesc = "UDP final check requests that this member has received.";
 +    
 +    final String udpFinalCheckResponsesSentDesc = "UDP final check responses that this member has sent.";
 +    final String udpFinalCheckResponsesReceivedDesc = "UDP final check responses that this member has received.";
 +
 +    StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
 +
 +    type = f.createType(
 +      statName,
 +      statDescription,
 +      new StatisticDescriptor[] {
 +        f.createLongCounter("sentMessages", sentMessagesDesc, "messages"),
 +        f.createLongCounter("commitMessages", sentCommitMessagesDesc, "messages"),
 +        f.createLongCounter("commitWaits", commitWaitsDesc, "messages"),
 +        f.createLongCounter("sentMessagesTime", sentMessagesTimeDesc, "nanoseconds", false),
 +        f.createLongGauge("sentMessagesMaxTime", sentMessagesMaxTimeDesc, "milliseconds", false),
 +        f.createLongCounter("broadcastMessages", broadcastMessagesDesc, "messages"),
 +        f.createLongCounter("broadcastMessagesTime", broadcastMessagesTimeDesc, "nanoseconds", false),
 +        f.createLongCounter("receivedMessages", receivedMessagesDesc, "messages"),
 +        f.createLongCounter("receivedBytes", receivedBytesDesc, "bytes"),
 +        f.createLongCounter("sentBytes", sentBytesDesc, "bytes"),
 +        f.createLongCounter("processedMessages", processedMessagesDesc, "messages"),
 +        f.createLongCounter("processedMessagesTime", processedMessagesTimeDesc, "nanoseconds", false),
 +        f.createLongCounter("messageProcessingScheduleTime", messageProcessingScheduleTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("overflowQueueSize", overflowQueueSizeDesc, "messages"),
 +        f.createIntGauge("waitingQueueSize", waitingQueueSizeDesc, "messages"),
 +        f.createIntGauge("overflowQueueThrottleCount", overflowQueueThrottleCountDesc, "delays"),
 +        f.createLongCounter("overflowQueueThrottleTime", overflowQueueThrottleTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("highPriorityQueueSize", highPriorityQueueSizeDesc, "messages"),
 +        f.createIntGauge("highPriorityQueueThrottleCount", highPriorityQueueThrottleCountDesc, "delays"),
 +        f.createLongCounter("highPriorityQueueThrottleTime", highPriorityQueueThrottleTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("partitionedRegionQueueSize", highPriorityQueueSizeDesc, "messages"),
 +        f.createIntGauge("partitionedRegionQueueThrottleCount", highPriorityQueueThrottleCountDesc, "delays"),
 +        f.createLongCounter("partitionedRegionQueueThrottleTime", highPriorityQueueThrottleTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("functionExecutionQueueSize", highPriorityQueueSizeDesc, "messages"),
 +        f.createIntGauge("functionExecutionQueueThrottleCount", highPriorityQueueThrottleCountDesc, "delays"),
 +        f.createLongCounter("functionExecutionQueueThrottleTime", highPriorityQueueThrottleTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("serialQueueSize", serialQueueSizeDesc, "messages"),
 +        f.createIntGauge("serialQueueBytes", serialQueueBytesDesc, "bytes"),
 +        f.createIntCounter("serialPooledThread", serialPooledThreadDesc, "threads"),
 +        f.createIntGauge("serialQueueThrottleCount", serialQueueThrottleCountDesc, "delays"),
 +        f.createLongCounter("serialQueueThrottleTime", serialQueueThrottleTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("serialThreads", serialThreadsDesc, "threads"),
 +        f.createIntGauge("processingThreads", processingThreadsDesc, "threads"),
 +        f.createIntGauge("highPriorityThreads", highPriorityThreadsDesc, "threads"),
 +        f.createIntGauge("partitionedRegionThreads", partitionedRegionThreadsDesc, "threads"),
 +        f.createIntGauge("functionExecutionThreads", functionExecutionThreadsDesc, "threads"),
 +        f.createIntGauge("waitingThreads", waitingThreadsDesc, "threads"),
 +        f.createLongCounter("messageChannelTime", messageChannelTimeDesc, "nanoseconds", false),
++        f.createLongCounter("udpDispatchRequestTime", udpDispatchRequestTimeDesc, "nanoseconds", false),
 +        f.createLongCounter("replyMessageTime", replyMessageTimeDesc, "nanoseconds", false),
 +        f.createLongCounter("distributeMessageTime", distributeMessageTimeDesc, "nanoseconds", false),
 +        f.createIntGauge("nodes", nodesDesc, "nodes"),
 +        f.createIntGauge("replyWaitsInProgress", replyWaitsInProgressDesc, "operations"),
 +        f.createIntCounter("replyWaitsCompleted", replyWaitsCompletedDesc, "operations"),
 +        f.createLongCounter("replyWaitTime", replyWaitTimeDesc, "nanoseconds", false),
 +        f.createLongGauge("replyWaitMaxTime", replyWaitMaxTimeDesc, "milliseconds", false),
 +        f.createLongCounter("replyTimeouts", replyTimeoutsDesc, "timeouts", false),
 +        f.createIntGauge("receivers", receiverConnectionsDesc, "sockets"),
 +        f.createIntGauge("sendersSO", sharedOrderedSenderConnectionsDesc, "sockets"),
 +        f.createIntGauge("sendersSU", sharedUnorderedSenderConnectionsDesc, "sockets"),
 +        f.createIntGauge("sendersTO", threadOrderedSenderConnectionsDesc, "sockets"),
 +        f.createIntGauge("sendersTU", threadUnorderedSenderConnectionsDesc, "sockets"),
 +        f.createIntCounter("failedAccepts", failedAcceptsDesc, "accepts"),
 +        f.createIntCounter("failedConnects", failedConnectsDesc, "connects"),
 +        f.createIntCounter("reconnectAttempts", reconnectAttemptsDesc, "connects"),
 +        f.createIntCounter("senderTimeouts", lostConnectionLeaseDesc, "expirations"),
 +
 +        f.createIntGauge("syncSocketWritesInProgress", "Current number of synchronous/blocking socket write calls in progress.", "writes"),
 +        f.createLongCounter("syncSocketWriteTime", "Total amount of time, in nanoseconds, spent in synchronous/blocking socket write calls.", "nanoseconds"),
 +        f.createIntCounter("syncSocketWrites", "Total number of completed synchronous/blocking socket write calls.", "writes"),
 +        f.createLongCounter("syncSocketWriteBytes", "Total number of bytes sent out in synchronous/blocking mode on sockets.", "bytes"),
 +
 +        f.createIntCounter("ucastReads", "Total number of unicast datagrams received", "datagrams"),
 +        f.createLongCounter("ucastReadBytes", "Total number of bytes received in unicast datagrams", "bytes"),
 +        f.createIntCounter("ucastWrites", "Total number of unicast datagram socket write calls.", "writes"),
 +        f.createLongCounter("ucastWriteBytes", "Total number of bytes sent out on unicast datagram sockets.", "bytes"),
 +        f.createIntCounter("ucastRetransmits", "Total number of unicast datagram socket retransmissions", "writes"),
 +
 +        f.createIntCounter("mcastReads", "Total number of multicast datagrams received", "datagrams"),
 +        f.createLongCounter("mcastReadBytes", "Total number of bytes received in multicast datagrams", "bytes"),
 +        f.createIntCounter("mcastWrites", "Total number of multicast datagram socket write calls.", "writes"),
 +        f.createLongCounter("mcastWriteBytes", "Total number of bytes sent out on multicast datagram sockets.", "bytes"),
 +        f.createIntCounter("mcastRetransmits", "Total number of multicast datagram socket retransmissions", "writes"),
 +        f.createIntCounter("mcastRetransmitRequests", "Total number of multicast datagram socket retransmission requests sent to other processes", "requests"),
 +
 +        f.createLongCounter("serializationTime", "Total amount of time, in nanoseconds, spent serializing objects. This includes pdx serializations.", "nanoseconds"),
 +        f.createIntCounter("serializations", "Total number of object serialization calls. This includes pdx serializations.", "ops"),
 +        f.createLongCounter("serializedBytes", "Total number of bytes produced by object serialization. This includes pdx serializations.", "bytes"),
 +        f.createIntCounter("pdxSerializations", "Total number of pdx serializations.", "ops"),
 +        f.createLongCounter("pdxSerializedBytes", "Total number of bytes produced by pdx serialization.", "bytes"),
 +        f.createLongCounter("deserializationTime", "Total amount of time, in nanoseconds, spent deserializing objects. This includes deserialization that results in a PdxInstance.", "nanoseconds"),
 +        f.createIntCounter("deserializations", "Total number of object deserialization calls. This includes deserialization that results in a PdxInstance.", "ops"),
 +        f.createLongCounter("deserializedBytes", "Total number of bytes read by object deserialization. This includes deserialization that results in a PdxInstance.", "bytes"),
 +        f.createIntCounter("pdxDeserializations", "Total number of pdx deserializations.", "ops"),
 +        f.createLongCounter("pdxDeserializedBytes", "Total number of bytes read by pdx deserialization.", "bytes"),
 +        f.createLongCounter("msgSerializationTime", "Total amount of time, in nanoseconds, spent serializing messages.", "nanoseconds"),
 +        f.createLongCounter("msgDeserializationTime", "Total amount of time, in nanoseconds, spent deserializing messages.", "nanoseconds"),
 +        f.createIntCounter("pdxInstanceDeserializations", "Total number of times getObject has been called on a PdxInstance.", "ops"),
 +        f.createLongCounter("pdxInstanceDeserializationTime", "Total amount of time, in nanoseconds, spent deserializing PdxInstances by calling getObject.", "nanoseconds"),
 +        f.createIntCounter("pdxInstanceCreations", "Total number of times a deserialization created a PdxInstance.", "ops"),
 +
 +        f.createLongCounter("batchSendTime", "Total amount of time, in nanoseconds, spent queueing and flushing message batches", "nanoseconds"),
 +        f.createLongCounter("batchWaitTime", "Reserved for future use", "nanoseconds"),
 +        f.createLongCounter("batchCopyTime", "Total amount of time, in nanoseconds, spent copying messages for batched transmission", "nanoseconds"),
 +        f.createLongCounter("batchFlushTime", "Total amount of time, in nanoseconds, spent flushing batched messages to the network", "nanoseconds"),
 +
 +        f.createIntGauge("asyncSocketWritesInProgress", "Current number of non-blocking socket write calls in progress.", "writes"),
 +        f.createIntCounter("asyncSocketWrites", "Total number of non-blocking socket write calls completed.", "writes"),
 +        f.createIntCounter("asyncSocketWriteRetries", "Total number of retries needed to write a single block of data using non-blocking socket write calls.", "writes"),
 +        f.createLongCounter("asyncSocketWriteTime", "Total amount of time, in nanoseconds, spent in non-blocking socket write calls.", "nanoseconds"),
 +        f.createLongCounter("asyncSocketWriteBytes", "Total number of bytes sent out on non-blocking sockets.", "bytes"),
 +
 +        f.createLongCounter("asyncQueueAddTime", "Total amount of time, in nanoseconds, spent in adding messages to async queue.", "nanoseconds"),
 +        f.createLongCounter("asyncQueueRemoveTime", "Total amount of time, in nanoseconds, spent in removing messages from async queue.", "nanoseconds"),
 +
 +        f.createIntGauge("asyncQueues", asyncQueuesDesc, "queues"),
 +        f.createIntGauge("asyncQueueFlushesInProgress", asyncQueueFlushesInProgressDesc, "operations"),
 +        f.createIntCounter("asyncQueueFlushesCompleted", asyncQueueFlushesCompletedDesc, "operations"),
 +        f.createLongCounter("asyncQueueFlushTime", asyncQueueFlushTimeDesc, "nanoseconds", false),
 +        f.createIntCounter("asyncQueueTimeoutExceeded", asyncQueueTimeoutExceededDesc, "timeouts"),
 +        f.createIntCounter("asyncQueueSizeExceeded", asyncQueueSizeExceededDesc, "operations"),
 +        f.createIntCounter("asyncDistributionTimeoutExceeded", asyncDistributionTimeoutExceededDesc, "operations"),
 +        f.createLongGauge("asyncQueueSize", asyncQueueSizeDesc, "bytes"),
 +        f.createLongCounter("asyncQueuedMsgs", asyncQueuedMsgsDesc, "msgs"),
 +        f.createLongCounter("asyncDequeuedMsgs", asyncDequeuedMsgsDesc, "msgs"),
 +        f.createLongCounter("asyncConflatedMsgs", asyncConflatedMsgsDesc, "msgs"),
 +
 +        f.createIntGauge("asyncThreads", asyncThreadsDesc, "threads"),
 +        f.createIntGauge("asyncThreadInProgress", asyncThreadInProgressDesc, "operations"),
 +        f.createIntCounter("asyncThreadCompleted", asyncThreadCompletedDesc, "operations"),
 +        f.createLongCounter("asyncThreadTime", asyncThreadTimeDesc, "nanoseconds", false),
 +
 +        f.createLongGauge("receiversTO", "Number of receiver threads owned by non-receiver threads in other members.", "threads"),
 +        f.createLongGauge("receiversTO2", "Number of receiver threads owned in turn by receiver threads in other members", "threads"),
 +
 +        f.createLongGauge("receiverDirectBufferSize", receiverDirectBufferSizeDesc, "bytes"),
 +        f.createLongGauge("receiverHeapBufferSize", receiverHeapBufferSizeDesc, "bytes"),
 +        f.createLongGauge("senderDirectBufferSize", senderDirectBufferSizeDesc, "bytes"),
 +        f.createLongGauge("senderHeapBufferSize", senderHeapBufferSizeDesc, "bytes"),
 +        f.createIntGauge("socketLocksInProgress", "Current number of threads waiting to lock a socket", "threads", false),
 +        f.createIntCounter("socketLocks", "Total number of times a socket has been locked.", "locks"),
 +        f.createLongCounter("socketLockTime", "Total amount of time, in nanoseconds, spent locking a socket", "nanoseconds", false),
 +        f.createIntGauge("bufferAcquiresInProgress", "Current number of threads waiting to acquire a buffer", "threads", false),
 +        f.createIntCounter("bufferAcquires", "Total number of times a buffer has been acquired.", "operations"),
 +        f.createLongCounter("bufferAcquireTime", "Total amount of time, in nanoseconds, spent acquiring a socket", "nanoseconds", false),
 +
 +        f.createIntGauge("messagesBeingReceived", "Current number of message being received off the network or being processed after reception.", "messages"),
 +        f.createLongGauge("messageBytesBeingReceived", "Current number of bytes consumed by messages being received or processed.", "bytes"),
 +
 +        f.createLongCounter("serialThreadStarts", "Total number of times a thread has been created for the serial message executor.", "starts", false),
 +        f.createLongCounter("viewThreadStarts", "Total number of times a thread has been created for the view message executor.", "starts", false),
 +        f.createLongCounter("processingThreadStarts", "Total number of times a thread has been created for the pool processing normal messages.", "starts", false),
 +        f.createLongCounter("highPriorityThreadStarts", "Total number of times a thread has been created for the pool handling high priority messages.", "starts", false),
 +        f.createLongCounter("waitingThreadStarts", "Total number of times a thread has been created for the waiting pool.", "starts", false),
 +        f.createLongCounter("partitionedRegionThreadStarts", "Total number of times a thread has been created for the pool handling partitioned region messages.", "starts", false),
 +        f.createLongCounter("functionExecutionThreadStarts", "Total number of times a thread has been created for the pool handling function execution messages.", "starts", false),
 +        f.createLongCounter("serialPooledThreadStarts", "Total number of times a thread has been created for the serial pool(s).", "starts", false),
 +        f.createLongCounter("TOSentMsgs", "Total number of messages sent on thread owned senders", "messages", false),
 +        f.createLongCounter("replyHandoffTime", replyHandoffTimeDesc, "nanoseconds"),
 +
 +        f.createIntGauge("partitionedRegionThreadJobs", partitionedRegionThreadJobsDesc, "messages"),
 +        f.createIntGauge("functionExecutionThreadJobs", functionExecutionThreadJobsDesc, "messages"),
 +        f.createIntGauge("viewThreads", viewThreadsDesc, "threads"),
 +        f.createIntGauge("serialThreadJobs", serialThreadJobsDesc, "messages"),
 +        f.createIntGauge("viewThreadJobs", viewThreadJobsDesc, "messages"),
 +        f.createIntGauge("serialPooledThreadJobs", serialPooledThreadJobsDesc, "messages"),
 +        f.createIntGauge("processingThreadJobs", processingThreadJobsDesc, "messages"),
 +        f.createIntGauge("highPriorityThreadJobs", highPriorityThreadJobsDesc, "messages"),
 +        f.createIntGauge("waitingThreadJobs", waitingThreadJobsDesc, "messages"),
 +
 +        f.createIntGauge("elders", eldersDesc, "elders"),
 +        f.createIntGauge("initialImageMessagesInFlight", initialImageMessagesInFlightDesc, "messages"),
 +        f.createIntGauge("initialImageRequestsInProgress", initialImageRequestsInProgressDesc, "requests"),
 +        
 +        //For GMSHealthMonitor
 +        f.createLongCounter("heartbeatRequestsSent", heartbeatRequestsSentDesc, "messages"),
 +        f.createLongCounter("heartbeatRequestsReceived", heartbeatRequestsReceivedDesc, "messages"),
 +        f.createLongCounter("heartbeatsSent", heartbeatsSentDesc, "messages"),
 +        f.createLongCounter("heartbeatsReceived", heartbeatsReceivedDesc, "messages"),
 +        f.createLongCounter("suspectsSent", suspectsSentDesc, "messages"),
 +        f.createLongCounter("suspectsReceived", suspectsReceivedDesc, "messages"),
 +        f.createLongCounter("finalCheckRequestsSent", finalCheckRequestsSentDesc, "messages"),
 +        f.createLongCounter("finalCheckRequestsReceived", finalCheckRequestsReceivedDesc, "messages"),
 +        f.createLongCounter("finalCheckResponsesSent", finalCheckResponsesSentDesc, "messages"),
 +        f.createLongCounter("finalCheckResponsesReceived", finalCheckResponsesReceivedDesc, "messages"),
 +        f.createLongCounter("tcpFinalCheckRequestsSent", tcpFinalCheckRequestsSentDesc, "nanoseconds", false),
 +        f.createLongCounter("tcpFinalCheckRequestsReceived", tcpFinalCheckRequestsReceivedDesc, "nanoseconds", false),
 +        f.createLongCounter("tcpFinalCheckResponsesSent", tcpFinalCheckResponsesSentDesc, "nanoseconds", false),
 +        f.createLongCounter("tcpFinalCheckResponsesReceived", tcpFinalCheckResponsesReceivedDesc, "nanoseconds", false),
 +        f.createLongCounter("udpFinalCheckRequestsSent", udpFinalCheckRequestsSentDesc, "messages"),
 +        f.createLongCounter("udpFinalCheckRequestsReceived", udpFinalCheckRequestsReceivedDesc, "messages"),
 +        f.createLongCounter("udpFinalCheckResponsesSent", udpFinalCheckResponsesSentDesc, "messages"),
 +        f.createLongCounter("udpFinalCheckResponsesReceived", udpFinalCheckResponsesReceivedDesc, "messages"),
 +      }
 +    );
 +
 +    // Initialize id fields
 +    sentMessagesId = type.nameToId("sentMessages");
 +    sentCommitMessagesId = type.nameToId("commitMessages");
 +    commitWaitsId = type.nameToId("commitWaits");
 +    sentMessagesTimeId = type.nameToId("sentMessagesTime");
 +    sentMessagesMaxTimeId = type.nameToId("sentMessagesMaxTime");
 +    broadcastMessagesId = type.nameToId("broadcastMessages");
 +    broadcastMessagesTimeId = type.nameToId("broadcastMessagesTime");
 +    receivedMessagesId = type.nameToId("receivedMessages");
 +    receivedBytesId = type.nameToId("receivedBytes");
 +    sentBytesId = type.nameToId("sentBytes");
 +    processedMessagesId = type.nameToId("processedMessages");
 +    processedMessagesTimeId = type.nameToId("processedMessagesTime");
 +    messageProcessingScheduleTimeId =
 +      type.nameToId("messageProcessingScheduleTime");
 +    messageChannelTimeId = type.nameToId("messageChannelTime");
++    udpDispatchRequestTimeId = type.nameToId("udpDispatchRequestTime");
 +    replyMessageTimeId = type.nameToId("replyMessageTime");
 +    distributeMessageTimeId = type.nameToId("distributeMessageTime");
 +    nodesId = type.nameToId("nodes");
 +    overflowQueueSizeId = type.nameToId("overflowQueueSize");
 +    waitingQueueSizeId = type.nameToId("waitingQueueSize");
 +    overflowQueueThrottleTimeId = type.nameToId("overflowQueueThrottleTime");
 +    overflowQueueThrottleCountId = type.nameToId("overflowQueueThrottleCount");
 +    highPriorityQueueSizeId = type.nameToId("highPriorityQueueSize");
 +    highPriorityQueueThrottleTimeId = type.nameToId("highPriorityQueueThrottleTime");
 +    highPriorityQueueThrottleCountId = type.nameToId("highPriorityQueueThrottleCount");
 +    partitionedRegionQueueSizeId = type.nameToId("partitionedRegionQueueSize");
 +    partitionedRegionQueueThrottleTimeId = type.nameToId("partitionedRegionQueueThrottleTime");
 +    partitionedRegionQueueThrottleCountId = type.nameToId("partitionedRegionQueueThrottleCount");
 +    functionExecutionQueueSizeId = type.nameToId("functionExecutionQueueSize");
 +    functionExecutionQueueThrottleTimeId = type.nameToId("functionExecutionQueueThrottleTime");
 +    functionExecutionQueueThrottleCountId = type.nameToId("functionExecutionQueueThrottleCount");
 +    serialQueueSizeId = type.nameToId("serialQueueSize");
 +    serialQueueBytesId = type.nameToId("serialQueueBytes");
 +    serialPooledThreadId = type.nameToId("serialPooledThread");
 +    serialQueueThrottleTimeId = type.nameToId("serialQueueThrottleTime");
 +    serialQueueThrottleCountId = type.nameToId("serialQueueThrottleCount");
 +    serialThreadsId = type.nameToId("serialThreads");
 +    processingThreadsId = type.nameToId("processingThreads");
 +    highPriorityThreadsId = type.nameToId("highPriorityThreads");
 +    partitionedRegionThreadsId = type.nameToId("partitionedRegionThreads");
 +    functionExecutionThreadsId = type.nameToId("functionExecutionThreads");
 +    waitingThreadsId = type.nameToId("waitingThreads");
 +    replyWaitsInProgressId = type.nameToId("replyWaitsInProgress");
 +    replyWaitsCompletedId = type.nameToId("replyWaitsCompleted");
 +    replyWaitTimeId = type.nameToId("replyWaitTime");
 +    replyTimeoutsId = type.nameToId("replyTimeouts");
 +    replyWaitMaxTimeId = type.nameToId("replyWaitMaxTime");
 +    receiverConnectionsId = type.nameToId("receivers");
 +    failedAcceptsId = type.nameToId("failedAccepts");
 +    failedConnectsId = type.nameToId("failedConnects");
 +    reconnectAttemptsId = type.nameToId("reconnectAttempts");
 +    lostConnectionLeaseId = type.nameToId("senderTimeouts");
 +    sharedOrderedSenderConnectionsId = type.nameToId("sendersSO");
 +    sharedUnorderedSenderConnectionsId = type.nameToId("sendersSU");
 +    threadOrderedSenderConnectionsId = type.nameToId("sendersTO");
 +    threadUnorderedSenderConnectionsId = type.nameToId("sendersTU");
 +
 +    syncSocketWritesInProgressId = type.nameToId("syncSocketWritesInProgress");
 +    syncSocketWriteTimeId = type.nameToId("syncSocketWriteTime");
 +    syncSocketWritesId = type.nameToId("syncSocketWrites");
 +    syncSocketWriteBytesId = type.nameToId("syncSocketWriteBytes");
 +
 +    ucastReadsId = type.nameToId("ucastReads");
 +    ucastReadBytesId = type.nameToId("ucastReadBytes");
 +    ucastWritesId = type.nameToId("ucastWrites");
 +    ucastWriteBytesId = type.nameToId("ucastWriteBytes");
 +    ucastRetransmitsId = type.nameToId("ucastRetransmits");
 +
 +    mcastReadsId = type.nameToId("mcastReads");
 +    mcastReadBytesId = type.nameToId("mcastReadBytes");
 +    mcastWritesId = type.nameToId("mcastWrites");
 +    mcastWriteBytesId = type.nameToId("mcastWriteBytes");
 +    mcastRetransmitsId = type.nameToId("mcastRetransmits");
 +    mcastRetransmitRequestsId = type.nameToId("mcastRetransmitRequests");
 +
 +    serializationTimeId = type.nameToId("serializationTime");
 +    serializationsId = type.nameToId("serializations");
 +    serializedBytesId = type.nameToId("serializedBytes");
 +    deserializationTimeId = type.nameToId("deserializationTime");
 +    deserializationsId = type.nameToId("deserializations");
 +    deserializedBytesId = type.nameToId("deserializedBytes");
 +    pdxSerializationsId = type.nameToId("pdxSerializations");
 +    pdxSerializedBytesId = type.nameToId("pdxSerializedBytes");
 +    pdxDeserializationsId = type.nameToId("pdxDeserializations");
 +    pdxDeserializedBytesId = type.nameToId("pdxDeserializedBytes");
 +    pdxInstanceDeserializationsId = type.nameToId("pdxInstanceDeserializations");
 +    pdxInstanceDeserializationTimeId = type.nameToId("pdxInstanceDeserializationTime");
 +    pdxInstanceCreationsId = type.nameToId("pdxInstanceCreations");
 +
 +    msgSerializationTimeId = type.nameToId("msgSerializationTime");
 +    msgDeserializationTimeId = type.nameToId("msgDeserializationTime");
 +
 +    batchSendTimeId = type.nameToId("batchSendTime");
 +    batchCopyTimeId = type.nameToId("batchCopyTime");
 +    batchWaitTimeId = type.nameToId("batchWaitTime");
 +    batchFlushTimeId = type.nameToId("batchFlushTime");
 +
 +    asyncSocketWritesInProgressId = type.nameToId("asyncSocketWritesInProgress");
 +    asyncSocketWritesId = type.nameToId("asyncSocketWrites");
 +    asyncSocketWriteRetriesId = type.nameToId("asyncSocketWriteRetries");
 +    asyncSocketWriteTimeId = type.nameToId("asyncSocketWriteTime");
 +    asyncSocketWriteBytesId = type.nameToId("asyncSocketWriteBytes");
 +
 +    asyncQueueAddTimeId = type.nameToId("asyncQueueAddTime");
 +    asyncQueueRemoveTimeId = type.nameToId("asyncQueueRemoveTime");
 +
 +    asyncQueuesId = type.nameToId("asyncQueues");
 +    asyncQueueFlushesInProgressId = type.nameToId("asyncQueueFlushesInProgress");
 +    asyncQueueFlushesCompletedId = type.nameToId("asyncQueueFlushesCompleted");
 +    asyncQueueFlushTimeId = type.nameToId("asyncQueueFlushTime");
 +    asyncQueueTimeoutExceededId = type.nameToId("asyncQueueTimeoutExceeded");
 +    asyncQueueSizeExceededId = type.nameToId("asyncQueueSizeExceeded");
 +    asyncDistributionTimeoutExceededId = type.nameToId("asyncDistributionTimeoutExceeded");
 +    asyncQueueSizeId = type.nameToId("asyncQueueSize");
 +    asyncQueuedMsgsId = type.nameToId("asyncQueuedMsgs");
 +    asyncDequeuedMsgsId = type.nameToId("asyncDequeuedMsgs");
 +    asyncConflatedMsgsId = type.nameToId("asyncConflatedMsgs");
 +
 +    asyncThreadsId = type.nameToId("asyncThreads");
 +    asyncThreadInProgressId = type.nameToId("asyncThreadInProgress");
 +    asyncThreadCompletedId = type.nameToId("asyncThreadCompleted");
 +    asyncThreadTimeId = type.nameToId("asyncThreadTime");
 +
 +    threadOwnedReceiversId = type.nameToId("receiversTO");
 +    threadOwnedReceiversId2 = type.nameToId("receiversTO2");
 +
 +    receiverDirectBufferSizeId = type.nameToId("receiverDirectBufferSize");
 +    receiverHeapBufferSizeId = type.nameToId("receiverHeapBufferSize");
 +    senderDirectBufferSizeId = type.nameToId("senderDirectBufferSize");
 +    senderHeapBufferSizeId = type.nameToId("senderHeapBufferSize");
 +
 +    socketLocksInProgressId = type.nameToId("socketLocksInProgress");
 +    socketLocksId = type.nameToId("socketLocks");
 +    socketLockTimeId = type.nameToId("socketLockTime");
 +
 +    bufferAcquiresInProgressId = type.nameToId("bufferAcquiresInProgress");
 +    bufferAcquiresId = type.nameToId("bufferAcquires");
 +    bufferAcquireTimeId = type.nameToId("bufferAcquireTime");
 +    messagesBeingReceivedId = type.nameToId("messagesBeingReceived");
 +    messageBytesBeingReceivedId = type.nameToId("messageBytesBeingReceived");
 +
 +    serialThreadStartsId = type.nameToId("serialThreadStarts");
 +    viewThreadStartsId = type.nameToId("viewThreadStarts");
 +    processingThreadStartsId = type.nameToId("processingThreadStarts");
 +    highPriorityThreadStartsId = type.nameToId("highPriorityThreadStarts");
 +    waitingThreadStartsId = type.nameToId("waitingThreadStarts");
 +    partitionedRegionThreadStartsId = type.nameToId("partitionedRegionThreadStarts");
 +    functionExecutionThreadStartsId = type.nameToId("functionExecutionThreadStarts");
 +    serialPooledThreadStartsId = type.nameToId("serialPooledThreadStarts");
 +    TOSentMsgId = type.nameToId("TOSentMsgs");
 +    replyHandoffTimeId = type.nameToId("replyHandoffTime");
 +    partitionedRegionThreadJobsId = type.nameToId("partitionedRegionThreadJobs");
 +    functionExecutionThreadJobsId = type.nameToId("functionExecutionThreadJobs");
 +    viewThreadsId = type.nameToId("viewThreads");
 +    serialThreadJobsId = type.nameToId("serialThreadJobs");
 +    viewProcessorThreadJobsId = type.nameToId("viewThreadJobs");
 +    serialPooledThreadJobsId = type.nameToId("serialPooledThreadJobs");
 +    pooledMessageThreadJobsId = type.nameToId("processingThreadJobs");
 +    highPriorityThreadJobsId = type.nameToId("highPriorityThreadJobs");
 +    waitingPoolThreadJobsId = type.nameToId("waitingThreadJobs");
 +
 +    eldersId = type.nameToId("elders");
 +    initialImageMessagesInFlightId = type.nameToId("initialImageMessagesInFlight");
 +    initialImageRequestsInProgressId = type.nameToId("initialImageRequestsInProgress");
 +    
 +    //For GMSHealthMonitor
 +    heartbeatRequestsSentId = type.nameToId("heartbeatRequestsSent");
 +    heartbeatRequestsReceivedId = type.nameToId("heartbeatRequestsReceived");
 +    heartbeatsSentId = type.nameToId("heartbeatsSent");
 +    heartbeatsReceivedId = type.nameToId("heartbeatsReceived");
 +    suspectsSentId = type.nameToId("suspectsSent");
 +    suspectsReceivedId = type.nameToId("suspectsReceived");
 +    finalCheckRequestsSentId = type.nameToId("finalCheckRequestsSent");
 +    finalCheckRequestsReceivedId = type.nameToId("finalCheckRequestsReceived");
 +    finalCheckResponsesSentId = type.nameToId("finalCheckResponsesSent");
 +    finalCheckResponsesReceivedId = type.nameToId("finalCheckResponsesReceived");
 +    tcpFinalCheckRequestsSentId = type.nameToId("tcpFinalCheckRequestsSent");
 +    tcpFinalCheckRequestsReceivedId = type.nameToId("tcpFinalCheckRequestsReceived");
 +    tcpFinalCheckResponsesSentId = type.nameToId("tcpFinalCheckResponsesSent");
 +    tcpFinalCheckResponsesReceivedId = type.nameToId("tcpFinalCheckResponsesReceived");
 +    udpFinalCheckRequestsSentId = type.nameToId("udpFinalCheckRequestsSent");
 +    udpFinalCheckRequestsReceivedId = type.nameToId("udpFinalCheckRequestsReceived");
 +    udpFinalCheckResponsesSentId = type.nameToId("udpFinalCheckResponsesSent");
 +    udpFinalCheckResponsesReceivedId = type.nameToId("udpFinalCheckResponsesReceived");
 +  }
 +
 +  /** The Statistics object that we delegate most behavior to */
 +  private final Statistics stats;
 +
 +//  private final HistogramStats replyHandoffHistogram;
 +//  private final HistogramStats replyWaitHistogram;
 +
 +  ////////////////////////  Constructors  ////////////////////////
 +
 +  /**
 +   * Creates a new <code>DistributionStats</code> and registers itself
 +   * with the given statistics factory.
 +   */
 +  public DistributionStats(StatisticsFactory f, long statId) {
 +    this.stats = f.createAtomicStatistics(type, "distributionStats", statId);
 +//    this.replyHandoffHistogram = new HistogramStats("ReplyHandOff", "nanoseconds", f,
 +//        new long[] {100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000}, false);
 +//    this.replyWaitHistogram = new HistogramStats("ReplyWait", "nanoseconds", f,
 +//        new long[] {100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000}, false);
 +    Buffers.initBufferStats(this);
 +  }
 +  /**
 +   * Used by tests to create an instance given its already existings stats.
 +   */
 +  public DistributionStats(Statistics stats) {
 +    this.stats = stats;
 +//    this.replyHandoffHistogram = null;
 +//    this.replyWaitHistogram = null;
 +  }
 +
 +  /**
 +   * Returns the current NanoTime or, if clock stats are disabled, zero.
 +   * @since 5.0
 +   */
 +  public static long getStatTime() {
 +    return enableClockStats? NanoTimer.getTime() : 0;
 +  }
 +
 +  //////////////////////  Instance Methods  //////////////////////
 +
 +  public void close() {
 +    this.stats.close();
 +  }
 +
 + /**
 +   * Returns the total number of messages sent by the distribution
 +   * manager
 +   */
 +  public long getSentMessages() {
 +    return this.stats.getLong(sentMessagesId);
 +  }
 +  public void incTOSentMsg() {
 +    this.stats.incLong(TOSentMsgId, 1);
 +  }
 +
 +  public long getSentCommitMessages() {
 +    return this.stats.getLong(sentCommitMessagesId);
 +  }
 +
 +  public long getCommitWaits() {
 +    return this.stats.getLong(commitWaitsId);
 +  }
 +
 +  /**
 +   * Increments the total number of messages sent by the distribution
 +   * manager
 +   */
 +  public void incSentMessages(long messages) {
 +    this.stats.incLong(sentMessagesId, messages);
 +  }
 +  /**
 +   * Increments the total number of transactino commit messages
 +   * sent by the distribution manager
 +   */
 +  public void incSentCommitMessages(long messages) {
 +    this.stats.incLong(sentCommitMessagesId, messages);
 +  }
 +  public void incCommitWaits() {
 +    this.stats.incLong(commitWaitsId, 1);
 +  }
 +
 +  /**
 +   * Returns the total number of nanoseconds spent sending messages.
 +   */
 +  public long getSentMessagesTime() {
 +    return this.stats.getLong(sentMessagesTimeId);
 +  }
 +
 +  /**
 +   * Increments the total number of nanoseconds spend sending messages.<p>
 +   * This also sets the sentMessagesMaxTime, if appropriate
 +   */
 +  public void incSentMessagesTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(sentMessagesTimeId, nanos);
 +      long millis = nanos / 1000000;
 +      if (getSentMessagesMaxTime() < millis) {
 +        this.stats.setLong(sentMessagesMaxTimeId, millis);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Returns the longest time required to distribute a message, in nanos
 +   */
 +  public long getSentMessagesMaxTime() {
 +    return this.stats.getLong(sentMessagesMaxTimeId);
 +  }
 +
 +
 +  /**
 +   * Returns the total number of messages broadcast by the distribution
 +   * manager
 +   */
 +  public long getBroadcastMessages() {
 +    return this.stats.getLong(broadcastMessagesId);
 +  }
 +
 +  /**
 +   * Increments the total number of messages broadcast by the distribution
 +   * manager
 +   */
 +  public void incBroadcastMessages(long messages) {
 +    this.stats.incLong(broadcastMessagesId, messages);
 +  }
 +
 +  /**
 +   * Returns the total number of nanoseconds spent sending messages.
 +   */
 +  public long getBroadcastMessagesTime() {
 +    return this.stats.getLong(broadcastMessagesTimeId);
 +  }
 +
 +  /**
 +   * Increments the total number of nanoseconds spend sending messages.
 +   */
 +  public void incBroadcastMessagesTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(broadcastMessagesTimeId, nanos);
 +    }
 +  }
 +
 +  /**
 +   * Returns the total number of messages received by the distribution
 +   * manager
 +   */
 +  public long getReceivedMessages() {
 +    return this.stats.getLong(receivedMessagesId);
 +  }
 +
 +  /**
 +   * Increments the total number of messages received by the distribution
 +   * manager
 +   */
 +  public void incReceivedMessages(long messages) {
 +    this.stats.incLong(receivedMessagesId, messages);
 +  }
 +
 +  /**
 +   * Returns the total number of bytes received by the distribution
 +   * manager
 +   */
 +  public long getReceivedBytes() {
 +    return this.stats.getLong(receivedBytesId);
 +  }
 +
 +  public void incReceivedBytes(long bytes) {
 +    this.stats.incLong(receivedBytesId, bytes);
 +  }
 +
 +  public void incSentBytes(long bytes) {
 +    this.stats.incLong(sentBytesId, bytes);
 +  }
 +
 +  /**
 +   * Returns the total number of messages processed by the distribution
 +   * manager
 +   */
 +  public long getProcessedMessages() {
 +    return this.stats.getLong(processedMessagesId);
 +  }
 +
 +  /**
 +   * Increments the total number of messages processed by the distribution
 +   * manager
 +   */
 +  public void incProcessedMessages(long messages) {
 +    this.stats.incLong(processedMessagesId, messages);
 +  }
 +
 +  /**
 +   * Returns the total number of nanoseconds spent processing messages.
 +   */
 +  public long getProcessedMessagesTime() {
 +    return this.stats.getLong(processedMessagesTimeId);
 +  }
 +
 +  /**
 +   * Increments the total number of nanoseconds spend processing messages.
 +   */
 +  public void incProcessedMessagesTime(long start) {
 +    if (enableClockStats) {
 +      this.stats.incLong(processedMessagesTimeId, getStatTime()-start);
 +    }
 +  }
 +
 +  /**
 +   * Returns the total number of nanoseconds spent scheduling messages to be processed.
 +   */
 +  public long getMessageProcessingScheduleTime() {
 +    return this.stats.getLong(messageProcessingScheduleTimeId);
 +  }
 +
 +  /**
 +   * Increments the total number of nanoseconds spent scheduling messages to be processed.
 +   */
 +  public void incMessageProcessingScheduleTime(long elapsed) {
 +    if (enableClockStats) {
 +      this.stats.incLong(messageProcessingScheduleTimeId, elapsed);
 +    }
 +  }
 +
 +  public int getOverflowQueueSize() {
 +    return this.stats.getInt(overflowQueueSizeId);
 +  }
 +
 +  public void incOverflowQueueSize(int messages) {
 +    this.stats.incInt(overflowQueueSizeId, messages);
 +  }
 +
 +  protected void incWaitingQueueSize(int messages) {
 +    this.stats.incInt(waitingQueueSizeId, messages);
 +  }
 +
 +  protected void incOverflowQueueThrottleCount(int delays) {
 +    this.stats.incInt(overflowQueueThrottleCountId, delays);
 +  }
 +  protected void incOverflowQueueThrottleTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(overflowQueueThrottleTimeId, nanos);
 +    }
 +  }
 +
 +  protected void incHighPriorityQueueSize(int messages) {
 +    this.stats.incInt(highPriorityQueueSizeId, messages);
 +  }
 +  protected void incHighPriorityQueueThrottleCount(int delays) {
 +    this.stats.incInt(highPriorityQueueThrottleCountId, delays);
 +  }
 +  protected void incHighPriorityQueueThrottleTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(highPriorityQueueThrottleTimeId, nanos);
 +    }
 +  }
 +
 +  protected void incPartitionedRegionQueueSize(int messages) {
 +    this.stats.incInt(partitionedRegionQueueSizeId, messages);
 +  }
 +  protected void incPartitionedRegionQueueThrottleCount(int delays) {
 +    this.stats.incInt(partitionedRegionQueueThrottleCountId, delays);
 +  }
 +  protected void incPartitionedRegionQueueThrottleTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(partitionedRegionQueueThrottleTimeId, nanos);
 +    }
 +  }
 +
 +  protected void incFunctionExecutionQueueSize(int messages) {
 +    this.stats.incInt(functionExecutionQueueSizeId, messages);
 +  }
 +  protected void incFunctionExecutionQueueThrottleCount(int delays) {
 +    this.stats.incInt(functionExecutionQueueThrottleCountId, delays);
 +  }
 +  protected void incFunctionExecutionQueueThrottleTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(functionExecutionQueueThrottleTimeId, nanos);
 +    }
 +  }
 +
 +  protected void incSerialQueueSize(int messages) {
 +    this.stats.incInt(serialQueueSizeId, messages);
 +  }
 +  protected void incSerialQueueBytes(int amount) {
 +    this.stats.incInt(serialQueueBytesId, amount);
 +  }
 +  public int getSerialQueueBytes() {
 +    return this.stats.getInt(serialQueueBytesId);
 +  }
 +  protected void incSerialPooledThread() {
 +    this.stats.incInt(serialPooledThreadId, 1);
 +  }
 +
 +  protected void incSerialQueueThrottleCount(int delays) {
 +    this.stats.incInt(serialQueueThrottleCountId, delays);
 +  }
 +  protected void incSerialQueueThrottleTime(long nanos) {
 +    if (enableClockStats) {
 +      this.stats.incLong(serialQueueThrottleTimeId, nanos);
 +    }
 +  }
 +  public int getNumProcessingThreads() {
 +    return this.stats.getInt(processingThreadsId);
 +  }
 +
 +  public void incNumProcessingThreads(int threads) {
 +    this.stats.incInt(processingThreadsId, threads);
 +  }
 +
 +  public int getNumSerialThreads() {
 +    return this.stats.getInt(serialThreadsId);
 +  }
 +
 +  public void incNumSerialThreads(int threads) {
 +    this.stats.incInt(serialThreadsId, threads);
 +  }
 +  protected void incWaitingThreads(int threads) {
 +    this.stats.incInt(waitingThreadsId, threads);
 +  }
 +
 +  protected void incHighPriorityThreads(int threads) {
 +    this.stats.incInt(highPriorityThreadsId, threads);
 +  }
 +
 +  protected void incPartitionedRegionThreads(int threads) {
 +    this.stats.incInt(partitionedRegionThreadsId, threads);
 +  }
 +
 +  protected void incFunctionExecutionThreads(int threads) {
 +    this.stats.incInt(functionExecutionThreadsId, threads);
 +  }
 +
 +  public void incMessageChannelTime(long delta) {
 +    if (enableClockStats) {
 +      this.stats.incLong(messageChannelTimeId, delta);
 +    }
 +  }
++  
++  public void incUDPDispatchRequestTime(long delta) {
++    if (enableClockStats) {
++      this.stats.incLong(udpDispatchRequestTimeId, delta);
++    }
++  }
 +
++  public long getUDPDispatchRequestTime() {
++    return this.stats.getLong(udpDispatchRequestTimeId);
++  }
++  
 +  public long getReplyMessageTime() {
 +    return this.stats.getLong(replyMessageTimeId);
 +  }
 +  public void incReplyMessageTime(long val) {
 +    if (enableClockStats) {
 +      this.stats.incLong(replyMessageTimeId, val);
 +    }
 +  }
 +
 +  public long getDistributeMessageTime() {
 +    return this.stats.getLong(distributeMessageTimeId);
 +  }
 +  public void incDistributeMessageTime(long val) {
 +    if (enableClockStats) {
 +      this.stats.incLong(distributeMessageTimeId, val);
 +    }
 +  }
 +
 +  public int getNodes() {
 +    return this.stats.getInt(nodesId);
 +  }
 +  public void setNodes(int val) {
 +    this.stats.setInt(nodesId, val);
 +  }
 +  public void incNodes(int val) {
 +    this.stats.incInt(nodesId, val);
 +  }
 +  public int getReplyWaitsInProgress() {
 +    return stats.getInt(replyWaitsInProgressId);
 +  }
 +  public int getReplyWaitsCompleted() {
 +    return stats.getInt(replyWaitsCompletedId);
 +  }
 +  public long getReplyWaitTime() {
 +    return stats.getLong(replyWaitTimeId);
 +  }
 +  public long getReplyWaitMaxTime() {
 +    return stats.getLong(replyWaitMaxTimeId);
 +  }
 +  public long startSocketWrite(boolean sync) {
 +    if (sync) {
 +      stats.incInt(syncSocketWritesInProgressId, 1);
 +    } else {
 +      stats.incInt(asyncSocketWritesInProgressId, 1);
 +    }
 +    return getStatTime();
 +  }
 +  public void endSocketWrite(boolean sync, long start, int bytesWritten, int retries) {
 +    final long now = getStatTime();
 +    if (sync) {
 +      stats.incInt(syncSocketWritesInProgressId, -1);
 +      stats.incInt(syncSocketWritesId, 1);
 +      stats.incLong(syncSocketWriteBytesId, bytesWritten);
 +      if (enableClockStats) {
 +        stats.incLong(syncSocketWriteTimeId, now-start);
 +      }
 +    } else {
 +      stats.incInt(asyncSocketWritesInProgressId, -1);
 +      stats.incInt(asyncSocketWritesId, 1);
 +      if (retries != 0) {
 +        stats.incInt(asyncSocketWriteRetriesId, retries);
 +      }
 +      stats.incLong(asyncSocketWriteBytesId, bytesWritten);
 +      if (enableClockStats) {
 +        stats.incLong(asyncSocketWriteTimeId, now-start);
 +      }
 +    }
 +  }
 +  public long startSocketLock() {
 +    stats.incInt(socketLocksInProgressId, 1);
 +    return getStatTime();
 +  }
 +  public void endSocketLock(long start) {
 +    long ts = getStatTime();
 +    stats.incInt(socketLocksInProgressId, -1);
 +    stats.incInt(socketLocksId, 1);
 +    stats.incLong(socketLockTimeId, ts-start);
 +  }
 +  public long startBufferAcquire() {
 +    stats.incInt(bufferAcquiresInProgressId, 1);
 +    return getStatTime();
 +  }
 +  public void endBufferAcquire(long start) {
 +    long ts = getStatTime();
 +    stats.incInt(bufferAcquiresInProgressId, -1);
 +    stats.incInt(bufferAcquiresId, 1);
 +    stats.incLong(bufferAcquireTimeId, ts-start);
 +  }
 +
 +  public void incUcastWriteBytes(int bytesWritten) {
 +    stats.incInt(ucastWritesId, 1);
 +    stats.incLong(ucastWriteBytesId, bytesWritten);
 +  }
 +
 +  public void incMcastWriteBytes(int bytesWritten) {
 +    stats.incInt(mcastWritesId, 1);
 +    stats.incLong(mcastWriteBytesId, bytesWritten);
 +  }
 +
 +  public int getMcastWrites() {
 +    return stats.getInt(mcastWritesId);
 +  }
 +  public int getMcastReads() {
 +    return stats.getInt(mcastReadsId);
 +  }
 +  public void incMcastReadBytes(int amount) {
 +    stats.incInt(mcastReadsId, 1);
 +    stats.incLong(mcastReadBytesId, amount);
 +  }
 +  public void incUcastReadBytes(int amount) {
 +    stats.incInt(ucastReadsId, 1);
 +    stats.incLong(ucastReadBytesId, amount);
 +  }
 +  public long startSerialization() {
 +    return getStatTime();
 +  }
 +  public void endSerialization(long start, int bytes) {
 +    if (enableClockStats) {
 +      stats.incLong(serializationTimeId, getStatTime()-start);
 +    }
 +    stats.incInt(serializationsId, 1);
 +    stats.incLong(serializedBytesId, bytes);
 +  }
 +  public long startPdxInstanceDeserialization() {
 +    return getStatTime();
 +  }
 +  public void endPdxInstanceDeserialization(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(pdxInstanceDeserializationTimeId, getStatTime()-start);
 +    }
 +    stats.incInt(pdxInstanceDeserializationsId, 1);
 +  }
 +  public void incPdxSerialization(int bytes) {
 +    stats.incInt(pdxSerializationsId, 1);
 +    stats.incLong(pdxSerializedBytesId, bytes);
 +  }
 +  public void incPdxDeserialization(int bytes) {
 +    stats.incInt(pdxDeserializationsId, 1);
 +    stats.incLong(pdxDeserializedBytesId, bytes);
 +  }
 +  public void incPdxInstanceCreations() {
 +    stats.incInt(pdxInstanceCreationsId, 1);
 +  }
 +  public long startDeserialization() {
 +    return getStatTime();
 +  }
 +  public void endDeserialization(long start, int bytes) {
 +    if (enableClockStats) {
 +      stats.incLong(deserializationTimeId, getStatTime()-start);
 +    }
 +    stats.incInt(deserializationsId, 1);
 +    stats.incLong(deserializedBytesId, bytes);
 +  }
 +  public long startMsgSerialization() {
 +    return getStatTime();
 +  }
 +  public void endMsgSerialization(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(msgSerializationTimeId, getStatTime()-start);
 +    }
 +  }
 +  public long startMsgDeserialization() {
 +    return getStatTime();
 +  }
 +  public void endMsgDeserialization(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(msgDeserializationTimeId, getStatTime()-start);
 +    }
 +  }
 +  /**
 +   * @return the timestamp that marks the start of the operation
 +   */
 +  public long startReplyWait() {
 +    stats.incInt(replyWaitsInProgressId, 1);
 +    return getStatTime();
 +  }
 +  public void endReplyWait(long startNanos, long initTime) {
 +    if (enableClockStats) {
 +      stats.incLong(replyWaitTimeId, getStatTime()-startNanos);
 +//      this.replyWaitHistogram.endOp(delta);
 +    }
 +    if (initTime != 0) {
 +      long mswait = System.currentTimeMillis() - initTime;
 +      if (mswait > getReplyWaitMaxTime()) {
 +        stats.setLong(replyWaitMaxTimeId, mswait);
 +      }
 +    }
 +    stats.incInt(replyWaitsInProgressId, -1);
 +    stats.incInt(replyWaitsCompletedId, 1);
 +    
 +    Breadcrumbs.setSendSide(null); // clear any recipient breadcrumbs set by the message
 +    Breadcrumbs.setProblem(null); // clear out reply-wait errors
 +  }
 +
 +  public void incReplyTimeouts() {
 +    stats.incLong(replyTimeoutsId, 1L);
 +  }
 +
 +  public long getReplyTimeouts() {
 +    return stats.getLong(replyTimeoutsId);
 +  }
 +
 +  public void incReceivers() {
 +    stats.incInt(receiverConnectionsId, 1);
 +  }
 +  public void decReceivers() {
 +    stats.incInt(receiverConnectionsId, -1);
 +  }
 +  public void incFailedAccept() {
 +    stats.incInt(failedAcceptsId, 1);
 +  }
 +  public void incFailedConnect() {
 +    stats.incInt(failedConnectsId, 1);
 +  }
 +  public void incReconnectAttempts() {
 +    stats.incInt(reconnectAttemptsId, 1);
 +  }
 +  public void incLostLease() {
 +    stats.incInt(lostConnectionLeaseId, 1);
 +  }
 +  public void incSenders(boolean shared, boolean preserveOrder) {
 +    if (shared) {
 +      if (preserveOrder) {
 +        stats.incInt(sharedOrderedSenderConnectionsId, 1);
 +      } else {
 +        stats.incInt(sharedUnorderedSenderConnectionsId, 1);
 +      }
 +    } else {
 +      if (preserveOrder) {
 +        stats.incInt(threadOrderedSenderConnectionsId, 1);
 +      } else {
 +        stats.incInt(threadUnorderedSenderConnectionsId, 1);
 +      }
 +    }
 +  }
 +  public int getSendersSU() {
 +    return stats.getInt(sharedUnorderedSenderConnectionsId);
 +  }
 +  public void decSenders(boolean shared, boolean preserveOrder) {
 +    if (shared) {
 +      if (preserveOrder) {
 +        stats.incInt(sharedOrderedSenderConnectionsId, -1);
 +      } else {
 +        stats.incInt(sharedUnorderedSenderConnectionsId, -1);
 +      }
 +    } else {
 +      if (preserveOrder) {
 +        stats.incInt(threadOrderedSenderConnectionsId, -1);
 +      } else {
 +        stats.incInt(threadUnorderedSenderConnectionsId, -1);
 +      }
 +    }
 +  }
 +
 +  public int getAsyncSocketWritesInProgress() {
 +     return stats.getInt(asyncSocketWritesInProgressId);
 +  }
 +  public int getAsyncSocketWrites() {
 +     return stats.getInt(asyncSocketWritesId);
 +  }
 +  public int getAsyncSocketWriteRetries() {
 +    return stats.getInt(asyncSocketWriteRetriesId);
 +  }
 +  public long getAsyncSocketWriteBytes() {
 +     return stats.getLong(asyncSocketWriteBytesId);
 +  }
 +  public long getAsyncSocketWriteTime() {
 +     return stats.getLong(asyncSocketWriteTimeId);
 +  }
 +  public long getAsyncQueueAddTime() {
 +     return stats.getLong(asyncQueueAddTimeId);
 +  }
 +  public void incAsyncQueueAddTime(long inc) {
 +    if (enableClockStats) {
 +      stats.incLong(asyncQueueAddTimeId, inc);
 +    }
 +  }
 +  public long getAsyncQueueRemoveTime() {
 +     return stats.getLong(asyncQueueRemoveTimeId);
 +  }
 +  public void incAsyncQueueRemoveTime(long inc) {
 +    if (enableClockStats) {
 +      stats.incLong(asyncQueueRemoveTimeId, inc);
 +    }
 +  }
 +
 +  public int getAsyncQueues() {
 +     return stats.getInt(asyncQueuesId);
 +  }
 +  public void incAsyncQueues(int inc) {
 +    stats.incInt(asyncQueuesId, inc);
 +  }
 +  public int getAsyncQueueFlushesInProgress() {
 +     return stats.getInt(asyncQueueFlushesInProgressId);
 +  }
 +  public int getAsyncQueueFlushesCompleted() {
 +     return stats.getInt(asyncQueueFlushesCompletedId);
 +  }
 +  public long getAsyncQueueFlushTime() {
 +     return stats.getLong(asyncQueueFlushTimeId);
 +  }
 +  public long startAsyncQueueFlush() {
 +    stats.incInt(asyncQueueFlushesInProgressId, 1);
 +    return getStatTime();
 +  }
 +  public void endAsyncQueueFlush(long start) {
 +    stats.incInt(asyncQueueFlushesInProgressId, -1);
 +    stats.incInt(asyncQueueFlushesCompletedId, 1);
 +    if (enableClockStats) {
 +      stats.incLong(asyncQueueFlushTimeId, getStatTime()-start);
 +    }
 +  }
 +  public int getAsyncQueueTimeouts() {
 +     return stats.getInt(asyncQueueTimeoutExceededId);
 +  }
 +  public void incAsyncQueueTimeouts(int inc) {
 +    stats.incInt(asyncQueueTimeoutExceededId, inc);
 +  }
 +  public int getAsyncQueueSizeExceeded() {
 +     return stats.getInt(asyncQueueSizeExceededId);
 +  }
 +  public void incAsyncQueueSizeExceeded(int inc) {
 +    stats.incInt(asyncQueueSizeExceededId, inc);
 +  }
 +  public int getAsyncDistributionTimeoutExceeded() {
 +     return stats.getInt(asyncDistributionTimeoutExceededId);
 +  }
 +  public void incAsyncDistributionTimeoutExceeded() {
 +    stats.incInt(asyncDistributionTimeoutExceededId, 1);
 +  }
 +
 +  public long getAsyncQueueSize() {
 +     return stats.getLong(asyncQueueSizeId);
 +  }
 +  public void incAsyncQueueSize(long inc) {
 +    stats.incLong(asyncQueueSizeId, inc);
 +  }
 +  public long getAsyncQueuedMsgs() {
 +     return stats.getLong(asyncQueuedMsgsId);
 +  }
 +  public void incAsyncQueuedMsgs() {
 +    stats.incLong(asyncQueuedMsgsId, 1);
 +  }
 +  public long getAsyncDequeuedMsgs() {
 +     return stats.getLong(asyncDequeuedMsgsId);
 +  }
 +  public void incAsyncDequeuedMsgs() {
 +    stats.incLong(asyncDequeuedMsgsId, 1);
 +  }
 +  public long getAsyncConflatedMsgs() {
 +     return stats.getLong(asyncConflatedMsgsId);
 +  }
 +  public void incAsyncConflatedMsgs() {
 +    stats.incLong(asyncConflatedMsgsId, 1);
 +  }
 +
 +  public int getAsyncThreads() {
 +     return stats.getInt(asyncThreadsId);
 +  }
 +  public void incAsyncThreads(int inc) {
 +    stats.incInt(asyncThreadsId, inc);
 +  }
 +  public int getAsyncThreadInProgress() {
 +     return stats.getInt(asyncThreadInProgressId);
 +  }
 +  public int getAsyncThreadCompleted() {
 +     return stats.getInt(asyncThreadCompletedId);
 +  }
 +  public long getAsyncThreadTime() {
 +     return stats.getLong(asyncThreadTimeId);
 +  }
 +  public long startAsyncThread() {
 +    stats.incInt(asyncThreadInProgressId, 1);
 +    return getStatTime();
 +  }
 +  public void endAsyncThread(long start) {
 +    stats.incInt(asyncThreadInProgressId, -1);
 +    stats.incInt(asyncThreadCompletedId, 1);
 +    if (enableClockStats) {
 +      stats.incLong(asyncThreadTimeId, getStatTime()-start);
 +    }
 +  }
 +
 +  /**
 +   * Returns a helper object so that the overflow queue can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public ThrottledQueueStatHelper getOverflowQueueHelper() {
 +    return new ThrottledQueueStatHelper() {
 +        public void incThrottleCount() {
 +          incOverflowQueueThrottleCount(1);
 +        }
 +        public void throttleTime(long nanos) {
 +          incOverflowQueueThrottleTime(nanos);
 +        }
 +        public void add() {
 +          incOverflowQueueSize(1);
 +        }
 +        public void remove() {
 +          incOverflowQueueSize(-1);
 +        }
 +        public void remove(int count) {
 +          incOverflowQueueSize(-count);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the waiting queue can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public QueueStatHelper getWaitingQueueHelper() {
 +    return new QueueStatHelper() {
 +        public void add() {
 +          incWaitingQueueSize(1);
 +        }
 +        public void remove() {
 +          incWaitingQueueSize(-1);
 +        }
 +        public void remove(int count) {
 +          incWaitingQueueSize(-count);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the high priority queue can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public ThrottledQueueStatHelper getHighPriorityQueueHelper() {
 +    return new ThrottledQueueStatHelper() {
 +        public void incThrottleCount() {
 +          incHighPriorityQueueThrottleCount(1);
 +        }
 +        public void throttleTime(long nanos) {
 +          incHighPriorityQueueThrottleTime(nanos);
 +        }
 +        public void add() {
 +          incHighPriorityQueueSize(1);
 +        }
 +        public void remove() {
 +          incHighPriorityQueueSize(-1);
 +        }
 +        public void remove(int count) {
 +          incHighPriorityQueueSize(-count);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the partitioned region queue can record its
 +   * stats to the proper distribution stats.
 +   * @since 5.0
 +   */
 +  public ThrottledQueueStatHelper getPartitionedRegionQueueHelper() {
 +    return new ThrottledQueueStatHelper() {
 +        public void incThrottleCount() {
 +          incPartitionedRegionQueueThrottleCount(1);
 +        }
 +        public void throttleTime(long nanos) {
 +          incPartitionedRegionQueueThrottleTime(nanos);
 +        }
 +        public void add() {
 +          incPartitionedRegionQueueSize(1);
 +        }
 +        public void remove() {
 +          incPartitionedRegionQueueSize(-1);
 +        }
 +        public void remove(int count) {
 +          incPartitionedRegionQueueSize(-count);
 +        }
 +      };
 +  }
 +  /**
 +   * Returns a helper object so that the partitioned region pool can record its
 +   * stats to the proper distribution stats.
 +   * @since 5.0.2
 +   */
 +  public PoolStatHelper getPartitionedRegionPoolHelper() {
 +    return new PoolStatHelper() {
 +        public void startJob() {
 +          incPartitionedRegionThreadJobs(1);
 +        }
 +        public void endJob() {
 +          incPartitionedRegionThreadJobs(-1);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the function execution queue can record its
 +   * stats to the proper distribution stats.
 +   * @since 6.0
 +   */
 +  public ThrottledQueueStatHelper getFunctionExecutionQueueHelper() {
 +    return new ThrottledQueueStatHelper() {
 +        public void incThrottleCount() {
 +          incFunctionExecutionQueueThrottleCount(1);
 +        }
 +        public void throttleTime(long nanos) {
 +          incFunctionExecutionQueueThrottleTime(nanos);
 +        }
 +        public void add() {
 +          incFunctionExecutionQueueSize(1);
 +        }
 +        public void remove() {
 +          incFunctionExecutionQueueSize(-1);
 +        }
 +        public void remove(int count) {
 +          incFunctionExecutionQueueSize(-count);
 +        }
 +      };
 +  }
 +  /**
 +   * Returns a helper object so that the function execution pool can record its
 +   * stats to the proper distribution stats.
 +   * @since 6.0
 +   */
 +  public PoolStatHelper getFunctionExecutionPoolHelper() {
 +    return new PoolStatHelper() {
 +        public void startJob() {
 +          incFunctionExecutionThreadJobs(1);
 +        }
 +        public void endJob() {
 +          incFunctionExecutionThreadJobs(-1);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the serial queue can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public ThrottledMemQueueStatHelper getSerialQueueHelper() {
 +    return new ThrottledMemQueueStatHelper() {
 +        public void incThrottleCount() {
 +          incSerialQueueThrottleCount(1);
 +        }
 +        public void throttleTime(long nanos) {
 +          incSerialQueueThrottleTime(nanos);
 +        }
 +        public void add() {
 +          incSerialQueueSize(1);
 +        }
 +        public void remove() {
 +          incSerialQueueSize(-1);
 +        }
 +        public void remove(int count) {
 +          incSerialQueueSize(-count);
 +        }
 +        public void addMem(int amount) {
 +          incSerialQueueBytes(amount);
 +        }
 +        public void removeMem(int amount) {
 +          incSerialQueueBytes(amount * (-1));
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the normal pool can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public PoolStatHelper getNormalPoolHelper() {
 +    return new PoolStatHelper() {
 +        public void startJob() {
 +          incNormalPoolThreadJobs(1);
 +        }
 +        public void endJob() {
 +          incNormalPoolThreadJobs(-1);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the waiting pool can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public PoolStatHelper getWaitingPoolHelper() {
 +    return new PoolStatHelper() {
 +        public void startJob() {
 +          incWaitingPoolThreadJobs(1);
 +        }
 +        public void endJob() {
 +          incWaitingPoolThreadJobs(-1);
 +        }
 +      };
 +  }
 +
 +  /**
 +   * Returns a helper object so that the highPriority pool can record its
 +   * stats to the proper distribution stats.
 +   * @since 3.5
 +   */
 +  public PoolStatHelper getHighPriorityPoolHelper() {
 +    return new PoolStatHelper() {
 +        public void startJob() {
 +          incHighPriorityThreadJobs(1);
 +        }
 +        public void endJob() {
 +          incHighPriorityThreadJobs(-1);
 +        }
 +      };
 +  }
 +
 +  public void incBatchSendTime(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(batchSendTimeId, getStatTime()-start);
 +    }
 +  }
 +  public void incBatchCopyTime(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(batchCopyTimeId, getStatTime()-start);
 +    }
 +  }
 +  public void incBatchWaitTime(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(batchWaitTimeId, getStatTime()-start);
 +    }
 +  }
 +  public void incBatchFlushTime(long start) {
 +    if (enableClockStats) {
 +      stats.incLong(batchFlushTimeId, getStatTime()-start);
 +    }
 +  }
 +  public void incUcastRetransmits() {
 +    stats.incInt(ucastRetransmitsId, 1);
 +  }
 +  public void incMcastRetransmits() {
 +    stats.incInt(mcastRetransmitsId, 1);
 +  }
 +  public void incMcastRetransmitRequests() {
 +    stats.incInt(mcastRetransmitRequestsId, 1);
 +  }
 +  public int getMcastRetransmits() {
 +    return stats.getInt(mcastRetransmitsId);
 +  }
 +
 +  public void incThreadOwnedReceivers(long value, int dominoCount)
 +  {
 +    if (dominoCount < 2) {
 +      stats.incLong(threadOwnedReceiversId, value);
 +    } else {
 +      stats.incLong(threadOwnedReceiversId2, value);
 +    }
 +  }
 +
 +  /**
 +   * @since 5.0.2.4
 +   */
 +  public void incReceiverBufferSize(int inc, boolean direct) {
 +    if (direct) {
 +      stats.incLong(receiverDirectBufferSizeId, inc);
 +    } else {
 +      stats.incLong(receiverHeapBufferSizeId, inc);
 +    }
 +  }
 +  /**
 +   * @since 5.0.2.4
 +   */
 +  public void incSenderBufferSize(int inc, boolean direct) {
 +    if (direct) {
 +      stats.incLong(senderDirectBufferSizeId, inc);
 +    } else {
 +      stats.incLong(senderHeapBufferSizeId, inc);
 +    }
 +  }
 +  public void incMessagesBeingReceived(boolean newMsg, int bytes) {
 +    if (newMsg) {
 +      stats.incInt(messagesBeingReceivedId, 1);
 +    }
 +    stats.incLong(messageBytesBeingReceivedId, bytes);
 +  }
 +  public void decMessagesBeingReceived(int bytes) {
 +    stats.incInt(messagesBeingReceivedId, -1);
 +    stats.incLong(messageBytesBeingReceivedId, -bytes);
 +  }
 +  public void incSerialThreadStarts() {
 +    stats.incLong(serialThreadStartsId, 1);
 +  }
 +  public void incViewThreadStarts() {
 +    stats.incLong(viewThreadStartsId, 1);
 +  }
 +  public void incProcessingThreadStarts() {
 +    stats.incLong(processingThreadStartsId, 1);
 +  }
 +  public void incHighPriorityThreadStarts() {
 +    stats.incLong(highPriorityThreadStartsId, 1);
 +  }
 +  public void incWaitingThreadStarts() {
 +    stats.incLong(waitingThreadStartsId, 1);
 +  }
 +  public void incPartitionedRegionThreadStarts() {
 +    stats.incLong(partitionedRegionThreadStartsId, 1);
 +  }
 +  public void incFunctionExecutionThreadStarts() {
 +    stats.incLong(functionExecutionThreadStartsId, 1);
 +  }
 +  public void incSerialPooledThreadStarts() {
 +    stats.incLong(serialPooledThreadStartsId, 1);
 +  }
 +
 +  public void incReplyHandOffTime(long start) {
 +    if (enableClockStats) {
 +      long delta = getStatTime() - start;
 +      stats.incLong(replyHandoffTimeId, delta);
 +//      this.replyHandoffHistogram.endOp(delta);
 +    }
 +  }
 +
 +  protected void incPartitionedRegionThreadJobs(int i) {
 +    this.stats.incInt(partitionedRegionThreadJobsId, i);
 +  }
 +
 +  protected void incFunctionExecutionThreadJobs(int i) {
 +    this.stats.incInt(functionExecutionThreadJobsId, i);
 +  }
 +
 +  public void incNumViewThreads(int threads) {
 +    this.stats.incInt(viewThreadsId, threads);
 +  }
 +
 +  public PoolStatHelper getSerialProcessorHelper() {
 +    return new PoolStatHelper() {
 +      public void startJob() {
 +        incNumSerialThreadJobs(1);
 +        if (logger.isTraceEnabled()) {
 +          logger.trace("[DM.SerialQueuedExecutor.execute] numSerialThreads={}", getNumSerialThreads());
 +        }
 +      }
 +      public void endJob() {
 +        incNumSerialThreadJobs(-1);
 +      }
 +    };
 +  }
 +
 +  protected void incNumSerialThreadJobs(int jobs) {
 +    this.stats.incInt(serialThreadJobsId, jobs);
 +  }
 +
 +  public PoolStatHelper getViewProcessorHelper() {
 +    return new PoolStatHelper() {
 +      public void startJob() {
 +        incViewProcessorThreadJobs(1);
 +        if (logger.isTraceEnabled()) {
 +          logger.trace("[DM.SerialQueuedExecutor.execute] numViewThreads={}", getNumViewThreads());
 +        }
 +      }
 +      public void endJob() {
 +        incViewProcessorThreadJobs(-1);
 +      }
 +    };
 +  }
 +
 +  public int getNumViewThreads() {
 +    return this.stats.getInt(viewThreadsId);
 +  }
 +
 +  protected void incViewProcessorThreadJobs(int jobs) {
 +    this.stats.incInt(viewProcessorT

<TRUNCATED>


[022/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/IBuilder.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/IBuilder.java
index 0000000,0000000..0e74fe6
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/IBuilder.java
@@@ -1,0 -1,0 +1,24 @@@
++/*
++ * Copyright (C) 2011 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++
++public interface IBuilder<T> {
++
++    T build();
++
++    int sizeof();
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/ICardinality.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/ICardinality.java
index 0000000,0000000..fd32154
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/ICardinality.java
@@@ -1,0 -1,0 +1,72 @@@
++/*
++ * Copyright (C) 2011 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++
++import java.io.IOException;
++
++
++public interface ICardinality {
++
++    /**
++     * @param o stream element
++     * @return false if the value returned by cardinality() is unaffected by the appearance of o in the stream.
++     */
++    boolean offer(Object o);
++
++    /**
++     * Offer the value as a hashed long value
++     *
++     * @param hashedLong - the hash of the item to offer to the estimator
++     * @return false if the value returned by cardinality() is unaffected by the appearance of hashedLong in the stream
++     */
++    boolean offerHashed(long hashedLong);
++
++    /**
++     * Offer the value as a hashed long value
++     *
++     * @param hashedInt - the hash of the item to offer to the estimator
++     * @return false if the value returned by cardinality() is unaffected by the appearance of hashedInt in the stream
++     */
++    boolean offerHashed(int hashedInt);
++
++    /**
++     * @return the number of unique elements in the stream or an estimate thereof
++     */
++    long cardinality();
++
++    /**
++     * @return size in bytes needed for serialization
++     */
++    int sizeof();
++
++    /**
++     * @return byte[]
++     * @throws IOException
++     */
++    byte[] getBytes() throws IOException;
++
++    /**
++     * Merges estimators to produce a new estimator for the combined streams
++     * of this estimator and those passed as arguments.
++     * <p/>
++     * Nor this estimator nor the one passed as parameters are modified.
++     *
++     * @param estimators Zero or more compatible estimators
++     * @throws CardinalityMergeException If at least one of the estimators is not compatible with this one
++     */
++    ICardinality merge(ICardinality... estimators) throws CardinalityMergeException;
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/MurmurHash.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/MurmurHash.java
index 0000000,0000000..139e029
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/MurmurHash.java
@@@ -1,0 -1,0 +1,245 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.hll;
++
++
++/**
++ * This is a very fast, non-cryptographic hash suitable for general hash-based
++ * lookup. See http://murmurhash.googlepages.com/ for more details.
++ * <p/>
++ * <p>
++ * The C version of MurmurHash 2.0 found at that site was ported to Java by
++ * Andrzej Bialecki (ab at getopt org).
++ * </p>
++ */
++public class MurmurHash
++{
++    public static int hash(Object o)
++    {
++        if (o == null)
++        {
++            return 0;
++        }
++        if (o instanceof Long)
++        {
++            return hashLong((Long) o);
++        }
++        if (o instanceof Integer)
++        {
++            return hashLong((Integer) o);
++        }
++        if (o instanceof Double)
++        {
++            return hashLong(Double.doubleToRawLongBits((Double) o));
++        }
++        if (o instanceof Float)
++        {
++            return hashLong(Float.floatToRawIntBits((Float) o));
++        }
++        if (o instanceof String)
++        {
++            return hash(((String) o).getBytes());
++        }
++        if (o instanceof byte[])
++        {
++            return hash((byte[]) o);
++        }
++        return hash(o.toString());
++    }
++
++    public static int hash(byte[] data)
++    {
++        return hash(data, 0, data.length, -1);
++    }
++
++    public static int hash(byte[] data, int seed)
++    {
++        return hash(data, 0, data.length, seed);
++    }
++
++    public static int hash(byte[] data, int offset, int length, int seed)
++    {
++        int m = 0x5bd1e995;
++        int r = 24;
++
++        int h = seed ^ length;
++
++        int len_4 = length >> 2;
++
++        for (int i = 0; i < len_4; i++)
++        {
++            int i_4 = i << 2;
++            int k = data[offset + i_4 + 3];
++            k = k << 8;
++            k = k | (data[offset + i_4 + 2] & 0xff);
++            k = k << 8;
++            k = k | (data[offset + i_4 + 1] & 0xff);
++            k = k << 8;
++            k = k | (data[offset + i_4 + 0] & 0xff);
++            k *= m;
++            k ^= k >>> r;
++            k *= m;
++            h *= m;
++            h ^= k;
++        }
++
++        // avoid calculating modulo
++        int len_m = len_4 << 2;
++        int left = length - len_m;
++
++        if (left != 0)
++        {
++            if (left >= 3)
++            {
++                h ^= (int) data[offset + length - 3] << 16;
++            }
++            if (left >= 2)
++            {
++                h ^= (int) data[offset + length - 2] << 8;
++            }
++            if (left >= 1)
++            {
++                h ^= (int) data[offset + length - 1];
++            }
++
++            h *= m;
++        }
++
++        h ^= h >>> 13;
++        h *= m;
++        h ^= h >>> 15;
++
++        return h;
++    }
++
++    public static int hashLong(long data)
++    {
++        int m = 0x5bd1e995;
++        int r = 24;
++
++        int h = 0;
++
++        int k = (int) data * m;
++        k ^= k >>> r;
++        h ^= k * m;
++
++        k = (int) (data >> 32) * m;
++        k ^= k >>> r;
++        h *= m;
++        h ^= k * m;
++
++        h ^= h >>> 13;
++        h *= m;
++        h ^= h >>> 15;
++
++        return h;
++    }
++
++    public static long hash64(Object o)
++    {
++        if (o == null)
++        {
++            return 0l;
++        }
++        else if (o instanceof String)
++        {
++            final byte[] bytes = ((String) o).getBytes();
++            return hash64(bytes, bytes.length);
++        }
++        else if (o instanceof byte[])
++        {
++            final byte[] bytes = (byte[]) o;
++            return hash64(bytes, bytes.length);
++        }
++        return hash64(o.toString());
++    }
++
++    // 64 bit implementation copied from here:  https://github.com/tnm/murmurhash-java
++
++    /**
++     * Generates 64 bit hash from byte array with default seed value.
++     *
++     * @param data   byte array to hash
++     * @param length length of the array to hash
++     * @return 64 bit hash of the given string
++     */
++    public static long hash64(final byte[] data, int length)
++    {
++        return hash64(data, length, 0xe17a1465);
++    }
++
++
++    /**
++     * Generates 64 bit hash from byte array of the given length and seed.
++     *
++     * @param data   byte array to hash
++     * @param length length of the array to hash
++     * @param seed   initial seed value
++     * @return 64 bit hash of the given array
++     */
++    public static long hash64(final byte[] data, int length, int seed)
++    {
++        final long m = 0xc6a4a7935bd1e995L;
++        final int r = 47;
++
++        long h = (seed & 0xffffffffl) ^ (length * m);
++
++        int length8 = length / 8;
++
++        for (int i = 0; i < length8; i++)
++        {
++            final int i8 = i * 8;
++            long k = ((long) data[i8 + 0] & 0xff) + (((long) data[i8 + 1] & 0xff) << 8)
++                    + (((long) data[i8 + 2] & 0xff) << 16) + (((long) data[i8 + 3] & 0xff) << 24)
++                    + (((long) data[i8 + 4] & 0xff) << 32) + (((long) data[i8 + 5] & 0xff) << 40)
++                    + (((long) data[i8 + 6] & 0xff) << 48) + (((long) data[i8 + 7] & 0xff) << 56);
++
++            k *= m;
++            k ^= k >>> r;
++            k *= m;
++
++            h ^= k;
++            h *= m;
++        }
++
++        switch (length % 8)
++        {
++            case 7:
++                h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48;
++            case 6:
++                h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40;
++            case 5:
++                h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32;
++            case 4:
++                h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24;
++            case 3:
++                h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16;
++            case 2:
++                h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8;
++            case 1:
++                h ^= (long) (data[length & ~7] & 0xff);
++                h *= m;
++        }
++        ;
++
++        h ^= h >>> r;
++        h *= m;
++        h ^= h >>> r;
++
++        return h;
++    }
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/RegisterSet.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/hll/RegisterSet.java
index 0000000,0000000..e35340f
new file mode 100755
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/hll/RegisterSet.java
@@@ -1,0 -1,0 +1,110 @@@
++/*
++ * Copyright (C) 2012 Clearspring Technologies, Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * 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 com.gemstone.gemfire.internal.hll;
++
++
++public class RegisterSet {
++
++    public final static int LOG2_BITS_PER_WORD = 6;
++    public final static int REGISTER_SIZE = 5;
++
++    public final int count;
++    public final int size;
++
++    private final int[] M;
++
++    public RegisterSet(int count) {
++        this(count, null);
++    }
++
++    public RegisterSet(int count, int[] initialValues) {
++        this.count = count;
++
++        if (initialValues == null) {
++            this.M = new int[getSizeForCount(count)];
++        } else {
++            this.M = initialValues;
++        }
++        this.size = this.M.length;
++    }
++
++    public static int getBits(int count) {
++        return count / LOG2_BITS_PER_WORD;
++    }
++
++    public static int getSizeForCount(int count) {
++        int bits = getBits(count);
++        if (bits == 0) {
++            return 1;
++        } else if (bits % Integer.SIZE == 0) {
++            return bits;
++        } else {
++            return bits + 1;
++        }
++    }
++
++    public void set(int position, int value) {
++        int bucketPos = position / LOG2_BITS_PER_WORD;
++        int shift = REGISTER_SIZE * (position - (bucketPos * LOG2_BITS_PER_WORD));
++        this.M[bucketPos] = (this.M[bucketPos] & ~(0x1f << shift)) | (value << shift);
++    }
++
++    public int get(int position) {
++        int bucketPos = position / LOG2_BITS_PER_WORD;
++        int shift = REGISTER_SIZE * (position - (bucketPos * LOG2_BITS_PER_WORD));
++        return (this.M[bucketPos] & (0x1f << shift)) >>> shift;
++    }
++
++    public boolean updateIfGreater(int position, int value) {
++        int bucket = position / LOG2_BITS_PER_WORD;
++        int shift = REGISTER_SIZE * (position - (bucket * LOG2_BITS_PER_WORD));
++        int mask = 0x1f << shift;
++
++        // Use long to avoid sign issues with the left-most shift
++        long curVal = this.M[bucket] & mask;
++        long newVal = value << shift;
++        if (curVal < newVal) {
++            this.M[bucket] = (int) ((this.M[bucket] & ~mask) | newVal);
++            return true;
++        } else {
++            return false;
++        }
++    }
++
++    public void merge(RegisterSet that) {
++        for (int bucket = 0; bucket < M.length; bucket++) {
++            int word = 0;
++            for (int j = 0; j < LOG2_BITS_PER_WORD; j++) {
++                int mask = 0x1f << (REGISTER_SIZE * j);
++
++                int thisVal = (this.M[bucket] & mask);
++                int thatVal = (that.M[bucket] & mask);
++                word |= (thisVal < thatVal) ? thatVal : thisVal;
++            }
++            this.M[bucket] = word;
++        }
++    }
++
++    int[] readOnlyBits() {
++        return M;
++    }
++
++    public int[] bits() {
++        int[] copy = new int[size];
++        System.arraycopy(M, 0, copy, 0, M.length);
++        return copy;
++    }
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
index f9539e5,0000000..dcd83cb
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/RegionProvider.java
@@@ -1,553 -1,0 +1,553 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.redis;
 +
 +import java.io.Closeable;
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.Map.Entry;
 +import java.util.Set;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentMap;
 +import java.util.concurrent.ScheduledExecutorService;
 +import java.util.concurrent.ScheduledFuture;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.locks.Lock;
 +import java.util.concurrent.locks.ReentrantLock;
 +
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.TransactionId;
 +import com.gemstone.gemfire.cache.query.IndexExistsException;
 +import com.gemstone.gemfire.cache.query.IndexInvalidException;
 +import com.gemstone.gemfire.cache.query.IndexNameConflictException;
 +import com.gemstone.gemfire.cache.query.Query;
 +import com.gemstone.gemfire.cache.query.QueryInvalidException;
 +import com.gemstone.gemfire.cache.query.QueryService;
 +import com.gemstone.gemfire.cache.query.RegionNotFoundException;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.redis.executor.ExpirationExecutor;
 +import com.gemstone.gemfire.internal.redis.executor.ListQuery;
 +import com.gemstone.gemfire.internal.redis.executor.SortedSetQuery;
- import com.gemstone.gemfire.internal.redis.executor.hll.HyperLogLogPlus;
++import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
 +import com.gemstone.gemfire.management.cli.Result;
 +import com.gemstone.gemfire.management.cli.Result.Status;
 +import com.gemstone.gemfire.management.internal.cli.commands.CreateAlterDestroyRegionCommands;
 +import com.gemstone.gemfire.redis.GemFireRedisServer;
 +
 +/**
 + * This class stands between {@link Executor} and {@link Cache#getRegion(String)}.
 + * This is needed because some keys for Redis represented as a {@link Region} in
 + * {@link GemFireRedisServer} come with additional state. Therefore getting, creating,
 + * or destroying a {@link Region} needs to be synchronized, which is done away with
 + * and abstracted by this class.
 + * 
 + * @author Vitaly Gavrilov
 + *
 + */
 +public class RegionProvider implements Closeable {
 +
 +  private final ConcurrentHashMap<ByteArrayWrapper, Region<?, ?>> regions;
 +
 +  /**
 +   * This is the Redis meta data {@link Region} that holds the {@link RedisDataType}
 +   * information for all Regions created. The mapping is a {@link String} key which is the name
 +   * of the {@link Region} created to hold the data to the RedisDataType it contains.
 +   */
 +  private final Region<String, RedisDataType> redisMetaRegion;
 +
 +  /**
 +   * This is the {@link RedisDataType#REDIS_STRING} {@link Region}. This is the Region
 +   * that stores all string contents
 +   */
 +  private final Region<ByteArrayWrapper, ByteArrayWrapper> stringsRegion;
 +
 +  /**
 +   * This is the {@link RedisDataType#REDIS_HLL} {@link Region}. This is the Region
 +   * that stores all HyperLogLog contents
 +   */
 +  private final Region<ByteArrayWrapper, HyperLogLogPlus> hLLRegion;
 +
 +  private final Cache cache;
 +  private final QueryService queryService;
 +  private final ConcurrentMap<ByteArrayWrapper, Map<Enum<?>, Query>> preparedQueries = new ConcurrentHashMap<ByteArrayWrapper, Map<Enum<?>, Query>>();
 +  private final ConcurrentMap<ByteArrayWrapper, ScheduledFuture<?>> expirationsMap;
 +  private final ScheduledExecutorService expirationExecutor;
 +  private final RegionShortcut defaultRegionType;
 +  private static final CreateAlterDestroyRegionCommands cliCmds = new CreateAlterDestroyRegionCommands();
 +  private final ConcurrentHashMap<String, Lock> locks;
 +
 +  public RegionProvider(Region<ByteArrayWrapper, ByteArrayWrapper> stringsRegion, Region<ByteArrayWrapper, HyperLogLogPlus> hLLRegion, Region<String, RedisDataType> redisMetaRegion, ConcurrentMap<ByteArrayWrapper, ScheduledFuture<?>> expirationsMap, ScheduledExecutorService expirationExecutor, RegionShortcut defaultShortcut) {
 +    if (stringsRegion == null || hLLRegion == null || redisMetaRegion == null)
 +      throw new NullPointerException();
 +    this.regions = new ConcurrentHashMap<ByteArrayWrapper, Region<?, ?>>();
 +    this.stringsRegion = stringsRegion;
 +    this.hLLRegion = hLLRegion;
 +    this.redisMetaRegion = redisMetaRegion;
 +    this.cache = GemFireCacheImpl.getInstance();
 +    this.queryService = cache.getQueryService();
 +    this.expirationsMap = expirationsMap;
 +    this.expirationExecutor = expirationExecutor;
 +    this.defaultRegionType = defaultShortcut;
 +    this.locks = new ConcurrentHashMap<String, Lock>();
 +  }
 +
 +  public boolean existsKey(ByteArrayWrapper key) {
 +    return this.redisMetaRegion.containsKey(key.toString());
 +  }
 +
 +  public Set<String> metaKeySet() {
 +    return this.redisMetaRegion.keySet();
 +  }
 +
 +  public Set<Map.Entry<String, RedisDataType>> metaEntrySet() {
 +    return this.redisMetaRegion.entrySet();
 +  }
 +
 +  public int getMetaSize() {
 +    return this.redisMetaRegion.size() - RedisConstants.NUM_DEFAULT_KEYS;
 +  }
 +
 +  private boolean metaRemoveEntry(ByteArrayWrapper key) {
 +    return this.redisMetaRegion.remove(key.toString()) != null;
 +  }
 +
 +  public RedisDataType metaPutIfAbsent(ByteArrayWrapper key, RedisDataType value) {
 +    return this.redisMetaRegion.putIfAbsent(key.toString(), value);
 +  }
 +
 +  public RedisDataType metaPut(ByteArrayWrapper key, RedisDataType value) {
 +    return this.redisMetaRegion.put(key.toString(), value);
 +  }
 +
 +  public RedisDataType metaGet(ByteArrayWrapper key) {
 +    return this.redisMetaRegion.get(key.toString());
 +  }
 +
 +  public Region<?, ?> getRegion(ByteArrayWrapper key) {
 +    return this.regions.get(key);
 +  }
 +
 +  public void removeRegionReferenceLocally(ByteArrayWrapper key, RedisDataType type) {
 +    Lock lock = this.locks.get(key.toString());
 +    boolean locked = false;
 +    try {
 +      locked = lock.tryLock();
 +      // If we cannot get the lock we ignore this remote event, this key has local event
 +      // that started independently, ignore this event to prevent deadlock
 +      if (locked) {
 +        cancelKeyExpiration(key);
 +        removeRegionState(key, type);
 +      }
 +    } finally {
 +      if (locked) {
 +        lock.unlock();
 +      }
 +    }
 +  }
 +
 +  public boolean removeKey(ByteArrayWrapper key) {
 +    RedisDataType type = getRedisDataType(key);
 +    return removeKey(key, type);
 +  }
 +
 +  public boolean removeKey(ByteArrayWrapper key, RedisDataType type) {
 +    return removeKey(key, type, true);
 +  }
 +
 +  public boolean removeKey(ByteArrayWrapper key, RedisDataType type, boolean cancelExpiration) {
 +    if (type == null || type == RedisDataType.REDIS_PROTECTED)
 +      return false;
 +    Lock lock = this.locks.get(key.toString());
 +    try {
 +      if (lock != null)  {// Strings/hlls will not have locks
 +        lock.lock();
 +      }
 +      metaRemoveEntry(key);
 +      try {
 +        if (type == RedisDataType.REDIS_STRING) {
 +          return this.stringsRegion.remove(key) != null;
 +        } else if (type == RedisDataType.REDIS_HLL) {
 +          return this.hLLRegion.remove(key) != null;
 +        } else {
 +          return destroyRegion(key, type);
 +        }
 +      } catch (Exception exc) {
 +        return false;
 +      } finally {
 +        if (cancelExpiration)
 +          cancelKeyExpiration(key);
 +        else
 +          removeKeyExpiration(key);
 +        if (lock != null)
 +          this.locks.remove(key.toString());
 +      }
 +    } finally {
 +      if (lock != null) {
 +        lock.unlock();
 +      }
 +    }
 +  }
 +
 +  public Region<?, ?> getOrCreateRegion(ByteArrayWrapper key, RedisDataType type, ExecutionHandlerContext context) {
 +    return getOrCreateRegion0(key, type, context, true);
 +  }
 +
 +  public void createRemoteRegionReferenceLocally(ByteArrayWrapper key, RedisDataType type) {
 +    if (type == null || type == RedisDataType.REDIS_STRING || type == RedisDataType.REDIS_HLL)
 +      return;
 +    Region<?, ?> r = this.regions.get(key);
 +    if (r != null)
 +      return;
 +    if (!this.regions.contains(key)) {
 +      String stringKey = key.toString();
 +      Lock lock = this.locks.get(stringKey);
 +      if (lock == null) {
 +        this.locks.putIfAbsent(stringKey, new ReentrantLock());
 +        lock = this.locks.get(stringKey);
 +      }
 +      boolean locked = false;
 +      try {
 +        locked = lock.tryLock();
 +        // If we cannot get the lock then this remote event may have been initialized
 +        // independently on this machine, so if we wait on the lock it is more than
 +        // likely we will deadlock just to do the same task. This event can be ignored
 +        if (locked) {
 +          r = cache.getRegion(key.toString());
 +          // If r is null, this implies that we are after a create/destroy
 +          // simply ignore. Calls to getRegion or getOrCreate will work correctly
 +          if (r == null)
 +            return;
 +
 +          if (type == RedisDataType.REDIS_LIST) {
 +            doInitializeList(key, r);
 +          } else if (type == RedisDataType.REDIS_SORTEDSET) {
 +            try {
 +              doInitializeSortedSet(key, r);
 +            } catch (RegionNotFoundException | IndexInvalidException e) {
 +              //ignore
 +            }
 +          }
 +          this.regions.put(key, r);
 +        }
 +      } finally {
 +        if (locked) {
 +          lock.unlock();
 +        }
 +      }
 +    }
 +  }
 +
 +  private Region<?, ?> getOrCreateRegion0(ByteArrayWrapper key, RedisDataType type, ExecutionHandlerContext context, boolean addToMeta) {
 +    checkDataType(key, type);
 +    Region<?, ?> r = this.regions.get(key);
 +    if (r != null && r.isDestroyed()) {
 +      removeKey(key, type);
 +      r = null;
 +    }
 +    if (r == null) {
 +      String stringKey = key.toString();
 +      Lock lock = this.locks.get(stringKey);
 +      if (lock == null) {
 +        this.locks.putIfAbsent(stringKey, new ReentrantLock());
 +        lock = this.locks.get(stringKey);
 +      }
 +
 +      try {
 +        lock.lock();
 +        r = regions.get(key);
 +        if (r == null) {
 +          boolean hasTransaction = context != null && context.hasTransaction(); // Can create without context
 +          CacheTransactionManager txm = null;
 +          TransactionId transactionId = null;
 +          try {
 +            if (hasTransaction) {
 +              txm = cache.getCacheTransactionManager();
 +              transactionId = txm.suspend();
 +            }
 +            Exception concurrentCreateDestroyException = null;
 +            do {
 +              concurrentCreateDestroyException = null;
 +              r = createRegionGlobally(stringKey);
 +              try {
 +                if (type == RedisDataType.REDIS_LIST) {
 +                  doInitializeList(key, r);
 +                } else if (type == RedisDataType.REDIS_SORTEDSET) {
 +                  try {
 +                    doInitializeSortedSet(key, r);
 +                  } catch (RegionNotFoundException | IndexInvalidException e) {
 +                    concurrentCreateDestroyException = e;
 +                  }
 +                }
 +              } catch (QueryInvalidException e) {
 +                if (e.getCause() instanceof RegionNotFoundException) {
 +                  concurrentCreateDestroyException = e;
 +                }
 +              }
 +            } while(concurrentCreateDestroyException != null);
 +            this.regions.put(key, r);            
 +            if (addToMeta) {
 +              RedisDataType existingType = metaPutIfAbsent(key, type);
 +              if (existingType != null && existingType != type)
 +                throw new RedisDataTypeMismatchException("The key name \"" + key + "\" is already used by a " + existingType.toString());
 +            }
 +          } finally {
 +            if (hasTransaction)
 +              txm.resume(transactionId);
 +          }
 +        }
 +      } finally {
 +        lock.unlock();
 +      }
 +    }
 +    return r;
 +  }
 +
 +  /**
 +   * SYNCHRONIZE EXTERNALLY OF this.locks.get(key.toString())!!!!!
 +   * 
 +   * @param key Key of region to destroy
 +   * @param type Type of region to destroyu
 +   * @return Flag if destroyed
 +   */
 +  private boolean destroyRegion(ByteArrayWrapper key, RedisDataType type) {
 +    Region<?, ?> r = this.regions.get(key);
 +    if (r != null) {
 +      try {
 +        r.destroyRegion();
 +      } catch (Exception e) {
 +        return false;
 +      } finally {
 +        removeRegionState(key, type);
 +      }
 +    }
 +    return true;
 +  }
 +
 +  /**
 +   * Do not call this method if you are not synchronized on the lock associated with this key
 +   * 
 +   * @param key Key of region to remove
 +   * @param type Type of key to remove all state
 +   */
 +  private void removeRegionState(ByteArrayWrapper key, RedisDataType type) {
 +    this.preparedQueries.remove(key);
 +    this.regions.remove(key);
 +  }
 +
 +  private void doInitializeSortedSet(ByteArrayWrapper key, Region<?, ?> r) throws RegionNotFoundException, IndexInvalidException {
 +    String fullpath = r.getFullPath();
 +    try {
 +      queryService.createIndex("scoreIndex", "entry.value.score", r.getFullPath() + ".entrySet entry");
 +      queryService.createIndex("scoreIndex2", "value.score", r.getFullPath() + ".values value");
 +    } catch (IndexNameConflictException | IndexExistsException | UnsupportedOperationException e) {
 +      // ignore, these indexes already exist or unsupported but make sure prepared queries are made
 +    }
 +    HashMap<Enum<?>, Query> queryList = new HashMap<Enum<?>, Query>();
 +    for (SortedSetQuery lq: SortedSetQuery.values()) {
 +      String queryString = lq.getQueryString(fullpath);
 +      Query query = this.queryService.newQuery(queryString);
 +      queryList.put(lq, query);
 +    }
 +    this.preparedQueries.put(key, queryList);
 +  }
 +
 +  private void doInitializeList(ByteArrayWrapper key, Region r) {
 +    r.put("head", Integer.valueOf(0));
 +    r.put("tail", Integer.valueOf(0));
 +    String fullpath = r.getFullPath();
 +    HashMap<Enum<?>, Query> queryList = new HashMap<Enum<?>, Query>();
 +    for (ListQuery lq: ListQuery.values()) {
 +      String queryString = lq.getQueryString(fullpath);
 +      Query query = this.queryService.newQuery(queryString);
 +      queryList.put(lq, query);
 +    }
 +    this.preparedQueries.put(key, queryList);
 +  }
 +
 +  /**
 +   * This method creates a Region globally with the given name. If
 +   * there is an error in the creation, a runtime exception will
 +   * be thrown.
 +   * 
 +   * @param key Name of Region to create
 +   * @return Region Region created globally
 +   */
 +  private Region<?, ?> createRegionGlobally(String key) {
 +    Region<?, ?> r = null;
 +    r = cache.getRegion(key);
 +    if (r != null) return r;
 +    do {
 +      Result result = cliCmds.createRegion(key, defaultRegionType, null, null, true, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
 +      r = cache.getRegion(key);
 +      if (result.getStatus() == Status.ERROR && r == null) {
 +        String err = "";
 +        while(result.hasNextLine())
 +          err += result.nextLine();
 +        throw new RegionCreationException(err);
 +      }
 +    } while(r == null); // The region can be null in the case that it is concurrently destroyed by
 +    // a remote even triggered internally by Geode
 +    return r;
 +  }
 +
 +  public Query getQuery(ByteArrayWrapper key, Enum<?> query) {
 +    return this.preparedQueries.get(key).get(query);
 +    /*
 +    if (query instanceof ListQuery) {
 +      return this.queryService.newQuery(((ListQuery)query).getQueryString(this.regions.get(key).getFullPath()));
 +    } else {
 +      return this.queryService.newQuery(((SortedSetQuery)query).getQueryString(this.regions.get(key).getFullPath()));
 +    }
 +     */
 +  }
 +
 +  /**
 +   * Checks if the given key is associated with the passed data type.
 +   * If there is a mismatch, a {@link RuntimeException} is thrown
 +   * 
 +   * @param key Key to check
 +   * @param type Type to check to
 +   */
 +  protected void checkDataType(ByteArrayWrapper key, RedisDataType type) {
 +    RedisDataType currentType = redisMetaRegion.get(key.toString());
 +    if (currentType == null)
 +      return;
 +    if (currentType == RedisDataType.REDIS_PROTECTED)
 +      throw new RedisDataTypeMismatchException("The key name \"" + key + "\" is protected");
 +    if (currentType != type)
 +      throw new RedisDataTypeMismatchException("The key name \"" + key + "\" is already used by a " + currentType.toString());
 +  }
 +
 +  public boolean regionExists(ByteArrayWrapper key) {
 +    return this.regions.containsKey(key);
 +  }
 +
 +  public Region<ByteArrayWrapper, ByteArrayWrapper> getStringsRegion() {
 +    return this.stringsRegion;
 +  }
 +
 +  public Region<ByteArrayWrapper, HyperLogLogPlus> gethLLRegion() {
 +    return this.hLLRegion;
 +  }
 +
 +  private RedisDataType getRedisDataType(String key) {
 +    return this.redisMetaRegion.get(key);
 +  }
 +
 +  public RedisDataType getRedisDataType(ByteArrayWrapper key) {
 +    return getRedisDataType(key.toString());
 +  }
 +
 +  /**
 +   * Sets the expiration for a key. The setting and modifying of a key expiration can only be set by a delay,
 +   * which means that both expiring after a time and at a time can be done but
 +   * the delay to expire at a time must be calculated before these calls. It is
 +   * also important to note that the delay is always handled in milliseconds
 +   * 
 +   * @param key The key to set the expiration for
 +   * @param delay The delay in milliseconds of the expiration
 +   * @return True is expiration set, false otherwise
 +   */
 +  public final boolean setExpiration(ByteArrayWrapper key, long delay) {
 +    RedisDataType type = getRedisDataType(key);
 +    if (type == null)
 +      return false;
 +    ScheduledFuture<?> future = this.expirationExecutor.schedule(new ExpirationExecutor(key, type, this), delay, TimeUnit.MILLISECONDS);
 +    this.expirationsMap.put(key, future);
 +    return true;
 +  }
 +
 +  /**
 +   * Modifies an expiration on a key
 +   * 
 +   * @param key String key to modify expiration on
 +   * @param delay Delay in milliseconds to reset the expiration to
 +   * @return True if reset, false if not
 +   */
 +  public final boolean modifyExpiration(ByteArrayWrapper key, long delay) {
 +    /*
 +     * Attempt to cancel future task
 +     */
 +    boolean canceled = cancelKeyExpiration(key);
 +
 +    if (!canceled)
 +      return false;
 +
 +    RedisDataType type = getRedisDataType(key);
 +    if (type == null)
 +      return false;
 +
 +    ScheduledFuture<?> future = this.expirationExecutor.schedule(new ExpirationExecutor(key, type, this), delay, TimeUnit.MILLISECONDS);
 +    this.expirationsMap.put(key, future);
 +    return true;
 +  }
 +
 +  /**
 +   * Removes an expiration from a key
 +   * 
 +   * @param key Key
 +   * @return True is expiration cancelled on the key, false otherwise
 +   */
 +  public final boolean cancelKeyExpiration(ByteArrayWrapper key) {
 +    ScheduledFuture<?> future = expirationsMap.remove(key);
 +    if (future == null)
 +      return false;
 +    return future.cancel(false);
 +  }
 +
 +  private boolean removeKeyExpiration(ByteArrayWrapper key) {
 +    return expirationsMap.remove(key) != null;
 +  }
 +
 +  /**
 +   * Check method if key has expiration
 +   * 
 +   * @param key Key
 +   * @return True if key has expiration, false otherwise
 +   */
 +  public boolean hasExpiration(ByteArrayWrapper key) {
 +    return this.expirationsMap.containsKey(key);
 +  }
 +
 +  /**
 +   * Get remaining expiration time
 +   * 
 +   * @param key Key
 +   * @return Remaining time in milliseconds or 0 if no delay or key doesn't exist
 +   */
 +  public final long getExpirationDelayMillis(ByteArrayWrapper key) {
 +    ScheduledFuture<?> future = this.expirationsMap.get(key);
 +    return future != null ? future.getDelay(TimeUnit.MILLISECONDS) : 0L;
 +  }
 +
 +  @Override
 +  public void close() {
 +    this.preparedQueries.clear();
 +  }
 +
 +  public String dumpRegionsCache() {
 +    StringBuilder builder = new StringBuilder();
 +    for (Entry<ByteArrayWrapper, Region<?, ?>> e : this.regions.entrySet()) {
 +      builder.append(e.getKey() + " --> {" + e.getValue() + "}\n");
 +    }
 +    return builder.toString();
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFAddExecutor.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFAddExecutor.java
index 95af34a,0000000..150078a
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFAddExecutor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFAddExecutor.java
@@@ -1,65 -1,0 +1,66 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package com.gemstone.gemfire.internal.redis.executor.hll;
 +
 +import java.util.List;
 +
 +import com.gemstone.gemfire.cache.Region;
++import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
 +import com.gemstone.gemfire.internal.redis.ByteArrayWrapper;
 +import com.gemstone.gemfire.internal.redis.Command;
 +import com.gemstone.gemfire.internal.redis.Coder;
 +import com.gemstone.gemfire.internal.redis.ExecutionHandlerContext;
 +import com.gemstone.gemfire.internal.redis.RedisConstants.ArityDef;
 +
 +public class PFAddExecutor extends HllExecutor {
 +
 +  @Override
 +  public void executeCommand(Command command, ExecutionHandlerContext context) {
 +    List<byte[]> commandElems = command.getProcessedCommand();
 +
 +    if (commandElems.size() < 2) {
 +      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.PFADD));
 +      return;
 +    }
 +
 +    ByteArrayWrapper key = command.getKey();
 +    checkAndSetDataType(key, context);
 +    Region<ByteArrayWrapper, HyperLogLogPlus> keyRegion = context.getRegionProvider().gethLLRegion();
 +
 +    HyperLogLogPlus hll = keyRegion.get(key);
 +
 +    boolean changed = false;
 +
 +    if (hll == null)
 +      hll = new HyperLogLogPlus(DEFAULT_HLL_DENSE);
 +
 +    for (int i = 2; i < commandElems.size(); i++) {
 +      byte[] bytes = commandElems.get(i);
 +      boolean offerChange = hll.offer(bytes);
 +      if (offerChange)
 +        changed = true;
 +    }
 +
 +    keyRegion.put(key, hll);
 +
 +    if (changed)
 +      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 1));
 +    else
 +      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 0));
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFCountExecutor.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFCountExecutor.java
index e081022,0000000..625a934
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFCountExecutor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFCountExecutor.java
@@@ -1,68 -1,0 +1,70 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.redis.executor.hll;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import com.gemstone.gemfire.cache.Region;
++import com.gemstone.gemfire.internal.hll.CardinalityMergeException;
++import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
 +import com.gemstone.gemfire.internal.redis.ByteArrayWrapper;
 +import com.gemstone.gemfire.internal.redis.Coder;
 +import com.gemstone.gemfire.internal.redis.Command;
 +import com.gemstone.gemfire.internal.redis.ExecutionHandlerContext;
 +import com.gemstone.gemfire.internal.redis.RedisConstants.ArityDef;
 +import com.gemstone.gemfire.internal.redis.RedisDataType;
 +
 +public class PFCountExecutor extends HllExecutor {
 +
 +  @Override
 +  public void executeCommand(Command command, ExecutionHandlerContext context) {
 +    List<byte[]> commandElems = command.getProcessedCommand();
 +
 +    if (commandElems.size() < 2) {
 +      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.PFCOUNT));
 +      return;
 +    }
 +
 +    Region<ByteArrayWrapper, HyperLogLogPlus> keyRegion = context.getRegionProvider().gethLLRegion();
 +
 +    List<HyperLogLogPlus> hlls = new ArrayList<HyperLogLogPlus>();
 +
 +    for (int i = 1; i < commandElems.size(); i++) {
 +      ByteArrayWrapper k = new ByteArrayWrapper(commandElems.get(i));
 +      checkDataType(k, RedisDataType.REDIS_HLL, context);
 +      HyperLogLogPlus h = keyRegion.get(k);
 +      if (h != null)
 +        hlls.add(h);
 +    }
 +    if (hlls.isEmpty()) {
 +      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 0));
 +      return;
 +    }
 +
 +    HyperLogLogPlus tmp = hlls.remove(0);
 +    HyperLogLogPlus[] estimators = hlls.toArray(new HyperLogLogPlus[hlls.size()]);
 +    try {
 +      tmp = (HyperLogLogPlus) tmp.merge(estimators);
 +    } catch (CardinalityMergeException e) {
 +      throw new RuntimeException(e);
 +    }
 +    long cardinality = tmp.cardinality();
 +    command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), cardinality));
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFMergeExecutor.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFMergeExecutor.java
index dd9afbc,0000000..f059cc2
mode 100755,000000..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFMergeExecutor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/hll/PFMergeExecutor.java
@@@ -1,72 -1,0 +1,74 @@@
 +/*
 + * 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 com.gemstone.gemfire.internal.redis.executor.hll;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import com.gemstone.gemfire.cache.Region;
++import com.gemstone.gemfire.internal.hll.CardinalityMergeException;
++import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
 +import com.gemstone.gemfire.internal.redis.ByteArrayWrapper;
 +import com.gemstone.gemfire.internal.redis.Coder;
 +import com.gemstone.gemfire.internal.redis.Command;
 +import com.gemstone.gemfire.internal.redis.ExecutionHandlerContext;
 +import com.gemstone.gemfire.internal.redis.RedisDataType;
 +import com.gemstone.gemfire.internal.redis.RedisConstants.ArityDef;
 +
 +public class PFMergeExecutor extends HllExecutor {
 +
 +  @Override
 +  public void executeCommand(Command command, ExecutionHandlerContext context) {
 +    List<byte[]> commandElems = command.getProcessedCommand();
 +
 +    if (commandElems.size() < 3) {
 +      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.PFMERGE));
 +      return;
 +    }
 +
 +    ByteArrayWrapper destKey = command.getKey();
 +    checkAndSetDataType(destKey, context);
 +    Region<ByteArrayWrapper, HyperLogLogPlus> keyRegion = context.getRegionProvider().gethLLRegion();
 +    HyperLogLogPlus mergedHLL = keyRegion.get(destKey);
 +    if (mergedHLL == null)
 +      mergedHLL = new HyperLogLogPlus(DEFAULT_HLL_DENSE);
 +    List<HyperLogLogPlus> hlls = new ArrayList<HyperLogLogPlus>();
 +
 +    for (int i = 2; i < commandElems.size(); i++) {
 +      ByteArrayWrapper k = new ByteArrayWrapper(commandElems.get(i));
 +      checkDataType(k, RedisDataType.REDIS_HLL, context);
 +      HyperLogLogPlus h = keyRegion.get(k);
 +      if (h != null)
 +        hlls.add(h);
 +    }
 +    if (hlls.isEmpty()) {
 +      context.getRegionProvider().removeKey(destKey);
 +      command.setResponse(Coder.getSimpleStringResponse(context.getByteBufAllocator(), "OK"));
 +      return;
 +    }
 +
 +    HyperLogLogPlus[] estimators = hlls.toArray(new HyperLogLogPlus[hlls.size()]);
 +    try {
 +      mergedHLL = (HyperLogLogPlus) mergedHLL.merge(estimators);
 +    } catch (CardinalityMergeException e) {
 +      throw new RuntimeException(e);
 +    }
 +    keyRegion.put(destKey, mergedHLL);
 +    command.setResponse(Coder.getSimpleStringResponse(context.getByteBufAllocator(), "OK"));
 +  }
 +
 +}



[097/100] [abbrv] incubator-geode git commit: GEODE-870: Handling multiple concurrent locator restarts. Elder locator nomination

Posted by ud...@apache.org.
GEODE-870: Handling multiple concurrent locator restarts. Elder locator nomination


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/dad8cfd8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/dad8cfd8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/dad8cfd8

Branch: refs/heads/feature/GEODE-870
Commit: dad8cfd83752886466e40449293388ba7456cd78
Parents: f7dd4fd
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Wed Feb 10 12:19:33 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 07:26:42 2016 +1100

----------------------------------------------------------------------
 .../gemfire/distributed/LocatorDUnitTest.java         | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dad8cfd8/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index a6cfba4..d5fe5f8 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@ -1443,8 +1443,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
     this.port1 = freeTCPPorts[0];
     this.port2 = freeTCPPorts[1];
     int port3 = freeTCPPorts[2];
-    deleteLocatorStateFile(port1, port2, port3);
-    final String host0 = getServerHostName(host);
+    DistributedTestUtils.deleteLocatorStateFile(port1, port2, port3);
+    final String host0 = NetworkUtils.getServerHostName(host);
     final String locators = host0 + "[" + port1 + "]," +
         host0 + "[" + port2 + "]," +
         host0 + "[" + port3 + "]";
@@ -1497,7 +1497,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
             return null;
           }
         };
-        DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
+        Wait.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
 
         // three applications plus
         assertEquals(6, system.getDM().getViewMembers().size());
@@ -1521,7 +1521,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
             return null;
           }
         };
-        DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
+        Wait.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
 
         final String newLocators = host0 + "[" + port2 + "]," +
             host0 + "[" + port3 + "]";
@@ -1549,7 +1549,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
             return null;
           }
         };
-        DistributedTestCase.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
+        Wait.waitForCriterion(waitCriterion, 10 * 1000, 200, true);
 
         int netviewId = vm1.invoke(() -> GMSJoinLeaveHelper.getViewId());
         assertEquals(netviewId, (int) vm2.invoke(() -> GMSJoinLeaveHelper.getViewId()));
@@ -1582,7 +1582,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
         try {
           Locator.startLocatorAndDS((int) args[0], logFile, (Properties) args[1]);
         } catch (IOException ex) {
-          fail("While starting process on port " + args[0], ex);
+          com.gemstone.gemfire.test.dunit.Assert.fail("While starting process on port " + args[0], ex);
         }
       }
     });
@@ -1595,7 +1595,7 @@ public class LocatorDUnitTest extends DistributedTestCase {
         try {
           Locator.startLocatorAndDS((int) args[0], logFile, (Properties) args[1]);
         } catch (IOException ex) {
-          fail("While starting process on port " + args[0], ex);
+          com.gemstone.gemfire.test.dunit.Assert.fail("While starting process on port " + args[0], ex);
         }
       }
     });


[070/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
index 0000000,f7d0714..690b55a
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
@@@ -1,0 -1,181 +1,181 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache;
+ 
+ import static org.junit.Assert.*;
+ 
+ import java.io.IOException;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ 
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl.OldValueImporter;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.DataAsAddress;
+ import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
+ import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
+ import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ import com.gemstone.gemfire.internal.util.BlobHelper;
+ 
+ public abstract class OldValueImporterTestBase {
+   @Before
+   public void setUp() throws Exception {
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+   }
+   
+   protected abstract OldValueImporter createImporter();
+   protected abstract Object getOldValueFromImporter(OldValueImporter ovi);
+   protected abstract void toData(OldValueImporter ovi, HeapDataOutputStream hdos) throws IOException;
+   protected abstract void fromData(OldValueImporter ovi, byte[] bytes) throws IOException, ClassNotFoundException;
+ 
+   @Test
+   public void testValueSerialization() throws IOException, ClassNotFoundException {
+     byte[] bytes = new byte[1024];
+     HeapDataOutputStream hdos = new HeapDataOutputStream(bytes);
+     OldValueImporter imsg = createImporter();
+ 
+     // null byte array value
+     {
+       OldValueImporter omsg = createImporter();
+       omsg.importOldBytes(null, false);
+       toData(omsg, hdos);
+       fromData(imsg, bytes);
+       assertEquals(null, getOldValueFromImporter(imsg));
+     }
+     
+     // null object value
+     {
+       OldValueImporter omsg = createImporter();
+       omsg.importOldObject(null, true);
+       toData(omsg, hdos);
+       fromData(imsg, bytes);
+       assertEquals(null, getOldValueFromImporter(imsg));
+     }
+     
+     // simple byte array
+     {
+       byte[] baValue = new byte[] {1,2,3,4,5,6,7,8,9};
+       OldValueImporter omsg = createImporter();
+       omsg.importOldBytes(baValue, false);
+       hdos = new HeapDataOutputStream(bytes);
+       toData(omsg, hdos);
+       fromData(imsg, bytes);
+       assertArrayEquals(baValue, (byte[])getOldValueFromImporter(imsg));
+     }
+     
+     // String in serialized form
+     {
+       String stringValue = "1,2,3,4,5,6,7,8,9";
+       byte[] stringValueBlob = EntryEventImpl.serialize(stringValue);
+       OldValueImporter omsg = createImporter();
+       omsg.importOldBytes(stringValueBlob, true);
+       hdos = new HeapDataOutputStream(bytes);
+       toData(omsg, hdos);
+       fromData(imsg, bytes);
+       assertArrayEquals(stringValueBlob, ((VMCachedDeserializable)getOldValueFromImporter(imsg)).getSerializedValue());
+     }
+     
+     // String in object form
+     {
+       String stringValue = "1,2,3,4,5,6,7,8,9";
+       byte[] stringValueBlob = EntryEventImpl.serialize(stringValue);
+       OldValueImporter omsg = createImporter();
+       omsg.importOldObject(stringValue, true);
+       hdos = new HeapDataOutputStream(bytes);
+       toData(omsg, hdos);
+       fromData(imsg, bytes);
+       assertArrayEquals(stringValueBlob, ((VMCachedDeserializable)getOldValueFromImporter(imsg)).getSerializedValue());
+     }
+     
+     // off-heap DataAsAddress byte array
+     {
+       SimpleMemoryAllocatorImpl sma =
 -          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+       try {
+         byte[] baValue = new byte[] {1,2};
 -        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValue, false, false, null);
++        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValue, false, false);
+         OldValueImporter omsg = createImporter();
+         omsg.importOldObject(baValueSO, false);
+         hdos = new HeapDataOutputStream(bytes);
+         toData(omsg, hdos);
+         fromData(imsg, bytes);
+         assertArrayEquals(baValue, (byte[])getOldValueFromImporter(imsg));
+       } finally {
+         SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+       }
+     }
+     // off-heap Chunk byte array
+     {
+       SimpleMemoryAllocatorImpl sma =
 -          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+       try {
+         byte[] baValue = new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
 -        Chunk baValueSO = (Chunk) sma.allocateAndInitialize(baValue, false, false, null);
++        ObjectChunk baValueSO = (ObjectChunk) sma.allocateAndInitialize(baValue, false, false);
+         OldValueImporter omsg = createImporter();
+         omsg.importOldObject(baValueSO, false);
+         hdos = new HeapDataOutputStream(bytes);
+         toData(omsg, hdos);
+         fromData(imsg, bytes);
+         assertArrayEquals(baValue, (byte[])getOldValueFromImporter(imsg));
+       } finally {
+         SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+       }
+     }
+     // off-heap DataAsAddress String
+     {
+       SimpleMemoryAllocatorImpl sma =
 -          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+       try {
+         String baValue = "12";
+         byte[] baValueBlob = BlobHelper.serializeToBlob(baValue);
 -        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValueBlob, true, false, null);
++        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValueBlob, true, false);
+         OldValueImporter omsg = createImporter();
+         omsg.importOldObject(baValueSO, true);
+         hdos = new HeapDataOutputStream(bytes);
+         toData(omsg, hdos);
+         fromData(imsg, bytes);
+         assertArrayEquals(baValueBlob, ((VMCachedDeserializable)getOldValueFromImporter(imsg)).getSerializedValue());
+       } finally {
+         SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+       }
+     }
+     // off-heap Chunk String
+     {
+       SimpleMemoryAllocatorImpl sma =
 -          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+       try {
+         String baValue = "12345678";
+         byte[] baValueBlob = BlobHelper.serializeToBlob(baValue);
 -        Chunk baValueSO = (Chunk) sma.allocateAndInitialize(baValueBlob, true, false, null);
++        ObjectChunk baValueSO = (ObjectChunk) sma.allocateAndInitialize(baValueBlob, true, false);
+         OldValueImporter omsg = createImporter();
+         omsg.importOldObject(baValueSO, true);
+         hdos = new HeapDataOutputStream(bytes);
+         toData(omsg, hdos);
+         fromData(imsg, bytes);
+         assertArrayEquals(baValueBlob, ((VMCachedDeserializable)getOldValueFromImporter(imsg)).getSerializedValue());
+       } finally {
+         SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+       }
+     }
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
index 0000000,3dc5a7d..b7bd47a
mode 000000,100755..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
@@@ -1,0 -1,75 +1,112 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
+ 
+ import static org.junit.Assert.*;
+ import static org.mockito.Matchers.*;
+ import static org.mockito.Mockito.*;
+ 
+ import java.net.Socket;
+ import java.nio.ByteBuffer;
+ 
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.offheap.HeapByteBufferMemoryChunkJUnitTest;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class MessageJUnitTest {
+ 
+   Message message;
+   Socket mockSocket;
+   MessageStats mockStats;
+   ByteBuffer msgBuffer;
++  ServerConnection mockServerConnection;
+   
+   @Before
+   public void setUp() throws Exception {
+     mockSocket = mock(Socket.class);
 -    message = new Message(5, Version.CURRENT);
 -    assertEquals(5, message.getNumberOfParts());
++    message = new Message(2, Version.CURRENT);
++    assertEquals(2, message.getNumberOfParts());
+     mockStats = mock(MessageStats.class);
+     msgBuffer = ByteBuffer.allocate(1000);
 -    message.setComms(mockSocket, msgBuffer, mockStats);
++    mockServerConnection = mock(ServerConnection.class);
++    message.setComms(mockServerConnection, mockSocket, msgBuffer, mockStats);
+   }
+ 
+   @Test
+   public void clearDoesNotThrowNPE() throws Exception{
+     // unsetComms clears the message's ByteBuffer, which was causing an NPE during shutdown
+     // when clear() was invoked
+     message.unsetComms();
+     message.clear();
+   }
+   
+   @Test
+   public void numberOfPartsIsAdjusted() {
+     int numParts = message.getNumberOfParts();
 -    message.setNumberOfParts(2*numParts);
 -    assertEquals(2*numParts, message.getNumberOfParts());
++    message.setNumberOfParts(2*numParts+1);
++    assertEquals(2*numParts+1, message.getNumberOfParts());
+     message.addBytesPart(new byte[1]);
+     message.addIntPart(2);
+     message.addLongPart(3);
+     message.addObjPart("4");
+     message.addStringPart("5");
+     assertEquals(5, message.getNextPartNumber());
+   }
+   
++  @Test
++  public void messageLongerThanMaxIntIsRejected() throws Exception {
++    Part[] parts = new Part[2];
++    Part mockPart1 = mock(Part.class);
++    when(mockPart1.getLength()).thenReturn(Integer.MAX_VALUE/2);
++    parts[0] = mockPart1;
++    parts[1] = mockPart1;
++    message.setParts(parts);
++    try {
++      message.send();
++    } catch (MessageTooLargeException e) {
++      assertTrue(e.getMessage().contains("exceeds maximum integer value"));
++      return;
++    }
++    fail("expected an exception but none was thrown");
++  }
++  
++  @Test
++  public void maxMessageSizeIsRespected() throws Exception {
++    Part[] parts = new Part[2];
++    Part mockPart1 = mock(Part.class);
++    when(mockPart1.getLength()).thenReturn(Message.MAX_MESSAGE_SIZE/2);
++    parts[0] = mockPart1;
++    parts[1] = mockPart1;
++    message.setParts(parts);
++    try {
++      message.send();
++    } catch (MessageTooLargeException e) {
++      assertFalse(e.getMessage().contains("exceeds maximum integer value"));
++      return;
++    }
++    fail("expected an exception but none was thrown");
++  }
++  
++  
+   // TODO many more tests are needed
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
index 0000000,ccc6b67..54eac9e
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
@@@ -1,0 -1,280 +1,238 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
 -import static org.mockito.Mockito.mock;
+ import static org.hamcrest.CoreMatchers.*;
+ 
+ import java.util.Arrays;
+ 
+ import org.assertj.core.api.JUnitSoftAssertions;
+ import org.junit.After;
+ import org.junit.AfterClass;
+ import org.junit.Before;
+ import org.junit.BeforeClass;
+ import org.junit.Rule;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ import org.junit.rules.ExpectedException;
+ 
 -import com.gemstone.gemfire.LogWriter;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class FragmentJUnitTest {
+ 
 -  private SimpleMemoryAllocatorImpl ma;
 -  private OutOfOffHeapMemoryListener ooohml;
 -  private OffHeapMemoryStats stats;
 -  private LogWriter lw;
 -  private UnsafeMemoryChunk.Factory umcFactory;
+   private UnsafeMemoryChunk[] slabs;
 -  private int numSlabs;
+ 
+   static {
+     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
+   }
+   
+   @Rule
+   public ExpectedException expectedException = ExpectedException.none();
+   
+   @Rule
+   public JUnitSoftAssertions softly = new JUnitSoftAssertions();
+ 
+ 
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+   }
+ 
+   @AfterClass
+   public static void tearDownAfterClass() throws Exception {
+   }
+ 
+   @Before
+   public void setUp() throws Exception {
 -    ooohml = mock(OutOfOffHeapMemoryListener.class);
 -    stats = mock(OffHeapMemoryStats.class);
 -    lw = mock(LogWriter.class);
 -    
 -    numSlabs = 2;
 -    umcFactory = new UnsafeMemoryChunk.Factory(){
 -      @Override
 -      public UnsafeMemoryChunk create(int size) {
 -        return new UnsafeMemoryChunk(size);
 -      }
 -    };
 -    slabs = allocateMemorySlabs();
++    UnsafeMemoryChunk slab1 = new UnsafeMemoryChunk((int)OffHeapStorage.MIN_SLAB_SIZE);
++    UnsafeMemoryChunk slab2 = new UnsafeMemoryChunk((int)OffHeapStorage.MIN_SLAB_SIZE);
++    slabs = new UnsafeMemoryChunk[]{slab1, slab2};
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
 -    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
++    for (int i=0; i < slabs.length; i++) {
++      slabs[i].release();
++    }
+   }
+   
 -  private UnsafeMemoryChunk[] allocateMemorySlabs() {
 -    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, numSlabs, OffHeapStorage.MIN_SLAB_SIZE * numSlabs, OffHeapStorage.MIN_SLAB_SIZE, umcFactory);
 -    return ma.getSlabs();
 -  }
 -
+   
+   @Test
+   public void fragmentConstructorThrowsExceptionForNon8ByteAlignedAddress() {
+       expectedException.expect(IllegalStateException.class);
+       expectedException.expectMessage("address was not 8 byte aligned");
+ 
+       new Fragment(slabs[0].getMemoryAddress() + 2, 0);
+       fail("Constructor failed to throw exception for non-8-byte alignment");
+   }
+ 
+   @Test
+   public void zeroSizeFragmentHasNoFreeSpace() {
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), 0);
+     assertThat(fragment.freeSpace(), is(0));
+   }
+ 
+   @Test
+   public void unallocatedFragmentHasFreeSpaceEqualToFragmentSize() {
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getSize()).isEqualTo((int)OffHeapStorage.MIN_SLAB_SIZE);
+     softly.assertThat(fragment.freeSpace()).isEqualTo((int)OffHeapStorage.MIN_SLAB_SIZE);
+   }
+ 
+   @Test
+   public void allocatingFromFragmentReducesFreeSpace() {
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256)).isEqualTo(true);
+     softly.assertThat(fragment.freeSpace()).isEqualTo(768);
+     softly.assertThat(fragment.getFreeIndex()).isEqualTo(256);
+   }
+ 
+   @Test
+   public void fragementAllocationIsUnsafeWithRespectToAllocationSize() {
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + (int)OffHeapStorage.MIN_SLAB_SIZE + 8)).isEqualTo(true);
+     softly.assertThat(fragment.freeSpace()).isEqualTo(-8);
+   }
+ 
+   @Test
+   public void getBlockSizeReturnsFreeSpace() {
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256)).isEqualTo(true);
+     softly.assertThat(fragment.getBlockSize()).isEqualTo(fragment.freeSpace());
+   }
+ 
+   @Test
+   public void getMemoryAdressIsAlwaysFragmentBaseAddress() {
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getMemoryAddress()).isEqualTo(slabs[0].getMemoryAddress());
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.getMemoryAddress()).isEqualTo(slabs[0].getMemoryAddress());
+   }
+   
+   @Test
+   public void getStateIsAlwaysStateUNUSED() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getState()).isEqualTo(MemoryBlock.State.UNUSED);
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.getState()).isEqualTo(MemoryBlock.State.UNUSED);
+   }
+ 
+   @Test
+   public void getFreeListIdIsAlwaysMinus1() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getFreeListId()).isEqualTo(-1);
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.getFreeListId()).isEqualTo(-1);
+   }
+ 
+   @Test
+   public void getRefCountIsAlwaysZero() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getRefCount()).isEqualTo(0);
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.getRefCount()).isEqualTo(0);
+   }
+ 
+   @Test
+   public void getDataTypeIsAlwaysNA() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getDataType()).isEqualTo("N/A");
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.getDataType()).isEqualTo("N/A");
+   }
+ 
+   @Test
+   public void isSerializedIsAlwaysFalse() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.isSerialized()).isEqualTo(false);
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.isSerialized()).isEqualTo(false);
+   }
+ 
+   @Test
+   public void isCompressedIsAlwaysFalse() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.isCompressed()).isEqualTo(false);
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.isCompressed()).isEqualTo(false);
+   }
+ 
+   @Test
+   public void getDataValueIsAlwaysNull() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     softly.assertThat(fragment.getDataValue()).isNull();
+     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
+     softly.assertThat(fragment.getDataValue()).isNull();
+   }
+ 
+   @Test
 -  public void getChunkTypeIsAlwaysNull() {
 -    slabs = allocateMemorySlabs();
 -    Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
 -    softly.assertThat(fragment.getChunkType()).isNull();
 -    fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
 -    softly.assertThat(fragment.getChunkType()).isNull();
 -  }
 -
 -  @Test
+   public void fragmentEqualsComparesMemoryBlockAddresses() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     Fragment sameFragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
+     softly.assertThat(fragment0.equals(sameFragment)).isEqualTo(true);
+     softly.assertThat(fragment0.equals(fragment1)).isEqualTo(false);
+   }
+ 
+   @Test
+   public void fragmentEqualsIsFalseForNonFragmentObjects() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     assertThat(fragment0.equals(slabs[0]), is(false));
+   }
+ 
+   @Test
+   public void fragmentHashCodeIsHashCodeOfItsMemoryAddress() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
+     Long fragmentAddress = fragment0.getMemoryAddress();
+     softly.assertThat(fragment0.hashCode()).isEqualTo(fragmentAddress.hashCode())
+                                            .isNotEqualTo(fragment1.hashCode());
+   }
+ 
+   @Test
+   public void fragmentFillSetsAllBytesToTheSameConstantValue() {
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     Long fragmentAddress = fragment.getMemoryAddress();
+     byte[] bytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
+     byte[] expectedBytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
 -    Arrays.fill(expectedBytes, Chunk.FILL_BYTE);;
++    Arrays.fill(expectedBytes, ObjectChunk.FILL_BYTE);;
+     fragment.fill();
+     UnsafeMemoryChunk.readAbsoluteBytes(fragmentAddress, bytes, 0, (int)OffHeapStorage.MIN_SLAB_SIZE);
+     assertThat(bytes, is(equalTo(expectedBytes)));
+   }
+ 
+   @Test
+   public void getNextBlockThrowsExceptionForFragment() {
+     expectedException.expect(UnsupportedOperationException.class);
+ 
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     fragment.getNextBlock();
+     fail("getNextBlock failed to throw UnsupportedOperationException");
+   }
+ 
+   @Test
+   public void getSlabIdThrowsExceptionForFragment() {
+     expectedException.expect(UnsupportedOperationException.class);
+ 
 -    slabs = allocateMemorySlabs();
+     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
+     fragment.getSlabId();
+     fail("getSlabId failed to throw UnsupportedOperationException");
+   }
+   
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
index 0000000,93f2039..6790f6a
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
@@@ -1,0 -1,46 +1,46 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+ 
+ @Category(IntegrationTest.class)
+ public class FreeListOffHeapRegionJUnitTest extends OffHeapRegionBase {
+ 
+   @Override
+   protected String getOffHeapMemorySize() {
+     return "20m";
+   }
+   
+   @Override
+   public void configureOffHeapStorage() {
+     System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "1m");
+   }
+ 
+   @Override
+   public void unconfigureOffHeapStorage() {
+     System.clearProperty("gemfire.OFF_HEAP_SLAB_SIZE");
+   }
+ 
+   @Override
+   public int perObjectOverhead() {
 -    return Chunk.OFF_HEAP_HEADER_SIZE;
++    return ObjectChunk.OFF_HEAP_HEADER_SIZE;
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
index 0000000,5e54b73..97ae486
mode 000000,100755..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java
@@@ -1,0 -1,230 +1,230 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.fail;
+ 
+ import java.io.PrintWriter;
+ import java.io.StringWriter;
+ import java.util.ArrayList;
+ import java.util.List;
+ 
+ import org.junit.After;
+ import org.junit.Assert;
+ import org.junit.Rule;
+ import org.junit.Test;
+ import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ /**
+  * Tests LifecycleListener
+  * 
+  * @author Kirk Lund
+  */
+ @Category(UnitTest.class)
+ public class LifecycleListenerJUnitTest {
+   @Rule
+   public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+ 
+   private final List<LifecycleListenerCallback> afterCreateCallbacks = new ArrayList<LifecycleListenerCallback>();
+   private final List<LifecycleListenerCallback> afterReuseCallbacks = new ArrayList<LifecycleListenerCallback>();
+   private final List<LifecycleListenerCallback> beforeCloseCallbacks = new ArrayList<LifecycleListenerCallback>();
+   private final TestLifecycleListener listener = new TestLifecycleListener(this.afterCreateCallbacks, this.afterReuseCallbacks, this.beforeCloseCallbacks);
+ 
+   @After
+   public void tearDown() throws Exception {
+     LifecycleListener.removeLifecycleListener(this.listener);
+     this.afterCreateCallbacks.clear();
+     this.afterReuseCallbacks.clear();
+     this.beforeCloseCallbacks.clear();
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+   }
+ 
+   @Test
+   public void testAddRemoveListener() {
+     LifecycleListener.addLifecycleListener(this.listener);
+     LifecycleListener.removeLifecycleListener(this.listener);
+ 
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
 -    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
++    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
+         new UnsafeMemoryChunk[] { slab });
+ 
+     Assert.assertEquals(0, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(0, this.beforeCloseCallbacks.size());
+ 
+     ma.close();
+ 
+     Assert.assertEquals(0, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(0, this.beforeCloseCallbacks.size());
+ 
+     LifecycleListener.removeLifecycleListener(this.listener);
+   }
+ 
+   @Test
+   public void testCallbacksAreCalledAfterCreate() {
+     LifecycleListener.addLifecycleListener(this.listener);
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
 -    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
++    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(),
+         new UnsafeMemoryChunk[] { slab });
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(0, this.beforeCloseCallbacks.size());
+ 
+     closeAndFree(ma);
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
+     
+     LifecycleListener.removeLifecycleListener(this.listener);
+   }
+ 
+   @Test
+   public void testCallbacksAreCalledAfterReuse() {
+ 
+     LifecycleListener.addLifecycleListener(this.listener);
+ 
+     System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "false");
+ 
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
+     SimpleMemoryAllocatorImpl ma = createAllocator(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(0, this.beforeCloseCallbacks.size());
+ 
+     ma.close();
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
+ 
+     ma = createAllocator(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), null);
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(1, this.afterReuseCallbacks.size());
+     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
+ 
+     SimpleMemoryAllocatorImpl ma2 = createAllocator(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
+     assertEquals(null, ma2);
+     
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(1, this.afterReuseCallbacks.size());
+     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
+ 
+     ma.close();
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(1, this.afterReuseCallbacks.size());
+     Assert.assertEquals(2, this.beforeCloseCallbacks.size());
+   }
+ 
+   private SimpleMemoryAllocatorImpl createAllocator(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats ohms, UnsafeMemoryChunk[] slab) {
+     try {
 -       return SimpleMemoryAllocatorImpl.create(ooohml, ohms, slab);
++       return SimpleMemoryAllocatorImpl.createForUnitTest(ooohml, ohms, slab);
+     } catch (IllegalStateException e) {
+       return null;
+     }
+   }
+   
+   private void closeAndFree(SimpleMemoryAllocatorImpl ma) {
+     System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
+     try {
+       ma.close();
+     } finally {
+       System.clearProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY);
+     }
+   }
+   
+   @Test
+   public void testCallbacksAreCalledAfterReuseWithFreeTrue() {
+ 
+     LifecycleListener.addLifecycleListener(this.listener);
+ 
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k
 -    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
++    SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(0, this.beforeCloseCallbacks.size());
+ 
+     closeAndFree(ma);
+ 
+     Assert.assertEquals(1, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
+ 
+     slab = new UnsafeMemoryChunk(1024); // 1k
 -    SimpleMemoryAllocatorImpl ma2 = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
++    SimpleMemoryAllocatorImpl ma2 = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab });
+ 
+     Assert.assertEquals(2, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(1, this.beforeCloseCallbacks.size());
+ 
+     closeAndFree(ma);
+ 
+     Assert.assertEquals(2, this.afterCreateCallbacks.size());
+     Assert.assertEquals(0, this.afterReuseCallbacks.size());
+     Assert.assertEquals(2, this.beforeCloseCallbacks.size());
+   }
+ 
+   static final class LifecycleListenerCallback {
+     private final SimpleMemoryAllocatorImpl allocator;
+     private final long timeStamp;
+     private final Throwable creationTime;
+ 
+     LifecycleListenerCallback(SimpleMemoryAllocatorImpl allocator) {
+       this.allocator = allocator;
+       this.timeStamp = System.currentTimeMillis();
+       this.creationTime = new Exception();
+     }
+   }
+ 
+   static class TestLifecycleListener implements LifecycleListener {
+     private final List<LifecycleListenerCallback> afterCreateCallbacks;
+     private final List<LifecycleListenerCallback> afterReuseCallbacks;
+     private final List<LifecycleListenerCallback> beforeCloseCallbacks;
+ 
+     TestLifecycleListener(List<LifecycleListenerCallback> afterCreateCallbacks, List<LifecycleListenerCallback> afterReuseCallbacks,
+         List<LifecycleListenerCallback> beforeCloseCallbacks) {
+       this.afterCreateCallbacks = afterCreateCallbacks;
+       this.afterReuseCallbacks = afterReuseCallbacks;
+       this.beforeCloseCallbacks = beforeCloseCallbacks;
+     }
+ 
+     @Override
+     public void afterCreate(SimpleMemoryAllocatorImpl allocator) {
+       this.afterCreateCallbacks.add(new LifecycleListenerCallback(allocator));
+     }
+ 
+     @Override
+     public void afterReuse(SimpleMemoryAllocatorImpl allocator) {
+       this.afterReuseCallbacks.add(new LifecycleListenerCallback(allocator));
+     }
+ 
+     @Override
+     public void beforeClose(SimpleMemoryAllocatorImpl allocator) {
+       this.beforeCloseCallbacks.add(new LifecycleListenerCallback(allocator));
+     }
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java
index 0000000,0000000..9271b53
new file mode 100644
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkJUnitTest.java
@@@ -1,0 -1,0 +1,902 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.offheap;
++
++import static org.assertj.core.api.Assertions.assertThat;
++import static org.junit.Assert.assertArrayEquals;
++import static org.junit.Assert.assertEquals;
++import static org.junit.Assert.assertNotNull;
++import static org.mockito.Mockito.atLeastOnce;
++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.times;
++import static org.mockito.Mockito.verify;
++import static org.mockito.Mockito.when;
++
++import java.io.IOException;
++import java.nio.ByteBuffer;
++
++import org.junit.After;
++import org.junit.Before;
++import org.junit.Test;
++import org.junit.experimental.categories.Category;
++
++import com.gemstone.gemfire.LogWriter;
++import com.gemstone.gemfire.compression.Compressor;
++import com.gemstone.gemfire.internal.DSCODE;
++import com.gemstone.gemfire.internal.HeapDataOutputStream;
++import com.gemstone.gemfire.internal.Version;
++import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
++import com.gemstone.gemfire.internal.cache.CachePerfStats;
++import com.gemstone.gemfire.internal.cache.EntryEventImpl;
++import com.gemstone.gemfire.internal.cache.RegionEntryContext;
++import com.gemstone.gemfire.internal.offheap.MemoryBlock.State;
++import com.gemstone.gemfire.test.junit.categories.UnitTest;
++
++@Category(UnitTest.class)
++public class ObjectChunkJUnitTest extends AbstractStoredObjectTestBase {
++
++  private MemoryAllocator ma;
++
++  static {
++    ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
++  }
++
++  @Before
++  public void setUp() {
++    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
++    OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
++    LogWriter lw = mock(LogWriter.class);
++
++    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 3, OffHeapStorage.MIN_SLAB_SIZE * 3, OffHeapStorage.MIN_SLAB_SIZE);
++  }
++
++  @After
++  public void tearDown() {
++    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
++  }
++
++  @Override
++  public Object getValue() {
++    return Long.valueOf(Long.MAX_VALUE);
++  }
++
++  @Override
++  public byte[] getValueAsByteArray() {
++    return convertValueToByteArray(getValue());
++  }
++
++  private byte[] convertValueToByteArray(Object value) {
++    return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong((Long) value).array();
++  }
++
++  @Override
++  public Object convertByteArrayToObject(byte[] valueInByteArray) {
++    return ByteBuffer.wrap(valueInByteArray).getLong();
++  }
++
++  @Override
++  public Object convertSerializedByteArrayToObject(byte[] valueInSerializedByteArray) {
++    return EntryEventImpl.deserialize(valueInSerializedByteArray);
++  }
++
++  @Override
++  public ObjectChunk createValueAsUnserializedStoredObject(Object value) {
++    byte[] valueInByteArray;
++    if (value instanceof Long) {
++      valueInByteArray = convertValueToByteArray(value);
++    } else {
++      valueInByteArray = (byte[]) value;
++    }
++
++    boolean isSerialized = false;
++    boolean isCompressed = false;
++
++    return createChunk(valueInByteArray, isSerialized, isCompressed);
++  }
++
++  @Override
++  public ObjectChunk createValueAsSerializedStoredObject(Object value) {
++    byte[] valueInSerializedByteArray = EntryEventImpl.serialize(value);
++
++    boolean isSerialized = true;
++    boolean isCompressed = false;
++
++    return createChunk(valueInSerializedByteArray, isSerialized, isCompressed);
++  }
++
++  private ObjectChunk createChunk(byte[] v, boolean isSerialized, boolean isCompressed) {
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed);
++    return chunk;
++  }
++
++  @Test
++  public void chunkCanBeCreatedFromAnotherChunk() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    ObjectChunk newChunk = new ObjectChunk(chunk);
++
++    assertNotNull(newChunk);
++    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
++
++    chunk.release();
++  }
++
++  @Test
++  public void chunkCanBeCreatedWithOnlyMemoryAddress() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    ObjectChunk newChunk = new ObjectChunk(chunk.getMemoryAddress());
++
++    assertNotNull(newChunk);
++    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
++
++    chunk.release();
++  }
++
++  @Test
++  public void chunkSliceCanBeCreatedFromAnotherChunk() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    int position = 1;
++    int end = 2;
++
++    ObjectChunk newChunk = (ObjectChunk) chunk.slice(position, end);
++
++    assertNotNull(newChunk);
++    assertThat(newChunk.getClass()).isEqualTo(ObjectChunkSlice.class);
++    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
++
++    chunk.release();
++  }
++
++  @Test
++  public void fillSerializedValueShouldFillWrapperWithSerializedValueIfValueIsSerialized() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    // mock the things
++    BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class);
++
++    byte userBits = 0;
++    byte serializedUserBits = 1;
++    chunk.fillSerializedValue(wrapper, userBits);
++
++    verify(wrapper, times(1)).setChunkData(chunk, serializedUserBits);
++
++    chunk.release();
++  }
++
++  @Test
++  public void fillSerializedValueShouldFillWrapperWithDeserializedValueIfValueIsNotSerialized() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    // mock the things
++    BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class);
++
++    byte userBits = 1;
++    chunk.fillSerializedValue(wrapper, userBits);
++
++    verify(wrapper, times(1)).setChunkData(chunk, userBits);
++
++    chunk.release();
++  }
++
++  @Test
++  public void getShortClassNameShouldReturnShortClassName() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.getShortClassName()).isEqualTo("ObjectChunk");
++
++    chunk.release();
++  }
++
++  @Test
++  public void chunksAreEqualsOnlyByAddress() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    ObjectChunk newChunk = new ObjectChunk(chunk.getMemoryAddress());
++    assertThat(chunk.equals(newChunk)).isTrue();
++
++    ObjectChunk chunkWithSameValue = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.equals(chunkWithSameValue)).isFalse();
++
++    Object someObject = getValue();
++    assertThat(chunk.equals(someObject)).isFalse();
++
++    chunk.release();
++    chunkWithSameValue.release();
++  }
++
++  @Test
++  public void chunksShouldBeComparedBySize() {
++    ObjectChunk chunk1 = createValueAsSerializedStoredObject(getValue());
++
++    ObjectChunk chunk2 = chunk1;
++    assertThat(chunk1.compareTo(chunk2)).isEqualTo(0);
++
++    ObjectChunk chunkWithSameValue = createValueAsSerializedStoredObject(getValue());
++    assertThat(chunk1.compareTo(chunkWithSameValue)).isEqualTo(Long.signum(chunk1.getMemoryAddress() - chunkWithSameValue.getMemoryAddress()));
++
++    ObjectChunk chunk3 = createValueAsSerializedStoredObject(Long.MAX_VALUE);
++    ObjectChunk chunk4 = createValueAsSerializedStoredObject(Long.MAX_VALUE);
++
++    int newSizeForChunk3 = 2;
++    int newSizeForChunk4 = 3;
++
++    assertThat(chunk3.compareTo(chunk4)).isEqualTo(Integer.signum(newSizeForChunk3 - newSizeForChunk4));
++
++    chunk1.release();
++    chunk4.release();
++  }
++
++  @Test
++  public void setSerializedShouldSetTheSerializedBit() {
++    Object regionEntryValue = getValue();
++    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
++
++    boolean isSerialized = false;
++    boolean isCompressed = false;
++
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
++
++    int headerBeforeSerializedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
++
++    assertThat(chunk.isSerialized()).isFalse();
++
++    chunk.setSerialized(true); // set to true
++
++    assertThat(chunk.isSerialized()).isTrue();
++
++    int headerAfterSerializedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
++
++    assertThat(headerAfterSerializedBitSet).isEqualTo(headerBeforeSerializedBitSet | ObjectChunk.IS_SERIALIZED_BIT);
++
++    chunk.release();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void setSerialziedShouldThrowExceptionIfChunkIsAlreadyReleased() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.release();
++    chunk.setSerialized(true);
++
++    chunk.release();
++  }
++
++  @Test
++  public void setCompressedShouldSetTheCompressedBit() {
++    Object regionEntryValue = getValue();
++    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
++
++    boolean isSerialized = false;
++    boolean isCompressed = false;
++
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
++
++    int headerBeforeCompressedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
++
++    assertThat(chunk.isCompressed()).isFalse();
++
++    chunk.setCompressed(true); // set to true
++
++    assertThat(chunk.isCompressed()).isTrue();
++
++    int headerAfterCompressedBitSet = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + ObjectChunk.REF_COUNT_OFFSET);
++
++    assertThat(headerAfterCompressedBitSet).isEqualTo(headerBeforeCompressedBitSet | ObjectChunk.IS_COMPRESSED_BIT);
++
++    chunk.release();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void setCompressedShouldThrowExceptionIfChunkIsAlreadyReleased() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.release();
++    chunk.setCompressed(true);
++
++    chunk.release();
++  }
++
++  @Test
++  public void setDataSizeShouldSetTheDataSizeBits() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    int beforeSize = chunk.getDataSize();
++
++    chunk.setDataSize(2);
++
++    int afterSize = chunk.getDataSize();
++
++    assertThat(afterSize).isEqualTo(2);
++    assertThat(afterSize).isNotEqualTo(beforeSize);
++
++    chunk.release();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void setDataSizeShouldThrowExceptionIfChunkIsAlreadyReleased() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.release();
++    chunk.setDataSize(1);
++
++    chunk.release();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyRetained() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.retain();
++    chunk.initializeUseCount();
++
++    chunk.release();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyReleased() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.release();
++    chunk.initializeUseCount();
++
++    chunk.release();
++  }
++
++  @Test
++  public void isSerializedPdxInstanceShouldReturnTrueIfItsPDXInstance() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    byte[] serailizedValue = chunk.getSerializedValue();
++    serailizedValue[0] = DSCODE.PDX;
++    chunk.setSerializedValue(serailizedValue);
++
++    assertThat(chunk.isSerializedPdxInstance()).isTrue();
++
++    serailizedValue = chunk.getSerializedValue();
++    serailizedValue[0] = DSCODE.PDX_ENUM;
++    chunk.setSerializedValue(serailizedValue);
++
++    assertThat(chunk.isSerializedPdxInstance()).isTrue();
++
++    serailizedValue = chunk.getSerializedValue();
++    serailizedValue[0] = DSCODE.PDX_INLINE_ENUM;
++    chunk.setSerializedValue(serailizedValue);
++
++    assertThat(chunk.isSerializedPdxInstance()).isTrue();
++
++    chunk.release();
++  }
++
++  @Test
++  public void isSerializedPdxInstanceShouldReturnFalseIfItsNotPDXInstance() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    assertThat(chunk.isSerializedPdxInstance()).isFalse();
++
++    chunk.release();
++  }
++
++  @Test
++  public void checkDataEqualsByChunk() {
++    ObjectChunk chunk1 = createValueAsSerializedStoredObject(getValue());
++    ObjectChunk sameAsChunk1 = chunk1;
++
++    assertThat(chunk1.checkDataEquals(sameAsChunk1)).isTrue();
++
++    ObjectChunk unserializedChunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk1.checkDataEquals(unserializedChunk)).isFalse();
++
++    ObjectChunk chunkDifferBySize = createValueAsSerializedStoredObject(getValue());
++    chunkDifferBySize.setSize(0);
++    assertThat(chunk1.checkDataEquals(chunkDifferBySize)).isFalse();
++
++    ObjectChunk chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1);
++    assertThat(chunk1.checkDataEquals(chunkDifferByValue)).isFalse();
++
++    ObjectChunk newChunk1 = createValueAsSerializedStoredObject(getValue());
++    assertThat(chunk1.checkDataEquals(newChunk1)).isTrue();
++
++    chunk1.release();
++    unserializedChunk.release();
++    chunkDifferBySize.release();
++    chunkDifferByValue.release();
++    newChunk1.release();
++  }
++
++  @Test
++  public void checkDataEqualsBySerializedValue() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    assertThat(chunk.checkDataEquals(new byte[1])).isFalse();
++
++    ObjectChunk chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1);
++    assertThat(chunk.checkDataEquals(chunkDifferByValue.getSerializedValue())).isFalse();
++
++    ObjectChunk newChunk = createValueAsSerializedStoredObject(getValue());
++    assertThat(chunk.checkDataEquals(newChunk.getSerializedValue())).isTrue();
++
++    chunk.release();
++    chunkDifferByValue.release();
++    newChunk.release();
++  }
++
++  @Test
++  public void getDecompressedBytesShouldReturnDecompressedBytesIfCompressed() {
++    Object regionEntryValue = getValue();
++    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
++
++    boolean isSerialized = true;
++    boolean isCompressed = true;
++
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
++
++    RegionEntryContext regionContext = mock(RegionEntryContext.class);
++    CachePerfStats cacheStats = mock(CachePerfStats.class);
++    Compressor compressor = mock(Compressor.class);
++
++    long startTime = 10000L;
++
++    // mock required things
++    when(regionContext.getCompressor()).thenReturn(compressor);
++    when(compressor.decompress(regionEntryValueAsBytes)).thenReturn(regionEntryValueAsBytes);
++    when(regionContext.getCachePerfStats()).thenReturn(cacheStats);
++    when(cacheStats.startDecompression()).thenReturn(startTime);
++
++    // invoke the thing
++    byte[] bytes = chunk.getDecompressedBytes(regionContext);
++
++    // verify the thing happened
++    verify(cacheStats, atLeastOnce()).startDecompression();
++    verify(compressor, times(1)).decompress(regionEntryValueAsBytes);
++    verify(cacheStats, atLeastOnce()).endDecompression(startTime);
++
++    assertArrayEquals(regionEntryValueAsBytes, bytes);
++
++    chunk.release();
++  }
++
++  @Test
++  public void incSizeShouldIncrementSize() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    int beforeSize = chunk.getSize();
++
++    chunk.incSize(1);
++    assertThat(chunk.getSize()).isEqualTo(beforeSize + 1);
++
++    chunk.incSize(2);
++    assertThat(chunk.getSize()).isEqualTo(beforeSize + 1 + 2);
++
++    chunk.release();
++  }
++
++  @Test
++  public void readyForFreeShouldResetTheRefCount() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    int refCountBeforeFreeing = chunk.getRefCount();
++    assertThat(refCountBeforeFreeing).isEqualTo(1);
++
++    chunk.readyForFree();
++
++    int refCountAfterFreeing = chunk.getRefCount();
++    assertThat(refCountAfterFreeing).isEqualTo(0);
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void readyForAllocationShouldThrowExceptionIfAlreadyAllocated() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    // chunk is already allocated when we created it, so calling readyForAllocation should throw exception.
++    chunk.readyForAllocation();
++
++    chunk.release();
++  }
++
++  @Test
++  public void checkIsAllocatedShouldReturnIfAllocated() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    chunk.checkIsAllocated();
++
++    chunk.release();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void checkIsAllocatedShouldThrowExceptionIfNotAllocated() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    chunk.release();
++    chunk.checkIsAllocated();
++
++    chunk.release();
++  }
++
++  @Test
++  public void sendToShouldWriteSerializedValueToDataOutputIfValueIsSerialized() throws IOException {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    ObjectChunk spyChunk = spy(chunk);
++
++    HeapDataOutputStream dataOutput = mock(HeapDataOutputStream.class);
++    ByteBuffer directByteBuffer = ByteBuffer.allocate(1024);
++
++    doReturn(directByteBuffer).when(spyChunk).createDirectByteBuffer();
++    doNothing().when(dataOutput).write(directByteBuffer);
++
++    spyChunk.sendTo(dataOutput);
++
++    verify(dataOutput, times(1)).write(directByteBuffer);
++
++    chunk.release();
++  }
++
++  @Test
++  public void sendToShouldWriteUnserializedValueToDataOutputIfValueIsUnserialized() throws IOException {
++    byte[] regionEntryValue = getValueAsByteArray();
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
++
++    // writeByte is a final method and cannot be mocked, so creating a real one
++    HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT);
++
++    chunk.sendTo(dataOutput);
++
++    byte[] actual = dataOutput.toByteArray();
++
++    byte[] expected = new byte[regionEntryValue.length + 2];
++    expected[0] = DSCODE.BYTE_ARRAY;
++    expected[1] = (byte) regionEntryValue.length;
++    System.arraycopy(regionEntryValue, 0, expected, 2, regionEntryValue.length);
++
++    assertNotNull(dataOutput);
++    assertThat(actual).isEqualTo(expected);
++
++    chunk.release();
++  }
++
++  @Test
++  public void sendAsByteArrayShouldWriteValueToDataOutput() throws IOException {
++    byte[] regionEntryValue = getValueAsByteArray();
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
++
++    // writeByte is a final method and cannot be mocked, so creating a real one
++    HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT);
++
++    chunk.sendAsByteArray(dataOutput);
++
++    byte[] actual = dataOutput.toByteArray();
++
++    byte[] expected = new byte[regionEntryValue.length + 1];
++    expected[0] = (byte) regionEntryValue.length;
++    System.arraycopy(regionEntryValue, 0, expected, 1, regionEntryValue.length);
++
++    assertNotNull(dataOutput);
++    assertThat(actual).isEqualTo(expected);
++
++    chunk.release();
++  }
++
++  @Test
++  public void createDirectByteBufferShouldCreateAByteBuffer() {
++    byte[] regionEntryValue = getValueAsByteArray();
++
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
++
++    ByteBuffer buffer = chunk.createDirectByteBuffer();
++
++    byte[] actual = new byte[regionEntryValue.length];
++    buffer.get(actual);
++
++    assertArrayEquals(regionEntryValue, actual);
++
++    chunk.release();
++  }
++
++  @Test
++  public void getDirectByteBufferShouldCreateAByteBuffer() {
++    byte[] regionEntryValue = getValueAsByteArray();
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(regionEntryValue);
++
++    ByteBuffer buffer = chunk.createDirectByteBuffer();
++    long bufferAddress = ObjectChunk.getDirectByteBufferAddress(buffer);
++
++    // returned address should be starting of the value (after skipping HEADER_SIZE bytes)
++    assertEquals(chunk.getMemoryAddress() + ObjectChunk.OFF_HEAP_HEADER_SIZE, bufferAddress);
++
++    chunk.release();
++  }
++
++  @Test(expected = AssertionError.class)
++  public void getAddressForReadingShouldFailIfItsOutsideOfChunk() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    chunk.getAddressForReading(0, chunk.getDataSize() + 1);
++
++    chunk.release();
++  }
++
++  @Test
++  public void getAddressForReadingShouldReturnDataAddressFromGivenOffset() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    int offset = 1;
++    long requestedAddress = chunk.getAddressForReading(offset, 1);
++
++    assertThat(requestedAddress).isEqualTo(chunk.getBaseDataAddress() + offset);
++
++    chunk.release();
++  }
++
++  @Test
++  public void getSizeInBytesShouldReturnSize() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    assertThat(chunk.getSizeInBytes()).isEqualTo(chunk.getSize());
++
++    chunk.release();
++  }
++
++  @Test(expected = AssertionError.class)
++  public void getUnsafeAddressShouldFailIfOffsetIsNegative() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    chunk.getUnsafeAddress(-1, 1);
++
++    chunk.release();
++  }
++
++  @Test(expected = AssertionError.class)
++  public void getUnsafeAddressShouldFailIfSizeIsNegative() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    chunk.getUnsafeAddress(1, -1);
++
++    chunk.release();
++  }
++
++  @Test(expected = AssertionError.class)
++  public void getUnsafeAddressShouldFailIfItsOutsideOfChunk() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++    chunk.getUnsafeAddress(0, chunk.getDataSize() + 1);
++
++    chunk.release();
++  }
++
++  @Test
++  public void getUnsafeAddressShouldReturnUnsafeAddress() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    int offset = 1;
++    long unsafeAddress = chunk.getUnsafeAddress(offset, 1);
++
++    assertThat(unsafeAddress).isEqualTo(chunk.getBaseDataAddress() + offset);
++
++    chunk.release();
++  }
++
++  @Test(expected = AssertionError.class)
++  public void readByteAndWriteByteShouldFailIfOffsetIsOutside() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    chunk.readByte(chunk.getDataSize() + 1);
++
++    chunk.writeByte(chunk.getDataSize() + 1, Byte.MAX_VALUE);
++
++    chunk.release();
++  }
++
++  @Test
++  public void writeByteShouldWriteAtCorrectLocation() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    byte valueBeforeWrite = chunk.readByte(2);
++
++    Byte expected = Byte.MAX_VALUE;
++    chunk.writeByte(2, expected);
++
++    Byte actual = chunk.readByte(2);
++
++    assertThat(actual).isNotEqualTo(valueBeforeWrite);
++    assertThat(actual).isEqualTo(expected);
++
++    chunk.release();
++  }
++
++  @Test
++  public void retainShouldIncrementRefCount() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.getRefCount()).isEqualTo(1);
++
++    chunk.retain();
++    assertThat(chunk.getRefCount()).isEqualTo(2);
++
++    chunk.retain();
++    assertThat(chunk.getRefCount()).isEqualTo(3);
++
++    chunk.release();
++    chunk.release();
++    chunk.release();
++    boolean retainAfterRelease = chunk.retain();
++
++    assertThat(retainAfterRelease).isFalse();
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void retainShouldThrowExceptionAfterMaxNumberOfTimesRetained() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    // loop though and invoke retain for MAX_REF_COUNT-1 times, as create chunk above counted as one reference
++    for (int i = 0; i < ObjectChunk.MAX_REF_COUNT - 1; i++)
++      chunk.retain();
++
++    // invoke for the one more time should throw exception
++    chunk.retain();
++  }
++
++  @Test
++  public void releaseShouldDecrementRefCount() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.getRefCount()).isEqualTo(1);
++
++    chunk.retain();
++    chunk.retain();
++    assertThat(chunk.getRefCount()).isEqualTo(3);
++
++    chunk.release();
++    assertThat(chunk.getRefCount()).isEqualTo(2);
++
++    chunk.release();
++    assertThat(chunk.getRefCount()).isEqualTo(1);
++
++    chunk.retain();
++    chunk.release();
++    assertThat(chunk.getRefCount()).isEqualTo(1);
++
++    chunk.release();
++    assertThat(chunk.getRefCount()).isEqualTo(0);
++  }
++
++  @Test(expected = IllegalStateException.class)
++  public void releaseShouldThrowExceptionIfChunkIsAlreadyReleased() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.release();
++    chunk.release();
++  }
++
++  @Test
++  public void testToStringForOffHeapByteSource() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    String expected = ":<dataSize=" + chunk.getDataSize() + " refCount=" + chunk.getRefCount() + " addr=" + Long.toHexString(chunk.getMemoryAddress()) + ">";
++    assertThat(chunk.toStringForOffHeapByteSource()).endsWith(expected);
++
++    // test toString
++    ObjectChunk spy = spy(chunk);
++    spy.toString();
++    verify(spy, times(1)).toStringForOffHeapByteSource();
++
++    chunk.release();
++  }
++
++  @Test
++  public void getStateShouldReturnAllocatedIfRefCountIsGreaterThanZero() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertEquals(State.ALLOCATED, chunk.getState());
++
++    chunk.release();
++  }
++
++  @Test
++  public void getStateShouldReturnDeallocatedIfRefCountIsZero() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.release();
++    assertEquals(State.DEALLOCATED, chunk.getState());
++  }
++
++  @Test(expected = UnsupportedOperationException.class)
++  public void getNextBlockShouldThrowUnSupportedOperationException() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.getNextBlock();
++
++    chunk.release();
++  }
++
++  @Test
++  public void getBlockSizeShouldBeSameSameGetSize() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertEquals(chunk.getSize(), chunk.getBlockSize());
++
++    chunk.release();
++  }
++
++  @Test(expected = UnsupportedOperationException.class)
++  public void copyBytesShouldThrowUnSupportedOperationException() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.copyBytes(1, 2, 1);
++
++    chunk.release();
++  }
++
++  @Test(expected = UnsupportedOperationException.class)
++  public void getSlabIdShouldThrowUnSupportedOperationException() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    chunk.getSlabId();
++
++    chunk.release();
++  }
++
++  @Test
++  public void getFreeListIdShouldReturnMinusOne() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.getFreeListId()).isEqualTo(-1);
++
++    chunk.release();
++  }
++
++  @Test
++  public void getDataTypeShouldReturnNull() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.getDataType()).isNull();
++
++    chunk.release();
++  }
++
++  @Test
++  public void getDataDataShouldReturnNull() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    assertThat(chunk.getDataValue()).isNull();
++  }
++
++  @Test(expected = UnsupportedOperationException.class)
++  public void getRawBytesShouldThrowExceptionIfValueIsCompressed() {
++    Object regionEntryValue = getValue();
++    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
++
++    boolean isSerialized = true;
++    boolean isCompressed = true;
++
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
++
++    chunk.getRawBytes();
++
++    chunk.release();
++  }
++
++  @Test
++  public void getSerializedValueShouldSerializeTheValue() {
++    Object regionEntryValue = getValue();
++    byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue);
++
++    boolean isSerialized = false;
++    boolean isCompressed = false;
++
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed);
++
++    byte[] serializedValue = chunk.getSerializedValue();
++
++    assertThat(serializedValue).isEqualTo(EntryEventImpl.serialize(regionEntryValueAsBytes));
++
++    chunk.release();
++  }
++
++  @Test
++  public void fillShouldFillTheChunk() {
++    boolean isSerialized = false;
++    boolean isCompressed = false;
++
++    ObjectChunk chunk = (ObjectChunk) ma.allocateAndInitialize(new byte[100], isSerialized, isCompressed);
++
++    // first fill the unused part with FILL_PATTERN
++    ObjectChunk.fill(chunk.getMemoryAddress());
++
++    // Validate that it is filled
++    chunk.validateFill();
++
++    chunk.release();
++  }
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java
index 0000000,0000000..fe55910
new file mode 100644
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkSliceJUnitTest.java
@@@ -1,0 -1,0 +1,72 @@@
++/*
++ * 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 com.gemstone.gemfire.internal.offheap;
++
++import static org.junit.Assert.assertEquals;
++import static org.junit.Assert.assertNotNull;
++
++import org.junit.Test;
++import org.junit.experimental.categories.Category;
++
++import com.gemstone.gemfire.test.junit.categories.UnitTest;
++
++@Category(UnitTest.class)
++public class ObjectChunkSliceJUnitTest extends ObjectChunkJUnitTest {
++
++  @Test
++  public void sliceShouldHaveAValidDataSize() {
++    int position = 1;
++    int end = 2;
++
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    ObjectChunkSlice slice = (ObjectChunkSlice) chunk.slice(position, end);
++
++    assertNotNull(slice);
++    assertEquals(ObjectChunkSlice.class, slice.getClass());
++
++    assertEquals(end - position, slice.getDataSize());
++  }
++
++  @Test
++  public void sliceShouldHaveAValidBaseDataAddress() {
++    int position = 1;
++    int end = 2;
++
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    ObjectChunkSlice slice = (ObjectChunkSlice) chunk.slice(position, end);
++
++    assertNotNull(slice);
++    assertEquals(ObjectChunkSlice.class, slice.getClass());
++
++    assertEquals(chunk.getBaseDataAddress() + position, slice.getBaseDataAddress());
++  }
++
++  @Test
++  public void sliceShouldHaveAValidBaseOffset() {
++    int position = 1;
++    int end = 2;
++
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++    ObjectChunkSlice slice = (ObjectChunkSlice) chunk.slice(position, end);
++
++    assertNotNull(slice);
++    assertEquals(ObjectChunkSlice.class, slice.getClass());
++
++    assertEquals(chunk.getBaseDataOffset() + position, slice.getBaseDataOffset());
++  }
++}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.java
index 0000000,0000000..4486845
new file mode 100644
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/ObjectChunkWithHeapFormJUnitTest.java
@@@ -1,0 -1,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 com.gemstone.gemfire.internal.offheap;
++
++import static org.junit.Assert.assertArrayEquals;
++import static org.junit.Assert.assertEquals;
++import static org.junit.Assert.assertNotNull;
++import static org.junit.Assert.assertNotSame;
++import static org.junit.Assert.assertSame;
++
++import org.junit.Test;
++import org.junit.experimental.categories.Category;
++
++import com.gemstone.gemfire.test.junit.categories.UnitTest;
++
++@Category(UnitTest.class)
++public class ObjectChunkWithHeapFormJUnitTest extends ObjectChunkJUnitTest {
++
++  @Test
++  public void getRawBytesShouldReturnCachedHeapForm() {
++    ObjectChunk chunk = createValueAsUnserializedStoredObject(getValue());
++
++    byte[] valueInBytes = getValueAsByteArray();
++    ObjectChunkWithHeapForm heapForm = new ObjectChunkWithHeapForm(chunk, valueInBytes);
++
++    assertNotNull(heapForm);
++
++    assertSame(valueInBytes, heapForm.getRawBytes());
++  }
++
++  @Test
++  public void getChunkWithoutHeapFormShouldReturnGemFireChunk() {
++    ObjectChunk chunk = createValueAsSerializedStoredObject(getValue());
++
++    byte[] valueInBytes = getValueAsByteArray();
++    ObjectChunkWithHeapForm heapForm = new ObjectChunkWithHeapForm(chunk, valueInBytes);
++
++    ObjectChunk chunkWithOutHeapForm = heapForm.getChunkWithoutHeapForm();
++
++    assertNotNull(chunkWithOutHeapForm);
++    assertEquals(ObjectChunk.class, chunkWithOutHeapForm.getClass());
++
++    assertEquals(chunk, heapForm.getChunkWithoutHeapForm());
++
++    assertEquals(chunk.getMemoryAddress(), chunkWithOutHeapForm.getMemoryAddress());
++    assertArrayEquals(chunk.getRawBytes(), chunkWithOutHeapForm.getRawBytes());
++    assertNotSame(valueInBytes, chunkWithOutHeapForm.getRawBytes());
++  }
++}


[040/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/InternalDistributedSystem.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/InternalDistributedSystem.java
index 276efec,0000000..a193699
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/InternalDistributedSystem.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/InternalDistributedSystem.java
@@@ -1,3056 -1,0 +1,3079 @@@
 +/*
 + * 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 com.gemstone.gemfire.distributed.internal;
 +
 +import java.io.File;
 +import java.io.IOException;
 +import java.io.Reader;
 +import java.lang.reflect.Array;
 +import java.net.InetAddress;
 +import java.util.ArrayList;
 +import java.util.Date;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.LinkedHashSet;
 +import java.util.List;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.SortedSet;
 +import java.util.StringTokenizer;
 +import java.util.TreeSet;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.CopyOnWriteArrayList;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.atomic.AtomicReference;
 +
 +import org.apache.logging.log4j.Logger;
 +
 +import com.gemstone.gemfire.CancelCriterion;
 +import com.gemstone.gemfire.CancelException;
 +import com.gemstone.gemfire.ForcedDisconnectException;
 +import com.gemstone.gemfire.GemFireConfigException;
 +import com.gemstone.gemfire.GemFireIOException;
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.StatisticDescriptor;
 +import com.gemstone.gemfire.Statistics;
 +import com.gemstone.gemfire.StatisticsType;
 +import com.gemstone.gemfire.StatisticsTypeFactory;
 +import com.gemstone.gemfire.SystemConnectException;
 +import com.gemstone.gemfire.SystemFailure;
 +import com.gemstone.gemfire.admin.AlertLevel;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.execute.internal.FunctionServiceManager;
++import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 +import com.gemstone.gemfire.distributed.DurableClientAttributes;
 +import com.gemstone.gemfire.distributed.internal.locks.GrantorRequestProcessor;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.distributed.internal.membership.MembershipManager;
 +import com.gemstone.gemfire.distributed.internal.membership.QuorumChecker;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.Services;
 +import com.gemstone.gemfire.distributed.internal.membership.gms.mgr.GMSMembershipManager;
 +import com.gemstone.gemfire.i18n.LogWriterI18n;
 +import com.gemstone.gemfire.internal.Assert;
 +import com.gemstone.gemfire.internal.DSFIDFactory;
 +import com.gemstone.gemfire.internal.DummyStatisticsImpl;
 +import com.gemstone.gemfire.internal.GemFireStatSampler;
 +import com.gemstone.gemfire.internal.InternalDataSerializer;
 +import com.gemstone.gemfire.internal.InternalInstantiator;
 +import com.gemstone.gemfire.internal.LinuxProcFsStatistics;
 +import com.gemstone.gemfire.internal.LocalStatisticsImpl;
 +import com.gemstone.gemfire.internal.OsStatisticsFactory;
 +import com.gemstone.gemfire.internal.SocketCreator;
 +import com.gemstone.gemfire.internal.StatisticsImpl;
 +import com.gemstone.gemfire.internal.StatisticsManager;
 +import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl;
 +import com.gemstone.gemfire.internal.SystemTimer;
 +import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
 +import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 +import com.gemstone.gemfire.internal.cache.CacheConfig;
 +import com.gemstone.gemfire.internal.cache.EventID;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.execute.FunctionServiceStats;
 +import com.gemstone.gemfire.internal.cache.execute.FunctionStats;
 +import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake;
 +import com.gemstone.gemfire.internal.cache.xmlcache.CacheServerCreation;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.logging.LogWriterFactory;
 +import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
 +import com.gemstone.gemfire.internal.logging.log4j.AlertAppender;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppender;
 +import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppenders;
 +import com.gemstone.gemfire.internal.offheap.MemoryAllocator;
 +import com.gemstone.gemfire.internal.offheap.OffHeapStorage;
 +import com.gemstone.gemfire.internal.tcp.ConnectionTable;
 +import com.gemstone.gemfire.internal.util.concurrent.StoppableCondition;
 +import com.gemstone.gemfire.internal.util.concurrent.StoppableReentrantLock;
 +import com.gemstone.gemfire.management.ManagementException;
 +import com.gemstone.gemfire.security.GemFireSecurityException;
 +
 +/**
 + * The concrete implementation of {@link DistributedSystem} that
 + * provides internal-only functionality.
 + *
 + * @author David Whitlock
 + * @since 3.0
 + *
 + */
 +public class InternalDistributedSystem
 +  extends DistributedSystem
 +  implements OsStatisticsFactory, StatisticsManager
 +{
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  public static final String DISABLE_MANAGEMENT_PROPERTY = "gemfire.disableManagement";
 +  
 +  /**
 +   * If auto-reconnect is going on this will hold a reference to it
 +   */
 +  public static volatile DistributedSystem systemAttemptingReconnect;
 +
 +  public static final CreationStackGenerator DEFAULT_CREATION_STACK_GENERATOR = new CreationStackGenerator() {
 +    @Override
 +    public Throwable generateCreationStack(final DistributionConfig config) {
 +      return null;
 +    }
 +  };
 +
 +  // the following is overridden from DistributedTestCase to fix #51058
 +  public static final AtomicReference<CreationStackGenerator> TEST_CREATION_STACK_GENERATOR = new AtomicReference<CreationStackGenerator>(DEFAULT_CREATION_STACK_GENERATOR);
 +  
 +  /** The distribution manager that is used to communicate with the
 +   * distributed system. */
 +  protected DM dm;
 +
 +  private final GrantorRequestProcessor.GrantorRequestContext grc;
 +  public GrantorRequestProcessor.GrantorRequestContext getGrantorRequestContext() {
 +    return grc;
 +  }
 +  
 +  /** Numeric id that identifies this node in a DistributedSystem */
 +  private long id;
 +
 +  /** The log writer used to log information messages */
 +  protected InternalLogWriter logWriter = null;
 +
 +  /** The log writer used to log security related messages */
 +  protected InternalLogWriter securityLogWriter = null;
 + 
 +  /** Distributed System clock */
 +  private DSClock clock;
 +
 +//  /** The log writer was provided by an external entity */
 +//  private boolean externalLogWriterProvided = false;
 +//
 +  private LogWriterAppender logWriterAppender = null;
 +
 +  private LogWriterAppender securityLogWriterAppender = null;
 +  
 +  /** Time this system was created */
 +  private final long startTime;
 +
 +  /**
 +   * Guards access to {@link #isConnected}
 +   */
 +  protected final Object isConnectedMutex = new Object();
 +  
 +  /** Is this <code>DistributedSystem</code> connected to a
 +   * distributed system? 
 +   *
 +   * Concurrency: volatile for reads and protected by synchronization of {@link #isConnectedMutex} for writes
 +   */
 +  protected volatile boolean isConnected;
 +
 +  /**
 +   * Set to true if this distributed system is a singleton; it will
 +   * always be the only member of the system.
 +   */
 +  private boolean isLoner = false;
 +
 +  /** The sampler for this DistributedSystem.
 +   */
 +  private GemFireStatSampler sampler = null;
 +
 +  /** A set of listeners that are invoked when this connection to the
 +   * distributed system is disconnected */
 +  private final Set listeners = new LinkedHashSet(); // needs to be ordered
 +
 +  /** Set of listeners that are invoked whenever a connection is created to
 +   * the distributed system */
 +  private static Set connectListeners = new LinkedHashSet(); // needs to be ordered
 +  
 +  /** auto-reconnect listeners */
 +  private static List<ReconnectListener> reconnectListeners = new ArrayList<ReconnectListener>();
 +  
 +  /**
 +   * whether this DS is one created to reconnect to the distributed 
 +   * system after a forced-disconnect.  This state is cleared once reconnect
 +   * is successful.
 +   */
 +  private boolean isReconnectingDS;
 +  
 +  /**
 +   * During a reconnect attempt this is used to perform quorum checks
 +   * before allowing a location service to be started up in this JVM.
 +   * If quorum checks fail then we delay starting location services until
 +   * a live locator can be contacted.
 +   */
 +  private QuorumChecker quorumChecker;
 +  
 +  /** sqlfire disconnect listener */
 +  private DisconnectListener sqlfDisconnectListener;
 +
 +  /**
 +   * A Constant that matches the ThreadGroup name of the shutdown hook.
 +   * This constant is used to insure consistency with LoggingThreadGroup.
 +   * Due to Bug 38407, be careful about moving this to another class.
 +   */
 +  public final static String SHUTDOWN_HOOK_NAME = "Distributed system shutdown hook";
 +  /**
 +   * A property to prevent shutdown hooks from being registered with the VM.
 +   * This is regarding bug 38407
 +   */
 +  public final static String DISABLE_SHUTDOWN_HOOK_PROPERTY = "gemfire.disableShutdownHook";
 +
 +  /**
 +   * A property to append to existing log-file instead of truncating it.
 +   */
 +  public final static String APPEND_TO_LOG_FILE = "gemfire.append-log";
 +
 +  ////////////////////  Configuration Fields  ////////////////////
 +
 +  /** The config object used to create this distributed system */
 +  private final DistributionConfig originalConfig;
 +
 +  /** The config object to which most configuration work is delegated */
 +  private DistributionConfig config;
 +
 +  private final boolean statsDisabled = Boolean.getBoolean("gemfire.statsDisabled");
 +
 +  private volatile boolean shareSockets = DistributionConfig.DEFAULT_CONSERVE_SOCKETS;
 +
 +  /** if this distributed system starts a locator, it is stored here */
 +  private InternalLocator startedLocator;
 +  
 +  private List<ResourceEventsListener> resourceListeners;
 +  
 +  private final boolean disableManagement = Boolean.getBoolean(DISABLE_MANAGEMENT_PROPERTY);
 +
 +  /**
 +   * Stack trace showing the creation of this instance of InternalDistributedSystem.
 +   */
 +  private final Throwable creationStack;
 +  
 +  /////////////////////  Static Methods  /////////////////////
 +
 +  /**
 +   * Creates a new instance of <code>InternalDistributedSystem</code>
 +   * with the given configuration.
 +   */
 +  public static InternalDistributedSystem newInstance(Properties config) {
 +    boolean success = false;
 +    InternalDataSerializer.checkSerializationVersion();
 +    try {
 +      SystemFailure.startThreads();
 +    InternalDistributedSystem newSystem = new InternalDistributedSystem(config);
 +    newSystem.initialize();
 +    reconnectAttemptCounter = 0; // reset reconnect count since we just got a new connection
 +    notifyConnectListeners(newSystem);
 +    success = true;
 +    return newSystem;
 +    } finally {
 +      if (!success) {
 +        LoggingThreadGroup.cleanUpThreadGroups(); // bug44365 - logwriters accumulate, causing mem leak
 +        SystemFailure.stopThreads();
 +      }
 +    }
 +  }
 +  
 +  
 +  /**
 +   * creates a non-functional instance for testing
 +   * @param nonDefault - non-default distributed system properties
 +   */
 +  public static InternalDistributedSystem newInstanceForTesting(DM dm, Properties nonDefault) {
 +    InternalDistributedSystem sys = new InternalDistributedSystem(nonDefault);
 +    sys.config = new RuntimeDistributionConfigImpl(sys);
 +    sys.dm = dm;
 +    sys.isConnected = true;
 +    return sys;
 +  }
 +
 +  /**
 +   * Returns a connection to the distributed system that is suitable
 +   * for administration.  For administration, we are not as strict
 +   * when it comes to existing connections.
 +   *
 +   * @since 4.0
 +   */
 +  public static DistributedSystem connectForAdmin(Properties props) {
 +    return DistributedSystem.connectForAdmin(props);
 +  }
 +
 +  /**
 +   * Returns a connected distributed system for this VM, or null
 +   * if there is no connected distributed system in this VM.
 +   * This method synchronizes on the existingSystems collection.
 +   *
 +   * <p>author bruce
 +   * @since 5.0
 +   */
 +  public static InternalDistributedSystem getConnectedInstance() {
 +    InternalDistributedSystem result = null;
 +    synchronized (existingSystemsLock) {
 +      if (!existingSystems.isEmpty()) {
 +        InternalDistributedSystem existingSystem =
 +          (InternalDistributedSystem) existingSystems.get(0);
 +        if (existingSystem.isConnected())
 +          result = existingSystem;
 +      }
 +    }
 +    return result;
 +  }
 +
 +  /**
 +   * Returns the current distributed system, if there is one.
 +   * Note: this method is no longer unsafe size existingSystems uses copy-on-write.
 +   * <p>author bruce
 +   * @since 5.0
 +   */
 +  public static InternalDistributedSystem unsafeGetConnectedInstance() {
 +    InternalDistributedSystem result = getAnyInstance();
 +    if (result != null) {
 +      if (!result.isConnected()) {
 +        result = null;
 +      }
 +    }
 +    return result;
 +  }
 +
 +  /**
 +   * @return distribution stats, or null if there is no distributed system available
 +   */
 +  public static DMStats getDMStats() {
 +    InternalDistributedSystem sys = getAnyInstance();
 +    if (sys != null && sys.dm != null) {
 +      return sys.dm.getStats();
 +    }
 +    return null;
 +  }
 +
 +  /**
 +   * @return a log writer, or null if there is no distributed system available
 +   */
 +  public static LogWriterI18n getLoggerI18n() {
 +    InternalDistributedSystem sys = getAnyInstance();
 +    if (sys != null && sys.logWriter != null) {
 +      return sys.logWriter.convertToLogWriterI18n();
 +    }
 +    return null;
 +  }
 +  
 +  public static InternalLogWriter getStaticInternalLogWriter() {
 +    InternalDistributedSystem sys = getAnyInstance();
 +    if (sys != null) {
 +      return sys.logWriter;
 +    }
 +    return null;
 +  }
 +  
 +  public InternalLogWriter getInternalLogWriter() {
 +    return this.logWriter;
 +  }
 +  
 +  public static InternalLogWriter getStaticSecurityInternalLogWriter() {
 +    InternalDistributedSystem sys = getAnyInstance();
 +    if (sys != null) {
 +      return sys.securityLogWriter;
 +    }
 +    return null;
 +  }
 +  
 +  public InternalLogWriter getSecurityInternalLogWriter() {
 +    InternalDistributedSystem sys = getAnyInstance();
 +    if (sys != null) {
 +      return sys.securityLogWriter;
 +    }
 +    return null;
 +  }
 +  
 +  /** reset the reconnectAttempt counter for a new go at reconnecting */
 +  private static void resetReconnectAttemptCounter() {
 +    reconnectAttemptCounter = 0;
 +  }
 +
 +
 +  //////////////////////  Constructors  //////////////////////
 +
 +  /**
 +   * Creates a new <code>InternalDistributedSystem</code> with the
 +   * given configuration properties.  Does all of the magic of finding
 +   * the "default" values of properties.  See {@link
 +   * DistributedSystem#connect} for a list of exceptions that may be
 +   * thrown.
 +   *
 +   * @param nonDefault
 +   *        The non-default configuration properties specified by the
 +   *        caller
 +   *
 +   * @see DistributedSystem#connect
 +   */
 +  private InternalDistributedSystem(Properties nonDefault) {
 +
 +    // register DSFID types first; invoked explicitly so that all message type
 +    // initializations do not happen in first deserialization on a possibly
 +    // "precious" thread
 +    DSFIDFactory.registerTypes();
 +
 +    Object o = nonDefault.remove(DistributionConfig.DS_RECONNECTING_NAME);
 +    if (o instanceof Boolean) {
 +      this.isReconnectingDS = ((Boolean)o).booleanValue();
 +    } else {
 +      this.isReconnectingDS = false;
 +    }
 +    
 +    o = nonDefault.remove(DistributionConfig.DS_QUORUM_CHECKER_NAME);
 +    if (o instanceof QuorumChecker) {
 +      this.quorumChecker = (QuorumChecker)o;
 +    }
 +
 +    o = nonDefault.remove(DistributionConfig.DS_CONFIG_NAME);
 +    if (o instanceof DistributionConfigImpl) {
 +      this.originalConfig = (DistributionConfigImpl) o;
 +    } else {
 +      this.originalConfig = new DistributionConfigImpl(nonDefault);
 +    }
 +    
 +    ((DistributionConfigImpl)this.originalConfig).checkForDisallowedDefaults(); // throws IllegalStateEx
 +    this.shareSockets = this.originalConfig.getConserveSockets();
 +    this.startTime = System.currentTimeMillis();
 +    this.grc = new GrantorRequestProcessor.GrantorRequestContext(stopper);
 +    
 +    elderLock = new StoppableReentrantLock(stopper);
 +    elderLockCondition = elderLock.newCondition();
 +
 +    this.creationStack = TEST_CREATION_STACK_GENERATOR.get().generateCreationStack(this.originalConfig);
 +
 +//    if (DistributionConfigImpl.multicastTest) {
 +//      this.logger.warning("Use of multicast has been forced");
 +//    }
 +//    if (DistributionConfigImpl.forceDisableTcp) {
 +//      this.logger.warning("Use of UDP has been forced");
 +//    }
 +//    if (com.gemstone.gemfire.distributed.internal.membership.jgroup.JGroupMembershipManager.multicastTest) {
 +//      this.logger.warning("Use of multicast for all distributed cache operations has been forced");
 +//    }
 +
 +  }
 +
 +  ////////////////////  Instance Methods  ////////////////////
 +  
 +  /**
 +   * Registers a listener to the system
 +   * 
 +   * @param listener
 +   *          listener to be added
 +   */
 +  public void addResourceListener(ResourceEventsListener listener) {
 +    resourceListeners.add(listener);
 +  }
 +  
 +  /**
 +   * Un-Registers a listener to the system
 +   * 
 +   * @param listener
 +   *          listener to be removed
 +   */
 +  public void removeResourceListener(ResourceEventsListener listener) {
 +    resourceListeners.remove(listener);
 +  }
 +
 +  /**
 +   * @return the listeners registered with the system
 +   */
 +  public List<ResourceEventsListener> getResourceListeners() {
 +    return resourceListeners;
 +  }
 +
 +  /**
 +   * Handles a particular event associated with a resource
 +   * 
 +   * @param event
 +   *          Resource event
 +   * @param resource
 +   *          resource on which event is generated
 +   */
 +  public void handleResourceEvent(ResourceEvent event, Object resource) {
 +    if (disableManagement) {
 +      return;
 +    }
 +    if (resourceListeners.size() == 0) {
 +      return;
 +    }
 +    notifyResourceEventListeners(event, resource);
 +  }
 +
 +  /** Returns true if system is a loner (for testing) */
 +  public boolean isLoner() {
 +    return this.isLoner;
 +  }
 +
 +  private MemoryAllocator offHeapStore = null;
 +  
 +  public MemoryAllocator getOffHeapStore() {
 +    return this.offHeapStore;
 +  }
 +  
 +  /**
 +   * Initializes this connection to a distributed system with the
 +   * current configuration state.
 +   */
 +  private void initialize() {
 +    if (this.originalConfig.getLocators().equals("")) {
 +      if (this.originalConfig.getMcastPort() != 0) {
 +        throw new GemFireConfigException("The "
 +                                          + DistributionConfig.LOCATORS_NAME
 +                                          + " attribute can not be empty when the "
 +                                          + DistributionConfig.MCAST_PORT_NAME
 +                                          + " attribute is non-zero.");
 +      } else {
 +        // no distribution
 +        this.isLoner = true;
 +      }
 +    }
 +
 +    this.config = new RuntimeDistributionConfigImpl(this);
 +    if (!this.isLoner) {
 +      this.attemptingToReconnect = (reconnectAttemptCounter > 0);
 +    }
 +    try {
 +    SocketCreator.getDefaultInstance(this.config);
 +
 +    // LOG: create LogWriterAppender(s) if log-file or security-log-file is specified
 +    final boolean hasLogFile = this.config.getLogFile() != null && !this.config.getLogFile().equals(new File(""));
 +    final boolean hasSecurityLogFile = this.config.getSecurityLogFile() != null && !this.config.getSecurityLogFile().equals(new File(""));
 +    LogService.configureLoggers(hasLogFile, hasSecurityLogFile);
 +    if (hasLogFile || hasSecurityLogFile) {
 +      
 +      // main log file
 +      if (hasLogFile) {
 +        // if log-file then create logWriterAppender
 +        this.logWriterAppender = LogWriterAppenders.getOrCreateAppender(LogWriterAppenders.Identifier.MAIN, this.isLoner, this.config, true);
 +      }
 +      
 +      // security log file
 +      if (hasSecurityLogFile) {
 +        // if security-log-file then create securityLogWriterAppender
 +        this.securityLogWriterAppender = LogWriterAppenders.getOrCreateAppender(LogWriterAppenders.Identifier.SECURITY, this.isLoner, this.config, false);
 +      } else {
 +        // let security route to regular log-file or stdout
 +      }
 +    }
 +    
 +    // LOG: create LogWriterLogger(s) for backwards compatibility of getLogWriter and getSecurityLogWriter
 +    if (this.logWriter == null) {
 +      this.logWriter = LogWriterFactory.createLogWriterLogger(this.isLoner, false, this.config, true);
 +      this.logWriter.fine("LogWriter is created.");
 +    }
 +    
 +//    logWriter.info("Created log writer for IDS@"+System.identityHashCode(this));
 +    
 +    if (this.securityLogWriter == null) {
 +      // LOG: whole new LogWriterLogger instance for security
 +      this.securityLogWriter = LogWriterFactory.createLogWriterLogger(this.isLoner, true, this.config, false);
 +      this.securityLogWriter.fine("SecurityLogWriter is created.");
 +    }
 +    
 +    Services.setLogWriter(this.logWriter);
 +    Services.setSecurityLogWriter(this.securityLogWriter);
 +
 +    this.clock = new DSClock(this.isLoner);
 +    
 +    if (this.attemptingToReconnect && logger.isDebugEnabled()) {
 +      logger.debug("This thread is initializing a new DistributedSystem in order to reconnect to other members");
 +    }
 +    // Note we need loners to load the license in case they are a
 +    // bridge server and will need to enforce the member limit
 +    if (Boolean.getBoolean(InternalLocator.FORCE_LOCATOR_DM_TYPE)) {
 +      this.locatorDMTypeForced = true;
 +    }
 +
 +    // Initialize the Diffie-Hellman and public/private keys
 +    try {
 +      HandShake.initCertsMap(this.config.getSecurityProps());
 +      HandShake.initPrivateKey(this.config.getSecurityProps());
 +      HandShake.initDHKeys(this.config);
 +    }
 +    catch (Exception ex) {
 +      throw new GemFireSecurityException(
 +        LocalizedStrings.InternalDistributedSystem_PROBLEM_IN_INITIALIZING_KEYS_FOR_CLIENT_AUTHENTICATION.toLocalizedString(), ex);
 +    }
 +
 +    final long offHeapMemorySize = OffHeapStorage.parseOffHeapMemorySize(getConfig().getOffHeapMemorySize());
 +
 +    this.offHeapStore = OffHeapStorage.createOffHeapStorage(getLogWriter(), this, offHeapMemorySize, this);
 +    
 +    // Note: this can only happen on a linux system
 +    if (getConfig().getLockMemory()) {
 +      // This calculation is not exact, but seems fairly close.  So far we have
 +      // not loaded much into the heap and the current RSS usage is already 
 +      // included the available memory calculation.
 +      long avail = LinuxProcFsStatistics.getAvailableMemory(logger);
 +      long size = offHeapMemorySize + Runtime.getRuntime().totalMemory();
 +      if (avail < size) {
 +        if (GemFireCacheImpl.ALLOW_MEMORY_LOCK_WHEN_OVERCOMMITTED) {
 +          logger.warn(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_MEMORY_OVERCOMMIT_WARN, size - avail));
 +        } else {
 +          throw new IllegalStateException(LocalizedStrings.InternalDistributedSystem_MEMORY_OVERCOMMIT.toLocalizedString(avail, size));
 +        }
 +      }
 +      
 +      logger.info("Locking memory. This may take a while...");
 +      GemFireCacheImpl.lockMemory();
 +      logger.info("Finished locking memory.");
 +    }
 +
 +    try {
 +      startInitLocator();
 +    } catch (InterruptedException e) {
 +      throw new SystemConnectException("Startup has been interrupted", e);
 +    }
 +
 +    synchronized (this.isConnectedMutex) {
 +      this.isConnected = true;
 +    }
 +    
 +    if (!this.isLoner) {
 +      try {
 +        if (this.quorumChecker != null) {
 +          this.quorumChecker.suspend();
 +        }
 +        this.dm = DistributionManager.create(this);
 +        // fix bug #46324
 +        if (InternalLocator.hasLocator()) {
 +          InternalLocator locator = InternalLocator.getLocator();
 +          getDistributionManager().addHostedLocators(getDistributedMember(), InternalLocator.getLocatorStrings(), locator.isSharedConfigurationEnabled());
 +        }
 +      }
 +      finally {
 +        if (this.dm == null && this.quorumChecker != null) {
 +          this.quorumChecker.resume();
 +        }
 +        setDisconnected();
 +      }
 +    }
 +    else {
 +      this.dm = new LonerDistributionManager(this, this.logWriter);
 +    }
 +    
 +    Assert.assertTrue(this.dm != null);
 +    Assert.assertTrue(this.dm.getSystem() == this);
 +
 +    try {
 +      this.id = this.dm.getChannelId();
 +    } catch (DistributedSystemDisconnectedException e) {
 +      // bug #48144 - The dm's channel threw an NPE.  It now throws this exception
 +      // but during startup we should instead throw a SystemConnectException
 +      throw new SystemConnectException(
 +          LocalizedStrings.InternalDistributedSystem_DISTRIBUTED_SYSTEM_HAS_DISCONNECTED
 +            .toLocalizedString(), e);
 +    }
 +
 +    synchronized (this.isConnectedMutex) {
 +      this.isConnected = true;
 +    }
 +    if (attemptingToReconnect  &&  (this.startedLocator == null)) {
 +      try {
 +        startInitLocator();
 +      } catch (InterruptedException e) {
 +        throw new SystemConnectException("Startup has been interrupted", e);
 +      }
 +    }
 +    try {
 +      endInitLocator();
 +    }
 +    catch (IOException e) {
 +      throw new GemFireIOException("Problem finishing a locator service start", e);
 +    }
 +
 +      if (!statsDisabled) {
 +        // to fix bug 42527 we need a sampler
 +        // even if sampling is not enabled.
 +      this.sampler = new GemFireStatSampler(this);
 +      this.sampler.start();
 +    }
 +
 +    if (this.logWriterAppender != null) {
 +      LogWriterAppenders.startupComplete(LogWriterAppenders.Identifier.MAIN);
 +    }
 +    if (this.securityLogWriterAppender != null) {
 +      LogWriterAppenders.startupComplete(LogWriterAppenders.Identifier.SECURITY);
 +    }
 +    
 +    //this.logger.info("ds created", new RuntimeException("DEBUG: STACK"));
 +
 +    //Log any instantiators that were registered before the log writer
 +    //was created
 +    InternalInstantiator.logInstantiators();
 +    }
 +    catch (RuntimeException ex) {
 +      this.config.close();
 +      throw ex;
 +    }
 +    
 +    resourceListeners = new CopyOnWriteArrayList<ResourceEventsListener>();
 +    this.reconnected = this.attemptingToReconnect;
 +    this.attemptingToReconnect = false;
 +  }
 +
 +  /**
 +   * @since 5.7
 +   */
 +  private void startInitLocator() throws InterruptedException {
 +    String locatorString = this.originalConfig.getStartLocator();
 +    if (locatorString.length() > 0) {
 +      // when reconnecting we don't want to join with a colocated locator unless
 +      // there is a quorum of the old members available
 +      if (attemptingToReconnect && !this.isConnected) {
 +        if (this.quorumChecker != null) {
 +          logger.info("performing a quorum check to see if location services can be started early");
 +          if (!quorumChecker.checkForQuorum(3*this.config.getMemberTimeout())) {
 +            logger.info("quorum check failed - not allowing location services to start early");
 +            return;
 +          }
 +          logger.info("Quorum check passed - allowing location services to start early");
 +        }
 +      }
 +      DistributionLocatorId locId = new DistributionLocatorId(locatorString);
 +      try {
 +        this.startedLocator = InternalLocator.createLocator(
 +            locId.getPort(), 
 +            null,
 +            null,
 +            this.logWriter, // LOG: this is after IDS has created LogWriterLoggers and Appenders 
 +            this.securityLogWriter, // LOG: this is after IDS has created LogWriterLoggers and Appenders
 +            locId.getHost(),
 +            locId.getHostnameForClients(),
 +            this.originalConfig.toProperties(), false);
 +        if(locId.isPeerLocator()) {
 +          boolean startedPeerLocation = false;
 +          try {
 +            this.startedLocator.startPeerLocation(true);
 +            startedPeerLocation = true;
 +          } finally {
 +            if (!startedPeerLocation) {
 +              this.startedLocator.stop();
 +            }
 +          }
 +        }
 +      } catch (IOException e) {
 +        throw new GemFireIOException( LocalizedStrings.
 +          InternalDistributedSystem_PROBLEM_STARTING_A_LOCATOR_SERVICE
 +            .toLocalizedString(), e);
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * @since 5.7
 +   */
 +  private void endInitLocator() throws IOException {
 +    InternalLocator loc = this.startedLocator;
 +    if (loc != null) {
 +      String locatorString = this.originalConfig.getStartLocator();
 +//      DistributionLocatorId locId = new DistributionLocatorId(locatorString);
 +      boolean finished = false;
 +      try {
 +        // during the period when the product is using only paper licenses we always
 +        // start server location services in order to be able to log information
 +        // about the use of cache servers
 +        //      if(locId.isServerLocator()) {
 +        loc.startServerLocation(this);
 +        //      }
 +      
 +        loc.endStartLocator(this);
 +        finished = true;
 +      } finally {
 +        if (!finished) {
 +          loc.stop();
 +        }
 +      }
 +    }
 +  }
 +
 +  /** record a locator as a dependent of this distributed system */
 +  public void setDependentLocator(InternalLocator theLocator) {
 +    this.startedLocator = theLocator;
 +  }
 +  
 +  /** Used by DistributionManager to fix bug 33362
 +   */
 +  void setDM(DM dm) {
 +    this.dm = dm;
 +  }
 +
 +  /**
 +   * Checks whether or not this connection to a distributed system is
 +   * closed.
 +   *
 +   * @throws DistributedSystemDisconnectedException
 +   *         This connection has been {@link #disconnect(boolean, String, boolean) disconnected}
 +   */
 +  private void checkConnected() {
 +    if (!isConnected()) {
 +      throw new DistributedSystemDisconnectedException(LocalizedStrings.InternalDistributedSystem_THIS_CONNECTION_TO_A_DISTRIBUTED_SYSTEM_HAS_BEEN_DISCONNECTED.toLocalizedString(),
 +          dm.getRootCause());
 +    }
 +  }
 +
 +  @Override
 +  public boolean isConnected() {
 +    if (this.dm == null) {
 +      return false;
 +    }
 +    if (this.dm.getCancelCriterion().cancelInProgress() != null) {
 +      return false;
 +    }
 +    if (this.isDisconnecting) {
 +      return false;
 +    }
 +    return this.isConnected;
 +  }
 +  
 +  /**
 +   * This class defers to the DM.  If we don't have a DM, we're dead.
 +   * @author jpenney
 +   */
 +  protected class Stopper extends CancelCriterion {
 +    @Override
 +    public String cancelInProgress() {
 +      checkFailure();
 +      if (dm == null) {
 +        return "No dm";
 +      }
 +      return dm.getCancelCriterion().cancelInProgress();
 +    }
 +    
 +    @Override
 +    public RuntimeException generateCancelledException(Throwable e) {
 +      if (dm == null) {
 +        return new DistributedSystemDisconnectedException("no dm", e);
 +      }
 +      return dm.getCancelCriterion().generateCancelledException(e);
 +    }
 +  }
 +  
 +  /**
 +   * Handles all cancellation queries for this distributed system
 +   */
 +  private final Stopper stopper = new Stopper();
 +  
 +  @Override
 +  public CancelCriterion getCancelCriterion() {
 +    return stopper;
 +  }
 +  
 +  public boolean isDisconnecting() {
 +    if (this.dm == null) {
 +      return true;
 +    }
 +    if (this.dm.getCancelCriterion().cancelInProgress() != null) {
 +      return true;
 +    }
 +    if (!this.isConnected) {
 +      return true;
 +    }
 +    return this.isDisconnecting;
 +    }
 +
 +  @Override
 +  public LogWriter getLogWriter() {
 +    return this.logWriter;
 +  }
 +  
 +  public DSClock getClock() {
 +    return this.clock;
 +  }
 +
 +  @Override
 +  public LogWriter getSecurityLogWriter() {
 +    return this.securityLogWriter;
 +  }
 +
 +  /*
 +  public Cache myCache;
 +
 +  public void setCache(Cache cache){
 +	  myCache=cache;
 +  }
 +  public Cache getCache(){
 +	  return myCache;
 +  }
 +  */
 +  /**
 +   * Returns the stat sampler
 +   */
 +  public GemFireStatSampler getStatSampler() {
 +    return this.sampler;
 +  }
 +  
 +  /** Has this system started the disconnect process? */
 +  protected volatile boolean isDisconnecting = false;
 +  
 +  /**
 +   * Disconnects this VM from the distributed system.  Shuts down the
 +   * distribution manager, and if necessary,
 +   */
 +  @Override
 +  public void disconnect() {
 +    disconnect(false, LocalizedStrings.InternalDistributedSystem_NORMAL_DISCONNECT.toLocalizedString(), false);
 +  }
 +  
 +  /**
 +   * Disconnects this member from the distributed system when an internal
 +   * error has caused distribution to fail (e.g., this member was shunned)
 +   * @param reason a string describing why the disconnect is occurring
 +   * @param cause an optional exception showing the reason for abnormal disconnect
 +   * @param shunned whether this member was shunned by the membership coordinator
 +   */
 +  public void disconnect(String reason, Throwable cause, boolean shunned) {
 +    boolean isForcedDisconnect = dm.getRootCause() instanceof ForcedDisconnectException;
 +    boolean reconnected = false;
 +    this.reconnected = false;
 +    if (isForcedDisconnect) {
 +      this.forcedDisconnect = true;
 +      resetReconnectAttemptCounter();
 +    
 +     reconnected = tryReconnect(true, reason, GemFireCacheImpl.getInstance());
 +    }
 +    if (!reconnected) {
 +      disconnect(false, reason, shunned);
 +    }
 +  }
 +  
 +  /**
 +   * This is how much time, in milliseconds to allow a disconnect listener
 +   * to run before we interrupt it.
 +   */
 +  static private final long MAX_DISCONNECT_WAIT =
 +    Long.getLong("DistributionManager.DISCONNECT_WAIT", 
 +        10 * 1000).longValue();
 +
 +  /**
 +   * Run a disconnect listener, checking for errors and
 +   * honoring the timeout {@link #MAX_DISCONNECT_WAIT}.
 +   *
 +   * @param dc the listener to run
 +   */
 +  private void runDisconnect(final DisconnectListener dc,
 +      ThreadGroup tg) {
 +    // Create a general handler for running the disconnect
 +    Runnable r = new Runnable() {
 +      public void run() {
 +        try {
 +          disconnectListenerThread.set(Boolean.TRUE);
 +          dc.onDisconnect(InternalDistributedSystem.this);
 +        }
 +        catch (CancelException e) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("Disconnect listener <{}> thwarted by cancellation: {}", dc, e, logger.isTraceEnabled() ? e : null);
 +          }
 +        }
 +      }
 +    };
 +
 +    // Launch it and wait a little bit
 +    Thread t = new Thread(tg, r, dc.toString());
 +    try {
 +      t.start();
 +      t.join(MAX_DISCONNECT_WAIT);
 +    }
 +    catch (InterruptedException e) {
 +      Thread.currentThread().interrupt();
 +      logger.warn(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_INTERRUPTED_WHILE_PROCESSING_DISCONNECT_LISTENER), e);
 +    }
 +
 +    // Make sure the listener gets the cue to die
 +    if (t.isAlive()) {
 +      logger.warn(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_DISCONNECT_LISTENER_STILL_RUNNING__0, dc));
 +      t.interrupt();
 +
 +      try {
 +        t.join(MAX_DISCONNECT_WAIT);
 +      }
 +      catch (InterruptedException e) {
 +        Thread.currentThread().interrupt();
 +      }
 +      
 +      if (t.isAlive()) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_DISCONNECT_LISTENER_IGNORED_ITS_INTERRUPT__0, dc));
 +      }
 +    }
 +    
 +  }
 +  
 +  public boolean isDisconnectListenerThread() {
 +    Boolean disconnectListenerThreadBoolean = 
 +      (Boolean) this.disconnectListenerThread.get();
 +
 +    return disconnectListenerThreadBoolean != null &&
 +           disconnectListenerThreadBoolean.booleanValue();
 +  }
 +  
 +  /**
 +   * Run a disconnect listener in the same thread sequence as the reconnect.
 +   * @param dc the listener to run
 +   * @param tg the thread group to run the listener in
 +   */
 +
 +  private void runDisconnectForReconnect(final DisconnectListener dc,
 +      ThreadGroup tg){
 +    try {
 +      dc.onDisconnect(InternalDistributedSystem.this);
 +    } catch (DistributedSystemDisconnectedException e) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Disconnect listener <{}> thwarted by shutdown: {}", dc, e, logger.isTraceEnabled() ? e : null);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * A logging thread group for the disconnect and shutdown listeners
 +   */
 +  private final ThreadGroup disconnectListenerThreadGroup = 
 +    LoggingThreadGroup.createThreadGroup("Disconnect Listeners");
 +  
 +  /**
 +   * Disconnect cache, run disconnect listeners.
 +   * 
 +   * @param doReconnect whether a reconnect will be done
 +   * @param reason the reason that the system is disconnecting
 +   * 
 +   * @return a collection of shutdownListeners
 +   */
 +  private HashSet doDisconnects(boolean doReconnect, String reason) {
 +    // Make a pass over the disconnect listeners, asking them _politely_
 +    // to clean up.
 +    HashSet shutdownListeners = new HashSet();
 +    for (;;) {
 +      DisconnectListener listener = null;
 +      synchronized (this.listeners) {
 +        Iterator itr = listeners.iterator();
 +        if (!itr.hasNext()) {
 +          break;
 +        }
 +        listener = (DisconnectListener)itr.next();
 +        if (listener instanceof ShutdownListener) {
 +          shutdownListeners.add(listener);
 +        }
 +        itr.remove();
 +      } // synchronized
 +     
 +      if (doReconnect){
 +        runDisconnectForReconnect(listener, disconnectListenerThreadGroup);
 +      } else {
 +        runDisconnect(listener, disconnectListenerThreadGroup);
 +      }
 +    } // for
 +    return shutdownListeners;
 +  }
 +  
 +  /**
 +   * Process the shutdown listeners.  It is essential that the DM has been
 +   * shut down before calling this step, to ensure that no new listeners are
 +   * registering.
 +   * 
 +   * @param shutdownListeners shutdown listeners initially registered with us
 +   */
 +  private void doShutdownListeners(HashSet shutdownListeners) {
 +    if (shutdownListeners == null) {
 +      return;
 +    }
 +
 +    // Process any shutdown listeners we reaped during first pass
 +    Iterator it = shutdownListeners.iterator();
 +    while (it.hasNext()) {
 +      ShutdownListener s = (ShutdownListener)it.next();
 +      try {
 +        s.onShutdown(this);
 +      }
 +      catch (VirtualMachineError err) {
 +        SystemFailure.initiateFailure(err);
 +        // If this ever returns, rethrow the error.  We're poisoned
 +        // now, so don't let this thread continue.
 +        throw err;
 +      }
 +      catch (Throwable t) {
 +        // Whenever you catch Error or Throwable, you must also
 +        // catch VirtualMachineError (see above).  However, there is
 +        // _still_ a possibility that you are dealing with a cascading
 +        // error condition, so you also need to check to see if the JVM
 +        // is still usable:
 +        SystemFailure.checkFailure();
 +        // things could break since we continue, but we want to disconnect!
 +        logger.fatal(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_SHUTDOWNLISTENER__0__THREW, s), t);
 +      }
 +    }
 +
 +    // During the window while we were running disconnect listeners, new
 +    // disconnect listeners may have appeared. After messagingDisabled is
 +    // set, no new ones will be created.  However, we must process any
 +    // that appeared in the interim.
 +    for (;;) {
 +      // Pluck next listener from the list
 +      DisconnectListener dcListener = null;
 +      ShutdownListener sdListener = null;
 +      synchronized (this.listeners) {
 +        Iterator itr = listeners.iterator();
 +        if (!itr.hasNext())
 +          break;
 +        dcListener = (DisconnectListener)itr.next();
 +        itr.remove();
 +        if (dcListener instanceof ShutdownListener)
 +          sdListener = (ShutdownListener)dcListener;
 +      }
 +
 +      // Run the disconnect
 +      runDisconnect(dcListener, disconnectListenerThreadGroup);
 +
 +      // Run the shutdown, if any
 +      if (sdListener != null) {
 +        try {
 +          // TODO: should we make sure this times out?
 +          sdListener.onShutdown(this);
 +        }
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          // things could break since we continue, but we want to disconnect!
 +          logger.fatal(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_DISCONNECTLISTENERSHUTDOWN_THREW), t);
 +        }
 +      }
 +    } // for
 +  }
 +  
 +  /**
 +   * break any potential circularity in {@link #loadEmergencyClasses()}
 +   */
 +  private static volatile boolean emergencyClassesLoaded = false;
 +  
 +  /**
 +   * Ensure that the MembershipManager class gets loaded.
 +   * 
 +   * @see SystemFailure#loadEmergencyClasses()
 +   */
 +  static public void loadEmergencyClasses() {
 +    if (emergencyClassesLoaded) return;
 +    emergencyClassesLoaded = true;
 +    GMSMembershipManager.loadEmergencyClasses();
 +  }
 +  
 +  /**
 +   * Closes the membership manager
 +   * 
 +   * @see SystemFailure#emergencyClose()
 +   */
 +  public void emergencyClose() {
 +    final boolean DEBUG = SystemFailure.TRACE_CLOSE;
 +    if (dm != null) {
 +      MembershipManager mm = dm.getMembershipManager();
 +      if (mm != null) {
 +        if (DEBUG) {
 +          System.err.println("DEBUG: closing membership manager");
 +        }
 +        mm.emergencyClose();
 +        if (DEBUG) {
 +          System.err.println("DEBUG: back from closing membership manager");
 +        }
 +      }
 +    }
 +    
 +    // Garbage collection
 +    // Leave dm alone; its CancelCriterion will help people die
 +    this.isConnected = false;
 +    if (dm != null) {
 +      dm.setRootCause(SystemFailure.getFailure());
 +    }
 +    this.isDisconnecting = true;
 +    this.listeners.clear();
 +    if (DEBUG) {
 +      System.err.println("DEBUG: done with InternalDistributedSystem#emergencyClose");
 +    }
 +  }
 +  
 +  private void setDisconnected() {
 +    synchronized (this.isConnectedMutex) {
 +      this.isConnected = false;
 +      isConnectedMutex.notifyAll();
 +    }
 +  }
 +
 +  private void waitDisconnected() {
 +    synchronized (this.isConnectedMutex) {
 +      while (this.isConnected) {
 +        boolean interrupted = Thread.interrupted();
 +        try {
 +          this.isConnectedMutex.wait();
 +        }
 +        catch (InterruptedException e) {
 +          interrupted = true;
 +          getLogWriter().convertToLogWriterI18n().warning(
 +            LocalizedStrings.InternalDistributedSystem_DISCONNECT_WAIT_INTERRUPTED, e);
 +        }
 +        finally {
 +          if (interrupted) {
 +            Thread.currentThread().interrupt();
 +          }
 +        }
 +      } // while
 +    }
 +  }
 +
 +  /**
 +   * Disconnects this VM from the distributed system. Shuts down the
 +   * distribution manager.
 +   * 
 +   * @param preparingForReconnect
 +   *          true if called by a reconnect operation
 +   * @param reason
 +   *          the reason the disconnect is being performed
 +   * @param keepAlive
 +   *          true if user requested durable subscriptions are to be retained at
 +   *          server.
 +   */
 +  protected void disconnect(boolean preparingForReconnect, String reason, boolean keepAlive) {
 +    boolean isShutdownHook = (shutdownHook != null)
 +                             && (Thread.currentThread() == shutdownHook);
 +
 +    if (!preparingForReconnect) {
 +//      logger.info("disconnecting IDS@"+System.identityHashCode(this));
 +      synchronized(reconnectListeners) {
 +        reconnectListeners.clear();
 +      }
 +      cancelReconnect();
 +    }
 +    
 +    final boolean isDebugEnabled = logger.isDebugEnabled();
 +    try {
 +      HashSet shutdownListeners = null;
 +      try {
 +        if (isDebugEnabled) {
 +          logger.debug("DistributedSystem.disconnect invoked on {}", this);
 +        }
 +        synchronized (GemFireCacheImpl.class) {
 +          // bug 36955, 37014: don't use a disconnect listener on the cache;
 +          // it takes too long.
 +          //
 +          // However, make sure cache is completely closed before starting
 +          // the distributed system close.
 +          GemFireCacheImpl currentCache = GemFireCacheImpl.getInstance();
 +          if (currentCache != null && !currentCache.isClosed()) {
 +            disconnectListenerThread.set(Boolean.TRUE); // bug #42663 - this must be set while closing the cache
 +            try {
 +              currentCache.close(reason, dm.getRootCause(), keepAlive, true); // fix for 42150
 +            } 
 +            catch (VirtualMachineError e) {
 +              SystemFailure.initiateFailure(e);
 +              throw e;
 +            }
 +            catch (Throwable e) {
 +              SystemFailure.checkFailure();
 +              // Whenever you catch Error or Throwable, you must also
 +              // check for fatal JVM error (see above).  However, there is
 +              logger.warn(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_EXCEPTION_TRYING_TO_CLOSE_CACHE), e);
 +            }
 +            finally {
 +              disconnectListenerThread.set(Boolean.FALSE);
 +            }
 +          } 
 +
 +          // While still holding the lock, make sure this instance is
 +          // marked as shutting down
 +          synchronized (this) {
 +            if (this.isDisconnecting) {
 +              // It's already started, but don't return
 +              // to the caller until it has completed.
 +              waitDisconnected();
 +              return;
 +            } // isDisconnecting
 +            this.isDisconnecting = true;
 +
 +            if (!preparingForReconnect) {
 +              // move cancelReconnect above this synchronized block fix for bug 35202
 +              if (this.reconnectDS != null) {
 +                // break recursion
 +                if (isDebugEnabled) {
 +                  logger.debug("disconnecting reconnected DS: {}", this.reconnectDS);
 +                }
 +                InternalDistributedSystem r = this.reconnectDS;
 +                this.reconnectDS = null;
 +                r.disconnect(false, null, false);
 +              }
 +            } // !reconnect
 +          } // synchronized (this)
 +        } // synchronized (GemFireCache.class)
 +
 +        if (!isShutdownHook) {
 +          shutdownListeners = doDisconnects(attemptingToReconnect, reason);
 +        }
 +    
 +        if (!this.attemptingToReconnect) {
 +          if (this.logWriterAppender != null) {
 +            LogWriterAppenders.stop(LogWriterAppenders.Identifier.MAIN);
 +          }
 +          if (this.securityLogWriterAppender != null) {
 +            // LOG:SECURITY: old code did NOT invoke this
 +            LogWriterAppenders.stop(LogWriterAppenders.Identifier.SECURITY);
 +          }
 +        }
 +        
 +        AlertAppender.getInstance().shuttingDown();
 +        
 +      }
 +      finally { // be ABSOLUTELY CERTAIN that dm closed
 +        try {
 +          // Do the bulk of the close...
 +          this.dm.close();
 +          // we close the locator after the DM so that when split-brain detection
 +          // is enabled, loss of the locator doesn't cause the DM to croak
 +          if (this.startedLocator != null) {
 +            this.startedLocator.stop(forcedDisconnect, preparingForReconnect, false);
 +            this.startedLocator = null;
 +          }
 +        } finally { // timer canceled
 +          // bug 38501: this has to happen *after*
 +          // the DM is closed :-(
 +          if (!preparingForReconnect) {
 +            SystemTimer.cancelSwarm(this);
 +          }
 +        } // finally timer cancelled
 +      } // finally dm closed
 +
 +      if (!isShutdownHook) {
 +        doShutdownListeners(shutdownListeners);
 +      }
 +
 +      // closing the Aggregate stats
 +      if(functionServiceStats != null){
 +        functionServiceStats.close();
 +      }
 +      // closing individual function stats
 +      for (FunctionStats functionstats : functionExecutionStatsMap.values()) {
 +        functionstats.close();
 +      }
 +
 +      (new FunctionServiceManager()).unregisterAllFunctions();
 +
 +      if (this.sampler != null) {
 +        this.sampler.stop();
 +        this.sampler = null;
 +      }
 +
 +      if (!this.attemptingToReconnect) {
 +        if (this.logWriterAppender != null) {
 +          LogWriterAppenders.destroy(LogWriterAppenders.Identifier.MAIN);
 +        }
 +        if (this.securityLogWriterAppender != null) {
 +          LogWriterAppenders.destroy(LogWriterAppenders.Identifier.SECURITY);
 +        }
 +      }
 +
 +      // NOTE: no logging after this point :-)
 +
 +      LoggingThreadGroup.cleanUpThreadGroups(); // bug35388 - logwriters accumulate, causing mem leak
 +      EventID.unsetDS();
 +
 +    }
 +    finally {
 +      try {
 +        if (getOffHeapStore() != null) {
 +          getOffHeapStore().close();
 +        }
 +      } finally {
 +      try {
 +        removeSystem(this);
 +        // Close the config object
 +        this.config.close();
 +      }
 +      finally {
 +        // Finally, mark ourselves as disconnected
 +        setDisconnected();
 +        SystemFailure.stopThreads();
 +      }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Returns the distribution manager for accessing this distributed system.
 +   */
 +  public DM getDistributionManager() {
 +    checkConnected();
 +    return this.dm;
 +  }
 +
 +  /**
 +   * Returns the distribution manager without checking for connected or not so
 +   * can also return null.
 +   */
 +  public final DM getDM() {
 +    return this.dm;
 +  }
 +  
 +  /**
 +   * If this DistributedSystem is attempting to reconnect to the distributed system
 +   * this will return the quorum checker created by the old MembershipManager for
 +   * checking to see if a quorum of old members can be reached.
 +   * @return the quorum checking service
 +   */
 +  public final QuorumChecker getQuorumChecker() {
 +    return this.quorumChecker;
 +  }
 +  
 +  /**
 +   * Returns true if this DS has been attempting to reconnect but
 +   * the attempt has been cancelled.
 +   */
 +  public boolean isReconnectCancelled() {
 +    return this.reconnectCancelled;
 +  }
 +
 +  /**
 +   * Returns whether or not this distributed system has the same
 +   * configuration as the given set of properties.
 +   *
 +   * @see DistributedSystem#connect
 +   */
 +  public boolean sameAs(Properties props, boolean isConnected) {
 +    return originalConfig.sameAs(DistributionConfigImpl.produce(props, isConnected));
 +  }
 +
 +  public boolean threadOwnsResources() {
 +    Boolean b = ConnectionTable.getThreadOwnsResourcesRegistration();
 +    if (b == null) {
 +      // thread does not have a preference so return default
 +      return !this.shareSockets;
 +    } else {
 +      return b.booleanValue();
 +    }
 +  }
 +
 +  /**
 +   * Returns whether or not the given configuration properties refer
 +   * to the same distributed system as this
 +   * <code>InternalDistributedSystem</code> connection.
 +   *
 +   * @since 4.0
 +   */
 +  public boolean sameSystemAs(Properties props) {
 +    DistributionConfig other = DistributionConfigImpl.produce(props);
 +    DistributionConfig me = this.getConfig();
 +
 +    if (!me.getBindAddress().equals(other.getBindAddress())) {
 +      return false;
 +    }
 +
 +    // @todo Do we need to compare SSL properties?
 +
 +    // locators
 +    String myLocators = me.getLocators();
 +    String otherLocators = other.getLocators();
 +
 +    // quick check
 +    if (myLocators.equals(otherLocators)) {
 +      return true;
 +
 +    } else {
 +      myLocators = canonicalizeLocators(myLocators);
 +      otherLocators = canonicalizeLocators(otherLocators);
 +
 +      return myLocators.equals(otherLocators);
 +    }
 +  }
 +
 +  /**
 +   * Canonicalizes a locators string so that they may be compared.
 +   *
 +   * @since 4.0
 +   */
 +  private static String canonicalizeLocators(String locators) {
 +    SortedSet sorted = new TreeSet();
 +    StringTokenizer st = new StringTokenizer(locators, ",");
 +    while (st.hasMoreTokens()) {
 +      String l = st.nextToken();
 +      StringBuffer canonical = new StringBuffer();
 +      DistributionLocatorId locId = new DistributionLocatorId(l);
 +      String addr = locId.getBindAddress();
 +      if (addr != null && addr.trim().length() > 0) {
 +        canonical.append(addr);
 +      }
 +      else {
 +        canonical.append(locId.getHost().getHostAddress());
 +      }
 +      canonical.append("[");
 +      canonical.append(String.valueOf(locId.getPort()));
 +      canonical.append("]");
 +      sorted.add(canonical.toString());
 +    }
 +
 +    StringBuffer sb = new StringBuffer();
 +    for (Iterator iter = sorted.iterator(); iter.hasNext(); ) {
 +      sb.append((String) iter.next());
 +      if (iter.hasNext()) {
 +        sb.append(",");
 +      }
 +    }
 +    return sb.toString();
 +  }
 +
 +  private final StoppableReentrantLock elderLock;
 +  private final StoppableCondition elderLockCondition;
 +  
 +  public StoppableReentrantLock getElderLock() {
 +    return elderLock;
 +  }
 +  public StoppableCondition getElderLockCondition() {
 +    return elderLockCondition;
 +  }
 +  
 +  /**
 +   * Returns the current configuration of this distributed system.
 +   */
 +  public DistributionConfig getConfig() {
 +    return this.config;
 +  }
 +
 +  /**
 +   * Returns the id of this connection to the distributed system.
 +   * This is actually the port of the distribution manager's
 +   * distribution channel.
 +   *
 +   * @see com.gemstone.gemfire.distributed.internal.DistributionChannel#getId
 +   */
 +  @Override
 +  public long getId() {
 +    return this.id;
 +  }
 +
 +  /**
 +   * Returns the string value of the distribution manager's id.
 +   */
 +  @Override
 +  public String getMemberId() {
 +    return String.valueOf(this.dm.getId());
 +  }
 +
 +  @Override
 +  public InternalDistributedMember getDistributedMember() {
 +    return this.dm.getId();
 +  }
 +  @Override
 +  public Set<DistributedMember> getAllOtherMembers() {
 +    return dm.getAllOtherMembers();
 +  }
 +  @Override
 +  public Set<DistributedMember> getGroupMembers(String group) {
 +    return dm.getGroupMembers(group);
 +  }
 +  
 +  
 +
 +  @Override
 +  public Set<DistributedMember> findDistributedMembers(InetAddress address) {
 +    Set<InternalDistributedMember> allMembers = dm.getDistributionManagerIdsIncludingAdmin();
 +    Set<DistributedMember> results = new HashSet<DistributedMember>(2);
 +    
 +    //Search through the set of all members
 +    for(InternalDistributedMember member: allMembers) {
 +      
 +      Set<InetAddress> equivalentAddresses = dm.getEquivalents(member.getInetAddress());
 +      //Check to see if the passed in address is matches one of the addresses on
 +      //the given member.
 +      if(address.equals(member.getInetAddress()) || equivalentAddresses.contains(address)) {
 +        results.add(member);
 +      }
 +    }
 +    
 +    return results;
 +  }
 +
 +  @Override
 +  public DistributedMember findDistributedMember(String name) {
 +    Set<DistributedMember> allMembers = dm.getDistributionManagerIdsIncludingAdmin();
 +    for(DistributedMember member : allMembers) {
 +      if(member.getName().equals(name)) {
 +        return member;
 +      }
 +    }
 +    return null;
 +  }
 +
 +  /**
 +   * Returns the configuration this distributed system was created with.
 +   */
 +  public DistributionConfig getOriginalConfig() {
 +    return this.originalConfig;
 +  }
 +  @Override
 +  public String getName() {
 +    return getOriginalConfig().getName();
 +  }
 +
 +  ///////////////////////  Utility Methods  ///////////////////////
 +
 +  /**
 +   * Since {@link DistributedSystem#connect} guarantees that there is
 +   * a canonical instance of <code>DistributedSystem</code> for each
 +   * configuration, we can use the default implementation of
 +   * <code>equals</code>.
 +   *
 +   * @see #sameAs
 +   */
 +  @Override
 +  public boolean equals(Object o) {
 +    return super.equals(o);
 +  }
 +
 +  /**
 +   * Since we use the default implementation of {@link #equals
 +   * equals}, we can use the default implementation of
 +   * <code>hashCode</code>.
 +   */
 +  @Override
 +  public int hashCode() {
 +    return super.hashCode();
 +  }
 +
 +  /**
 +   * Returns a string describing this connection to distributed system
 +   * (including highlights of its configuration).
 +   */
 +  @Override
 +  public String toString() {
 +    StringBuffer sb = new StringBuffer();
 +    sb.append("Connected ");
 +    String name = this.getName();
 +    if (name != null && !name.equals("")) {
 +      sb.append("\"");
 +      sb.append(name);
 +      sb.append("\" ");
 +    }
 +    sb.append("(id=");
 +    sb.append(Integer.toHexString(System.identityHashCode(this)));
 +    sb.append(") ");
 +
 +    sb.append("to distributed system using ");
 +    int port = this.config.getMcastPort();
 +    if (port != 0) {
 +      sb.append("multicast port ");
 +      sb.append(port);
 +      sb.append(" ");
 +
 +    } else {
 +      sb.append("locators \"");
 +      sb.append(this.config.getLocators());
 +      sb.append("\" ");
 +    }
 +
 +    File logFile = this.config.getLogFile();
 +    sb.append("logging to ");
 +    if (logFile == null || logFile.equals(new File(""))) {
 +      sb.append("standard out ");
 +
 +    } else {
 +      sb.append(logFile);
 +      sb.append(" ");
 +    }
 +
 +    sb.append(" started at ");
 +    sb.append((new Date(this.startTime)).toString());
 +    
 +    if (!this.isConnected()) {
 +      sb.append(" (closed)");
 +    }
 +
 +    return sb.toString().trim();
 +  }
 +
 +  private final ArrayList<Statistics> statsList = new ArrayList<Statistics>();
 +  private int statsListModCount = 0;
 +  private long statsListUniqueId = 1;
 +  private final Object statsListUniqueIdLock = new Object();
 +  
 +  // As the function execution stats can be lot in number, its better to put
 +  // them in a map so that it will be accessible immediately
 +  private final ConcurrentHashMap<String, FunctionStats>  functionExecutionStatsMap = new ConcurrentHashMap<String, FunctionStats>();
 +  private FunctionServiceStats functionServiceStats = null;
 +  
 +  public int getStatListModCount() {
 +    return this.statsListModCount;
 +  }
 +  public List<Statistics> getStatsList() {
 +    return this.statsList;
 +  }
 +
 +  @Override
 +  public final int getStatisticsCount() {
 +    int result = 0;
 +    List<Statistics> statsList = this.statsList;
 +    if (statsList != null) {
 +      result = statsList.size();
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public final Statistics findStatistics(long id) {
 +    List<Statistics> statsList = this.statsList;
 +    synchronized (statsList) {
 +      for (Statistics s : statsList) {
 +        if (s.getUniqueId() == id) {
 +          return s;
 +        }
 +      }
 +    }
 +    throw new RuntimeException(LocalizedStrings.PureStatSampler_COULD_NOT_FIND_STATISTICS_INSTANCE.toLocalizedString());
 +  }
 +  
 +  @Override
 +  public final boolean statisticsExists(long id) {
 +    List<Statistics> statsList = this.statsList;
 +    synchronized (statsList) {
 +      for (Statistics s : statsList) {
 +        if (s.getUniqueId() == id) {
 +          return true;
 +        }
 +      }
 +    }
 +    return false;
 +  }
 +
 +  @Override
 +  public final Statistics[] getStatistics() {
 +    List<Statistics> statsList = this.statsList;
 +    synchronized (statsList) {
 +      return (Statistics[])statsList.toArray(new Statistics[statsList.size()]);
 +    }
 +  }
 +  
 +  // StatisticsFactory methods
 +  public Statistics createStatistics(StatisticsType type) {
 +    return createOsStatistics(type, null, 0, 0);
 +  }
 +  public Statistics createStatistics(StatisticsType type, String textId) {
 +    return createOsStatistics(type, textId, 0, 0);
 +  }
 +  public Statistics createStatistics(StatisticsType type, String textId, long numericId) {
 +    return createOsStatistics(type, textId, numericId, 0);
 +  }
 +  public Statistics createOsStatistics(StatisticsType type, String textId, long numericId, int osStatFlags) {
 +    if (this.statsDisabled) {
 +      return new DummyStatisticsImpl(type, textId, numericId);
 +    }
 +    long myUniqueId;
 +    synchronized (statsListUniqueIdLock) {
 +      myUniqueId = statsListUniqueId++; // fix for bug 30597
 +    }
 +    Statistics result = new LocalStatisticsImpl(type, textId, numericId, myUniqueId, false, osStatFlags, this);
 +    synchronized (statsList) {
 +      statsList.add(result);
 +      statsListModCount++;
 +    }
 +    return result;
 +  }
 +
 +  public FunctionStats getFunctionStats(String textId) {
 +    FunctionStats stats = (FunctionStats)functionExecutionStatsMap.get(textId);
 +    if (stats == null) {
 +      stats = new FunctionStats(this, textId);
 +      FunctionStats oldStats = functionExecutionStatsMap.putIfAbsent(textId,
 +          stats);
 +      if (oldStats != null) {
 +        stats.close();
 +        stats = oldStats;
 +      }
 +    }
 +    return stats;
 +  }
 +
 +  
 +  public FunctionServiceStats getFunctionServiceStats() {
 +    if (functionServiceStats == null) {
 +      synchronized (this) {
 +        if(functionServiceStats == null){
 +          functionServiceStats = new FunctionServiceStats(this, "FunctionExecution");
 +        }
 +      }
 +    }
 +    return functionServiceStats;
 +  }
 +
 +  /**
 +   * For every registered statistic instance call the specified visitor.
 +   * This method was added to fix bug 40358
 +   */
 +  public void visitStatistics(StatisticsVisitor visitor) {
 +    synchronized (this.statsList) {
 +      for (Statistics s: this.statsList) {
 +        visitor.visit(s);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Used to "visit" each instance of Statistics registered with
 +   * @see #visitStatistics
 +   */
 +  public interface StatisticsVisitor {
 +    public void visit(Statistics stat);
 +  }
 +  
 +  public Set<String> getAllFunctionExecutionIds() {
 +    return functionExecutionStatsMap.keySet();
 +  }
 +  
 +  
 +  public Statistics[] findStatisticsByType(final StatisticsType type) {
 +    final ArrayList hits = new ArrayList();
 +    visitStatistics(new StatisticsVisitor() {
 +        public void visit(Statistics s) {
 +          if (type == s.getType()) {
 +            hits.add(s);
 +          }
 +        }
 +      });
 +    Statistics[] result = new Statistics[hits.size()];
 +    return (Statistics[])hits.toArray(result);
 +  }
 +  
 +  public Statistics[] findStatisticsByTextId(final String textId) {
 +    final ArrayList hits = new ArrayList();
 +    visitStatistics(new StatisticsVisitor() {
 +        public void visit(Statistics s) {
 +          if (s.getTextId().equals(textId)) {
 +            hits.add(s);
 +          }
 +        }
 +      });
 +    Statistics[] result = new Statistics[hits.size()];
 +    return (Statistics[])hits.toArray(result);
 +  }
 +  public Statistics[] findStatisticsByNumericId(final long numericId) {
 +    final ArrayList hits = new ArrayList();
 +    visitStatistics(new StatisticsVisitor() {
 +        public void visit(Statistics s) {
 +          if (numericId == s.getNumericId()) {
 +            hits.add(s);
 +          }
 +        }
 +      });
 +    Statistics[] result = new Statistics[hits.size()];
 +    return (Statistics[])hits.toArray(result);
 +  }
 +  public Statistics findStatisticsByUniqueId(final long uniqueId) {
 +    synchronized (this.statsList) {
 +      for (Statistics s: this.statsList) {
 +        if (uniqueId == s.getUniqueId()) {
 +          return s;
 +        }
 +      }
 +    }
 +    return null;
 +  }
 +
 +  /** for internal use only. Its called by {@link LocalStatisticsImpl#close}. */
 +  public void destroyStatistics(Statistics stats) {
 +    synchronized (statsList) {
 +      if (statsList.remove(stats)) {
 +        statsListModCount++;
 +      }
 +    }
 +  }
 +
 +  public Statistics createAtomicStatistics(StatisticsType type) {
 +    return createAtomicStatistics(type, null, 0);
 +  }
 +  public Statistics createAtomicStatistics(StatisticsType type, String textId) {
 +    return createAtomicStatistics(type, textId, 0);
 +  }
 +  public Statistics createAtomicStatistics(StatisticsType type, String textId, long numericId) {
 +    if (this.statsDisabled) {
 +      return new DummyStatisticsImpl(type, textId, numericId);
 +    }
 +    
 +    long myUniqueId;
 +    synchronized (statsListUniqueIdLock) {
 +      myUniqueId = statsListUniqueId++; // fix for bug 30597
 +    }
 +    Statistics result = StatisticsImpl.createAtomicNoOS(type, textId, numericId, myUniqueId, this);
 +    synchronized (statsList) {
 +      statsList.add(result);
 +      statsListModCount++;
 +    }
 +    return result;
 +  }
 +
 +
 +  // StatisticsTypeFactory methods
 +  private final static StatisticsTypeFactory tf = StatisticsTypeFactoryImpl.singleton();
 +
 +  /**
 +   * Creates or finds a StatisticType for the given shared class.
 +   */
 +  public StatisticsType createType(String name, String description,
 +                                   StatisticDescriptor[] stats) {
 +    return tf.createType(name, description, stats);
 +  }
 +  public StatisticsType findType(String name) {
 +    return tf.findType(name);
 +  }
 +  public StatisticsType[] createTypesFromXml(Reader reader)
 +    throws IOException {
 +    return tf.createTypesFromXml(reader);
 +  }
 +
 +  public StatisticDescriptor createIntCounter(String name, String description,
 +                                              String units) {
 +    return tf.createIntCounter(name, description, units);
 +  }
 +  public StatisticDescriptor createLongCounter(String name, String description,
 +                                               String units) {
 +    return tf.createLongCounter(name, description, units);
 +  }
 +  public StatisticDescriptor createDoubleCounter(String name, String description,
 +                                                 String units) {
 +    return tf.createDoubleCounter(name, description, units);
 +  }
 +  public StatisticDescriptor createIntGauge(String name, String description,
 +                                            String units) {
 +    return tf.createIntGauge(name, description, units);
 +  }
 +  public StatisticDescriptor createLongGauge(String name, String description,
 +                                             String units) {
 +    return tf.createLongGauge(name, description, units);
 +  }
 +  public StatisticDescriptor createDoubleGauge(String name, String description,
 +                                               String units) {
 +    return tf.createDoubleGauge(name, description, units);
 +  }
 +  public StatisticDescriptor createIntCounter(String name, String description,
 +                                              String units, boolean largerBetter) {
 +    return tf.createIntCounter(name, description, units, largerBetter);
 +  }
 +  public StatisticDescriptor createLongCounter(String name, String description,
 +                                               String units, boolean largerBetter) {
 +    return tf.createLongCounter(name, description, units, largerBetter);
 +  }
 +  public StatisticDescriptor createDoubleCounter(String name, String description,
 +                                                 String units, boolean largerBetter) {
 +    return tf.createDoubleCounter(name, description, units, largerBetter);
 +  }
 +  public StatisticDescriptor createIntGauge(String name, String description,
 +                                            String units, boolean largerBetter) {
 +    return tf.createIntGauge(name, description, units, largerBetter);
 +  }
 +  public StatisticDescriptor createLongGauge(String name, String description,
 +                                             String units, boolean largerBetter) {
 +    return tf.createLongGauge(name, description, units, largerBetter);
 +  }
 +  public StatisticDescriptor createDoubleGauge(String name, String description,
 +                                               String units, boolean largerBetter) {
 +    return tf.createDoubleGauge(name, description, units, largerBetter);
 +  }
 +
 +  public long getStartTime() {
 +    return this.startTime;
 +  }
 +
 +  /**
 +   * Makes note of a <code>ConnectListener</code> whose
 +   * <code>onConnect</code> method will be invoked when a connection is
 +   * created to a distributed system.
 +   * @return set of currently existing system connections
 +   */
 +  public static List addConnectListener(ConnectListener listener) {
 +    synchronized (existingSystemsLock) {
 +      synchronized (connectListeners) {
 +        connectListeners.add(listener);
 +        return existingSystems;
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Makes note of a <code>ReconnectListener</code> whose
 +   * <code>onReconnect</code> method will be invoked when a connection is
 +   * recreated to a distributed system during auto-reconnect.<p>
 +   * 
 +   * The ReconnectListener set is cleared after a disconnect.
 +   */
 +  public static void addReconnectListener(ReconnectListener listener) {
 +//    (new ManagerLogWriter(LogWriterImpl.FINE_LEVEL, System.out)).fine("registering reconnect listener: " + listener);
 +    synchronized (existingSystemsLock) {
 +      synchronized (reconnectListeners) {
 +        reconnectListeners.add(listener);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Removes a <code>ConnectListener</code> from the list of
 +   * listeners that will be notified when a connection is created to
 +   * a distributed system.
 +   * @return true if listener was in the list
 +   */
 +  public static boolean removeConnectListener(ConnectListener listener) {
 +    synchronized (connectListeners) {
 +      return connectListeners.remove(listener);
 +    }
 +  }
 +
 +  /**
 +   * Notifies all registered <code>ConnectListener</code>s that a
 +   * connection to a distributed system has been created.
 +   */
 +  private static void notifyConnectListeners(InternalDistributedSystem sys) {
 +    synchronized (connectListeners) {
 +      for (Iterator iter = connectListeners.iterator(); iter.hasNext();) {
 +        try {
 +          ConnectListener listener = (ConnectListener) iter.next();
 +          listener.onConnect(sys);
 +        }
 +        catch (VirtualMachineError err) {
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error.  We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        catch (Throwable t) {
 +          // Whenever you catch Error or Throwable, you must also
 +          // catch VirtualMachineError (see above).  However, there is
 +          // _still_ a possibility that you are dealing with a cascading
 +          // error condition, so you also need to check to see if the JVM
 +          // is still usable:
 +          SystemFailure.checkFailure();
 +          sys.getLogWriter().convertToLogWriterI18n().severe(LocalizedStrings.InternalDistributedSystem_CONNECTLISTENER_THREW, t);
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Removes a <code>ReconnectListener</code> from the list of
 +   * listeners that will be notified when a connection is recreated to
 +   * a distributed system.
 +   */
 +  public static void removeReconnectListener(ReconnectListener listener) {
 +    synchronized (reconnectListeners) {
 +      reconnectListeners.remove(listener);
 +    }
 +  }
 +
 +  /**
 +   * Notifies all registered <code>ReconnectListener</code>s that a
 +   * connection to a distributed system has been recreated.
 +   */
 +  private static void notifyReconnectListeners(InternalDistributedSystem oldsys, InternalDistributedSystem newsys, boolean starting) {
 +    List<ReconnectListener> listeners;
 +    synchronized (reconnectListeners) {
 +      listeners = new ArrayList<ReconnectListener>(reconnectListeners);
 +    }
 +    for (ReconnectListener listener: listeners) {
 +      try {
 +        if (starting) {
 +          listener.reconnecting(oldsys);
 +        } else {
 +          listener.onReconnect(oldsys, newsys);
 +        }
 +      } catch (Throwable t) {
 +        Error err;
 +        if (t instanceof OutOfMemoryError || t instanceof UnknownError) {
 +          err = (Error)t;
 +          SystemFailure.initiateFailure(err);
 +          // If this ever returns, rethrow the error. We're poisoned
 +          // now, so don't let this thread continue.
 +          throw err;
 +        }
 +        // Whenever you catch Error or Throwable, you must also
 +        // check for fatal JVM error (see above).  However, there is
 +        // _still_ a possibility that you are dealing with a cascading
 +        // error condition, so you also need to check to see if the JVM
 +        // is still usable:
 +        SystemFailure.checkFailure();
 +        logger.fatal(LocalizedMessage.create(LocalizedStrings.InternalDistributedSystem_CONNECTLISTENER_THREW), t);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Notifies all resource event listeners. All exceptions are caught here and
 +   * only a warning message is printed in the log
 +   * 
 +   * @param event
 +   *          Enumeration depicting particular resource event
 +   * @param resource
 +   *          the actual resource object.
 +   */
 +  private void notifyResourceEventListeners(ResourceEvent event, Object resource) {
 +    for (Iterator<ResourceEventsListener> iter = resourceListeners.iterator(); iter
 +        .hasNext();) {
 +      try {
 +        ResourceEventsListener listener = (ResourceEventsListener) iter.next();
 +        listener.handleEvent(event, resource);
 +      } catch(CancelException e) {
 +        //ignore
 +      } catch (ManagementException ex) {
 +        if (event == ResourceEvent.CACHE_CREATE) {
 +          throw ex;
 +        } else {
 +          logger.warn(ex.getMessage(), ex);
 +        }
 +      } catch (Exception err) {
 +        logger.warn(err.getMessage(), err);
 +      } catch (VirtualMachineError e) {
 +        SystemFailure.initiateFailure(e);
 +        throw e;
 +      } catch (Throwable t) {
 +        SystemFailure.checkFailure();
 +        logger.warn(t.getMessage(), t);
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * sqlfire's disconnect listener is invoked before the cache is closed when
 +   * there is a forced disconnect
 +   */
 +  public void setSqlfForcedDisconnectListener(DisconnectListener listener) {
 +    synchronized(this.listeners) { 
 +      this.sqlfDisconnectListener = listener;
 +    }
 +  }
 +  
 +  private void notifySqlfForcedDisconnectListener() {
 +    if (this.sqlfDisconnectListener != null) {
 +      final boolean isDebugEnabled = logger.isDebugEnabled();
 +      try {
 +        if (isDebugEnabled) {
 +          logger.debug("notifying sql disconnect listener");
 +        }
 +        this.sqlfDisconnectListener.onDisconnect(this);
 +      } catch (VirtualMachineError e) {
 +        SystemFailure.initiateFailure(e);
 +        throw e;
 +      } catch (Throwable e) {
 +        SystemFailure.checkFailure();
 +        // TODO: should these be logged or ignored?  We need to see them
 +        logger.info("", e);
 +      }
 +      if (isDebugEnabled) {
 +        logger.debug("finished notifying sql disconnect listener");
 +      }
 +    }
 +  }
 +  
 +  
 +
 +  /**
 +   * Makes note of a <code>DisconnectListener</code> whose
 +   * <code>onDisconnect</code> method will be invoked when this
 +   * connection to the distributed system is disconnected.
 +   */
 +  public void addDisconnectListener(DisconnectListener listener) {
 +    synchronized (this.listeners) {
 +      this.listeners.add(listener);
 +
 +      Boolean disconnectListenerThreadBoolean = 
 +        (Boolean) disconnectListenerThread.get();
 +
 +      if (disconnectListenerThreadBoolean == null ||
 +          !disconnectListenerThreadBoolean.booleanValue()) {
 +        // Don't add disconnect listener after messaging has been disabled.
 +        // Do this test _after_ adding the listener to narrow the window.
 +        // It's possible to miss it still and never invoke the listener, but
 +        // other shutdown conditions will presumably get flagged.
 +        String reason = this.stopper.cancelInProgress();
 +        if (reason != null) {
 +          this.listeners.remove(listener); // don't leave in the list!
 +          throw new DistributedSystemDisconnectedException(LocalizedStrings.InternalDistributedSystem_NO_LISTENERS_PERMITTED_AFTER_SHUTDOWN_0.toLocalizedString(reason), dm.getRootCause());
 +        }
 +      }
 +    } // synchronized
 +  }
 +  
 +  /**
 +   * A non-null value of Boolean.TRUE will identify a thread being used to
 +   * execute disconnectListeners. {@link #addDisconnectListener} will
 +   * not throw ShutdownException if the value is Boolean.TRUE.
 +   */
 +  final ThreadLocal disconnectListenerThread = new ThreadLocal();
 +
 +  /**
 +   * Removes a <code>DisconnectListener</code> from the list of
 +   * listeners that will be notified when this connection to the
 +   * distributed system is disconnected.
 +   * @return true if listener was in the list
 +   */
 +  public boolean removeDisconnectListener(DisconnectListener listener) {
 +    synchronized (this.listeners) {
 +      return this.listeners.remove(listener);
 +    }
 +  }
 +
 +  /**
 +   * Returns any existing <code>InternalDistributedSystem</code> instance.
 +   * Returns <code>null</code> if no instance exists.
 +   */
 +  public static InternalDistributedSystem getAnyInstance() {
 +    List l = existingSystems;
 +    if (l.isEmpty()) {
 +      return null;
 +    }
 +    else {
 +      return (InternalDistributedSystem)l.get(0);
 +    }
 +  }
 +  /**
 +   * Test hook
 +   */
 +  public static List getExistingSystems() {
 +    return existingSystems;
 +  }
 +
 +  @Override
 +  public Properties getProperties() {
 +    return this.config.toProperties();
 +  }
 +  
 +  @Override
 +  public Properties getSecurityProperties() {
 +    return this.config.getSecurityProps();
 +  }
 +
 +  /**
 +   * Fires an "informational" <code>SystemMembershipEvent</code> in
 +   * admin VMs.
 +   *
 +   * @since 4.0
 +   */
 +  public void fireInfoEvent(Object callback) {
 +    throw new UnsupportedOperationException(LocalizedStrings.InternalDistributedSystem_NOT_IMPLEMENTED_YET.toLocalizedString());
 +  }
 +
 +  /**
 +   * Installs a shutdown hook to ensure
 +   * that we are disconnected if an application VM shuts down
 +   * without first calling disconnect itself.
 +     */
 +  public static final Thread shutdownHook;
 +
 +  static {
 +    // Create a shutdown hook to cleanly close connection if
 +    // VM shuts down with an open connection.
 +    ThreadGroup tg = LoggingThreadGroup.createThreadGroup(SHUTDOWN_HOOK_NAME);
 +    Thread tmp_shutdownHook = null;
 +    try {
 +      //Added for bug 38407
 +      if( ! Boolean.getBoolean(DISABLE_SHUTDOWN_HOOK_PROPERTY)) {
 +        tmp_shutdownHook = new Thread(tg, new Runnable() {
 +          public void run() {
 +            DistributedSystem ds = InternalDistributedSystem.getAnyInstance();
 +            setThreadsSocketPolicy(true /* conserve sockets */);
 +            if (ds != null && ds.isConnected()) {
 +              LogWriterI18n log = ((InternalDistributedSystem)ds).getInternalLogWriter();
 +              log.info(LocalizedStrings.InternalDistributedSystem_shutdownHook_shuttingdown);
 +              DurableClientAttributes dca = ((InternalDistributedSystem)ds).getDistributedMember().getDurableClientAttributes();
 +              boolean isDurableClient = false;
 +              
 +              if(dca != null) {
 +                  isDurableClient = ((dca.getId() == null || dca.getId().isEmpty()) ? false : true);
 +              }
 +                            	 
 +              ((InternalDistributedSystem)ds).disconnect(false,
 +                  LocalizedStrings.InternalDistributedSystem_NORMAL_DISCONNECT
 +                      .toLocalizedString(), isDurableClient/*keep alive drive from this*/);
 +              // this was how we wanted to do it for 5.7, but there were shutdown
 +              // issues in PR/dlock (see bug 39287)
 +//              InternalDistributedSystem ids = (InternalDistributedSystem)ds;
 +//              if (ids.getDistributionManager() != null &&
 +//                  ids.getDistributionManager().getMembershipManager() != null) {
 +//                ids.getDistributionManager().getMembershipManager()
 +//                  .uncleanShutdown("VM is exiting", null);
 +//              }
 +            }
 +          }
 +        }, SHUTDOWN_HOOK_NAME);
 +        Runtime.getRuntime().addShutdownHook(tmp_shutdownHook);
 +      }
 +    } finally {
 +      shutdownHook = tmp_shutdownHook;
 +    }
 +  }
 +  ///////////////////////  Inner Classes  ///////////////////////
 +
 +  /**
 +   * A listener that gets invoked before this connection to the
 +   * distributed system is disconnected.
 +   */
 +  public interface DisconnectListener {
 +
 +    /**
 +     * Invoked before a connection to the distributed system is
 +     * disconnected.
 +     *
 +     * @param sys the the system we are disconnecting from
 +     * process should take before returning.
 +     */
 +    public void onDisconnect(InternalDistributedSystem sys);
 +
 +  }
 +  
 +  /**
 +   * A listener that gets invoked before and after a successful auto-reconnect
 +   */
 +  public interface ReconnectListener {
 +    /**
 +     * Invoked when reconnect attempts are initiated
 +     * 
 +     * @param oldSystem the old DS, which is in a partially disconnected state
 +     * and cannot be used for messaging
 +     */
 +    public void reconnecting(InternalDistributedSystem oldSystem);
 +    
 +    /**
 +     * Invoked after a reconnect to the distributed system
 +     * @param oldSystem the old DS
 +     * @param newSystem the new DS
 +     */
 +    public void onReconnect(InternalDistributedSystem oldSystem, InternalDistributedSystem newSystem);
 +  }
 +
 +  /**
 +   * A listener that gets invoked after this connection to the
 +   * distributed system is disconnected
 +   * @author jpenney
 +   *
 +   */
 +  public interface ShutdownListener extends DisconnectListener {
 +    /**
 +     * Invoked after the connection to the distributed system has
 +     * been disconnected
 +     * @param sys
 +     */
 +    public void onShutdown(InternalDistributedSystem sys);
 +  }
 +
 +  /**
 +   * Integer representing number of tries already made
 +   * to reconnect and that failed.
 +   * */
 +  private volatile static int reconnectAttemptCounter = 0;
 +  public static int getReconnectAttemptCounter() {
 +    return reconnectAttemptCounter;
 +  }
 +  
 +  /**
 +   * The time at which reconnect attempts last began
 +   */
 +  private static long reconnectAttemptTime;
 +
 +  /**
 +   * Boolean indicating if DS needs to reconnect and reconnect
 +   * is in progress.
 +   * */
 +  private volatile boolean attemptingToReconnect = false;
 +  
 +  /**
 +   * Boolean indicating this DS joined through a reconnect attempt
 +   */
 +  private volatile boolean reconnected = false;
 +  
 +  /**
 +   * Boolean indicating that this member has been shunned by other members
 +   * or a network partition has occurred
 +   */
 +  private volatile boolean forcedDisconnect = false;
 +
 +  /**
 +   * Used to keep track of the DS created by doing an reconnect on this.
 +   */
 +  private volatile InternalDistributedSystem reconnectDS;
 +  /**
 +   * Was this distributed system started with FORCE_LOCATOR_DM_TYPE=true?
 +   * We need to know when reconnecting.
 +   */
 +  private boolean locatorDMTypeForced;
 +  
 +  
 +  /**
 +   * Returns true if we are reconnecting the distributed system or
 +   * reconnect has completed.  If this returns true it means that
 +   * this instance of the DS is now disconnected and unusable.
 +   */
 +  public boolean isReconnecting(){
 +    return attemptingToReconnect || (reconnectDS != null);
 +  }
 +  
 +  /**
 +   * Returns true if we are reconnecting the distributed system
 +   * and this instance was created for one of the connection
 +   * attempts.  If the connection succeeds this state is cleared
 +   * and this method will commence to return false.
 +   */
 +  public boolean isReconnectingDS() {
 +    return this.isReconnectingDS;
 +  }
 +  
 +  /**
 +   * returns the membership socket of the old
 +   * distributed system, if available, when
 +   * isReconnectingDS returns true.  This is
 +   * used to connect the new DM to the distributed
 +   * system through RemoteTransportConfig.
 +   */
 +  public Object oldDSMembershipInfo() {
 +    if (this.quorumChecker != null) {
 +      return this.quorumChecker.getMembershipInfo();
 +    }
 +    return null;
 +  }
 +  
 +  /**
 +   * Returns true if this DS reconnected to the distributed system after
 +   * a forced disconnect or loss of required-roles
 +   */
 +  public boolean reconnected() {
 +    return this.reconnected;
 +  }
 +  
 +  /**
 +   * Returns true if this DS has been kicked out of the distributed system
 +   */
 +  public boolean forcedDisconnect() {
 +    return this.forcedDisconnect;
 +  }
 +
 +  /**
 +   * If true then this DS will never reconnect.
 +   */
 +  private boolean reconnectCancelled = false;
 +  private Object reconnectCancelledLock = new Object();
 +
 +  /** Make sure this instance of DS never does a reconnect.
 +   * Also if reconnect is in progress cancel it.
 +   */
 +  public void cancelReconnect() {
 +//    (new ManagerLogWriter(LogWriterImpl.FINE_LEVEL, System.out)).fine("cancelReconnect invoked", new Exception("stack trace"));
 +    synchronized(this.reconnectCancelledLock) {
 +      this.reconnectCancelled = t

<TRUNCATED>


[090/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
index 0000000,3577e38..bde948d
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/DummyQRegion.java
@@@ -1,0 -1,252 +1,252 @@@
+ /*
+  * 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.
+  */
+ /*
+  * DummyQRegion.java
+  *
+  * Created on March 15, 2005, 6:40 PM
+  */
+ 
+ package com.gemstone.gemfire.cache.query.internal.index;
+ 
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Set;
+ 
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.query.internal.QRegion;
+ import com.gemstone.gemfire.cache.query.internal.ResultsBag;
+ import com.gemstone.gemfire.cache.query.internal.ResultsSet;
+ import com.gemstone.gemfire.cache.query.internal.types.TypeUtils;
+ import com.gemstone.gemfire.cache.query.types.ObjectType;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.RegionEntry;
+ import com.gemstone.gemfire.internal.cache.RegionEntryContext;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ 
+ /**
+  *
+  * @author vaibhav
+  */
+ public class DummyQRegion extends QRegion {
+   
+   private RegionEntry entry = null;
+   private ObjectType valueType = TypeUtils.OBJECT_TYPE;
+   private ObjectType keyType = TypeUtils.OBJECT_TYPE;
+   
+   private ResultsBag values = null;
+   private ResultsSet keys = null;
+   private ResultsSet entries = null;
+   private List valueInList = null;
+   private Object[] valueInArray = null;
+   
+   public DummyQRegion(Region region) {
+     super(region, false);
+     Class constraint = region.getAttributes().getValueConstraint();
+     if (constraint != null)
+       valueType = TypeUtils.getObjectType(constraint);
+     
+     constraint = region.getAttributes().getKeyConstraint();
+     if (constraint != null)
+       keyType = TypeUtils.getObjectType(constraint);
+     values = new ResultsBag(((GemFireCacheImpl)region.getCache()).getCachePerfStats());
+     values.setElementType(valueType);
+     keys = new ResultsSet();
+     keys.setElementType(keyType);
+     entries = new ResultsSet();
+     entries.setElementType(TypeUtils.getRegionEntryType(region)); // gets key and value types from region
+   }
+   
+   @Override
+   public boolean equals(Object o) { //  for findbugs
+     return super.equals(o);
+   }
+   
+   @Override
+   public int hashCode() { // for findbugs
+     return super.hashCode();
+   }
+   
+   public void setEntry(RegionEntry e){
+     this.entry = e;
+   }
+   
+   public RegionEntry getEntry(){
+     return this.entry;
+   }
+   
+   @Override
+   public SelectResults getKeys() {
+     if(keys == null){
+       keys = new ResultsSet();
+       keys.setElementType(keyType);
+     }
+     keys.clear();
+     keys.add(entry.getKey());
+     return keys;
+   }
+   
+   @Override
+   public Set keySet() {
+     return (ResultsSet)getKeys();
+   }
+   
+   @Override
+   public Set keys() {
+     return keySet();
+   }
+   
+   @Override
+   public Collection values() {
+    return getValues();
+   }
+   
+   @Override
+   public Set asSet() {
+     return getValues().asSet(); 
+   }
+   
+   @Override
+   public List asList() {
+     if(valueInList == null){
+       valueInList = new  ArrayList(1);      
+     }
+     valueInList.clear();
+     Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
 -    if (val instanceof Chunk) {
 -      @Retained @Released Chunk ohval = (Chunk) val;
++    if (val instanceof ObjectChunk) {
++      @Retained @Released ObjectChunk ohval = (ObjectChunk) val;
+       try {
+         // TODO OFFHEAP: val may be off-heap PdxInstance
+         val = ohval.getDeserializedValue(getRegion(), this.entry);
+       } finally {
+         ohval.release();
+       }
+     } else if (val instanceof CachedDeserializable) {
+       val = ((CachedDeserializable)val).getDeserializedValue(getRegion(), this.entry);
+     } 
+     valueInList.add(val);
+     return valueInList;
+   }
+   
+   @Override
+   public Object[] toArray() {
+     if(valueInArray == null){
+       valueInArray = new  Object[1];      
+     }   
+     Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
 -    if (val instanceof Chunk) {      
 -      @Retained @Released Chunk ohval = (Chunk) val;
++    if (val instanceof ObjectChunk) {      
++      @Retained @Released ObjectChunk ohval = (ObjectChunk) val;
+       try {
+         // TODO OFFHEAP: val may be off-heap PdxInstance
+         val = ohval.getDeserializedValue(getRegion(), this.entry);
+       } finally {
+         ohval.release();
+       }
+     } else if (val instanceof CachedDeserializable) {
+       val = ((CachedDeserializable)val).getDeserializedValue(getRegion(), this.entry);
+     } 
+     valueInArray[0] = val;
+     return valueInArray;
+   }
+   
+   @Override
+   public SelectResults getValues() {
+     if(values == null){
+       values = new ResultsBag(((GemFireCacheImpl)getRegion().getCache()).getCachePerfStats());
+       values.setElementType(valueType);
+     }
+     values.clear();
+     Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
 -    if (val instanceof Chunk) {
 -      @Retained @Released Chunk ohval = (Chunk) val;
++    if (val instanceof ObjectChunk) {
++      @Retained @Released ObjectChunk ohval = (ObjectChunk) val;
+       try {
+         // TODO OFFHEAP: val may be off-heap PdxInstance
+         val = ohval.getDeserializedValue(getRegion(), this.entry);
+       } finally {
+         ohval.release();
+       }
+     } else if (val instanceof CachedDeserializable) {
+       val = ((CachedDeserializable)val).getDeserializedValue(getRegion(), this.entry);
+     } 
+     values.add(val);
+     return values;
+   }
+   
+   @Override
+   public SelectResults getEntries() {
+     if(entries == null){
+       entries = new ResultsSet();
+       entries.setElementType(TypeUtils.getRegionEntryType(getRegion()));
+     }
+     entries.clear();
+     // return collection of Region.Entry, not (dotless) RegionEntry
+     Region rgn = getRegion();
+     // unwrap until we get the LocalRegion
+     while (!(rgn instanceof LocalRegion)) {
+       rgn = ((QRegion)TypeUtils.checkCast(rgn, QRegion.class)).getRegion();
+     }
+     entries.add(((LocalRegion)rgn).new NonTXEntry(entry));
+     return entries;
+   }
+   
+   @Override
+   public SelectResults entrySet() {
+     return getEntries();
+   }
+   
+   @Override
+   public Set entries(boolean recursive) {
+     return (ResultsSet)getEntries();
+   }
+   
+   @Override
+   public Region.Entry getEntry(Object key) {
+     LocalRegion.NonTXEntry e =(LocalRegion.NonTXEntry)super.getEntry(key);
+     Region.Entry retVal = null;
+     if(e != null &&  this.entry == e.getRegionEntry()) {
+         retVal = e;
+      } 
+     return retVal;
+   }
+   
+   @Override
+   public Iterator iterator() {
+     return values().iterator();
+   }
+   
+   @Override
+   public int size() {
+     return 1;
+   } 
+   
+   @Override
+   public Object[] toArray(Object[] obj) {
+     throw new RuntimeException(LocalizedStrings.DummyQRegion_NOT_YET_IMPLEMENTED.toLocalizedString());
+   }
+   
+   @Override
+   public String toString(){
+     return "DQR "+super.toString();
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
index 0000000,465c038..a30a264
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/HashIndex.java
@@@ -1,0 -1,1573 +1,1573 @@@
+ /*
+  * 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 com.gemstone.gemfire.cache.query.internal.index;
+ 
+ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+ 
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.EntryDestroyedException;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionAttributes;
+ import com.gemstone.gemfire.cache.query.AmbiguousNameException;
+ import com.gemstone.gemfire.cache.query.FunctionDomainException;
+ import com.gemstone.gemfire.cache.query.IndexStatistics;
+ import com.gemstone.gemfire.cache.query.IndexType;
+ import com.gemstone.gemfire.cache.query.NameResolutionException;
+ import com.gemstone.gemfire.cache.query.QueryException;
+ import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+ import com.gemstone.gemfire.cache.query.QueryService;
+ import com.gemstone.gemfire.cache.query.SelectResults;
+ import com.gemstone.gemfire.cache.query.TypeMismatchException;
+ import com.gemstone.gemfire.cache.query.internal.AttributeDescriptor;
+ import com.gemstone.gemfire.cache.query.internal.CompiledComparison;
+ import com.gemstone.gemfire.cache.query.internal.CompiledIteratorDef;
+ import com.gemstone.gemfire.cache.query.internal.CompiledPath;
+ import com.gemstone.gemfire.cache.query.internal.CompiledSortCriterion;
+ import com.gemstone.gemfire.cache.query.internal.CompiledValue;
+ import com.gemstone.gemfire.cache.query.internal.CqEntry;
+ import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
+ import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
+ import com.gemstone.gemfire.cache.query.internal.IndexInfo;
+ import com.gemstone.gemfire.cache.query.internal.QRegion;
+ import com.gemstone.gemfire.cache.query.internal.QueryMonitor;
+ import com.gemstone.gemfire.cache.query.internal.QueryObserver;
+ import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
+ import com.gemstone.gemfire.cache.query.internal.QueryUtils;
+ import com.gemstone.gemfire.cache.query.internal.RuntimeIterator;
+ import com.gemstone.gemfire.cache.query.internal.Support;
+ import com.gemstone.gemfire.cache.query.internal.index.HashIndex.IMQEvaluator.HashIndexComparator;
+ import com.gemstone.gemfire.cache.query.internal.index.IndexStore.IndexStoreEntry;
+ import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
+ import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
+ import com.gemstone.gemfire.cache.query.internal.types.TypeUtils;
+ import com.gemstone.gemfire.cache.query.types.ObjectType;
+ import com.gemstone.gemfire.internal.Assert;
+ import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.RegionEntry;
+ import com.gemstone.gemfire.internal.cache.Token;
+ import com.gemstone.gemfire.internal.cache.persistence.query.CloseableIterator;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.annotations.Released;
+ import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+ import com.gemstone.gemfire.pdx.internal.PdxString;
+ 
+ /**
+  * A HashIndex is an index that can be used for equal and not equals queries It
+  * is created only when called explicitly with createHashIndex It requires the
+  * indexed expression be a path expression and the from clause has only one
+  * iterator. This implies there is only one value in the index for each region
+  * entry.
+  * 
+  * This index does not support the storage of projection attributes.
+  * 
+  * Currently this implementation only supports an index on a region path.
+  * 
+  */
+ public class HashIndex extends AbstractIndex {
+   private static final Logger logger = LogService.getLogger();
+   
+   /**
+    * ThreadLocal for Map for under update RegionEntries=>oldKey (reverse map) if
+    * {@link IndexManager#INPLACE_OBJECT_MODIFICATION} is false.
+    */
+   protected ThreadLocal<Object2ObjectOpenHashMap> entryToOldKeysMap;
+ 
+   /**
+    * Map for valueOf(indexedExpression)=>RegionEntries. SortedMap<Object,
+    * (RegionEntry | List<RegionEntry>)>. Package access for unit tests.
+    */
+   final HashIndexSet entriesSet;
+ 
+   /**
+    * Map for RegionEntries=>value of indexedExpression (reverse map)
+  maintained by the HashIndexSet entrieSet
+    */
+   private ConcurrentMap<Object, Object> entryToValuesMap = null;
+ 
+   private boolean indexOnRegionKeys = false;
+ 
+   private boolean indexOnValues = false;
+ 
+   // used for sorting asc and desc queries
+   private HashIndexComparator comparator;
+ 
+   /**
+    * Create a HashIndex that can be used when executing queries.
+    * 
+    * @param indexName
+    *          the name of this index, used for statistics collection
+    * @param indexedExpression
+    *          the expression to index on, a function dependent on region entries
+    *          individually, limited to a path expression.
+    * @param fromClause
+    *          expression that evaluates to the collection(s) that will be
+    *          queried over, must contain one and only one region path, and only
+    *          one iterator.
+    * @param projectionAttributes
+    *          not used
+    * @param definitions
+    *          the canonicalized definitions
+    */
+   public HashIndex(String indexName, Region region, String fromClause,
+       String indexedExpression, String projectionAttributes,
+       String origFromClause, String origIndexExpr, String[] definitions,
+       IndexStatistics stats) {
+     super(indexName, region, fromClause, indexedExpression,
+         projectionAttributes, origFromClause, origIndexExpr, definitions, stats);
+     RegionAttributes ra = region.getAttributes();
+ 
+ 
+     if (IndexManager.isObjectModificationInplace()) {
+       entryToValuesMap = new ConcurrentHashMap(ra.getInitialCapacity(),
+           ra.getLoadFactor(), ra.getConcurrencyLevel());
+     }
+     else {
+       if (entryToOldKeysMap == null) {
+         entryToOldKeysMap = new ThreadLocal<Object2ObjectOpenHashMap>();
+       }
+     }
+     
+     entriesSet = new HashIndexSet();
+   }
+ 
+   /**
+    * Get the index type
+    * 
+    * @return the type of index
+    */
+   public IndexType getType() {
+     return IndexType.HASH;
+   }
+ 
+   @Override
+   protected boolean isCompactRangeIndex() {
+     return false;
+   }
+ 
+   @Override
+   public void initializeIndex(boolean loadEntries) throws IMQException {
+     long startTime = System.nanoTime();
+     this.evaluator.initializeIndex(loadEntries);
+     this.internalIndexStats.incNumUpdates(((IMQEvaluator) this.evaluator)
+         .getTotalEntriesUpdated());
+     long endTime = System.nanoTime();
+     this.internalIndexStats.incUpdateTime(endTime - startTime);
+   }
+ 
+   void addMapping(RegionEntry entry) throws IMQException {
+     this.evaluator.evaluate(entry, true);
+     this.internalIndexStats.incNumUpdates();
+   }
+ 
+   /**
+    * Add/Updates the index forward and reverse map. If index key for a
+    * RegionEntry is found same as previous key no update is performed.
+    * 
+    * This also updates the {@link IndexStatistics} numKeys and numValues as and
+    * when appropriate. One thing to notice though is no increment in numValues
+    * is performed if old key and new index key are found equal using
+    * {@link Object#equals(Object)}.
+    * 
+    * @param key
+    * @param entry
+    * @throws IMQException
+    */
+   private void basicAddMapping(Object key, RegionEntry entry)
+       throws IMQException {
+ 
+     try {
+       if (DefaultQuery.testHook != null) {
+         DefaultQuery.testHook.doTestHook(3);
+       }
+       Object newKey = TypeUtils.indexKeyFor(key);
+       if (newKey.equals(QueryService.UNDEFINED)) {
+         Object targetObject = getTargetObjectForUpdate(entry);
+         if (Token.isInvalidOrRemoved(targetObject)) {
+           //This should not happen as a token should only be added during gii
+           //meaning we do not have an old mapping
+           // we will continue to remove the old mapping to be safe and log a fine level message
+           Object oldKey = null;
+           if (IndexManager.isObjectModificationInplace() && this.entryToValuesMap.containsKey(entry)){
+             oldKey = this.entryToValuesMap.get(entry);
+           }
+           else if (!IndexManager.isObjectModificationInplace() && this.entryToOldKeysMap != null) {
+             Map oldKeyMap = this.entryToOldKeysMap.get();
+             if (oldKeyMap != null) {
+               oldKey = TypeUtils.indexKeyFor(oldKeyMap.get(entry));
+             }
+           }
+           if (oldKey != null) {
+             if (logger.isDebugEnabled()) { 
+               logger.debug("A removed or invalid token was being added, and we had an old mapping.");
+             }
+             removeFromEntriesSet(oldKey, entry, true);
+           }
+           return;
+         }
+       }
+       
+       // Before adding the entry with new value, remove it from reverse map and
+       // using the oldValue remove entry from the forward map.
+       // Reverse-map is used based on the system property
+       Object oldKey = getOldKey(entry);
+       
+       int indexSlot = this.entriesSet.add(newKey, entry);
+       
+       if (indexSlot >= 0) {
+         // Update the reverse map
+         if (IndexManager.isObjectModificationInplace()) {
+           this.entryToValuesMap.put(entry, newKey);
+         }
+         if (newKey != null && oldKey != null) {
+           removeFromEntriesSet(oldKey, entry, false, indexSlot);
+         }
+         // Update Stats after real addition
+         internalIndexStats.incNumValues(1);
+ 
+       }
+     } catch (TypeMismatchException ex) {
+       throw new IMQException("Could not add object of type "
+           + key.getClass().getName(), ex);
+     }
+   }
+   
+   private Object getOldKey(RegionEntry entry) throws TypeMismatchException {
+     Object oldKey = null;
+     if (IndexManager.isObjectModificationInplace() && this.entryToValuesMap.containsKey(entry)) {
+       oldKey = this.entryToValuesMap.get(entry);
+     } else if (!IndexManager.isObjectModificationInplace() && this.entryToOldKeysMap != null) {
+       Map oldKeyMap = this.entryToOldKeysMap.get();
+       if (oldKeyMap != null) {
+         oldKey = TypeUtils.indexKeyFor(oldKeyMap.get(entry));
+       }
+     }
+     return oldKey;
+   }
+ 
+   /**
+    * @param opCode
+    *          one of OTHER_OP, BEFORE_UPDATE_OP, AFTER_UPDATE_OP.
+    */
+   void removeMapping(RegionEntry entry, int opCode) throws IMQException {
+     // logger.debug("##### In RemoveMapping: entry : "
+     // + entry );
+     if (opCode == BEFORE_UPDATE_OP) {
+       // Either take key from reverse map OR evaluate it using IMQEvaluator.
+       if (!IndexManager.isObjectModificationInplace()) {
+         // It will always contain 1 element only, for this thread.
+         entryToOldKeysMap.set(new Object2ObjectOpenHashMap(1));
+         this.evaluator.evaluate(entry, false);
+       }
+     } else {
+       // Need to reset the thread-local map as many puts and destroys might
+       // happen in same thread.
+       if (entryToOldKeysMap != null) {
+         entryToOldKeysMap.remove();
+       }
+       this.evaluator.evaluate(entry, false);
+       this.internalIndexStats.incNumUpdates();
+     }
+   }
+ 
+   /**
+    * Remove an index entry for a RegionEntry when invalidate/destroy is called
+    * OR new index key is inserted for the RegionEntry. In case of update only
+    * forward map is cleared of old key and NO update is performed on reverse map
+    * as that has already been done during
+    * {@link HashIndex#basicAddMapping(Object, RegionEntry)}.
+    * 
+    * @param key
+    *          - Index key.
+    * @param entry
+    *          RegionEntry for which is being updated by user.
+    * @param updateReverseMap
+    *          true only when RegionEntry is invalidated/destroyed.
+    * @throws IMQException
+    */
+   private void basicRemoveMapping(Object key, RegionEntry entry,
+       boolean updateReverseMap) throws IMQException {
+     // after removal, trim the ArrayList to prevent
+     // too much extra space.
+     // Ideally we would only trim if there is excessive
+     // space, but there is no way to ask an ArrayList what
+     // it's current capacity is..so we trim after every
+     // removal
+     try {
+       Object newKey = TypeUtils.indexKeyFor(key);
+       removeFromEntriesSet(newKey, entry, updateReverseMap);
+     } catch (TypeMismatchException ex) {
+       throw new IMQException("Could not add object of type "
+           + key.getClass().getName(), ex);
+     }
+   }
+   
+   private void removeFromEntriesSet(Object newKey, RegionEntry entry, boolean updateReverseMap) {
+     removeFromEntriesSet(newKey, entry, updateReverseMap, -1);
+   }
+   
+   private void removeFromEntriesSet(Object newKey, RegionEntry entry, boolean updateReverseMap, int ignoreThisSlot) {
+     if (this.entriesSet.remove(newKey, entry, ignoreThisSlot)) {
+       if (updateReverseMap && IndexManager.isObjectModificationInplace()) {
+         entryToValuesMap.remove(entry);
+       }
+       internalIndexStats.incNumValues(-1);
+     }
+   }
+ 
+   // // IndexProtocol interface implementation
+   public boolean clear() throws QueryException {
+     throw new UnsupportedOperationException("Not yet implemented");
+   }
+ 
+   /**
+    * computes the resultset of an equijoin query
+    */
+   public List queryEquijoinCondition(IndexProtocol indx,
+       ExecutionContext context) throws TypeMismatchException,
+       FunctionDomainException, NameResolutionException,
+       QueryInvocationTargetException {
+     // get a read lock when doing a lookup
+     long start = updateIndexUseStats();
+     ((AbstractIndex)indx).updateIndexUseStats();
+     List data = new ArrayList();
+     Iterator  inner = null;
+     try {
+       // We will iterate over each of the valueToEntries Map to obtain the keys
+       Iterator outer = entriesSet.iterator();
+       if(indx instanceof CompactRangeIndex){
+         inner = ((CompactRangeIndex) indx).getIndexStorage().iterator(null);
+       } else{
+         inner = ((RangeIndex) indx).getValueToEntriesMap().entrySet().iterator();
+       }
+       Map.Entry outerEntry = null;
+       Object innerEntry = null;
+       Object outerKey = null;
+       Object innerKey = null;
+       // boolean incrementOuter = true;
+       boolean incrementInner = true;
+     outer: 
+       while (outer.hasNext()) {
+         // if (incrementOuter) {
+         outerEntry = (Map.Entry) outer.next();
+         //}
+         outerKey = outerEntry.getKey();
+       inner:
+         while (!incrementInner || inner.hasNext()) {
+           if (incrementInner) {
+             innerEntry = inner.next();
+             if(innerEntry instanceof IndexStoreEntry){
+               innerKey = ((IndexStoreEntry)innerEntry).getDeserializedKey();
+             } else{
+               innerKey = ((Map.Entry)innerEntry).getKey();
+             }
+           }
+           int compare = ((Comparable) outerKey).compareTo(innerKey);
+           if (compare == 0) {
+             Object innerValue = null;
+             if(innerEntry instanceof IndexStoreEntry){
+               innerValue = ((CompactRangeIndex) indx).getIndexStorage().get(outerKey);
+             } else{
+               innerValue = ((Map.Entry)innerEntry).getValue();
+             }
+             populateListForEquiJoin(data,
+                 outerEntry.getValue(),
+                 innerValue, context, innerKey);            
+             
+             incrementInner = true;
+             continue outer;
+           }
+           else if (compare < 0) {
+             //Asif :The outer key is smaller than the inner key. That means
+             // that we need
+             // to increment the outer loop without moving inner loop.
+             //incrementOuter = true;
+             incrementInner = false;
+             continue outer;
+           }
+           else {
+             //The outer key is greater than inner key , so increment the
+             // inner loop without changing outer
+             incrementInner = true;
+           }
+         }
+         break;
+       }
+       return data;
+     }
+     finally {
+       ((AbstractIndex)indx).updateIndexUseEndStats(start);
+       updateIndexUseEndStats(start);
+       if (inner != null && indx instanceof CompactRangeIndex) {
+         ((CloseableIterator<IndexStoreEntry>) inner).close();
+       }
+     }
+   }
+ 
+   /**
+    * This evaluates the left and right side of a EQUI-JOIN where condition for
+    * which this Index was used. Like, if condition is "p.ID = e.ID",
+    * {@link IndexInfo} will contain Left as p.ID, Right as e.ID and operator as
+    * TOK_EQ. This method will evaluate p.ID OR e.ID based on if it is inner or
+    * outer RegionEntry, and verify the p.ID = e.ID.
+    * 
+    * @param entry
+    * @param context
+    * @param indexInfo
+    * @param keyVal
+    * @return true if entry value and index value are consistent.
+    * @throws FunctionDomainException
+    * @throws TypeMismatchException
+    * @throws NameResolutionException
+    * @throws QueryInvocationTargetException
+    */
+   private boolean verifyInnerAndOuterEntryValues(RegionEntry entry,
+       ExecutionContext context, IndexInfo indexInfo, Object keyVal)
+       throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+     // Verify index key in value.
+     CompactRangeIndex index = (CompactRangeIndex) indexInfo._getIndex();
+     RuntimeIterator runtimeItr = index.getRuntimeIteratorForThisIndex(context, indexInfo);
+     if (runtimeItr != null) {
+       runtimeItr.setCurrent(getTargetObject(entry));
+     }
+     return evaluateEntry(indexInfo, context, keyVal);
+   }
+ 
+   // TODO:Decsribe & test the function
+   /**
+    * @param outerEntries
+    *          is a Set<RegionEntry>
+    * @param innerEntries
+    *          is a Set<RegionEntry>
+    * @param key
+    * @throws QueryInvocationTargetException
+    * @throws NameResolutionException
+    * @throws TypeMismatchException
+    * @throws FunctionDomainException
+    */
+   private void populateListForEquiJoin(List list, Collection outerEntries,
+       Collection innerEntries, ExecutionContext context, Object key)
+       throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+ 
+     Assert.assertTrue((outerEntries != null && innerEntries != null),
+         "OuterEntries or InnerEntries must not be null");
+ 
+     Object values[][] = new Object[2][];
+     int j = 0;
+     Iterator itr = null;
+     while (j < 2) {
+       if (j == 0) {
+         itr = outerEntries.iterator();
+       } else {
+         itr = innerEntries.iterator();
+       }
+       // TODO :Asif Identify appropriate size of the List
+ 
+       // extract the values from the RegionEntries
+       List dummy = new ArrayList();
+       RegionEntry re = null;
+       while (itr.hasNext()) {
+         re = (RegionEntry) itr.next();
+         // Bug#41010: We need to verify if Inner and Outer Entries
+         // are consistent with index key values.
+         boolean ok = true;
+         if (re.isUpdateInProgress()) {
+           IndexInfo[] indexInfo = (IndexInfo[]) context
+               .cacheGet(CompiledValue.INDEX_INFO);
+           IndexInfo indInfo = (j == 0) ? indexInfo[0] : indexInfo[1];
+ 
+           ok = verifyInnerAndOuterEntryValues(re, context, indInfo, key);
+         }
+         if (ok) {
+           dummy.add(getTargetObject(re));
+         }
+       }
+       dummy.toArray(values[j++] = new Object[dummy.size()]);
+     }
+     list.add(values);
+   }
+ 
+   public int getSizeEstimate(Object key, int operator, int matchLevel)
+       throws TypeMismatchException {
+     // Get approx size;
+     int size = 0;
+     long start = updateIndexUseStats(false);
+     try {
+       switch (operator) {
+       case OQLLexerTokenTypes.TOK_EQ: {
+         key = TypeUtils.indexKeyFor(key);
+         size = this.entriesSet.size(key);
+       }
+       break;
+       case OQLLexerTokenTypes.TOK_NE_ALT:
+       case OQLLexerTokenTypes.TOK_NE:
+         size = this.region.size();
+         key = TypeUtils.indexKeyFor(key);
+         size = this.entriesSet.size(key);
+         break;
+       }
+     } finally {
+       updateIndexUseEndStats(start, false);
+     }
+     return size;
+   }
+ 
+   /**
+    * Convert a RegionEntry or THashSet<RegionEntry> to be consistently a
+    * Collection
+    */
+   private Collection regionEntryCollection(Object regionEntries) {
+     if (regionEntries == null) {
+       return null;
+     }
+     if (regionEntries instanceof RegionEntry) {
+       return Collections.singleton(regionEntries);
+     }
+     return (Collection) regionEntries;
+   }
+ 
+   /** Method called while appropriate lock held on index */
+   private void lockedQueryPrivate(Object key, int operator, Collection results,
+       CompiledValue iterOps, RuntimeIterator runtimeItr,
+       ExecutionContext context, Set keysToRemove, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection)
+       throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException {
+     if (keysToRemove == null) {
+       keysToRemove = new HashSet(0);
+     }
+     int limit = -1;
+ 
+     Boolean applyLimit = (Boolean) context
+         .cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX);
+     if (applyLimit != null && applyLimit.booleanValue()) {
+       limit = ((Integer) context.cacheGet(CompiledValue.RESULT_LIMIT))
+           .intValue();
+     }
+ 
+     Boolean orderByClause = (Boolean) context
+         .cacheGet(CompiledValue.CAN_APPLY_ORDER_BY_AT_INDEX);
+     boolean applyOrderBy = false;
+     boolean asc = true;
+     List orderByAttrs = null;
+     boolean multiColOrderBy = false;
+     if (orderByClause != null && orderByClause.booleanValue()) {
+       orderByAttrs = (List) context.cacheGet(CompiledValue.ORDERBY_ATTRIB);
+       CompiledSortCriterion csc = (CompiledSortCriterion) orderByAttrs.get(0);
+       asc = !csc.getCriterion();
+       applyOrderBy = true;
+       multiColOrderBy = orderByAttrs.size() > 1;
+     }
+     evaluate(key, operator, results, iterOps, runtimeItr, context,
+         keysToRemove, projAttrib, intermediateResults, isIntersection, limit,
+         applyOrderBy, orderByAttrs);
+   }
+ 
+   /** Method called while appropriate lock held on index */
+   void lockedQuery(Object lowerBoundKey, int lowerBoundOperator,
+       Object upperBoundKey, int upperBoundOperator, Collection results,
+       Set keysToRemove, ExecutionContext context) throws TypeMismatchException,
+       FunctionDomainException, NameResolutionException,
+       QueryInvocationTargetException {
+     throw new UnsupportedOperationException(
+         "Range grouping for HashIndex condition is not supported");
+ 
+   }
+ 
+   private void evaluate(Object key, int operator, Collection results,
+       CompiledValue iterOps, RuntimeIterator runtimeItr,
+       ExecutionContext context, Set keysToRemove, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection, int limit,
+       boolean applyOrderBy, List orderByAttribs) throws TypeMismatchException,
+       FunctionDomainException, NameResolutionException,
+       QueryInvocationTargetException {
+     boolean multiColOrderBy = false;
+     if (keysToRemove == null) {
+       keysToRemove = new HashSet(0);
+     }
+     key = TypeUtils.indexKeyFor(key);
+     if(key == null) {
+       key = IndexManager.NULL;
+     }
+     boolean asc = true;
+     if (applyOrderBy) {
+       CompiledSortCriterion csc = (CompiledSortCriterion) orderByAttribs.get(0);
+       asc = !csc.getCriterion();
+       multiColOrderBy = orderByAttribs.size() > 1;
+     }
+ 
+     try {
+       long iteratorCreationTime = GemFireCacheImpl.getInstance().cacheTimeMillis();
+       
+       switch (operator) {
+       case OQLLexerTokenTypes.TOK_EQ:
+         assert keysToRemove.isEmpty();
+         addToResultsFromEntries(this.entriesSet.get(key), results, iterOps,
+             runtimeItr, context, projAttrib, intermediateResults,
+             isIntersection, multiColOrderBy ? -1 : limit, keysToRemove, applyOrderBy, asc, iteratorCreationTime);
+         break;
+       case OQLLexerTokenTypes.TOK_NE_ALT:
+       case OQLLexerTokenTypes.TOK_NE: {
+         keysToRemove.add(key);
+         addToResultsFromEntries(this.entriesSet.getAllNotMatching(keysToRemove), results, iterOps,
+             runtimeItr, context, projAttrib, intermediateResults,
+             isIntersection, multiColOrderBy ? -1 : limit, keysToRemove, applyOrderBy, asc, iteratorCreationTime);
+         }
+         break;
+       default:
+         throw new AssertionError("Operator = " + operator);
+       } // end switch
+     } catch (ClassCastException ex) {
+       if (operator == OQLLexerTokenTypes.TOK_EQ) { // result is empty
+         // set
+         return;
+       } else if (operator == OQLLexerTokenTypes.TOK_NE
+           || operator == OQLLexerTokenTypes.TOK_NE_ALT) { // put
+         keysToRemove.add(key);
+         long iteratorCreationTime = GemFireCacheImpl.getInstance().cacheTimeMillis();
+         addToResultsFromEntries(this.entriesSet.getAllNotMatching(keysToRemove), results, iterOps,
+             runtimeItr, context, projAttrib, intermediateResults,
+             isIntersection, multiColOrderBy ? -1 : limit, keysToRemove, applyOrderBy, asc,
+                 iteratorCreationTime);
+       } else { // otherwise throw exception
+         throw new TypeMismatchException("", ex);
+       }
+     }
+   }
+ 
+   @Override
+   void instantiateEvaluator(IndexCreationHelper ich) {
+     this.evaluator = new IMQEvaluator(ich);
+     this.entriesSet.setEvaluator((HashIndex.IMQEvaluator)evaluator);
+     this.comparator = ((IMQEvaluator) evaluator).comparator;
+   }
+ 
+   public ObjectType getResultSetType() {
+     return this.evaluator.getIndexResultSetType();
+   }
+ 
+ 
+   /**
+    * @param entriesIter
+    *          is Iterable<RegionEntry>
+    */
+   private void addToResultsFromEntries(Iterator entriesIter, Collection result,
+       CompiledValue iterOps, RuntimeIterator runtimeItr,
+       ExecutionContext context, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection, int limit, Set keysToRemove, boolean applyOrderBy, boolean asc, long iteratorCreationTime)
+       throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+     QueryObserver observer = QueryObserverHolder.getInstance();
+     if ( result == null
+         || (limit != -1 && result != null && result.size() == limit)) {
+       return;
+     }
+     List orderedKeys = null;
+     List orderedResults = null;
+     if(applyOrderBy) {
+       orderedKeys = new ArrayList();
+       orderedResults = new ArrayList();
+     }
+     int i = 0;
+     while (entriesIter.hasNext()) {
+       // Check if query execution on this thread is canceled.
+       QueryMonitor.isQueryExecutionCanceled();
+       if (IndexManager.testHook != null) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("IndexManager TestHook is set in addToResultsFromEntries.");
+         }
+         IndexManager.testHook.hook(11);
+       }
+       Object obj = entriesIter.next();
+       Object key = null;
+       if (obj != null && obj != HashIndexSet.REMOVED) {
+         RegionEntry re = (RegionEntry) obj;
+         if (applyOrderBy) {
+           key = ((HashIndex.IMQEvaluator)evaluator).evaluateKey(obj);
+           orderedKeys.add(new Object[]{key,i++});
+           addValueToResultSet(re, orderedResults, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, limit, observer, iteratorCreationTime);
+         } else {
+           addValueToResultSet(re, result, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, limit, observer, iteratorCreationTime);
+         }
+       }
+     }
+     if (applyOrderBy) {
+       /*
+        * For orderby queries, 
+        * 1. Store the keys in a list along with the order.
+        * 2. Store the results in another temp list.
+        * 3. Sort the keys. The order will also get sorted.
+        * 4. Fetch the result objects from the temp list according to 
+        *    the sorted orders from the sorted list and add to the result 
+        *    collection.
+        */
+       Collections.sort(orderedKeys, comparator);
+       if (!asc) {
+         Collections.reverse(orderedKeys);
+       }
+       Object[] temp = orderedResults.toArray();
+       List tempResults = new ArrayList(temp.length);
+       for (Object o : orderedKeys) {
+         int index = (Integer) ((Object[])o)[1];
+         tempResults.add(temp[index]);
+       }
+       result.addAll(tempResults);
+     }
+   }
+ 
+   private void addValueToResultSet(RegionEntry re, Collection result,
+       CompiledValue iterOps, RuntimeIterator runtimeItr,
+       ExecutionContext context, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection, int limit,
+       QueryObserver observer, long iteratorCreationTime) throws FunctionDomainException,
+       TypeMismatchException, NameResolutionException,
+       QueryInvocationTargetException {
+     Object value = getTargetObject(re);
+     if (value != null) {
+       boolean ok = true;
+       //If the region entry is currently being updated or it has been modified since starting iteration
+       //we will reevaluate to be sure the value still matches the key
+       if (re.isUpdateInProgress() || IndexManager.needsRecalculation(iteratorCreationTime, re.getLastModified())) {
+         IndexInfo indexInfo = (IndexInfo) context
+             .cacheGet(CompiledValue.INDEX_INFO);
+         if (runtimeItr == null) {
+           runtimeItr = getRuntimeIteratorForThisIndex(context, indexInfo);
+           if (runtimeItr == null) {
+             //could not match index with iterator
+             throw new QueryInvocationTargetException("Query alias's must be used consistently");
+           }
+         }
+         runtimeItr.setCurrent(value);
+         // Verify index key in region entry value.
+         ok = evaluateEntry(indexInfo, context, null);
+       }
+       if (runtimeItr != null) {
+         runtimeItr.setCurrent(value);
+       }
+       if (ok && runtimeItr != null && iterOps != null) {
+         ok = QueryUtils.applyCondition(iterOps, context);
+       }
+       if (ok) {
+         if (context != null && context.isCqQueryContext()) {
+           result.add(new CqEntry(re.getKey(), value));
+         } else {
+           applyProjection(projAttrib, context, result, value,
+               intermediateResults, isIntersection);
+         }
+         if (limit != -1 && result.size() == limit) {
+           observer.limitAppliedAtIndexLevel(this, limit, result);
+           return;
+         }
+       }
+     }
+   }
+   
+   /**
+    * This evaluates the left and right side of a where condition for which this
+    * Index was used. Like, if condition is "ID > 1", {@link IndexInfo} will
+    * contain Left as ID, Right as '1' and operator as TOK_GT. This method will
+    * evaluate ID from region entry value and verify the ID > 1.
+    * 
+    * Note: IndexInfo is created for each query separately based on the condition
+    * being evaluated using the Index.
+    * 
+    * @param indexInfo
+    * @param context
+    * @param keyVal
+    * @return true if RegionEntry value satisfies the where condition (contained
+    *         in IndexInfo).
+    * @throws FunctionDomainException
+    * @throws TypeMismatchException
+    * @throws NameResolutionException
+    * @throws QueryInvocationTargetException
+    */
+   private boolean evaluateEntry(IndexInfo indexInfo, ExecutionContext context,
+       Object keyVal) throws FunctionDomainException, TypeMismatchException,
+       NameResolutionException, QueryInvocationTargetException {
+     CompiledValue path = ((IndexInfo) indexInfo)._path();
+     Object left = path.evaluate(context);
+     CompiledValue key = ((IndexInfo) indexInfo)._key();
+     Object right = null;
+ 
+     // For CompiledUndefined indexInfo has null key.
+     if (keyVal == null && key == null) {
+       if (left == QueryService.UNDEFINED) {
+         return true;
+       } else {
+         return false;
+       }
+     }
+ 
+     if (key != null) {
+       right = key.evaluate(context);
+     } else {
+       right = keyVal;
+     }
+ 
+     int operator = indexInfo._operator();
+     if (left == null && right == null) {
+       return Boolean.TRUE;
+     } else {
+       return ((Boolean) TypeUtils.compare(left, right, operator))
+           .booleanValue();
+     }
+   }
+ 
+   /**
+    * Get the object of interest from the region entry. For now it always gets
+    * the deserialized value.
+    */
+   private Object getTargetObject(RegionEntry entry) {
+     if (this.indexOnValues) {
+       Object o = entry.getValue((LocalRegion) getRegion()); // OFFHEAP: incrc, deserialize, decrc
+       try {
+         if (o == Token.INVALID) {
+           return null;
+         }
+         if (o instanceof CachedDeserializable) {
+           return ((CachedDeserializable) o).getDeserializedForReading();
+         }
+       } catch (EntryDestroyedException ede) {
+         return null;
+       }
+       return o;
+     } else if (this.indexOnRegionKeys) {
+       return entry.getKey();
+     }
+     return ((LocalRegion) getRegion()).new NonTXEntry(entry);
+   }
+   
+   // TODO OFFHEAP: may return PdxInstance
+   private Object getTargetObjectForUpdate(RegionEntry entry) {
+     if (this.indexOnValues) {
+       Object o = entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
+       try {
 -        if (o instanceof Chunk) {
 -          Chunk ohval = (Chunk) o;
++        if (o instanceof ObjectChunk) {
++          ObjectChunk ohval = (ObjectChunk) o;
+           try {
+             o = ohval.getDeserializedForReading();
+           } finally {
+             ohval.release();
+           }
+         } else if (o instanceof CachedDeserializable) {
+           o = ((CachedDeserializable)o).getDeserializedForReading();
+         }
+       } catch (EntryDestroyedException ede) {
+         return Token.INVALID;
+       }
+       return o;
+     } else if (this.indexOnRegionKeys) {
+       return entry.getKey();
+     }
+     return ((LocalRegion) getRegion()).new NonTXEntry(entry);
+   }
+ 
+   void recreateIndexData() throws IMQException {
+     // Mark the data maps to null & call the initialization code of index
+     this.entriesSet.clear();
+     if (IndexManager.isObjectModificationInplace()) {
+       entryToValuesMap.clear();
+     }
+     int numKeys = (int) this.internalIndexStats.getNumberOfKeys();
+     if (numKeys > 0) {
+       this.internalIndexStats.incNumKeys(-numKeys);
+     }
+     int numValues = (int) this.internalIndexStats.getNumberOfValues();
+     if (numValues > 0) {
+       this.internalIndexStats.incNumValues(-numValues);
+     }
+     int updates = (int) this.internalIndexStats.getNumUpdates();
+     if (updates > 0) {
+       this.internalIndexStats.incNumUpdates(updates);
+     }
+     this.initializeIndex(true);
+   }
+ 
+   public String dump() {
+     StringBuffer sb = new StringBuffer(toString()).append(" {\n");
+ //    sb.append("Null Values\n");
+ //    Iterator nI = nullMappedEntries.iterator();
+ //    while (nI.hasNext()) {
+ //      RegionEntry e = (RegionEntry) nI.next();
+ //      Object value = getTargetObject(e);
+ //      sb.append("  RegionEntry.key = ").append(e.getKey());
+ //      sb.append("  Value.type = ").append(value.getClass().getName());
+ //      if (value instanceof Collection) {
+ //        sb.append("  Value.size = ").append(((Collection) value).size());
+ //      }
+ //      sb.append("\n");
+ //    }
+ //    sb.append(" -----------------------------------------------\n");
+ //    sb.append("Undefined Values\n");
+ //    Iterator uI = undefinedMappedEntries.iterator();
+ //    while (uI.hasNext()) {
+ //      RegionEntry e = (RegionEntry) uI.next();
+ //      Object value = getTargetObject(e);
+ //      sb.append("  RegionEntry.key = ").append(e.getKey());
+ //      sb.append("  Value.type = ").append(value.getClass().getName());
+ //      if (value instanceof Collection) {
+ //        sb.append("  Value.size = ").append(((Collection) value).size());
+ //      }
+ //      sb.append("\n");
+ //    }
+     sb.append(" -----------------------------------------------\n");
+     Iterator i1 = this.entriesSet.iterator();
+     while (i1.hasNext()) {
+       Map.Entry indexEntry = (Map.Entry) i1.next();
+       sb.append(" Key = " + indexEntry.getKey()).append("\n");
+       sb.append(" Value Type = ")
+           .append(" " + indexEntry.getValue().getClass().getName())
+           .append("\n");
+       if (indexEntry.getValue() instanceof Collection) {
+         sb.append(" Value Size = ")
+             .append(" " + ((Collection) indexEntry.getValue()).size())
+             .append("\n");
+       } else if (indexEntry.getValue() instanceof RegionEntry) {
+         sb.append(" Value Size = ").append(" " + 1).append("\n");
+       } else {
+         throw new AssertionError("value instance of "
+             + indexEntry.getValue().getClass().getName());
+       }
+       Collection entrySet = regionEntryCollection(indexEntry.getValue());
+       Iterator i2 = entrySet.iterator();
+       while (i2.hasNext()) {
+         RegionEntry e = (RegionEntry) i2.next();
+         Object value = getTargetObject(e);
+         sb.append("  RegionEntry.key = ").append(e.getKey());
+         sb.append("  Value.type = ").append(value.getClass().getName());
+         if (value instanceof Collection) {
+           sb.append("  Value.size = ").append(((Collection) value).size());
+         }
+         sb.append("\n");
+         // sb.append(" Value.type = ").append(value).append("\n");
+       }
+       sb.append(" -----------------------------------------------\n");
+     }
+     sb.append("}// Index ").append(getName()).append(" end");
+     return sb.toString();
+   }
+ 
+   protected InternalIndexStatistics createStats(String indexName) {
+     return new RangeIndexStatistics(indexName);
+   }
+ 
+   class RangeIndexStatistics extends InternalIndexStatistics {
+     private IndexStats vsdStats;
+ 
+     public RangeIndexStatistics(String indexName) {
+       this.vsdStats = new IndexStats(getRegion().getCache().getDistributedSystem(), indexName);
+     }
+ 
+     /**
+      * Return the total number of times this index has been updated
+      */
+     public long getNumUpdates() {
+       return this.vsdStats.getNumUpdates();
+     }
+ 
+     public void incNumValues(int delta) {
+       this.vsdStats.incNumValues(delta);
+     }
+ 
+     public void incNumUpdates() {
+       this.vsdStats.incNumUpdates();
+     }
+ 
+     public void incNumUpdates(int delta) {
+       this.vsdStats.incNumUpdates(delta);
+     }
+ 
+     public void updateNumKeys(long numKeys) {
+       this.vsdStats.updateNumKeys(numKeys);
+     }
+ 
+     public void incNumKeys(long numKeys) {
+       this.vsdStats.incNumKeys(numKeys);
+     }
+ 
+     public void incUpdateTime(long delta) {
+       this.vsdStats.incUpdateTime(delta);
+     }
+ 
+     public void incUpdatesInProgress(int delta) {
+       this.vsdStats.incUpdatesInProgress(delta);
+     }
+ 
+     public void incNumUses() {
+       this.vsdStats.incNumUses();
+     }
+ 
+     public void incUseTime(long delta) {
+       this.vsdStats.incUseTime(delta);
+     }
+ 
+     public void incUsesInProgress(int delta) {
+       this.vsdStats.incUsesInProgress(delta);
+     }
+ 
+     public void incReadLockCount(int delta) {
+       this.vsdStats.incReadLockCount(delta);
+     }
+ 
+     /**
+      * Returns the total amount of time (in nanoseconds) spent updating this
+      * index.
+      */
+     public long getTotalUpdateTime() {
+       return this.vsdStats.getTotalUpdateTime();
+     }
+ 
+     /**
+      * Returns the total number of times this index has been accessed by a
+      * query.
+      */
+     public long getTotalUses() {
+       return this.vsdStats.getTotalUses();
+     }
+ 
+     /**
+      * Returns the number of keys in this index.
+      */
+     public long getNumberOfKeys() {
+       return this.vsdStats.getNumberOfKeys();
+     }
+ 
+     /**
+      * Returns the number of values in this index.
+      */
+     public long getNumberOfValues() {
+       return this.vsdStats.getNumberOfValues();
+     }
+ 
+     /**
+      * Return the number of values for the specified key in this index.
+      */
+     public long getNumberOfValues(Object key) {
+       Object rgnEntries = HashIndex.this.entriesSet.get(key);
+       if (rgnEntries == null) {
+         return 0;
+       }
+       if (rgnEntries instanceof RegionEntry) {
+         return 1;
+       } else {
+         return ((Collection) rgnEntries).size();
+       }
+     }
+ 
+     /**
+      * Return the number of read locks taken on this index
+      */
+     public int getReadLockCount() {
+       return this.vsdStats.getReadLockCount();
+     }
+ 
+     public void close() {
+       this.vsdStats.close();
+     }
+ 
+     public String toString() {
+       StringBuffer sb = new StringBuffer();
+       sb.append("No Keys = ").append(getNumberOfKeys()).append("\n");
+       sb.append("No Values = ").append(getNumberOfValues()).append("\n");
+       sb.append("No Uses = ").append(getTotalUses()).append("\n");
+       sb.append("No Updates = ").append(getNumUpdates()).append("\n");
+       sb.append("Total Update time = ").append(getTotalUpdateTime())
+           .append("\n");
+       return sb.toString();
+     }
+   }
+ 
+   class IMQEvaluator implements IndexedExpressionEvaluator {
+     private Cache cache;
+     private List fromIterators = null;
+     private CompiledValue indexedExpr = null;
+     final private String[] canonicalIterNames;
+     private ObjectType indexResultSetType = null;
+     private Region rgn = null;
+     private Map dependencyGraph = null;
+     final HashIndexComparator comparator = new HashIndexComparator();
+ 
+     /*
+      * The boolean if true indicates that the 0th iterator is on entries
+      * . If the 0th iterator is on collection of Region.Entry objects, then the
+      * RegionEntry object used in Index data objects is obtained directly from
+      * its corresponding Region.Entry object. However if the 0th iterator is not
+      * on entries then the boolean is false. In this case the additional
+      * projection attribute gives us the original value of the iterator while
+      * the Region.Entry object is obtained from 0th iterator. It is possible to
+      * have index being created on a Region Entry itself , instead of a Region.
+      * A Map operator( Compiled Index Operator) used with Region enables, us to
+      * create such indexes. In such case the 0th iterator, even if it represents
+      * a collection of Objects which are not Region.Entry objects, still the
+      * boolean remains true, as the Entry object can be easily obtained from the
+      * 0th iterator. In this case, the additional projection attribute s not
+      * null as it is used to evaluate the Entry object from the 0th iterator.
+      */
+     private boolean isFirstItrOnEntry = false;
+     // Asif: List of modified iterators, not null only when the boolean
+     // isFirstItrOnEntry is false.
+     private List indexInitIterators = null;
+     // The additional Projection attribute representing the value of the
+     // original 0th iterator. If the isFirstItrOnEntry is false, then it is not
+     // null. However if the isFirstItrOnEntry is true and this attribute is not
+     // null, this indicates that the 0th iterator is derived using an individual
+     // entry thru Map operator on the Region.
+     private CompiledValue additionalProj = null;
+     // This is not null iff the boolean isFirstItrOnEntry is false.
+     private CompiledValue modifiedIndexExpr = null;
+     private ObjectType addnlProjType = null;
+     private int initEntriesUpdated = 0;
+     private boolean hasInitOccuredOnce = false;
+     private boolean hasIndxUpdateOccuredOnce = false;
+     private ExecutionContext initContext = null;
+     private int iteratorSize = -1;
+ 
+     /** Creates a new instance of IMQEvaluator */
+     IMQEvaluator(IndexCreationHelper helper) {
+       this.cache = helper.getCache();
+       this.fromIterators = helper.getIterators();
+       this.indexedExpr = helper.getCompiledIndexedExpression();
+       this.canonicalIterNames = ((FunctionalIndexCreationHelper) helper).canonicalizedIteratorNames;
+       this.rgn = helper.getRegion();
+ 
+       // The modified iterators for optmizing Index cxreation
+       isFirstItrOnEntry = ((FunctionalIndexCreationHelper) helper).isFirstIteratorRegionEntry;
+       additionalProj = ((FunctionalIndexCreationHelper) helper).additionalProj;
+       Object params1[] = { new QRegion(rgn, false) };
+       initContext = new ExecutionContext(params1, cache);
+       if (isFirstItrOnEntry) {
+         this.indexInitIterators = this.fromIterators;
+       } else {
+         this.indexInitIterators = ((FunctionalIndexCreationHelper) helper).indexInitIterators;
+         modifiedIndexExpr = ((FunctionalIndexCreationHelper) helper).modifiedIndexExpr;
+         addnlProjType = ((FunctionalIndexCreationHelper) helper).addnlProjType;
+       }
+       this.iteratorSize = this.indexInitIterators.size();
+       if (this.additionalProj instanceof CompiledPath) {
+         String tailId = ((CompiledPath) this.additionalProj).getTailID();
+         if (tailId.equals("key")) {
+           // index on keys
+           indexOnRegionKeys = true;
+         } else if (!isFirstItrOnEntry) {
+           // its not entries, its on value.
+           indexOnValues = true;
+         }
+       }
+     }
+ 
+     public String getIndexedExpression() {
+       return HashIndex.this.getCanonicalizedIndexedExpression();
+     }
+ 
+     public String getProjectionAttributes() {
+       return HashIndex.this.getCanonicalizedProjectionAttributes();
+     }
+ 
+     public String getFromClause() {
+       return HashIndex.this.getCanonicalizedFromClause();
+     }
+ 
+     public void expansion(List expandedResults, Object lowerBoundKey, Object upperBoundKey, int lowerBoundOperator, int upperBoundOperator, Object value) throws IMQException {
+       //no-op
+     }
+     
+     /**
+      * @param add
+      *          true if adding to index, false if removing
+      */
+     public void evaluate(RegionEntry target, boolean add) throws IMQException {
+       assert !target.isInvalid() : "value in RegionEntry should not be INVALID";
+       ExecutionContext context = null;
+       try {
+         context = createExecutionContext(target);
+         doNestedIterations(0, add, context);
+ 
+       } catch (IMQException imqe) {
+         throw imqe;
+       } catch (Exception e) {
+         throw new IMQException(e);
+       } finally {
+         if (context != null) {
+           context.popScope();
+         }
+       }
+     }
+ 
+     /**
+      * This function is used for creating Index data at the start
+      * 
+      */
+     public void initializeIndex(boolean loadEntries) throws IMQException {
+       this.initEntriesUpdated = 0;
+       try {
+         // Asif: Since an index initialization can happen multiple times
+         // for a given region, due to clear operation, we are using harcoded
+         // scope ID of 1 , as otherwise if obtained from ExecutionContext
+         // object, it will get incremented on very index initialization
+         this.initContext.newScope(1);
+         for (int i = 0; i < this.iteratorSize; i++) {
+           CompiledIteratorDef iterDef = (CompiledIteratorDef) this.indexInitIterators
+               .get(i);
+           RuntimeIterator rIter = null;
+           if (!this.hasInitOccuredOnce) {
+             iterDef.computeDependencies(this.initContext);
+             rIter = iterDef.getRuntimeIterator(this.initContext);
+             this.initContext
+                 .addToIndependentRuntimeItrMapForIndexCreation(iterDef);
+           }
+           if (rIter == null) {
+             rIter = iterDef.getRuntimeIterator(this.initContext);
+           }
+           this.initContext.bindIterator(rIter);
+         }
+         this.hasInitOccuredOnce = true;
+         if (this.indexResultSetType == null) {
+           this.indexResultSetType = createIndexResultSetType();
+         }
+         if(loadEntries) {
+           doNestedIterationsForIndexInit(0,
+              this.initContext.getCurrentIterators());
+         }
+       } catch (IMQException imqe) {
+         throw imqe;
+       } catch (Exception e) {
+         throw new IMQException(e);
+       } finally {
+         this.initContext.popScope();
+       }
+     }
+ 
+     private void doNestedIterationsForIndexInit(int level, List runtimeIterators)
+         throws TypeMismatchException, AmbiguousNameException,
+         FunctionDomainException, NameResolutionException,
+         QueryInvocationTargetException, IMQException {
+       if (level == 1) {
+         ++this.initEntriesUpdated;
+       }
+       if (level == this.iteratorSize) {
+         applyProjectionForIndexInit(runtimeIterators);
+       } else {
+         RuntimeIterator rIter = (RuntimeIterator) runtimeIterators.get(level);
+         // System.out.println("Level = "+level+" Iter = "+rIter.getDef());
+         Collection c = rIter.evaluateCollection(this.initContext);
+         if (c == null)
+           return;
+         Iterator cIter = c.iterator();
+         while (cIter.hasNext()) {
+           rIter.setCurrent(cIter.next());
+           doNestedIterationsForIndexInit(level + 1, runtimeIterators);
+         }
+       }
+     }
+ 
+     /*
+      * This function is used to obtain Indxe data at the time of index
+      * creation. Each element of the List is an Object Array of size 3. The 0th
+      * element of Object Array stores the value of Index Expression. The 1st
+      * element of ObjectArray contains the RegionEntry object ( If the booelan
+      * isFirstItrOnEntry is false, then the 0th iterator will give us the
+      * Region.Entry object which can be used to obtain the underlying
+      * RegionEntry object. If the boolean is true & additional projection
+      * attribute is not null, then the Region.Entry object can be obtained by
+      * evaluating the additional projection attribute. If the boolean
+      * isFirstItrOnEntry is tru e& additional projection attribute is null, then
+      * teh 0th iterator itself will evaluate to Region.Entry Object.
+      * 
+      * The 2nd element of Object Array contains the Struct object ( tuple)
+      * created. If the boolean isFirstItrOnEntry is false, then the first
+      * attribute of the Struct object is obtained by evaluating the additional
+      * projection attribute.
+      */
+     private void applyProjectionForIndexInit(List currentRuntimeIters)
+         throws FunctionDomainException, TypeMismatchException,
+         NameResolutionException, QueryInvocationTargetException, IMQException {
+       if (QueryMonitor.isLowMemory()) {
+         throw new IMQException(LocalizedStrings.IndexCreationMsg_CANCELED_DUE_TO_LOW_MEMORY.toLocalizedString());
+       }
+       
+       Object indexKey = null;
+       RegionEntry re = null;
+       indexKey = this.isFirstItrOnEntry ? this.indexedExpr
+           .evaluate(this.initContext) : modifiedIndexExpr
+           .evaluate(this.initContext);
+       if (indexKey == null) {
+         indexKey = IndexManager.NULL;
+       }
+       LocalRegion.NonTXEntry temp = null;
+       if (this.isFirstItrOnEntry && this.additionalProj != null) {
+         temp = (LocalRegion.NonTXEntry) additionalProj
+             .evaluate(this.initContext);
+       } else {
+         temp = (LocalRegion.NonTXEntry) (((RuntimeIterator) currentRuntimeIters
+             .get(0)).evaluate(this.initContext));
+       }
+       re = temp.getRegionEntry();
+       basicAddMapping(indexKey, re);
+ 
+     }
+ 
+     /**
+      * @param add
+      *          true if adding to index, false if removing
+      * @param context
+      */
+     private void doNestedIterations(int level, boolean add,
+         ExecutionContext context) throws TypeMismatchException,
+         AmbiguousNameException, FunctionDomainException,
+         NameResolutionException, QueryInvocationTargetException, IMQException {
+       List iterList = context.getCurrentIterators();
+       if (level == this.iteratorSize) {
+         applyProjection(add, context);
+       } else {
+         RuntimeIterator rIter = (RuntimeIterator) iterList.get(level);
+         // System.out.println("Level = "+level+" Iter = "+rIter.getDef());
+         Collection c = rIter.evaluateCollection(context);
+         if (c == null)
+           return;
+         Iterator cIter = c.iterator();
+         while (cIter.hasNext()) {
+           rIter.setCurrent(cIter.next());
+           doNestedIterations(level + 1, add, context);
+         }
+       }
+     }
+ 
+     /**
+      * @param add
+      *          true if adding, false if removing from index
+      * @param context
+      */
+     private void applyProjection(boolean add, ExecutionContext context)
+         throws FunctionDomainException, TypeMismatchException,
+         NameResolutionException, QueryInvocationTargetException, IMQException {
+       Object indexKey = indexedExpr.evaluate(context);
+       if (indexKey == null) {
+         indexKey = IndexManager.NULL;
+       }
+ 
+       RegionEntry entry = ((DummyQRegion) context.getBindArgument(1))
+           .getEntry();
+       // Get thread local reverse map if available.
+       if (add) {
+         // Add new index entries before removing old ones.
+         basicAddMapping(indexKey, entry);
+         if (entryToOldKeysMap != null) {
+           entryToOldKeysMap.remove();
+         }
+       } else {
+         if (entryToOldKeysMap != null) {
+           Map oldKeyMap = entryToOldKeysMap.get();
+           if (oldKeyMap != null) {
+             oldKeyMap.put(entry, indexKey);
+           }
+           else {
+             basicRemoveMapping(indexKey, entry, true);
+           }
+         }
+         else {
+           basicRemoveMapping(indexKey, entry, true);
+         }
+       }
+     }
+ 
+     // The struct type calculation is modified if the
+     // 0th iterator is modified to make it dependent on Entry
+     private ObjectType createIndexResultSetType() {
+       List currentIterators = this.initContext.getCurrentIterators();
+       int len = currentIterators.size();
+       ObjectType type = null;
+       // String fieldNames[] = new String[len];
+       ObjectType fieldTypes[] = new ObjectType[len];
+       int start = this.isFirstItrOnEntry ? 0 : 1;
+       for (; start < len; start++) {
+         RuntimeIterator iter = (RuntimeIterator) currentIterators.get(start);
+         // fieldNames[start] = iter.getInternalId();
+         fieldTypes[start] = iter.getElementType();
+       }
+       if (!this.isFirstItrOnEntry) {
+         // fieldNames[0] = "iter1";
+         fieldTypes[0] = addnlProjType;
+       }
+       type = (len == 1) ? fieldTypes[0] : new StructTypeImpl(
+           this.canonicalIterNames, fieldTypes);
+       return type;
+     }
+ 
+     int getTotalEntriesUpdated() {
+       return this.initEntriesUpdated;
+     }
+ 
+     public ObjectType getIndexResultSetType() {
+       return this.indexResultSetType;
+     }
+ 
+     public List getAllDependentIterators() {
+       return fromIterators;
+     }
+ 
+     private ExecutionContext createExecutionContext(RegionEntry target) {
+       DummyQRegion dQRegion = new DummyQRegion(rgn);
+       dQRegion.setEntry(target);
+       Object params[] = { dQRegion };
+       ExecutionContext context = new ExecutionContext(params, this.cache);
+       context.newScope(IndexCreationHelper.INDEX_QUERY_SCOPE_ID);
+       try {
+         if (this.dependencyGraph != null) {
+           context.setDependencyGraph(dependencyGraph);
+         }
+         for (int i = 0; i < this.iteratorSize; i++) {
+           CompiledIteratorDef iterDef = (CompiledIteratorDef) fromIterators
+               .get(i);
+           // We are re-using the same ExecutionContext on every evaluate -- this
+           // is not how ExecutionContext was intended to be used.
+           // Asif: Compute the dependency only once. The call to methods of this
+           // class are thread safe as for update lock on Index is taken .
+           if (this.dependencyGraph == null) {
+             iterDef.computeDependencies(context);
+           }
+           RuntimeIterator rIter = iterDef.getRuntimeIterator(context);
+           context.addToIndependentRuntimeItrMapForIndexCreation(iterDef);
+           context.bindIterator(rIter);
+         }
+         // Save the dependency graph for future updates.
+         if (dependencyGraph == null) {
+           dependencyGraph = context.getDependencyGraph();
+         }
+ 
+         Support
+             .Assert(
+                 this.indexResultSetType != null,
+                 "IMQEvaluator::evaluate:The StrcutType should have been initialized during index creation");
+       } catch (Exception e) {
+         e.printStackTrace(System.out);
+         throw new Error("Unable to reevaluate, this should not happen");
+       } finally {
+ 
+       }
+       return context;
+     }
+ 
+     public Object evaluateKey(Object object) {
+       Object value = object;
+       
+       ExecutionContext newContext = null;
+ 
+       if (object instanceof RegionEntry) {
+         RegionEntry regionEntry = (RegionEntry) object;
+         newContext = createExecutionContext(regionEntry);
+         value = getTargetObjectForUpdate(regionEntry);
+       }
+ 
+       // context we use is the update context, from IMQEvaluator
+       List iterators = newContext.getCurrentIterators();
+       RuntimeIterator itr = (RuntimeIterator) iterators.get(0);
+       itr.setCurrent(value);
+ 
+       Object key = null;
+       try {
+         key = this.indexedExpr.evaluate(newContext);
+       } catch (Exception e) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("Could not reevaluate key for hash index");
+         }
+       }
+       
+       if (key == null) {
+         key = IndexManager.NULL;
+       }
+       return key;
+     }
+ 
+     class HashIndexComparator implements Comparator {
+       public int compare(Object arg0, Object arg1) {
+         //This comparator is used to sort results from the hash index
+         //However some values may have been updated since being added to the result set.
+         //In these cases UNDEFINED values could be present.  So we 
+         //don't really care how UNDEFINED is sorted, in the end, this doesn't really matter anyways.
+         //We check to see if an update was in progress.  If so (and is the way these turn to undefined),
+         //the value is reevaluated and removed from the result set if it does not match the 
+         //search criteria.  This occurs in addToResultsFromEntries()
+         Object key0 = ((Object[])arg0)[0];
+         Object key1 = ((Object[])arg1)[0];
+       
+         Comparable comp0 = (Comparable) key0;
+         Comparable comp1 = (Comparable) key1;
+         return comp0.compareTo(comp1);
+       }
+     }
+ 
+   }
+ 
+   void lockedQuery(Object key, int operator, Collection results,
+       CompiledValue iterOps, RuntimeIterator indpndntItr,
+       ExecutionContext context, List projAttrib,
+       SelectResults intermediateResults, boolean isIntersection)
+       throws TypeMismatchException, FunctionDomainException,
+       NameResolutionException, QueryInvocationTargetException {
+     this.lockedQueryPrivate(key, operator, results, iterOps, indpndntItr,
+         context, null, projAttrib, intermediateResults, isIntersection);
+   }
+ 
+   void lockedQuery(Object key, int operator, Collection results,
+       Set keysToRemove, ExecutionContext context) throws TypeMismatchException,
+       FunctionDomainException, NameResolutionException,
+       QueryInvocationTargetException {
+     this.lockedQueryPrivate(key, operator, results, null, null, context,
+         keysToRemove, null, null, true);
+   }
+ 
+   @Override
+   void addMapping(Object key, Object value, RegionEntry entry)
+       throws IMQException {
+     // TODO Auto-generated method stub
+ 
+   }
+ 
+   @Override
+   void saveMapping(Object key, Object value, RegionEntry entry)
+       throws IMQException {
+     // TODO Auto-generated method stub
+   }
+   
+   public boolean isEmpty() {
+     return entriesSet.isEmpty();
+   }
+   
+ //  public String printAll() {
+ //    return this.entriesSet.printAll();
+ //  }
+ }


[019/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java
index 9bdf56c,0000000..5fa4fc4
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/CacheServerSSLConnectionDUnitTest.java
@@@ -1,424 -1,0 +1,424 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.IOException;
 +import java.io.PrintWriter;
 +import java.io.StringWriter;
 +import java.util.Properties;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.security.AuthenticationRequiredException;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.util.test.TestUtil;
 +
 +/**
 + * Tests cacheserver ssl support added. See https://svn.gemstone.com/trac/gemfire/ticket/48995 for details
 + * @author tushark
 + *
 + */
 +public class CacheServerSSLConnectionDUnitTest extends DistributedTestCase {
 +  
 +  private static final long serialVersionUID = 1L;
 +  private Cache cache;
 +  private CacheServer cacheServer;
 +  private ClientCache clientCache;
 +  private int cacheServerPort;
 +  private String hostName;
 +  
 +  private static final String TRUSTED_STORE = "trusted.keystore";
 +  private static final String CLIENT_KEY_STORE = "client.keystore";
 +  private static final String CLIENT_TRUST_STORE = "client.truststore";
 +  private static final String SERVER_KEY_STORE = "cacheserver.keystore";
 +  private static final String SERVER_TRUST_STORE = "cacheserver.truststore";
 +  
 +  private static CacheServerSSLConnectionDUnitTest instance = new CacheServerSSLConnectionDUnitTest("CacheServerSSLConnectionDUnit");
 +  
 +  
 +  public void setUp() throws Exception {
 +    disconnectAllFromDS();
 +    super.setUp();
 +  }
 +
 +  public CacheServerSSLConnectionDUnitTest(String name) {
 +    super(name);
 +  }  
 +
 +  public Cache createCache(Properties props) throws Exception
 +  {
 +    props.setProperty("mcast-port", "0");
 +    props.setProperty("locators", "");
 +    cache = new CacheFactory(props).create();
 +    if (cache == null) {
 +      throw new Exception("CacheFactory.create() returned null ");
 +    }
 +    return cache;
 +  }
 +  
 +  private void createServer() throws IOException{
 +    cacheServerPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +    cacheServer = cache.addCacheServer();
 +    cacheServer.setPort(cacheServerPort);
 +    cacheServer.start();
 +    hostName = cacheServer.getHostnameForClients();
 +  }
 +  
 +  public int getCacheServerPort(){
 +    return cacheServerPort;
 +  }
 +  
 +  public String getCacheServerHost(){
 +    return hostName;
 +  }
 +  
 +  public void stopCacheServer(){
 +    this.cacheServer.stop();
 +  }
 +  
 +  
 +  @SuppressWarnings("rawtypes")
 +  public void setUpServerVM(boolean cacheServerSslenabled) throws Exception {
 +    Properties gemFireProps = new Properties();
 +
 +    String cacheServerSslprotocols = "any";
 +    String cacheServerSslciphers = "any";
 +    boolean cacheServerSslRequireAuth = true;
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_ENABLED_NAME,
 +        String.valueOf(cacheServerSslenabled));
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_PROTOCOLS_NAME,
 +        cacheServerSslprotocols);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_CIPHERS_NAME,
 +        cacheServerSslciphers);
 +    gemFireProps.put(
 +        DistributionConfig.SERVER_SSL_REQUIRE_AUTHENTICATION_NAME,
 +        String.valueOf(cacheServerSslRequireAuth));
 +
 +    String keyStore = TestUtil.getResourcePath(CacheServerSSLConnectionDUnitTest.class, SERVER_KEY_STORE);
 +    String trustStore = TestUtil.getResourcePath(CacheServerSSLConnectionDUnitTest.class, SERVER_TRUST_STORE);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_TYPE_NAME, "jks");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_NAME, keyStore);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_PASSWORD_NAME, "password");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_NAME, trustStore);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_PASSWORD_NAME, "password");
 +    
 +    StringWriter sw = new StringWriter();
 +    PrintWriter writer = new PrintWriter(sw);
 +    gemFireProps.list(writer);
 +    System.out.println("Starting cacheserver ds with following properties \n" + sw);
 +    createCache(gemFireProps);
 +    
 +    RegionFactory factory = cache.createRegionFactory(RegionShortcut.REPLICATE);
 +    Region r = factory.create("serverRegion");
 +    r.put("serverkey", "servervalue");
 +  }
 +  
 +  public void setUpClientVM(String host, int port,
 +      boolean cacheServerSslenabled, boolean cacheServerSslRequireAuth,
 +      String keyStore, String trustStore, boolean subscription) {
 +
 +    Properties gemFireProps = new Properties();
 +
 +    String cacheServerSslprotocols = "any";
 +    String cacheServerSslciphers = "any";
 +
 +    String keyStorePath = TestUtil.getResourcePath(CacheServerSSLConnectionDUnitTest.class, keyStore);
 +    String trustStorePath = TestUtil.getResourcePath(CacheServerSSLConnectionDUnitTest.class, trustStore);
 +    //using new server-ssl-* properties
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_ENABLED_NAME,
 +        String.valueOf(cacheServerSslenabled));
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_PROTOCOLS_NAME,
 +        cacheServerSslprotocols);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_CIPHERS_NAME,
 +        cacheServerSslciphers);
 +    gemFireProps.put(
 +        DistributionConfig.SERVER_SSL_REQUIRE_AUTHENTICATION_NAME,
 +        String.valueOf(cacheServerSslRequireAuth));
 +
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_TYPE_NAME, "jks");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_NAME, keyStorePath);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_PASSWORD_NAME, "password");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_NAME, trustStorePath);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_PASSWORD_NAME, "password");
 +
 +    StringWriter sw = new StringWriter();
 +    PrintWriter writer = new PrintWriter(sw);
 +    gemFireProps.list(writer);
 +    System.out.println("Starting client ds with following properties \n" + sw.getBuffer());
 +    
 +    ClientCacheFactory clientCacheFactory = new ClientCacheFactory(gemFireProps);
 +    clientCacheFactory.setPoolSubscriptionEnabled(subscription).addPoolServer(host, port);
 +    clientCache = clientCacheFactory.create();
 +    
 +    ClientRegionFactory<String,String> regionFactory = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY);
 +    Region<String, String> region = regionFactory.create("serverRegion");  
 +    assertNotNull(region);
 +  }
 +  
 +  public void doClientRegionTest(){
 +    Region<String, String> region = clientCache.getRegion("serverRegion");
 +    assertEquals("servervalue",region.get("serverkey"));
 +    region.put("clientkey", "clientvalue");
 +    assertEquals("clientvalue",region.get("clientkey"));
 +  }
 +  
 +  public void doServerRegionTest(){
 +    Region<String, String> region = cache.getRegion("serverRegion");
 +    assertEquals("servervalue",region.get("serverkey"));    
 +    assertEquals("clientvalue",region.get("clientkey"));
 +  }
 +  
 +  
 +  public static void setUpServerVMTask(boolean cacheServerSslenabled) throws Exception{
 +    instance.setUpServerVM(cacheServerSslenabled);
 +  }
 +  
 +  public static void createServerTask() throws Exception {
 +    instance.createServer();
 +  }
 +  
 +  public static void setUpClientVMTask(String host, int port,
 +      boolean cacheServerSslenabled, boolean cacheServerSslRequireAuth, String keyStore, String trustStore)
 +      throws Exception {
 +    instance.setUpClientVM(host, port, cacheServerSslenabled,
 +        cacheServerSslRequireAuth, keyStore, trustStore, true);
 +  }
 +  public static void setUpClientVMTaskNoSubscription(String host, int port,
 +      boolean cacheServerSslenabled, boolean cacheServerSslRequireAuth, String keyStore, String trustStore)
 +      throws Exception {
 +    instance.setUpClientVM(host, port, cacheServerSslenabled,
 +        cacheServerSslRequireAuth, keyStore, trustStore, false);
 +  }
 +  
 +  public static void doClientRegionTestTask() {
 +    instance.doClientRegionTest();
 +  }
 +  
 +  public static void doServerRegionTestTask() {
 +    instance.doServerRegionTest();
 +  }
 +  
 +  public static Object[] getCacheServerEndPointTask() {
 +    Object[] array = new Object[2];
 +    array[0] = instance.getCacheServerHost();
 +    array[1] = instance.getCacheServerPort();
 +    return array;
 +  }
 +  
 +  public static void closeCacheTask(){
 +    if (instance != null && instance.cache != null) {
 +      instance.cache.close();
 +    }
 +  }
 +  
 +  public static void closeClientCacheTask(){
 +    if (instance != null && instance.clientCache != null) {
 +      instance.clientCache.close();
 +    }
 +  }
 +  
 +  public void testCacheServerSSL() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
 +    
 +    boolean cacheServerSslenabled = true;
 +    boolean cacheClientSslenabled = true;
 +    boolean cacheClientSslRequireAuth = true;
 +    
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpServerVMTask", new Object[]{cacheServerSslenabled});
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "createServerTask");
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled));
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask());
 +    
-     Object array[] = (Object[])serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "getCacheServerEndPointTask"); 
++    Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); 
 +    String hostName = (String)array[0];
 +    int port = (Integer) array[1];
 +    Object params[] = new Object[6];
 +    params[0] = hostName;
 +    params[1] = port;
 +    params[2] = cacheClientSslenabled;
 +    params[3] = cacheClientSslRequireAuth;
 +    params[4] = CLIENT_KEY_STORE;
 +    params[5] = CLIENT_TRUST_STORE;
 +    //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port);
 +    clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTask", params);
-     clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doClientRegionTestTask");
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doServerRegionTestTask");
++    clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask());
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask());
 +    
 +  }
 +  
 +  
 +  public void testNonSSLClient() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
 +    
 +    boolean cacheServerSslenabled = true;
 +    boolean cacheClientSslenabled = false;
 +    boolean cacheClientSslRequireAuth = true;
 +    
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpServerVMTask", new Object[]{cacheServerSslenabled});
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "createServerTask");
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled));
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask());
 +    
-     Object array[] = (Object[])serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "getCacheServerEndPointTask"); 
++    Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); 
 +    String hostName = (String)array[0];
 +    int port = (Integer) array[1];
 +    Object params[] = new Object[6];
 +    params[0] = hostName;
 +    params[1] = port;
 +    params[2] = cacheClientSslenabled;
 +    params[3] = cacheClientSslRequireAuth;
 +    params[4] = TRUSTED_STORE;
 +    params[5] = TRUSTED_STORE;
 +    IgnoredException expect = IgnoredException.addIgnoredException("javax.net.ssl.SSLException", serverVM);
 +    IgnoredException expect2 = IgnoredException.addIgnoredException("IOException", serverVM);
 +    try{
 +      //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port);    
 +      clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTaskNoSubscription", params);
-       clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doClientRegionTestTask");
-       serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doServerRegionTestTask");
++      clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask());
++      serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask());
 +      fail("Test should fail as non-ssl client is trying to connect to ssl configured server");
 +    } catch (Exception rmiException) {
 +      Throwable e = rmiException.getCause();
 +      //getLogWriter().info("ExceptionCause at clientVM " + e);
 +      if (e instanceof com.gemstone.gemfire.cache.client.ServerOperationException) {
 +        Throwable t = e.getCause();
 +        //getLogWriter().info("Cause is " + t);
 +        assertTrue(t instanceof com.gemstone.gemfire.security.AuthenticationRequiredException);
 +      } else {
 +        //getLogWriter().error("Unexpected exception ", e);
 +        fail("Unexpected Exception: " + e + " expected: "
 +            + AuthenticationRequiredException.class);
 +      }
 +    } finally {
 +      expect.remove();
 +      expect2.remove();
 +    }
 +  }
 +  
 +  public void testSSLClientWithNoAuth() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
 +
 +    boolean cacheServerSslenabled = true;
 +    boolean cacheClientSslenabled = true;
 +    boolean cacheClientSslRequireAuth = false;
 +
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpServerVMTask", new Object[]{cacheServerSslenabled});
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "createServerTask");
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled));
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask());
 +
-     Object array[] = (Object[])serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "getCacheServerEndPointTask"); 
++    Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); 
 +    String hostName = (String)array[0];
 +    int port = (Integer) array[1];
 +    Object params[] = new Object[6];
 +    params[0] = hostName;
 +    params[1] = port;
 +    params[2] = cacheClientSslenabled;
 +    params[3] = cacheClientSslRequireAuth;
 +    params[4] = CLIENT_KEY_STORE;
 +    params[5] = CLIENT_TRUST_STORE;
 +    //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port);
 +    try {
 +      clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTask", params);
-       clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doClientRegionTestTask");
-       serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doServerRegionTestTask");
++      clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask());
++      serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask());
 +    } catch (Exception rmiException) {
 +      Throwable e = rmiException.getCause();
 +      //getLogWriter().info("ExceptionCause at clientVM " + e);
 +      if (e instanceof com.gemstone.gemfire.cache.client.ServerOperationException) {
 +        Throwable t = e.getCause();
 +        //getLogWriter().info("Cause is " + t);
 +        assertTrue(t instanceof com.gemstone.gemfire.security.AuthenticationRequiredException);
 +      } else {
 +        //getLogWriter().error("Unexpected exception ", e);
 +        fail("Unexpected Exception...expected "
 +            + AuthenticationRequiredException.class);
 +      }
 +    }
 +  }
 +  
 +  public void testSSLClientWithNonSSLServer() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
 +    
 +    boolean cacheServerSslenabled = false;
 +    boolean cacheClientSslenabled = true;
 +    boolean cacheClientSslRequireAuth = true;
 +    
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpServerVMTask", new Object[]{cacheServerSslenabled});
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "createServerTask");
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.setUpServerVMTask(cacheServerSslenabled));
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.createServerTask());
 +    
-     Object array[] = (Object[])serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "getCacheServerEndPointTask"); 
++    Object array[] = (Object[])serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.getCacheServerEndPointTask()); 
 +    String hostName = (String)array[0];
 +    int port = (Integer) array[1];
 +    Object params[] = new Object[6];
 +    params[0] = hostName;
 +    params[1] = port;
 +    params[2] = cacheClientSslenabled;
 +    params[3] = cacheClientSslRequireAuth;
 +    params[4] = TRUSTED_STORE;
 +    params[5] = TRUSTED_STORE;
 +    IgnoredException expect = IgnoredException.addIgnoredException("javax.net.ssl.SSLHandshakeException", serverVM);
 +    try{
 +      //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port);    
 +      clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "setUpClientVMTask", params);
-       clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doClientRegionTestTask");
-       serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "doServerRegionTestTask");
++      clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doClientRegionTestTask());
++      serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.doServerRegionTestTask());
 +      fail("Test should fail as ssl client with ssl enabled is trying to connect to server with ssl disabled");
 +    }catch (Exception rmiException) {
 +      
 +      //ignore
 +      
 +      /*Throwable e = rmiException.getCause();
 +      getLogWriter().info("ExceptionCause at clientVM " + e);
 +      if (e instanceof com.gemstone.gemfire.cache.client.ServerOperationException) {
 +        Throwable t = e.getCause();
 +        getLogWriter().info("Cause is " + t);
 +        assertTrue(t instanceof com.gemstone.gemfire.security.AuthenticationRequiredException);
 +      } else {
 +        getLogWriter().error("Unexpected exception ", e);
 +        fail("Unexpected Exception...expected "
 +            + AuthenticationRequiredException.class);
 +      }*/
 +    } finally {
 +      expect.remove();
 +    }
 +  }
 +  
 +  @Override
 +  protected final void preTearDown() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
-     clientVM.invoke(CacheServerSSLConnectionDUnitTest.class, "closeClientCacheTask");
-     serverVM.invoke(CacheServerSSLConnectionDUnitTest.class, "closeCacheTask");
++    clientVM.invoke(() -> CacheServerSSLConnectionDUnitTest.closeClientCacheTask());
++    serverVM.invoke(() -> CacheServerSSLConnectionDUnitTest.closeCacheTask());
 +  }
 +}
 +

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorLoadBalancingDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorLoadBalancingDUnitTest.java
index 3c6a980,0000000..6f4d404
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorLoadBalancingDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorLoadBalancingDUnitTest.java
@@@ -1,499 -1,0 +1,502 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.IOException;
 +import java.io.Serializable;
 +import java.net.InetAddress;
 +import java.net.UnknownHostException;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +
 +import org.junit.Assert;
 +
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.client.internal.locator.ClientConnectionRequest;
 +import com.gemstone.gemfire.cache.client.internal.locator.ClientConnectionResponse;
 +import com.gemstone.gemfire.cache.client.internal.locator.QueueConnectionRequest;
 +import com.gemstone.gemfire.cache.client.internal.locator.QueueConnectionResponse;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache.server.ServerLoad;
 +import com.gemstone.gemfire.cache.server.ServerLoadProbeAdapter;
 +import com.gemstone.gemfire.cache.server.ServerMetrics;
 +import com.gemstone.gemfire.distributed.Locator;
 +import com.gemstone.gemfire.distributed.internal.InternalLocator;
 +import com.gemstone.gemfire.distributed.internal.ServerLocation;
 +import com.gemstone.gemfire.distributed.internal.ServerLocator;
 +import com.gemstone.gemfire.distributed.internal.tcpserver.TcpClient;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 +import com.gemstone.gemfire.internal.cache.PoolFactoryImpl;
 +import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 +import com.gemstone.gemfire.internal.logging.LocalLogWriter;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnableIF;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +
 +/**
 + * @author dsmith
 + *
 + */
 +public class LocatorLoadBalancingDUnitTest extends LocatorTestBase {
 +  
 +  /**
 +   * The number of connections that we can be off by in the balancing tests
 +   * We need this little fudge factor, because the locator can receive an update
 +   * from the bridge server after it has made incremented its counter for a client
 +   * connection, but the client hasn't connected yet. This wipes out the estimation
 +   * on the locator.  This means that we may be slighly off in our balance.
 +   * 
 +   * TODO grid fix this hole in the locator.
 +   */
 +  private static final int ALLOWABLE_ERROR_IN_COUNT = 1;
 +  protected static final long MAX_WAIT = 60000;
 +
 +  public LocatorLoadBalancingDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  /**
 +   * Test the locator discovers a bridge server and is initialized with 
 +   * the correct load for that bridge server.
 +   */
 +  public void testDiscovery() {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +//    vm0.invoke(new SerializableRunnable() {
 +//      public void run() {
 +//        System.setProperty("gemfire.DistributionAdvisor.VERBOSE", "true");
 +//      }
 +//    });
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    
 +    String locators = getLocatorString(host, locatorPort);
 +    
 +    int serverPort = startBridgeServerInVM(vm1, new String[] {"a", "b"},  locators);
 +    
 +    ServerLoad expectedLoad = new ServerLoad(0f, 1 / 800.0f, 0f, 1f);
 +    ServerLocation expectedLocation = new ServerLocation(NetworkUtils.getServerHostName(vm0
 +        .getHost()), serverPort);
 +    Map expected = new HashMap();
 +    expected.put(expectedLocation, expectedLoad);
 +    
 +    checkLocatorLoad(vm0, expected);
 +    
 +    int serverPort2 = startBridgeServerInVM(vm2, new String[] {"a", "b"},  locators);
 +    
 +    ServerLocation expectedLocation2 = new ServerLocation(NetworkUtils.getServerHostName(vm0
 +        .getHost()), serverPort2);
 +    
 +    expected.put(expectedLocation2, expectedLoad);
 +    checkLocatorLoad(vm0, expected);
 +  }
 +  
 +  /**
 +   * Test that the locator will properly estimate the load for servers when
 +   * it receives connection requests. 
 +   */
 +  public void testEstimation() throws UnknownHostException, IOException, ClassNotFoundException {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    String locators = getLocatorString(host, locatorPort);
 +    
 +    int serverPort = startBridgeServerInVM(vm1, new String[] {"a", "b"},  locators);
 +    
 +    ServerLoad expectedLoad = new ServerLoad(2/800f, 1 / 800.0f, 0f, 1f);
 +    ServerLocation expectedLocation = new ServerLocation(NetworkUtils.getServerHostName(host), serverPort);
 +    Map expected = new HashMap();
 +    expected.put(expectedLocation, expectedLoad);
 +    
 +    ClientConnectionResponse response;
 +    response = (ClientConnectionResponse) TcpClient.requestToServer(InetAddress
 +        .getByName(NetworkUtils.getServerHostName(host)), locatorPort,
 +        new ClientConnectionRequest(Collections.EMPTY_SET, null), 10000);
 +    Assert.assertEquals(expectedLocation, response.getServer());
 +    
 +    response = (ClientConnectionResponse) TcpClient.requestToServer(InetAddress
 +        .getByName(NetworkUtils.getServerHostName(host)), locatorPort,
 +        new ClientConnectionRequest(Collections.EMPTY_SET, null), 10000, true);
 +    Assert.assertEquals(expectedLocation, response.getServer());
 +    
 +    //we expect that the connection load load will be 2 * the loadPerConnection
 +    checkLocatorLoad(vm0, expected);
 +    
 +    QueueConnectionResponse response2;
 +    response2 = (QueueConnectionResponse) TcpClient.requestToServer(InetAddress
 +        .getByName(NetworkUtils.getServerHostName(host)), locatorPort,
 +        new QueueConnectionRequest(null, 2,
 +            Collections.EMPTY_SET, null, false), 10000, true);
 +    Assert.assertEquals(Collections.singletonList(expectedLocation), response2.getServers());
 +    
 +    response2 = (QueueConnectionResponse) TcpClient
 +        .requestToServer(InetAddress.getByName(NetworkUtils.getServerHostName(host)),
 +            locatorPort, new QueueConnectionRequest(null, 5, Collections.EMPTY_SET, null,
 +                false), 10000, true);
 +    
 +    Assert.assertEquals(Collections.singletonList(expectedLocation), response2.getServers());
 +
 +    //we expect that the queue load will increase by 2
 +    expectedLoad.setSubscriptionConnectionLoad(2f);
 +    checkLocatorLoad(vm0, expected);
 +  }
 +  
 +  /**
 +   * Test to make sure the bridge servers communicate
 +   * their updated load to the controller when the load
 +   * on the bridge server changes.
++   * @throws Exception 
 +   */
-   public void testLoadMessaging() {
++  public void testLoadMessaging() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    String locators = getLocatorString(host, locatorPort);
 +    
 +    final int serverPort = startBridgeServerInVM(vm1, new String[] {"a", "b"},  locators);
 +    
 +    //We expect 0 load
 +    Map expected = new HashMap();
 +    ServerLocation expectedLocation = new ServerLocation(NetworkUtils.getServerHostName(host), serverPort);
 +    ServerLoad expectedLoad = new ServerLoad(0f, 1 / 800.0f, 0f, 1f);
 +    expected.put(expectedLocation, expectedLoad);
 +    checkLocatorLoad(vm0, expected);
 +    
 +    PoolFactoryImpl pf = new PoolFactoryImpl(null);
 +    pf.addServer(NetworkUtils.getServerHostName(host), serverPort);
 +    pf.setMinConnections(8);
 +    pf.setMaxConnections(8);
 +    pf.setSubscriptionEnabled(true);
 +    startBridgeClientInVM(vm2, pf.getPoolAttributes(), new String[] {REGION_NAME});
 +    
 +    //We expect 8 client to server connections. The queue requires
 +    //an additional client to server connection, but that shouldn't show up here.
 +    expectedLoad = new ServerLoad(8/800f, 1 / 800.0f, 1f, 1f);
 +    expected.put(expectedLocation, expectedLoad);
 +    
 +    
 +    checkLocatorLoad(vm0, expected);
 +    
 +    stopBridgeMemberVM(vm2);
 +    
 +    //Now we expect 0 load
 +    expectedLoad = new ServerLoad(0f, 1 / 800.0f, 0f, 1f);
 +    expected.put(expectedLocation, expectedLoad);
 +    checkLocatorLoad(vm0, expected);
 +  }
 +  
 +  /**
 +   * Test to make sure that the locator
 +   * balancing load between two servers.
++   * @throws Exception 
 +   */
-   public void testBalancing() {
++  public void testBalancing() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    String locators = getLocatorString(host, locatorPort);
 +    
 +    startBridgeServerInVM(vm1, new String[] {"a", "b"},  locators);
 +    startBridgeServerInVM(vm2, new String[] {"a", "b"},  locators);
 +    
 +    PoolFactoryImpl pf = new PoolFactoryImpl(null);
 +    pf.addLocator(NetworkUtils.getServerHostName(host), locatorPort);
 +    pf.setMinConnections(80);
 +    pf.setMaxConnections(80);
 +    pf.setSubscriptionEnabled(false);
 +    pf.setIdleTimeout(-1);
 +    startBridgeClientInVM(vm3, pf.getPoolAttributes(), new String[] {REGION_NAME});
 +    
 +    waitForPrefilledConnections(vm3, 80);
 +    
 +    checkConnectionCount(vm1, 40);
 +    checkConnectionCount(vm2, 40);
 +  }
 +
 +  private void checkConnectionCount(VM vm, final int count) {
 +    SerializableRunnableIF checkConnectionCount = new SerializableRunnable("checkConnectionCount") {
 +      public void run() {
 +        Cache cache = (Cache) remoteObjects.get(CACHE_KEY);
 +        final CacheServerImpl server = (CacheServerImpl)
 +            cache.getCacheServers().get(0);
 +        WaitCriterion wc = new WaitCriterion() {
 +          String excuse;
 +          public boolean done() {
 +            int sz = server.getAcceptor().getStats()
 +                .getCurrentClientConnections();
 +            if (Math.abs(sz - count) <= ALLOWABLE_ERROR_IN_COUNT) {
 +              return true;
 +            }
 +            excuse = "Found " + sz + " connections, expected " + count;
 +            return false;
 +          }
 +          public String description() {
 +            return excuse;
 +          }
 +        };
 +        Wait.waitForCriterion(wc, 5 * 60 * 1000, 1000, true);
 +      }
 +    };
 +    
 +    vm.invoke(checkConnectionCount);
 +  }
 +  
-   private void waitForPrefilledConnections(VM vm, final int count) {
++  private void waitForPrefilledConnections(VM vm, final int count) throws Exception {
 +    waitForPrefilledConnections(vm, count, POOL_NAME);
 +  }
 +
-   private void waitForPrefilledConnections(VM vm, final int count, final String poolName) {
++  private void waitForPrefilledConnections(VM vm, final int count, final String poolName) throws Exception {
 +    SerializableRunnable runnable = new SerializableRunnable("waitForPrefilledConnections") {
 +      public void run() {
 +        final PoolImpl pool = (PoolImpl) PoolManager.getAll().get(poolName);
 +        WaitCriterion ev = new WaitCriterion() {
 +          public boolean done() {
 +            return pool.getConnectionCount() >= count; 
 +          }
 +          public String description() {
 +            return "connection count never reached " + count;
 +          }
 +        };
 +        Wait.waitForCriterion(ev, MAX_WAIT, 200, true);
 +      }
 +    };
 +    if(vm == null) {
 +      runnable.run();
 +    } else {
 +      vm.invoke(runnable);
 +    }
 +  }
 +  
 +  /** Test that the locator balances load between
 +   * three servers with intersecting server groups.
 +   * Server:    1       2       3
 +   * Groups:    a       a,b     b
++   * @throws Exception 
 +   */
-   public void testIntersectingServerGroups() {
++  public void testIntersectingServerGroups() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    String locators = getLocatorString(host, locatorPort);
 +    
 +    int serverPort1 = startBridgeServerInVM(vm1, new String[] {"a"},  locators);
 +    startBridgeServerInVM(vm2, new String[] {"a", "b"},  locators);
 +    startBridgeServerInVM(vm3, new String[] {"b"},  locators);
 +    
 +    PoolFactoryImpl pf = new PoolFactoryImpl(null);
 +    pf.addLocator(NetworkUtils.getServerHostName(host), locatorPort);
 +    pf.setMinConnections(12);
 +    pf.setSubscriptionEnabled(false);
 +    pf.setServerGroup("a");
 +    pf.setIdleTimeout(-1);
 +    startBridgeClientInVM(null, pf.getPoolAttributes(), new String[] {REGION_NAME});
 +    waitForPrefilledConnections(null, 12);
 +    
 +    checkConnectionCount(vm1, 6);
 +    checkConnectionCount(vm2, 6);
 +    checkConnectionCount(vm3, 0);
 +    
 +    LogWriterUtils.getLogWriter().info("pool1 prefilled");
 +    
 +    PoolFactoryImpl pf2 = (PoolFactoryImpl) PoolManager.createFactory();
 +    pf2.init(pf.getPoolAttributes());
 +    pf2.setServerGroup("b");
 +    PoolImpl pool2= (PoolImpl) pf2.create("testPool2");
 +    waitForPrefilledConnections(null, 12, "testPool2");
 +
 +    // The load will not be perfect, because we created all of the connections
 +    //for group A first.
 +    checkConnectionCount(vm1, 6);
 +    checkConnectionCount(vm2, 9);
 +    checkConnectionCount(vm3, 9);
 +    
 +    LogWriterUtils.getLogWriter().info("pool2 prefilled");
 +    
 +    ServerLocation location1 = new ServerLocation(NetworkUtils.getServerHostName(host), serverPort1);
 +    PoolImpl pool1 = (PoolImpl) PoolManager.getAll().get(POOL_NAME);
 +    Assert.assertEquals("a", pool1.getServerGroup());
 +    
 +    //Use up all of the pooled connections on pool1, and acquire 3 more
 +    for(int i = 0; i < 15; i++) {
 +      pool1.acquireConnection();
 +    }
 +    
 +    LogWriterUtils.getLogWriter().info("aquired 15 connections in pool1");
 +    
 +    //now the load should be equal
 +    checkConnectionCount(vm1, 9);
 +    checkConnectionCount(vm2, 9);
 +    checkConnectionCount(vm3, 9);
 +    
 +    //use up all of the pooled connections on pool2
 +    for(int i = 0; i < 12; i++) {
 +      pool2.acquireConnection();
 +    }
 +    
 +    LogWriterUtils.getLogWriter().info("aquired 12 connections in pool2");
 +    
 +    //interleave creating connections in both pools
 +    for(int i = 0; i < 6; i++) {
 +      pool1.acquireConnection();
 +      pool2.acquireConnection();
 +    }
 +    
 +    LogWriterUtils.getLogWriter().info("interleaved 6 connections from pool1 with 6 connections from pool2");
 +    
 +    //The load should still be balanced
 +    checkConnectionCount(vm1, 13);
 +    checkConnectionCount(vm2, 13);
 +    checkConnectionCount(vm3, 13);
 +    
 +  }
 +  
-   public void testCustomLoadProbe() {
++  public void testCustomLoadProbe() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +//    VM vm3 = host.getVM(3);
 +    
 +    int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
 +    startLocatorInVM(vm0, locatorPort, "");
 +    String locators = getLocatorString(host, locatorPort);
 +    
 +    ServerLoad load1= new ServerLoad(.3f, .01f, .44f, 4564f);
 +    ServerLoad load2= new ServerLoad(23.2f, 1.1f, 22.3f, .3f);
 +    int serverPort1 = startBridgeServerInVM(vm1, null, locators, new String[] {REGION_NAME}, new MyLoadProbe(load1 ));
 +    int serverPort2 = startBridgeServerInVM(vm2, null, locators, new String[] {REGION_NAME}, new MyLoadProbe(load2 ));
 +    
 +    HashMap expected = new HashMap();
 +    ServerLocation l1 = new ServerLocation(NetworkUtils.getServerHostName(host), serverPort1);
 +    ServerLocation l2 = new ServerLocation(NetworkUtils.getServerHostName(host), serverPort2);
 +    expected.put(l1, load1);
 +    expected.put(l2, load2);
 +    checkLocatorLoad(vm0, expected);
 +    
 +    load1.setConnectionLoad(25f);
 +    changeLoad(vm1, load1);
 +    load2.setSubscriptionConnectionLoad(3.5f);
 +    changeLoad(vm2, load2);
 +    checkLocatorLoad(vm0, expected);
 +    
 +    load1 = new ServerLoad(1f, .1f, 0f, 1f);
 +    load2 = new ServerLoad(2f, 5f, 0f, 2f);
 +    expected.put(l1, load1);
 +    expected.put(l2, load2);
 +    changeLoad(vm1, load1);
 +    changeLoad(vm2, load2);
 +    checkLocatorLoad(vm0, expected);
 +    
 +    PoolFactoryImpl pf = new PoolFactoryImpl(null);
 +    pf.addLocator(NetworkUtils.getServerHostName(host), locatorPort);
 +    pf.setMinConnections(20);
 +    pf.setSubscriptionEnabled(true);
 +    pf.setIdleTimeout(-1);
 +    startBridgeClientInVM(null, pf.getPoolAttributes(), new String[] {REGION_NAME});
 +    waitForPrefilledConnections(null, 20);
 +    
 +    //The first 10 connection should to go vm1, then 1 to vm2, then another 9 to vm1
 +    //because have unequal values for loadPerConnection
 +    checkConnectionCount(vm1, 19);
 +    checkConnectionCount(vm2, 1);
 +  }
 +  
 +  public void checkLocatorLoad(VM vm, final Map expected) {
 +    vm.invoke(new SerializableRunnable() {
 +      public void run() {
 +        List locators = Locator.getLocators();
 +        Assert.assertEquals(1, locators.size());
 +        InternalLocator locator = (InternalLocator) locators.get(0);
 +        final ServerLocator sl = locator.getServerLocatorAdvisee();
 +        InternalLogWriter log = new LocalLogWriter(InternalLogWriter.FINEST_LEVEL, System.out);
 +        sl.getDistributionAdvisor().dumpProfiles("PROFILES= ");
 +        WaitCriterion ev = new WaitCriterion() {
 +          public boolean done() {
 +            return expected.equals(sl.getLoadMap());
 +          }
 +          public String description() {
 +            return "load map never became equal to " + expected;
 +          }
 +        };
 +        Wait.waitForCriterion(ev, MAX_WAIT, 200, true);
 +      }
 +    });
 +  }
 +  
 +  private void changeLoad(VM vm, final ServerLoad newLoad) {
 +    vm.invoke(new SerializableRunnable() {
 +
 +      public void run() {
 +        Cache cache = (Cache) remoteObjects.get(CACHE_KEY);
 +        CacheServer server = (CacheServer) cache.getCacheServers().get(0);
 +        MyLoadProbe probe = (MyLoadProbe) server.getLoadProbe();
 +        probe.setLoad(newLoad);
 +      }
 +      
 +    });
 +  }
 +  
 +  private static class MyLoadProbe extends ServerLoadProbeAdapter implements Serializable {
 +    private ServerLoad load;
 +    
 +    public MyLoadProbe(ServerLoad load) {
 +      this.load = load;
 +    }
 +    
 +    public ServerLoad getLoad(ServerMetrics metrics) {
 +      float connectionLoad = load.getConnectionLoad()
 +          + metrics.getConnectionCount() * load.getLoadPerConnection();
 +      float queueLoad = load.getSubscriptionConnectionLoad() + metrics.getSubscriptionConnectionCount()
 +          * load.getLoadPerSubscriptionConnection();
 +      return new ServerLoad(connectionLoad, load.getLoadPerConnection(),
 +          queueLoad, load.getLoadPerSubscriptionConnection());
 +    }
 +    
 +    public void setLoad(ServerLoad load) {
 +      this.load = load;
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorTestBase.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorTestBase.java
index f35e2fa,0000000..a89d648
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorTestBase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/LocatorTestBase.java
@@@ -1,365 -1,0 +1,365 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.File;
 +import java.io.IOException;
 +import java.net.InetAddress;
 +import java.net.InetSocketAddress;
 +import java.net.UnknownHostException;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.Pool;
 +import com.gemstone.gemfire.cache.client.PoolManager;
 +import com.gemstone.gemfire.cache.server.ServerLoadProbe;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.distributed.Locator;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.cache.PoolFactoryImpl;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * @author dsmith
 + *
 + */
 +public abstract class LocatorTestBase  extends DistributedTestCase {
 +  protected static final String CACHE_KEY = "CACHE";
 +  protected static final String LOCATOR_KEY = "LOCATOR";
 +  protected static final String REGION_NAME = "A_REGION";
 +  protected static final String POOL_NAME = "daPool";
 +  protected static final Object CALLBACK_KEY = "callback";
 +  /** A map for storing temporary objects in a remote VM so that they can be used
 +   * between calls. Cleared after each test.
 +   */
 +  protected static final HashMap remoteObjects = new HashMap();
 +
 +  public LocatorTestBase(String name) {
 +    super(name);
 +  }
 +  
 +  @Override
 +  protected final void preTearDown() throws Exception {
 +    
 +    SerializableRunnable tearDown = new SerializableRunnable("tearDown") {
 +      public void run() {
 +        Locator locator = (Locator) remoteObjects.get(LOCATOR_KEY);
 +        if(locator != null) {
 +          try {
 +            locator.stop();
 +          } catch(Exception e) {
 +            //do nothing
 +          }
 +        }
 +        
 +        Cache cache = (Cache) remoteObjects.get(CACHE_KEY);
 +        if(cache != null) {
 +          try {
 +            cache.close();
 +          } catch(Exception e) {
 +            //do nothing
 +          }
 +        }
 +        remoteObjects.clear();
 +        
 +      }
 +    };
 +    //We seem to like leaving the DS open if we can for
 +    //speed, but lets at least destroy our cache and locator.
 +    Invoke.invokeInEveryVM(tearDown);
 +    tearDown.run();
 +    
 +    postTearDownLocatorTestBase();
 +  }
 +  
 +  protected void postTearDownLocatorTestBase() throws Exception {
 +  }
 +  
 +  protected void startLocatorInVM(final VM vm, final int locatorPort, final String otherLocators) {
 +    vm.invoke(new SerializableRunnable("Create Locator") {
 +
 +      final String testName= getUniqueName();
 +      public void run() {
 +        disconnectFromDS();
 +        Properties props = new Properties();
 +        props.setProperty(DistributionConfig.MCAST_PORT_NAME, String.valueOf(0));
 +        props.setProperty(DistributionConfig.LOCATORS_NAME, otherLocators);
 +        props.setProperty(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
 +        props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "false");
 +        try {
 +          File logFile = new File(testName + "-locator" + locatorPort
 +              + ".log");
 +          InetAddress bindAddr = null;
 +          try {
 +            bindAddr = InetAddress.getByName(NetworkUtils.getServerHostName(vm.getHost()));
 +          } catch (UnknownHostException uhe) {
 +            Assert.fail("While resolving bind address ", uhe);
 +          }
 +          Locator locator = Locator.startLocatorAndDS(locatorPort, logFile, bindAddr, props);
 +          remoteObjects.put(LOCATOR_KEY, locator);
 +        } catch (IOException ex) {
 +          Assert.fail("While starting locator on port " + locatorPort, ex);
 +        }
 +      }
 +    });
 +  }
 +  
 +  
 +  
 +  protected void stopLocatorInVM(VM vm) {
 +    vm.invoke(new SerializableRunnable("Stop Locator") {
 +      public void run() {
 +        Locator locator = (Locator) remoteObjects.remove(LOCATOR_KEY);
 +        locator.stop();
 +      }
 +    });
 +  }
 +  
 +  protected int startBridgeServerInVM(VM vm, String[] groups, String locators) {
 +    return startBridgeServerInVM(vm, groups, locators, new String[] {REGION_NAME});
 +  }
 +  
 +  protected int addCacheServerInVM(VM vm, final String[] groups) {
 +    SerializableCallable connect =
 +      new SerializableCallable("Add Bridge server") {
 +
 +      public Object call() throws Exception {
 +        Cache cache = (Cache) remoteObjects.get(CACHE_KEY);
 +        CacheServer server = cache.addCacheServer();
 +        final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +        server.setPort(serverPort);
 +        server.setGroups(groups);
 +        server.start();
 +        return new Integer(serverPort);
 +      }
 +    };
 +    Integer port = (Integer) vm.invoke(connect);
 +    return port.intValue();
 +  }
 +  
 +  protected int startBridgeServerInVM(VM vm, final String[] groups, final String locators, final String[] regions) {
 +    return startBridgeServerInVM(vm, groups, locators, regions, CacheServer.DEFAULT_LOAD_PROBE);
 +  }
 +  
 +  protected int startBridgeServerInVM(VM vm, final String[] groups, final String locators, final String[] regions, final ServerLoadProbe probe) {
 +    SerializableCallable connect =
 +      new SerializableCallable("Start bridge server") {
 +          public Object call() throws IOException  {
 +            Properties props = new Properties();
 +            props.setProperty(DistributionConfig.MCAST_PORT_NAME, String.valueOf(0));
 +            props.setProperty(DistributionConfig.LOCATORS_NAME, locators);
 +            DistributedSystem ds = getSystem(props);
 +            Cache cache = CacheFactory.create(ds);
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setEnableBridgeConflation(true);
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            RegionAttributes attrs = factory.create();
 +            for(int i = 0; i < regions.length; i++) {
 +              cache.createRegion(regions[i], attrs);
 +            }
 +            CacheServer server = cache.addCacheServer();
 +            final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +            server.setPort(serverPort);
 +            server.setGroups(groups);
 +            server.setLoadProbe(probe);
 +            server.start();
 +            
 +            remoteObjects.put(CACHE_KEY, cache);
 +            
 +            return new Integer(serverPort);
 +          }
 +        };
 +    Integer port = (Integer) vm.invoke(connect);
 +    return port.intValue();
 +  }
 +  
 +  protected int startBridgeServerWithEmbeddedLocator(VM vm, final String[] groups, final String locators, final String[] regions, final ServerLoadProbe probe) {
 +    SerializableCallable connect =
 +      new SerializableCallable("Start bridge server") {
 +          public Object call() throws IOException  {
 +            Properties props = new Properties();
 +            props.setProperty(DistributionConfig.MCAST_PORT_NAME, String.valueOf(0));
 +            props.setProperty(DistributionConfig.START_LOCATOR_NAME, locators);
 +            props.setProperty(DistributionConfig.LOCATORS_NAME, locators);
 +            DistributedSystem ds = getSystem(props);
 +            Cache cache = CacheFactory.create(ds);
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setEnableBridgeConflation(true);
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            RegionAttributes attrs = factory.create();
 +            for(int i = 0; i < regions.length; i++) {
 +              cache.createRegion(regions[i], attrs);
 +            }
 +            CacheServer server = cache.addCacheServer();
 +            server.setGroups(groups);
 +            server.setLoadProbe(probe);
 +            final int serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +            server.setPort(serverPort);
 +            server.start();
 +            
 +            remoteObjects.put(CACHE_KEY, cache);
 +            
 +            return new Integer(serverPort);
 +          }
 +        };
 +    Integer port = (Integer) vm.invoke(connect);
 +    return port.intValue();
 +  }
 +  
-   protected void  startBridgeClientInVM(VM vm, final String group, final String host, final int port) {
++  protected void  startBridgeClientInVM(VM vm, final String group, final String host, final int port) throws Exception {
 +    startBridgeClientInVM(vm, group, host, port, new String[] {REGION_NAME});
 +  }
 +  
 +
-   protected void startBridgeClientInVM(VM vm, final String group, final String host, final int port, final String[] regions) {
++  protected void startBridgeClientInVM(VM vm, final String group, final String host, final int port, final String[] regions) throws Exception {
 +    PoolFactoryImpl pf = new PoolFactoryImpl(null);
 +    pf.addLocator(host, port)
 +    .setServerGroup(group)
 +    .setPingInterval(200)
 +    .setSubscriptionEnabled(true)
 +    .setSubscriptionRedundancy(-1);
 +    startBridgeClientInVM(vm, pf.getPoolAttributes(), regions);
 +  }
 +  
-   protected void  startBridgeClientInVM(VM vm, final Pool pool, final String[] regions) {
++  protected void  startBridgeClientInVM(VM vm, final Pool pool, final String[] regions) throws Exception {
 +    SerializableRunnable connect =
 +      new SerializableRunnable("Start bridge client") {
 +          public void run() {
 +            Properties props = new Properties();
 +            props.setProperty(DistributionConfig.MCAST_PORT_NAME, String.valueOf(0));
 +            props.setProperty(DistributionConfig.LOCATORS_NAME, "");
 +            DistributedSystem ds = getSystem(props);
 +            Cache cache = CacheFactory.create(ds);
 +            AttributesFactory factory = new AttributesFactory();
 +            factory.setScope(Scope.LOCAL);
 +//            factory.setEnableBridgeConflation(true);
 +//            factory.setDataPolicy(DataPolicy.NORMAL);
 +            factory.setPoolName(POOL_NAME);
 +            PoolFactoryImpl pf= (PoolFactoryImpl) PoolManager.createFactory();
 +            pf.init(pool);
 +            LocatorDiscoveryCallback locatorCallback = new MyLocatorCallback();
 +            remoteObjects.put(CALLBACK_KEY, locatorCallback);
 +            pf.setLocatorDiscoveryCallback(locatorCallback);
 +            pf.create(POOL_NAME);
 +
 +
 +            RegionAttributes attrs = factory.create();
 +            for(int i = 0; i < regions.length; i++) {
 +              cache.createRegion(regions[i], attrs);
 +            }
 +            
 +            remoteObjects.put(CACHE_KEY, cache);
 +          }
 +    };
 +    
 +    if(vm == null) {
 +      connect.run();
 +    } else {
 +      vm.invoke(connect);
 +    }
 +  }
 +  
 +  protected void stopBridgeMemberVM(VM vm) {
 +   vm.invoke(new SerializableRunnable("Stop bridge member") {
 +    public void run() {
 +      Cache cache = (Cache) remoteObjects.remove(CACHE_KEY);
 +      cache.close();
 +      disconnectFromDS();
 +    }
 +   });
 +  }
 +  
 +  public String getLocatorString(Host host, int locatorPort) {
 +    return getLocatorString(host, new int[] {locatorPort});
 +  }
 +  
 +  public String getLocatorString(Host host, int[] locatorPorts) {
 +    StringBuffer str = new StringBuffer();
 +    for(int i = 0; i < locatorPorts.length; i++) {
 +      str.append(NetworkUtils.getServerHostName(host))
 +          .append("[")
 +          .append(locatorPorts[i])
 +          .append("]");
 +      if(i < locatorPorts.length - 1) {
 +        str.append(",");
 +      }
 +    }
 +    
 +    return str.toString();
 +  }
 +  
 +  protected static class MyLocatorCallback extends LocatorDiscoveryCallbackAdapter {
 +
 +    private final Set discoveredLocators = new HashSet();
 +    private final Set removedLocators = new HashSet();
 +    
 +    public synchronized void locatorsDiscovered(List locators) {
 +      discoveredLocators.addAll(locators);
 +      notifyAll();
 +    }
 +
 +    public synchronized void locatorsRemoved(List locators) {
 +      removedLocators.addAll(locators);
 +      notifyAll();
 +    }
 +    
 +    public boolean waitForDiscovery(InetSocketAddress locator, long time) throws InterruptedException {
 +      return waitFor(discoveredLocators, locator, time);
 +    }
 +    
 +    public boolean waitForRemove(InetSocketAddress locator, long time) throws InterruptedException {
 +      return waitFor(removedLocators, locator, time);
 +    }
 +    
 +    private synchronized boolean waitFor(Set set, InetSocketAddress locator, long time) throws InterruptedException {
 +      long remaining = time;
 +      long endTime = System.currentTimeMillis() + time;
 +      while(!set.contains(locator) && remaining >= 0) {
 +        wait(remaining);
 +        remaining = endTime - System.currentTimeMillis(); 
 +      }
 +      return set.contains(locator);
 +    }
 +    
 +    public synchronized Set getDiscovered() {
 +      return new HashSet(discoveredLocators);
 +    }
 +    
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/SSLNoClientAuthDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/SSLNoClientAuthDUnitTest.java
index bb1cc09,0000000..e23fb76
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/SSLNoClientAuthDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/client/internal/SSLNoClientAuthDUnitTest.java
@@@ -1,277 -1,0 +1,277 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.client.internal;
 +
 +import java.io.IOException;
 +import java.io.PrintWriter;
 +import java.io.StringWriter;
 +import java.util.Properties;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.security.AuthenticationRequiredException;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.util.test.TestUtil;
 +
 +/**
 + * Test for GEODE-396
 + */
 +public class SSLNoClientAuthDUnitTest extends DistributedTestCase {
 +  
 +  private static final long serialVersionUID = 1L;
 +  private Cache cache;
 +  private CacheServer cacheServer;
 +  private ClientCache clientCache;
 +  private int cacheServerPort;
 +  private String hostName;
 +  
 +  private static final String DEFAULT_STORE = "default.keystore";
 +  
 +  private static SSLNoClientAuthDUnitTest instance = new SSLNoClientAuthDUnitTest("SSLNoClientAuthDUnitTest");
 +  
 +  
 +  public void setUp() throws Exception {
 +    disconnectAllFromDS();
 +    super.setUp();
 +  }
 +
 +  public SSLNoClientAuthDUnitTest(String name) {
 +    super(name);
 +  }  
 +
 +  public Cache createCache(Properties props) throws Exception
 +  {
 +    props.setProperty("mcast-port", "0");
 +    props.setProperty("locators", "");
 +    cache = new CacheFactory(props).create();
 +    if (cache == null) {
 +      throw new Exception("CacheFactory.create() returned null ");
 +    }
 +    return cache;
 +  }
 +  
 +  private void createServer() throws IOException{
 +    cacheServerPort = AvailablePortHelper.getRandomAvailableTCPPort();
 +    cacheServer = cache.addCacheServer();
 +    cacheServer.setPort(cacheServerPort);
 +    cacheServer.start();
 +    hostName = cacheServer.getHostnameForClients();
 +  }
 +  
 +  public int getCacheServerPort(){
 +    return cacheServerPort;
 +  }
 +  
 +  public String getCacheServerHost(){
 +    return hostName;
 +  }
 +  
 +  public void stopCacheServer(){
 +    this.cacheServer.stop();
 +  }
 +  
 +  
 +  @SuppressWarnings("rawtypes")
 +  public void setUpServerVM(boolean cacheServerSslenabled) throws Exception {
 +    Properties gemFireProps = new Properties();
 +
 +    String cacheServerSslprotocols = "any";
 +    String cacheServerSslciphers = "any";
 +    boolean cacheServerSslRequireAuth = false;
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_ENABLED_NAME,
 +        String.valueOf(cacheServerSslenabled));
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_PROTOCOLS_NAME,
 +        cacheServerSslprotocols);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_CIPHERS_NAME,
 +        cacheServerSslciphers);
 +    gemFireProps.put(
 +        DistributionConfig.SERVER_SSL_REQUIRE_AUTHENTICATION_NAME,
 +        String.valueOf(cacheServerSslRequireAuth));
 +
 +    String keyStore = TestUtil.getResourcePath(SSLNoClientAuthDUnitTest.class, DEFAULT_STORE);
 +    String trustStore = TestUtil.getResourcePath(SSLNoClientAuthDUnitTest.class, DEFAULT_STORE);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_TYPE_NAME, "jks");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_NAME, keyStore);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_PASSWORD_NAME, "password");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_NAME, trustStore);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_PASSWORD_NAME, "password");
 +    
 +    StringWriter sw = new StringWriter();
 +    PrintWriter writer = new PrintWriter(sw);
 +    gemFireProps.list(writer);
 +    System.out.println("Starting cacheserver ds with following properties \n" + sw);
 +    createCache(gemFireProps);
 +    
 +    RegionFactory factory = cache.createRegionFactory(RegionShortcut.REPLICATE);
 +    Region r = factory.create("serverRegion");
 +    r.put("serverkey", "servervalue");
 +  }
 +  
 +  public void setUpClientVM(String host, int port,
 +      boolean cacheServerSslenabled, boolean cacheServerSslRequireAuth,
 +      String keyStore, String trustStore) {
 +
 +    Properties gemFireProps = new Properties();
 +
 +    String cacheServerSslprotocols = "any";
 +    String cacheServerSslciphers = "any";
 +
 +    String keyStorePath = TestUtil.getResourcePath(SSLNoClientAuthDUnitTest.class, keyStore);
 +    String trustStorePath = TestUtil.getResourcePath(SSLNoClientAuthDUnitTest.class, trustStore);
 +    //using new server-ssl-* properties
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_ENABLED_NAME,
 +        String.valueOf(cacheServerSslenabled));
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_PROTOCOLS_NAME,
 +        cacheServerSslprotocols);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_CIPHERS_NAME,
 +        cacheServerSslciphers);
 +    gemFireProps.put(
 +        DistributionConfig.SERVER_SSL_REQUIRE_AUTHENTICATION_NAME,
 +        String.valueOf(cacheServerSslRequireAuth));
 +
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_TYPE_NAME, "jks");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_NAME, keyStorePath);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_KEYSTORE_PASSWORD_NAME, "password");
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_NAME, trustStorePath);
 +    gemFireProps.put(DistributionConfig.SERVER_SSL_TRUSTSTORE_PASSWORD_NAME, "password");
 +
 +    StringWriter sw = new StringWriter();
 +    PrintWriter writer = new PrintWriter(sw);
 +    gemFireProps.list(writer);
 +    System.out.println("Starting client ds with following properties \n" + sw.getBuffer());
 +    
 +    ClientCacheFactory clientCacheFactory = new ClientCacheFactory(gemFireProps);
 +    clientCacheFactory.addPoolServer(host, port);
 +    clientCache = clientCacheFactory.create();
 +    
 +    ClientRegionFactory<String,String> regionFactory = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY);
 +    Region<String, String> region = regionFactory.create("serverRegion");  
 +    assertNotNull(region);
 +  }
 +  
 +  public void doClientRegionTest(){
 +    Region<String, String> region = clientCache.getRegion("serverRegion");
 +    assertEquals("servervalue",region.get("serverkey"));
 +    region.put("clientkey", "clientvalue");
 +    assertEquals("clientvalue",region.get("clientkey"));
 +  }
 +  
 +  public void doServerRegionTest(){
 +    Region<String, String> region = cache.getRegion("serverRegion");
 +    assertEquals("servervalue",region.get("serverkey"));    
 +    assertEquals("clientvalue",region.get("clientkey"));
 +  }
 +  
 +  
 +  public static void setUpServerVMTask(boolean cacheServerSslenabled) throws Exception{
 +    instance.setUpServerVM(cacheServerSslenabled);
 +  }
 +  
 +  public static void createServerTask() throws Exception {
 +    instance.createServer();
 +  }
 +  
 +  public static void setUpClientVMTask(String host, int port,
 +      boolean cacheServerSslenabled, boolean cacheServerSslRequireAuth, String keyStore, String trustStore)
 +      throws Exception {
 +    instance.setUpClientVM(host, port, cacheServerSslenabled, cacheServerSslRequireAuth, keyStore, trustStore);
 +  }
 +  
 +  public static void doClientRegionTestTask() {
 +    instance.doClientRegionTest();
 +  }
 +  
 +  public static void doServerRegionTestTask() {
 +    instance.doServerRegionTest();
 +  }
 +  
 +  public static Object[] getCacheServerEndPointTask() {
 +    Object[] array = new Object[2];
 +    array[0] = instance.getCacheServerHost();
 +    array[1] = instance.getCacheServerPort();
 +    return array;
 +  }
 +  
 +  public static void closeCacheTask(){
 +    if (instance != null && instance.cache != null) {
 +      instance.cache.close();
 +    }
 +  }
 +  
 +  public static void closeClientCacheTask(){
 +    if (instance != null && instance.clientCache != null) {
 +      instance.clientCache.close();
 +    }
 +  }
 +  
 +  /**
 +   * Test for GEODE-396
 +   */
 +  public void testSSLServerWithNoAuth() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
 +
 +    boolean cacheServerSslenabled = true;
 +    boolean cacheClientSslenabled = true;
 +    boolean cacheClientSslRequireAuth = true;
 +
-     serverVM.invoke(SSLNoClientAuthDUnitTest.class, "setUpServerVMTask", new Object[]{cacheServerSslenabled});
-     serverVM.invoke(SSLNoClientAuthDUnitTest.class, "createServerTask");
++    serverVM.invoke(() -> SSLNoClientAuthDUnitTest.setUpServerVMTask(cacheServerSslenabled));
++    serverVM.invoke(() -> SSLNoClientAuthDUnitTest.createServerTask());
 +
-     Object array[] = (Object[])serverVM.invoke(SSLNoClientAuthDUnitTest.class, "getCacheServerEndPointTask"); 
++    Object array[] = (Object[])serverVM.invoke(() -> SSLNoClientAuthDUnitTest.getCacheServerEndPointTask()); 
 +    String hostName = (String)array[0];
 +    int port = (Integer) array[1];
 +    Object params[] = new Object[6];
 +    params[0] = hostName;
 +    params[1] = port;
 +    params[2] = cacheClientSslenabled;
 +    params[3] = cacheClientSslRequireAuth;
 +    params[4] = DEFAULT_STORE;
 +    params[5] = DEFAULT_STORE;
 +    //getLogWriter().info("Starting client with server endpoint " + hostName + ":" + port);
 +    try {
 +      clientVM.invoke(SSLNoClientAuthDUnitTest.class, "setUpClientVMTask", params);
-       clientVM.invoke(SSLNoClientAuthDUnitTest.class, "doClientRegionTestTask");
-       serverVM.invoke(SSLNoClientAuthDUnitTest.class, "doServerRegionTestTask");
++      clientVM.invoke(() -> SSLNoClientAuthDUnitTest.doClientRegionTestTask());
++      serverVM.invoke(() -> SSLNoClientAuthDUnitTest.doServerRegionTestTask());
 +    } catch (Exception rmiException) {
 +      Throwable e = rmiException.getCause();
 +      //getLogWriter().info("ExceptionCause at clientVM " + e);
 +      fail("Unexpected Exception " + e);
 +    }
 +  }
 +  
 +  @Override
 +  protected final void preTearDown() throws Exception {
 +    final Host host = Host.getHost(0);
 +    VM serverVM = host.getVM(1);
 +    VM clientVM = host.getVM(2);
-     clientVM.invoke(SSLNoClientAuthDUnitTest.class, "closeClientCacheTask");
-     serverVM.invoke(SSLNoClientAuthDUnitTest.class, "closeCacheTask");
++    clientVM.invoke(() -> SSLNoClientAuthDUnitTest.closeClientCacheTask());
++    serverVM.invoke(() -> SSLNoClientAuthDUnitTest.closeCacheTask());
 +  }
 +}


[007/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
index d3b065c,0000000..7a4d09e
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
@@@ -1,9177 -1,0 +1,9177 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.ByteArrayOutputStream;
 +import java.io.DataInput;
 +import java.io.DataInputStream;
 +import java.io.DataOutput;
 +import java.io.DataOutputStream;
 +import java.io.IOException;
 +import java.io.Serializable;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Comparator;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.Iterator;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Random;
 +import java.util.Set;
 +import java.util.concurrent.LinkedBlockingQueue;
 +
 +import junit.framework.Assert;
 +import junit.framework.AssertionFailedError;
 +
 +import org.apache.logging.log4j.Logger;
 +import org.junit.Ignore;
 +
 +import com.gemstone.gemfire.DataSerializable;
 +import com.gemstone.gemfire.DataSerializer;
 +import com.gemstone.gemfire.Instantiator;
 +import com.gemstone.gemfire.InvalidDeltaException;
 +import com.gemstone.gemfire.LogWriter;
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.AttributesMutator;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheEvent;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheLoader;
 +import com.gemstone.gemfire.cache.CacheLoaderException;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.CacheWriterException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.EntryExistsException;
 +import com.gemstone.gemfire.cache.EntryNotFoundException;
 +import com.gemstone.gemfire.cache.ExpirationAction;
 +import com.gemstone.gemfire.cache.ExpirationAttributes;
 +import com.gemstone.gemfire.cache.InterestPolicy;
 +import com.gemstone.gemfire.cache.LoaderHelper;
 +import com.gemstone.gemfire.cache.Operation;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionEvent;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.SubscriptionAttributes;
 +import com.gemstone.gemfire.cache.TimeoutException;
 +import com.gemstone.gemfire.cache.TransactionEvent;
 +import com.gemstone.gemfire.cache.TransactionId;
 +import com.gemstone.gemfire.cache.TransactionListener;
 +import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.distributed.internal.DMStats;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 +import com.gemstone.gemfire.internal.AvailablePortHelper;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.InternalDataSerializer;
 +import com.gemstone.gemfire.internal.InternalInstantiator;
 +import com.gemstone.gemfire.internal.Version;
 +import com.gemstone.gemfire.internal.cache.EntryExpiryTask;
 +import com.gemstone.gemfire.internal.cache.ExpiryTask;
 +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.internal.cache.PartitionedRegion;
 +import com.gemstone.gemfire.internal.cache.RegionEntry;
 +import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 +import com.gemstone.gemfire.internal.cache.TXStateProxy;
 +import com.gemstone.gemfire.internal.cache.Token;
 +import com.gemstone.gemfire.internal.cache.TombstoneService;
 +import com.gemstone.gemfire.internal.cache.delta.Delta;
 +import com.gemstone.gemfire.internal.cache.versions.RegionVersionHolder;
 +import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
 +import com.gemstone.gemfire.internal.cache.versions.VMRegionVersionVector;
 +import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 +import com.gemstone.gemfire.internal.logging.LogService;
 +import com.gemstone.gemfire.internal.offheap.MemoryChunkWithRefCount;
 +import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.RMIException;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +import com.gemstone.gemfire.test.dunit.WaitCriterion;
 +import com.gemstone.gemfire.test.dunit.IgnoredException;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +
 +
 +/**
 + * Abstract superclass of {@link Region} tests that involve more than
 + * one VM.
 + */
 +public abstract class MultiVMRegionTestCase extends RegionTestCase {
 +
 +  private static final Logger logger = LogService.getLogger();
 +  
 +  Properties props = new Properties();
 +
 +  final int putRange_1Start = 1;
 +
 +  final int putRange_1End = 5;
 +
 +  final int putRange_2Start = 6;
 +
 +  final int putRange_2End = 10;
 +
 +  final int putRange_3Start = 11;
 +
 +  final int putRange_3End = 15;
 +
 +  final int putRange_4Start = 16;
 +
 +  final int putRange_4End = 20;
 +
 +  final int removeRange_1Start = 2;
 +
 +  final int removeRange_1End = 4;
 +
 +  final int removeRange_2Start = 7;
 +
 +  final int removeRange_2End = 9;
 +
 +  public MultiVMRegionTestCase(String name) {
 +    super(name);
 +  }
 +  
 +  public static void caseTearDown() throws Exception {
 +    disconnectAllFromDS();
 +  }
 +  
 +  @Override
 +  protected final void postTearDownRegionTestCase() throws Exception {
 +    DistributedTestCase.cleanupAllVms();
 +    CCRegion = null;
 +  }
 +
 +  // @todo can be used in tests
 +//  protected CacheSerializableRunnable createRegionTask(final String name) {
 +//    return new CacheSerializableRunnable("Create Region") {
 +//      public void run2() throws CacheException {
 +//        assertNotNull(createRegion(name));
 +//      }
 +//    };
 +//  }
 +
 +
 +  ////////  Test Methods
 +
 +  /**
 +   * This is a for the ConcurrentMap operations.
 +   * 4 VMs are used to
 +   * create the region and operations are performed on one of the nodes
 +   */
 +  public void testConcurrentOperations() throws Exception {
 +    SerializableRunnable createRegion = new CacheSerializableRunnable(
 +    "createRegion") {
 +
 +      public void run2() throws CacheException {
 +        Cache cache = getCache();
 +        RegionAttributes regionAttribs = getRegionAttributes();
 +        cache.createRegion("R1",
 +            regionAttribs);
 +      }
 +    };
 +
 +    Host host = Host.getHost(0);
 +    // create the VM(0 - 4)
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    vm0.invoke(createRegion);
 +    vm1.invoke(createRegion);
 +    vm2.invoke(createRegion);
 +    vm3.invoke(createRegion);
 +    concurrentMapTest("/R1");
 +  }
 +
 +  /**
 +   * Do putIfAbsent(), replace(Object, Object),
 +   * replace(Object, Object, Object), remove(Object, Object) operations
 +   */
 +  public void concurrentMapTest(final String rName) {
 +    
 +    //String exceptionStr = "";
 +    VM vm0 = Host.getHost(0).getVM(0);
 +    vm0.invoke(new CacheSerializableRunnable("doConcurrentMapOperations") {
 +      public void run2() throws CacheException {
 +        Cache cache = getCache();
 +        final Region pr = cache.getRegion(rName);
 +        assertNotNull(rName + " not created", pr);
 +               
 +        // test successful putIfAbsent
 +        for (int i = putRange_1Start; i <= putRange_1End; i++) {
 +          Object putResult = pr.putIfAbsent(Integer.toString(i),
 +                                            Integer.toString(i));
 +          assertNull("Expected null, but got " + putResult + " for key " + i,
 +                     putResult);
 +        }
 +        int size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                    pr.isEmpty());
 +        
 +        // test unsuccessful putIfAbsent
 +        for (int i = putRange_1Start; i <= putRange_1End; i++) {
 +          Object putResult = pr.putIfAbsent(Integer.toString(i),
 +                                            Integer.toString(i + 1));
 +          assertEquals("for i=" + i, Integer.toString(i), putResult);
 +          assertEquals("for i=" + i, Integer.toString(i), pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                    pr.isEmpty());
 +               
 +        // test successful replace(key, oldValue, newValue)
 +        for (int i = putRange_1Start; i <= putRange_1End; i++) {
 +         boolean replaceSucceeded = pr.replace(Integer.toString(i),
 +                                               Integer.toString(i),
 +                                               "replaced" + i);
 +          assertTrue("for i=" + i, replaceSucceeded);
 +          assertEquals("for i=" + i, "replaced" + i, pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                   pr.isEmpty());
 +               
 +        // test unsuccessful replace(key, oldValue, newValue)
 +        for (int i = putRange_1Start; i <= putRange_2End; i++) {
 +         boolean replaceSucceeded = pr.replace(Integer.toString(i),
 +                                               Integer.toString(i), // wrong expected old value
 +                                               "not" + i);
 +         assertFalse("for i=" + i, replaceSucceeded);
 +         assertEquals("for i=" + i,
 +                      i <= putRange_1End ? "replaced" + i : null,
 +                      pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                   pr.isEmpty());
 +                                    
 +        // test successful replace(key, value)
 +        for (int i = putRange_1Start; i <= putRange_1End; i++) {
 +          Object replaceResult = pr.replace(Integer.toString(i),
 +                                            "twice replaced" + i);
 +          assertEquals("for i=" + i, "replaced" + i, replaceResult);
 +          assertEquals("for i=" + i,
 +                       "twice replaced" + i,
 +                       pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                    pr.isEmpty());
 +                                    
 +        // test unsuccessful replace(key, value)
 +        for (int i = putRange_2Start; i <= putRange_2End; i++) {
 +          Object replaceResult = pr.replace(Integer.toString(i),
 +                                           "thrice replaced" + i);
 +          assertNull("for i=" + i, replaceResult);
 +          assertNull("for i=" + i, pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                    pr.isEmpty());
 +                                    
 +        // test unsuccessful remove(key, value)
 +        for (int i = putRange_1Start; i <= putRange_2End; i++) {
 +          boolean removeResult = pr.remove(Integer.toString(i),
 +                                           Integer.toString(-i));
 +          assertFalse("for i=" + i, removeResult);
 +          assertEquals("for i=" + i,
 +                       i <= putRange_1End ? "twice replaced" + i : null,
 +                       pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", putRange_1End, size);
 +        assertFalse("isEmpty doesnt return proper state of the region", 
 +                    pr.isEmpty());
 +
 +        // test successful remove(key, value)
 +        for (int i = putRange_1Start; i <= putRange_1End; i++) {
 +          boolean removeResult = pr.remove(Integer.toString(i),
 +                                           "twice replaced" + i);
 +          assertTrue("for i=" + i, removeResult);
 +          assertEquals("for i=" + i, null, pr.get(Integer.toString(i)));
 +        }
 +        size = pr.size();
 +        assertEquals("Size doesn't return expected value", 0, size);
 +        assertTrue("isEmpty doesnt return proper state of the region", 
 +                 pr.isEmpty());
 +        }
 +    });
 +    
 +    
 +    /*
 +     * destroy the Region.
 +     */
 +    vm0.invoke(new CacheSerializableRunnable("destroyRegionOp") {
 +               
 +       public void run2() {
 +         Cache cache = getCache();
 +         Region pr = cache.getRegion(rName);
 +         assertNotNull("Region already destroyed.", pr);
 +         pr.destroyRegion();
 +         assertTrue("Region isDestroyed false", pr.isDestroyed());
 +         assertNull("Region not destroyed.", cache.getRegion(rName));
 +       }
 +     });
 +  }
 +
 +  /**
 +   * Tests that doing a {@link Region#put put} in a distributed region
 +   * one VM updates the value in another VM.
 +   */
 +  public void testDistributedUpdate() {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    final Object key = "KEY";
 +    final Object oldValue = "OLD_VALUE";
 +    final Object newValue = "NEW_VALUE";
 +
 +    SerializableRunnable put =
 +      new CacheSerializableRunnable("Put key/value") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            region.put(key, oldValue);
 +            flushIfNecessary(region);
 +          }
 +      };
 +
 +    vm0.invoke(put);
 +    vm1.invoke(put);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Update") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          region.put(key, newValue);
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Validate update") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          Region.Entry entry = region.getEntry(key);
 +          assertNotNull(entry);
 +          assertEquals(newValue, entry.getValue());
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Tests that distributed updates are delivered in order
 +   *
 +   * <P>
 +   *
 +   * Note that this test does not make sense for regions that are
 +   * {@link Scope#DISTRIBUTED_NO_ACK} for which we do not guarantee
 +   * the ordering of updates for a single producer/single consumer.
 +   *
 +   * DISABLED 4-16-04 - the current implementation assumes events
 +   * are processed synchronously, which is no longer true.
 +   */
 +  public void _ttestOrderedUpdates() throws Throwable {
 +    if (getRegionAttributes().getScope() ==
 +        Scope.DISTRIBUTED_NO_ACK) {
 +      return;
 +    }
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final int lastNumber = 10;
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create region entry") {
 +          public void run2() throws CacheException {
 +            Region region = createRegion(name);
 +            region.create(key, null);
 +          }
 +        };
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set listener") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          region.setUserAttribute(new LinkedBlockingQueue());
 +          region.getAttributesMutator().addCacheListener(new
 +            CacheListenerAdapter() {
 +              public void afterUpdate(EntryEvent e) {
 +                Region region2 = e.getRegion();
 +                LinkedBlockingQueue queue =
 +                  (LinkedBlockingQueue) region2.getUserAttribute();
 +                Object value = e.getNewValue();
 +                assertNotNull(value);
 +                try {
 +                  com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("++ Adding " + value);
 +                  queue.put(value);
 +
 +                } catch (InterruptedException ex) {
 +                  com.gemstone.gemfire.test.dunit.Assert.fail("Why was I interrupted?", ex);
 +                }
 +              }
 +            });
 +          flushIfNecessary(region);
 +        }
 +      });
 +    AsyncInvocation ai1 =
 +      vm1.invokeAsync(new CacheSerializableRunnable("Verify") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            LinkedBlockingQueue queue =
 +              (LinkedBlockingQueue) region.getUserAttribute();
 +            for (int i = 0; i <= lastNumber; i++) {
 +              try {
 +                com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("++ Waiting for " + i);
 +                Integer value = (Integer) queue.take();
 +                com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().info("++ Got " + value);
 +                assertEquals(i, value.intValue());
 +
 +              } catch (InterruptedException ex) {
 +                com.gemstone.gemfire.test.dunit.Assert.fail("Why was I interrupted?", ex);
 +              }
 +            }
 +          }
 +        });
 +
 +    AsyncInvocation ai0 =
 +      vm0.invokeAsync(new CacheSerializableRunnable("Populate") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            for (int i = 0; i <= lastNumber; i++) {
 +//              com.gemstone.gemfire.internal.GemFireVersion.waitForJavaDebugger(getLogWriter());
 +              region.put(key, new Integer(i));
 +            }
 +          }
 +        });
 +
 +    ThreadUtils.join(ai0, 30 * 1000);
 +    ThreadUtils.join(ai1, 30 * 1000);
 +
 +    if (ai0.exceptionOccurred()) {
 +      com.gemstone.gemfire.test.dunit.Assert.fail("ai0 failed", ai0.getException());
 +
 +    } else if (ai1.exceptionOccurred()) {
 +      com.gemstone.gemfire.test.dunit.Assert.fail("ai1 failed", ai1.getException());
 +    }
 +  }
 +
 +  /**
 +   * Tests that doing a distributed get results in a
 +   * <code>netSearch</code>.
 +   */
 +  public void testDistributedGet() {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Populate region") {
 +        public void run2() throws CacheException {
 +          Region region = createRegion(name);
 +          region.put(key, value);
 +        }
 +      });
 +
 +    SerializableRunnable get = new CacheSerializableRunnable("Distributed get") {
 +        public void run2() throws CacheException {
 +          Region region = createRegion(name);
 +          assertEquals(value, region.get(key));
 +        }
 +    };
 +
 +
 +    vm1.invoke(get);
 +  }
 +
 +  /**
 +   * Tests that doing a {@link Region#put put} on a distributed region
 +   * in one VM does not effect a region in a different VM that does
 +   * not have that key defined.
 +   */
 +  public void testDistributedPutNoUpdate()
 +    throws InterruptedException {
 +
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    Thread.sleep(250);
 +
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    vm0.invoke(new CacheSerializableRunnable("Put key/value") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.put(key, value);
 +        }
 +      });
 +
 +    Thread.sleep(250);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify no update") {
 +        public void run2() throws CacheException {
 +          Region region = getRootRegion().getSubregion(name);
 +          Region.Entry entry = region.getEntry(key);
 +          if (getRegionAttributes().getDataPolicy().withReplication() ||
 +              getRegionAttributes().getPartitionAttributes() != null) {
 +            assertEquals(value, region.get(key));
 +          }
 +          else {
 +            assertNull(entry);
 +          }
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Two VMs create a region. One populates a region entry.  The other
 +   * VM defines that entry.  The first VM updates the entry.  The
 +   * second VM should see the updated value.
 +   */
 +  public void testDefinedEntryUpdated() {
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object oldValue = "OLD_VALUE";
 +    final Object newValue = "NEW_VALUE";
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create and populate") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.put(key, oldValue);
 +        }
 +      });
 +    vm1.invoke(new CacheSerializableRunnable("Define entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          if (!getRegionAttributes().getDataPolicy().withReplication())
 +            region.create(key, null);
 +        }
 +      });
 +    vm0.invoke(new CacheSerializableRunnable("Update entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.put(key, newValue);
 +        }
 +      });
 +    Invoke.invokeRepeatingIfNecessary(vm1, new CacheSerializableRunnable("Get entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          assertEquals(newValue, region.get(key));
 +        }
 +      }, getRepeatTimeoutMs());
 +  }
 +
 +
 +  /**
 +   * Tests that {@linkplain Region#destroy destroying} an entry is
 +   * propagated to all VMs that define that entry.
 +   */
 +  public void testDistributedDestroy() throws InterruptedException {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +//DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to create region");
 +            Region region = createRegion(name);
 +            assertTrue(!region.isDestroyed());
 +            Region root = region.getParentRegion();
 +            assertTrue(!root.isDestroyed());
 +          }
 +        };
 +
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +    vm2.invoke(create);
 +
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    SerializableRunnable put =
 +      new CacheSerializableRunnable("Put key/value") {
 +          public void run2() throws CacheException {
 +//DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to put");
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            region.put(key, value);
 +            assertTrue(!region.isDestroyed());
 +            assertTrue(!region.getParentRegion().isDestroyed());
 +            flushIfNecessary(region);
 +          }
 +        };
 +
 +    vm0.invoke(put);
 +    vm1.invoke(put);
 +    vm2.invoke(put);
 +
 +    SerializableRunnable verifyPut =
 +      new CacheSerializableRunnable("Verify Put") {
 +          public void run2() throws CacheException {
 +            Region root = getRootRegion();
 +            assertTrue(!root.isDestroyed());
 +            Region region = root.getSubregion(name);
 +            assertTrue(!region.isDestroyed());
 +//DebuggerSupport.waitForJavaDebugger(getLogWriter(), " about to get");
 +            assertEquals(value, region.getEntry(key).getValue());
 +          }
 +        };
 +
 +    vm0.invoke(verifyPut);
 +    vm1.invoke(verifyPut);
 +    vm2.invoke(verifyPut);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy Entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.destroy(key);
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    CacheSerializableRunnable verifyDestroy =
 +      new CacheSerializableRunnable("Verify entry destruction") {
 +          public void run2() throws CacheException {
 +            Region root = getRootRegion();
 +            assertTrue(!root.isDestroyed());
 +            Region region = root.getSubregion(name);
 +            assertTrue(!region.isDestroyed());
 +            assertNull(region.getEntry(key));
 +          }
 +        };
 +    vm0.invoke(verifyDestroy);
 +    vm1.invoke(verifyDestroy);
 +    vm2.invoke(verifyDestroy);
 +  }
 +
 +  /**
 +   * Tests that {@linkplain Region#destroy destroying} a region is
 +   * propagated to all VMs that define that region.
 +   */
 +  public void testDistributedRegionDestroy()
 +    throws InterruptedException {
 +
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Invoke.invokeInEveryVM(create);
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy Region") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.destroyRegion();
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    Invoke.invokeInEveryVM(new CacheSerializableRunnable("Verify region destruction") {
 +      public void run2() throws CacheException {
 +        WaitCriterion ev = new WaitCriterion() {
 +          public boolean done() {
 +            return getRootRegion().getSubregion(name) == null;
 +          }
 +          public String description() {
 +            return "Waiting for region " + name + " to be destroyed";
 +          }
 +        };
 +        Wait.waitForCriterion(ev, 60 * 1000, 10, true);
 +        Region region = getRootRegion().getSubregion(name);
 +        assertNull(region);
 +      }
 +    });
 +  }
 +
 +  /**
 +   * Tests that a {@linkplain Region#localDestroy} does not effect
 +   * other VMs that define that entry.
 +   */
 +  public void testLocalDestroy() throws InterruptedException {
 +    if (!supportsLocalDestroyAndLocalInvalidate()) {
 +      return;
 +    }
 +    // test not valid for persistBackup region since they have to be
 +    // mirrored KEYS_VALUES
 +    if (getRegionAttributes().getDataPolicy().withPersistence()) return;
 +
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    Thread.sleep(250);
 +
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    SerializableRunnable put =
 +      new CacheSerializableRunnable("Put key/value") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            region.put(key, value);
 +          }
 +        };
 +
 +    vm0.invoke(put);
 +    vm1.invoke(put);
 +
 +    Thread.sleep(250);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Local Destroy Entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.localDestroy(key);
 +        }
 +      });
 +
 +    Thread.sleep(250);
 +
 +    SerializableRunnable verify =
 +      new CacheSerializableRunnable("Verify entry existence") {
 +          public void run2() throws CacheException {
 +            Region region = getRootRegion().getSubregion(name);
 +            assertNotNull(region.getEntry(key));
 +          }
 +        };
 +    vm1.invoke(verify);
 +  }
 +
 +  /**
 +   * Tests that a {@link Region#localDestroyRegion} is not propagated
 +   * to other VMs that define that region.
 +   */
 +  public void testLocalRegionDestroy()
 +    throws InterruptedException {
 +
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    Thread.sleep(250);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Local Destroy Region") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.localDestroyRegion();
 +        }
 +      });
 +
 +    Thread.sleep(250);
 +
 +    SerializableRunnable verify =
 +      new CacheSerializableRunnable("Verify region existence") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            assertNotNull(region);
 +          }
 +        };
 +    vm1.invoke(verify);
 +  }
 +
 +  /**
 +   * Tests that {@linkplain Region#invalidate invalidating} an entry is
 +   * propagated to all VMs that define that entry.
 +   */
 +  public void testDistributedInvalidate() {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    // vm2 is on a different gemfire system
 +    vm2.invoke(create);
 +
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    SerializableRunnable put =
 +      new CacheSerializableRunnable("Put key/value") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            region.put(key, value);
 +            flushIfNecessary(region);
 +          }
 +        };
 +
 +    vm0.invoke(put);
 +    vm1.invoke(put);
 +    vm2.invoke(put);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Invalidate Entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.invalidate(key);
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    CacheSerializableRunnable verify =
 +      new CacheSerializableRunnable("Verify entry invalidation") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            Region.Entry entry = region.getEntry(key);
 +            assertNotNull(entry);
 +            if (entry.getValue() != null) {
 +              // changed from severe to fine because it is possible
 +              // for this to return non-null on d-no-ack
 +              // that is was invokeRepeatingIfNecessary is called
 +              com.gemstone.gemfire.test.dunit.LogWriterUtils.getLogWriter().fine("invalidated entry has value of " + entry.getValue());
 +            }
 +            assertNull(entry.getValue());
 +          }
 +        };
 +
 +
 +    vm1.invoke(verify);
 +    vm2.invoke(verify);
 +  }
 +
 +  /**
 +   * Tests that {@linkplain Region#invalidate invalidating} an entry
 +   * in multiple VMs does not cause any problems.
 +   */
 +  public void testDistributedInvalidate4() throws InterruptedException {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    int vmCount = host.getVMCount();
 +    for (int i = 0; i < vmCount; i++) {
 +      VM vm = host.getVM(i);
 +      vm.invoke(create);
 +    }
 +
 +    SerializableRunnable put =
 +        new CacheSerializableRunnable("put entry") {
 +            public void run2() throws CacheException {
 +              Region region =
 +                  getRootRegion().getSubregion(name);
 +              region.put(key, value);
 +              flushIfNecessary(region);
 +            }
 +          };
 +
 +      for (int i = 0; i < vmCount; i++) {
 +        VM vm = host.getVM(i);
 +        vm.invoke(put);
 +      }
 +
 +      SerializableRunnable invalidate =
 +      new CacheSerializableRunnable("Invalidate Entry") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.invalidate(key);
 +          flushIfNecessary(region);
 +        }
 +      };
 +
 +    for (int i = 0; i < vmCount; i++) {
 +      VM vm = host.getVM(i);
 +      vm.invoke(invalidate);
 +    }
 +
 +    SerializableRunnable verify =
 +      new CacheSerializableRunnable("Verify entry invalidation") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            Region.Entry entry = region.getEntry(key);
 +            assertNotNull(entry);
 +            assertNull(entry.getValue());
 +          }
 +        };
 +
 +    for (int i = 0; i < vmCount; i++) {
 +      VM vm = host.getVM(i);
 +      vm.invoke(verify);
 +    }
 +  }
 +
 +  /**
 +   * Tests that {@linkplain Region#invalidateRegion invalidating} a
 +   * region is propagated to all VMs that define that entry.
 +   */
 +  public void testDistributedRegionInvalidate()
 +    throws InterruptedException {
 +    if (!supportsSubregions()) {
 +      return;
 +    }
 +    final String name = this.getUniqueName();
 +    final String subname = "sub";
 +    final boolean useSubs = getRegionAttributes().getPartitionAttributes() == null;
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            Region region;
 +            region = createRegion(name);
 +            if (useSubs) {
 +              region.createSubregion(subname, region.getAttributes());
 +            }
 +          }
 +        };
 +
 +    Invoke.invokeInEveryVM(create);
 +
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +    final Object key2 = "KEY2";
 +    final Object value2 = "VALUE2";
 +
 +    SerializableRunnable put =
 +      new CacheSerializableRunnable("Put key/value") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            region.put(key, value);
 +            region.put(key2, value2);
 +            flushIfNecessary(region);
 +
 +            if (useSubs) {
 +              Region subregion = region.getSubregion(subname);
 +              subregion.put(key, value);
 +              subregion.put(key2, value2);
 +              flushIfNecessary(subregion);
 +            }
 +          }
 +        };
 +
 +    Invoke.invokeInEveryVM(put);
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Invalidate Region") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.invalidateRegion();
 +        }
 +      });
 +
 +    CacheSerializableRunnable verify =
 +      new CacheSerializableRunnable("Verify region invalidation") {
 +          public void run2() throws CacheException {
 +            Region region =
 +              getRootRegion().getSubregion(name);
 +            {
 +              Region.Entry entry = region.getEntry(key);
 +              assertNotNull(entry);
 +              Object v = entry.getValue();
 +              assertNull("Expected null but was " + v, v);
 +
 +              entry = region.getEntry(key2);
 +              assertNotNull(entry);
 +              assertNull(entry.getValue());
 +            }
 +
 +            if (useSubs) {
 +              Region subregion = region.getSubregion(subname);
 +              Region.Entry entry = subregion.getEntry(key);
 +              assertNotNull(entry);
 +              assertNull(entry.getValue());
 +
 +              entry = subregion.getEntry(key2);
 +              assertNotNull(entry);
 +              assertNull(entry.getValue());
 +            }
 +          }
 +        };
 +
 +    Invoke.invokeInEveryVMRepeatingIfNecessary(verify, getRepeatTimeoutMs());
 +  }
 +
 +  /**
 +   * Tests that a {@link CacheListener} is invoked in a remote VM.
 +   */
 +  public void testRemoteCacheListener() throws InterruptedException {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object oldValue = "OLD_VALUE";
 +    final Object newValue = "NEW_VALUE";
 +//    final Object key2 = "KEY2";
 +//    final Object value2 = "VALUE2";
 +
 +    SerializableRunnable populate =
 +      new CacheSerializableRunnable("Create Region and Put") {
 +          public void run2() throws CacheException {
 +            Region region = createRegion(name);
 +            region.put(key, oldValue);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    final VM vm0 = host.getVM(0);
 +    final VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(populate);
 +    vm1.invoke(populate);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set listener") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterUpdate2(EntryEvent event) {
 +                assertEquals(Operation.UPDATE, event.getOperation());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +                assertEquals(key, event.getKey());
 +                assertEquals(oldValue, event.getOldValue());
 +                assertEquals(newValue, event.getNewValue());
 +                assertFalse(event.getOperation().isLoad());
 +                assertFalse(event.getOperation().isLocalLoad());
 +                assertFalse(event.getOperation().isNetLoad());
 +                assertFalse(event.getOperation().isNetSearch());
 +                if (event.getRegion().getAttributes().getOffHeap()) {
 +                  // since off heap always serializes the old value is serialized and available
 +                  assertEquals(oldValue, event.getSerializedOldValue().getDeserializedValue());
 +                } else {
 +                  assertEquals(null, event.getSerializedOldValue()); // since it was put originally in this VM
 +                }
 +                DataInputStream dis = new DataInputStream(new ByteArrayInputStream(event.getSerializedNewValue().getSerializedValue()));
 +                try {
 +                  assertEquals(newValue, DataSerializer.readObject(dis));
 +                } catch (Exception e) {
 +                  com.gemstone.gemfire.test.dunit.Assert.fail("Unexpected Exception", e);
 +                }
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    // I see no reason to pause here.
 +    // The test used to pause here but only if no-ack.
 +    // But we have no operations to wait for.
 +    // The last thing we did was install a listener in vm1
 +    // and it is possible that vm0 does not yet know we have
 +    // a listener but for this test it does not matter.
 +    // So I'm commenting out the following pause:
 +    //pauseIfNecessary();
 +    // If needed then do a flushIfNecessary(region) after adding the cache listener
 +
 +    vm0.invoke(new CacheSerializableRunnable("Update") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.put(key, newValue, getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Update") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +
 +          // Setup listener for next test
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterInvalidate2(EntryEvent event) {
 +                assertEquals(Operation.INVALIDATE, event.getOperation());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +                assertEquals(key, event.getKey());
 +                assertEquals(newValue, event.getOldValue());
 +                assertNull(event.getNewValue());
 +                assertFalse(event.getOperation().isLoad());
 +                assertFalse(event.getOperation().isLocalLoad());
 +                assertFalse(event.getOperation().isNetLoad());
 +                assertFalse(event.getOperation().isNetSearch());
 +                assertNull(event.getSerializedNewValue());
 +                DataInputStream dis = new DataInputStream(new ByteArrayInputStream(event.getSerializedOldValue().getSerializedValue()));
 +                try {
 +                  assertEquals(newValue, DataSerializer.readObject(dis));
 +                } catch (Exception e) {
 +                  com.gemstone.gemfire.test.dunit.Assert.fail("Unexpected Exception", e);
 +                }
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Invalidate") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.invalidate(key, getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Invalidate") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +
 +          // Setup listener for next test
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterDestroy2(EntryEvent event) {
 +                assertTrue(event.getOperation().isDestroy());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +                assertEquals(key, event.getKey());
 +                assertNull(event.getOldValue());
 +                assertNull(event.getNewValue());
 +                assertFalse(event.getOperation().isLoad());
 +                assertFalse(event.getOperation().isLocalLoad());
 +                assertFalse(event.getOperation().isNetLoad());
 +                assertFalse(event.getOperation().isNetSearch());
 +                assertNull(event.getSerializedOldValue());
 +                assertNull(event.getSerializedNewValue());
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.destroy(key, getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Destroy") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +
 +          // Setup listener for next test
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterRegionInvalidate2(RegionEvent event) {
 +                assertEquals(Operation.REGION_INVALIDATE, event.getOperation());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Invalidate Region") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.invalidateRegion(getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Invalidate Region") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +
 +          // Setup listener for next test
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterRegionDestroy2(RegionEvent event) {
 +                assertEquals(Operation.REGION_DESTROY, event.getOperation());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy Region") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.destroyRegion(getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Destroy Region") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +        }
 +      });
 +  }
 +
 +
 +  /**
 +   * Tests that a {@link CacheListener} is invoked in a remote VM.
 +   */
 +  public void testRemoteCacheListenerInSubregion() throws InterruptedException {
 +    if (!supportsSubregions()) {
 +      return;
 +    }
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    final VM vm0 = host.getVM(0);
 +    final VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create Root") {
 +      public void run2() throws CacheException {
 +        createRootRegion();
 +      }
 +    });
 +
 +    vm1.invoke(create);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set listener") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterRegionInvalidate2(RegionEvent event) {
 +                assertEquals(Operation.REGION_INVALIDATE, event.getOperation());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Invalidate Root Region") {
 +        public void run2() throws CacheException {
 +          getRootRegion().invalidateRegion(getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Invalidate Region") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +
 +          // Setup listener for next test
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          listener = new TestCacheListener() {
 +              public void afterRegionDestroy2(RegionEvent event) {
 +                assertEquals(Operation.REGION_DESTROY, event.getOperation());
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(event.getCallbackArgument(), event.getDistributedMember());
 +              }
 +            };
 +          region.getAttributesMutator().addCacheListener(listener);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy Root Region") {
 +        public void run2() throws CacheException {
 +          getRootRegion().destroyRegion(getSystem().getDistributedMember());
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("Verify Destroy Region") {
 +        public void run2() throws CacheException {
 +          listener.waitForInvocation(3000, 10);
 +        }
 +      });
 +  }
 +
 +
 +  /**
 +   * Indicate whether this region supports netload
 +   * @return true if it supports netload
 +   */
 +  protected boolean supportsNetLoad() {
 +    return true;
 +  }
 +  
 +  /**
 +   * Tests that a {@link CacheLoader} is invoked in a remote VM.  This
 +   * essentially tests <code>netLoad</code>.
 +   */
 +  public void testRemoteCacheLoader() throws InterruptedException {
 +    if (!supportsNetLoad()) {
 +      return;
 +    }
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set CacheLoader") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          loader = new TestCacheLoader() {
 +              public Object load2(LoaderHelper helper)
 +                throws CacheLoaderException {
 +                assertEquals(region, helper.getRegion());
 +                assertEquals(key, helper.getKey());
 +                assertNull(helper.getArgument());
 +
 +                return value;
 +              }
 +            };
 +          region.getAttributesMutator().setCacheLoader(loader);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Remote load") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          assertEquals(value, region.get(key));
 +        }
 +      });
 +
 +    vm1.invoke(new SerializableRunnable("Verify loader") {
 +        public void run() {
 +          assertTrue(loader.wasInvoked());
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Tests that the parameter passed to a remote {@link CacheLoader}
 +   * is actually passed.
 +   */
 +  public void testRemoteCacheLoaderArg() throws InterruptedException {
 +    if (!supportsNetLoad()) {
 +      return;
 +    }
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +    final String arg = "ARG";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +            // Can't test non-Serializable callback argument here
 +            // because netLoad will not occur because there are no
 +            // other members with the region defined when it is
 +            // created.  Hooray for intelligent messaging.
 +          }
 +        };
 +
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set CacheLoader") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          loader = new TestCacheLoader() {
 +              public Object load2(LoaderHelper helper)
 +                throws CacheLoaderException {
 +                assertEquals(region, helper.getRegion());
 +                assertEquals(key, helper.getKey());
 +                assertEquals(arg, helper.getArgument());
 +
 +                return value;
 +              }
 +            };
 +          region.getAttributesMutator().setCacheLoader(loader);
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Remote load") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +
 +          try {
 +            // Use a non-serializable arg object
 +            region.get(key, new Object() { });
 +            fail("Should have thrown an IllegalArgumentException");
 +
 +          } catch (IllegalArgumentException ex) {
 +            // pass...
 +          }
 +          assertNull(region.getEntry(key));
 +          try {
 +           assertEquals(value, region.get(key, arg));
 +          }
 +          catch(IllegalArgumentException e) {}
 +       }
 +      });
 +
 +    vm1.invoke(new SerializableRunnable("Verify loader") {
 +        public void run() {
 +          assertTrue(loader.wasInvoked());
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Tests that a remote {@link CacheLoader} that throws a {@link
 +   * CacheLoaderException} results is propagated back to the caller.
 +   */
 +  public void testRemoteCacheLoaderException() throws InterruptedException {
 +    if (!supportsNetLoad()) {
 +      return;
 +    }
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +//    final Object value = "VALUE";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set CacheLoader") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          loader = new TestCacheLoader() {
 +              public Object load2(LoaderHelper helper)
 +                throws CacheLoaderException {
 +                assertEquals(region, helper.getRegion());
 +                assertEquals(key, helper.getKey());
 +                assertNull(helper.getArgument());
 +
 +                String s = "Test Exception";
 +                throw new CacheLoaderException(s);
 +              }
 +            };
 +          region.getAttributesMutator().setCacheLoader(loader);
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Remote load") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          try {
 +            region.get(key);
 +            fail("Should have thrown a CacheLoaderException");
 +
 +          } catch (CacheLoaderException ex) {
 +            // pass...
 +          }
 +        }
 +      });
 +
 +    vm1.invoke(new SerializableRunnable("Verify loader") {
 +        public void run() {
 +          assertTrue(loader.wasInvoked());
 +        }
 +      });
 +  }
 +
 +
 +  public void testCacheLoaderWithNetSearch() throws CacheException {
 +    if (!supportsNetLoad()) {
 +      return;
 +    }
 +    // some tests use mirroring by default (e.g. persistBackup regions)
 +    // if so, then this test won't work right
 +    if (getRegionAttributes().getDataPolicy().withReplication()
 +        || getRegionAttributes().getDataPolicy().isPreloaded()) {
 +      return;
 +    }
 +
 +    final String name = this.getUniqueName();
 +    final Object key = this.getUniqueName();
 +    final Object value = new Integer(42);
 +
 +    Host host = Host.getHost(0);
 +    // use vm on other gemfire system
 +    VM vm1 = host.getVM(1);
 +    vm1.invoke(new CacheSerializableRunnable("set remote value") {
 +      public void run2() throws CacheException {
 +//        final TestCacheLoader remoteloader = new TestCacheLoader() {
 +//            public Object load2(LoaderHelper helper)
 +//              throws CacheLoaderException {
 +//
 +//              assertEquals(key, helper.getKey());
 +//              assertEquals(name, helper.getRegion().getName());
 +//              return value;
 +//            }
 +//          };
 +//
 +//        AttributesFactory factory =
 +//          new AttributesFactory(getRegionAttributes());
 +//        factory.setCacheLoader(remoteloader);
 +        Region rgn = createRegion(name);
 +        rgn.put(key, value);
 +        flushIfNecessary(rgn);
 +      }
 +    });
 +
 +    final TestCacheLoader loader1 = new TestCacheLoader() {
 +        public Object load2(LoaderHelper helper)
 +          throws CacheLoaderException {
 +
 +          assertEquals(key, helper.getKey());
 +          assertEquals(name, helper.getRegion().getName());
 +
 +          try {
 +            helper.getRegion().getAttributes();
 +            Object result = helper.netSearch(false);
 +            assertEquals(value, result);
 +            return result;
 +          } catch (TimeoutException ex) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("Why did I time out?", ex);
 +          }
 +          return null;
 +        }
 +      };
 +
 +    AttributesFactory f = new AttributesFactory(getRegionAttributes());
 +    f.setCacheLoader(loader1);
 +    Region region =
 +      createRegion(name, f.create());
 +
 +    loader1.wasInvoked();
 +
 +    Region.Entry entry = region.getEntry(key);
 +    assertNull(entry);
 +    region.create(key, null);
 +
 +    entry = region.getEntry(key);
 +    assertNotNull(entry);
 +    assertNull(entry.getValue());
 +
 +    // make sure value is still there in vm1
 +    vm1.invoke(new CacheSerializableRunnable("verify remote value") {
 +      public void run2() throws CacheException {
 +        Region rgn = getRootRegion().getSubregion(name);
 +        assertEquals(value, rgn.getEntry(key).getValue());
 +      }
 +    });
 +
 +//    com.gemstone.gemfire.internal.util.DebuggerSupport.waitForJavaDebugger(getLogWriter());
 +    assertEquals(value, region.get(key));
 +    // if global scope, then a netSearch is done BEFORE the loader is invoked,
 +    // so we get the value but the loader is never invoked.
 +    if (region.getAttributes().getScope().isGlobal()) {
 +      assertTrue(!loader1.wasInvoked());
 +    }
 +    else {
 +      assertTrue(loader1.wasInvoked());
 +    }
 +    assertEquals(value, region.getEntry(key).getValue());
 +  }
 +
 +
 +  public void testCacheLoaderWithNetLoad() throws CacheException {
 +
 +
 +    // replicated regions and partitioned regions make no sense for this
 +    // test
 +    if (getRegionAttributes().getDataPolicy().withReplication() ||
 +        getRegionAttributes().getDataPolicy().isPreloaded() ||
 +        getRegionAttributes().getPartitionAttributes() != null)
 +    {
 +      return;
 +    }
 +
 +    final String name = this.getUniqueName();
 +    final Object key = this.getUniqueName();
 +    final Object value = new Integer(42);
 +
 +    Host host = Host.getHost(0);
 +    // use vm on other gemfire system
 +    VM vm1 = host.getVM(1);
 +    vm1.invoke(new CacheSerializableRunnable("set up remote loader") {
 +      public void run2() throws CacheException {
 +        final TestCacheLoader remoteloader = new TestCacheLoader() {
 +            public Object load2(LoaderHelper helper)
 +              throws CacheLoaderException {
 +
 +              assertEquals(key, helper.getKey());
 +              assertEquals(name, helper.getRegion().getName());
 +              return value;
 +            }
 +          };
 +
 +        AttributesFactory factory =
 +          new AttributesFactory(getRegionAttributes());
 +        factory.setCacheLoader(remoteloader);
 +        createRegion(name, factory.create());
 +      }
 +    });
 +
 +    final TestCacheLoader loader1 = new TestCacheLoader() {
 +        public Object load2(LoaderHelper helper)
 +          throws CacheLoaderException {
 +
 +          assertEquals(key, helper.getKey());
 +          assertEquals(name, helper.getRegion().getName());
 +
 +          try {
 +            helper.getRegion().getAttributes();
 +            Object result = helper.netSearch(true);
 +            assertEquals(value, result);
 +            return result;
 +          } catch (TimeoutException ex) {
 +            com.gemstone.gemfire.test.dunit.Assert.fail("Why did I time out?", ex);
 +          }
 +          return null;
 +        }
 +      };
 +
 +    AttributesFactory f = new AttributesFactory(getRegionAttributes());
 +    f.setCacheLoader(loader1);
 +    Region region = createRegion(name, f.create());
 +
 +    loader1.wasInvoked();
 +
 +    Region.Entry entry = region.getEntry(key);
 +    assertNull(entry);
 +
 +    region.create(key, null);
 +
 +    entry = region.getEntry(key);
 +    assertNotNull(entry);
 +    assertNull(entry.getValue());
 +
 +//    com.gemstone.gemfire.internal.util.DebuggerSupport.waitForJavaDebugger(getLogWriter());
 +    assertEquals(value, region.get(key));
 +
 +    assertTrue(loader1.wasInvoked());
 +    assertEquals(value, region.getEntry(key).getValue());
 +  }
 +
 +
 +  /**
 +   * Tests that {@link Region#get} returns <code>null</code> when
 +   * there is no remote loader.
 +   */
 +  public void testNoRemoteCacheLoader() throws InterruptedException {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +//    final Object value = "VALUE";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            createRegion(name);
 +          }
 +        };
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Remote load") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          assertNull(region.get(key));
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Tests that a remote <code>CacheLoader</code> is not invoked if
 +   * the remote region has an invalid entry (that is, a key, but no
 +   * value).
 +   */
 +  public void testNoLoaderWithInvalidEntry() {
 +    if (!supportsNetLoad()) {
 +      return;
 +    }
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object value = "VALUE";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            Region region = createRegion(name);
 +            loader = new TestCacheLoader() {
 +                public Object load2(LoaderHelper helper)
 +                  throws CacheLoaderException {
 +
 +                  return value;
 +                }
 +              };
 +            region.getAttributesMutator().setCacheLoader(loader);
 +          }
 +        };
 +
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    vm1.invoke(new CacheSerializableRunnable("Create invalid entry") {
 +      public void run2() throws CacheException {
 +        Region region =
 +          getRootRegion().getSubregion(name);
 +          region.create(key, null);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Remote get") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +// DebuggerSupport.waitForJavaDebugger(getLogWriter());
 +          assertEquals(value, region.get(key));
 +          assertTrue(loader.wasInvoked());
 +        }
 +      });
 +
 +    vm1.invoke(new SerializableRunnable("Verify loader") {
 +        public void run() {
 +          assertFalse(loader.wasInvoked());
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Tests that a remote {@link CacheWriter} is invoked and that
 +   * <code>CacheWriter</code> arguments and {@link
 +   * CacheWriterException}s are propagated appropriately.
 +   */
 +  public void testRemoteCacheWriter() throws InterruptedException {
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object oldValue = "OLD_VALUE";
 +    final Object newValue = "NEW_VALUE";
 +    final Object arg = "ARG";
 +    final Object exception = "EXCEPTION";
 +
 +    final Object key2 = "KEY2";
 +    final Object value2 = "VALUE2";
 +
 +    SerializableRunnable create =
 +      new CacheSerializableRunnable("Create Region") {
 +          public void run2() throws CacheException {
 +            Region region = createRegion(name);
 +
 +            // Put key2 in the region before any callbacks are
 +            // registered, so it can be destroyed later
 +            region.put(key2, value2);
 +            assertEquals(1, region.size());
 +            if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +              GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +              SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +              LocalRegion reRegion;
 +              reRegion = (LocalRegion) region;
 +              RegionEntry re = reRegion.getRegionEntry(key2);
 +              MemoryChunkWithRefCount mc = (MemoryChunkWithRefCount) re._getValue();
 +              assertEquals(1, mc.getRefCount());
 +              assertEquals(1, ma.getStats().getObjects());
 +            }
 +          }
 +        };
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(create);
 +    vm1.invoke(create);
 +
 +    ////////  Create
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set Writer") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          writer = new TestCacheWriter() {
 +              public void beforeCreate2(EntryEvent event)
 +                throws CacheWriterException {
 +
 +                if (exception.equals(event.getCallbackArgument())) {
 +                  String s = "Test Exception";
 +                  throw new CacheWriterException(s);
 +                }
 +
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isCreate());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(key, event.getKey());
 +                assertEquals(null, event.getOldValue());
 +                assertEquals(oldValue, event.getNewValue());
 +                assertFalse(event.getOperation().isLoad());
 +                assertFalse(event.getOperation().isLocalLoad());
 +                assertFalse(event.getOperation().isNetLoad());
 +                assertFalse(event.getOperation().isNetSearch());
 +
 +              }
 +            };
 +          region.getAttributesMutator().setCacheWriter(writer);
 +          flushIfNecessary(region);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create with Exception") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          try {
 +            region.put(key, oldValue, exception);
 +            fail("Should have thrown a CacheWriterException");
 +
 +          } catch (CacheWriterException ex) {
 +            assertNull(region.getEntry(key));
 +            assertEquals(1, region.size());
 +            if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +              GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +              SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +              assertEquals(1, ma.getStats().getObjects());
 +            }
 +          }
 +        }
 +      });
 +
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create with Argument") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.put(key, oldValue, arg);
 +          assertEquals(2, region.size());
 +          if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +            GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +            SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +            assertEquals(2, ma.getStats().getObjects());
 +            LocalRegion reRegion;
 +            reRegion = (LocalRegion) region;
 +            MemoryChunkWithRefCount mc = (MemoryChunkWithRefCount) reRegion.getRegionEntry(key)._getValue();
 +            assertEquals(1, mc.getRefCount());
 +          }
 +        }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    ////////  Update
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set Writer") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          writer = new TestCacheWriter() {
 +              public void beforeUpdate2(EntryEvent event)
 +                throws CacheWriterException {
 +
 +                Object argument = event.getCallbackArgument();
 +                if (exception.equals(argument)) {
 +                  String s = "Test Exception";
 +                  throw new CacheWriterException(s);
 +                }
 +
 +                assertEquals(arg, argument);
 +
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isUpdate());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(key, event.getKey());
 +                assertEquals(oldValue, event.getOldValue());
 +                assertEquals(newValue, event.getNewValue());
 +                assertFalse(event.getOperation().isLoad());
 +                assertFalse(event.getOperation().isLocalLoad());
 +                assertFalse(event.getOperation().isNetLoad());
 +                assertFalse(event.getOperation().isNetSearch());
 +
 +              }
 +            };
 +          region.getAttributesMutator().setCacheWriter(writer);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Update with Exception") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          try {
 +            region.put(key, newValue, exception);
 +            fail("Should have thrown a CacheWriterException");
 +
 +          } catch (CacheWriterException ex) {
 +            Region.Entry entry = region.getEntry(key);
 +            assertEquals(oldValue, entry.getValue());
 +            assertEquals(2, region.size());
 +            if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +              GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +              SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +              assertEquals(2, ma.getStats().getObjects());
 +              LocalRegion reRegion;
 +              reRegion = (LocalRegion) region;
 +              MemoryChunkWithRefCount mc = (MemoryChunkWithRefCount) reRegion.getRegionEntry(key)._getValue();
 +              assertEquals(1, mc.getRefCount());
 +            }
 +          }
 +        }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Update with Argument") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.put(key, newValue, arg);
 +          assertEquals(2, region.size());
 +          if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +            GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +            SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +            assertEquals(2, ma.getStats().getObjects());
 +          }
 +        }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    ////////  Destroy
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set Writer") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          writer = new TestCacheWriter() {
 +              public void beforeDestroy2(EntryEvent event)
 +                throws CacheWriterException {
 +
 +                Object argument = event.getCallbackArgument();
 +                if (exception.equals(argument)) {
 +                  String s = "Test Exception";
 +                  throw new CacheWriterException(s);
 +                }
 +
 +                assertEquals(arg, argument);
 +
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isDestroy());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +                assertEquals(key, event.getKey());
 +                assertEquals(newValue, event.getOldValue());
 +                assertNull(event.getNewValue());
 +                assertFalse(event.getOperation().isLoad());
 +                assertFalse(event.getOperation().isLocalLoad());
 +                assertFalse(event.getOperation().isNetLoad());
 +                assertFalse(event.getOperation().isNetSearch());
 +              }
 +            };
 +          region.getAttributesMutator().setCacheWriter(writer);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy with Exception") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          try {
 +            region.destroy(key, exception);
 +            fail("Should have thrown a CacheWriterException");
 +
 +          } catch (CacheWriterException ex) {
 +            assertNotNull(region.getEntry(key));
 +            assertEquals(2, region.size());
 +            if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +              GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +              SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +              assertEquals(2, ma.getStats().getObjects());
 +            }
 +          }
 +        }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy with Argument") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          region.destroy(key, arg);
 +          assertEquals(1, region.size());
 +          if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +            GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +            SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +            assertEquals(1, ma.getStats().getObjects());
 +          }
 +       }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    ////////  Region Destroy
 +
 +    vm1.invoke(new CacheSerializableRunnable("Set Writer") {
 +        public void run2() throws CacheException {
 +          final Region region =
 +            getRootRegion().getSubregion(name);
 +          writer = new TestCacheWriter() {
 +              public void beforeRegionDestroy2(RegionEvent event)
 +                throws CacheWriterException {
 +
 +                Object argument = event.getCallbackArgument();
 +                if (exception.equals(argument)) {
 +                  String s = "Test Exception";
 +                  throw new CacheWriterException(s);
 +                }
 +
 +                assertEquals(arg, argument);
 +
 +                assertEquals(region, event.getRegion());
 +                assertTrue(event.getOperation().isRegionDestroy());
 +                assertTrue(event.getOperation().isDistributed());
 +                assertFalse(event.getOperation().isExpiration());
 +                assertTrue(event.isOriginRemote());
 +              }
 +            };
 +          region.getAttributesMutator().setCacheWriter(writer);
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy with Exception") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          try {
 +            region.destroyRegion(exception);
 +            fail("Should have thrown a CacheWriterException");
 +
 +          } catch (CacheWriterException ex) {
 +            if (region.isDestroyed()) {
 +              com.gemstone.gemfire.test.dunit.Assert.fail("should not have an exception if region is destroyed", ex);
 +            }
 +            assertEquals(1, region.size());
 +            if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +              GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +              SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +              assertEquals(1, ma.getStats().getObjects());
 +            }
 +          }
 +        }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +
 +    vm0.invoke(new CacheSerializableRunnable("Destroy with Argument") {
 +        public void run2() throws CacheException {
 +          Region region =
 +            getRootRegion().getSubregion(name);
 +          assertEquals(1, region.size());
 +          if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +            GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +            SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +            assertEquals(1, ma.getStats().getObjects());
 +          }
 +          region.destroyRegion(arg);
 +          if (region.getAttributes().getOffHeap() && !(region instanceof PartitionedRegion)) {
 +            GemFireCacheImpl gfc = (GemFireCacheImpl) getCache();
 +            final SimpleMemoryAllocatorImpl ma = (SimpleMemoryAllocatorImpl) gfc.getOffHeapStore();
 +            WaitCriterion waitForStatChange = new WaitCriterion() {
 +              public boolean done() {
 +                return ma.getStats().getObjects() == 0;
 +              }
 +              public String description() {
 +                return "never saw off-heap object count go to zero. Last value was " + ma.getStats().getObjects();
 +              }
 +            };
 +            Wait.waitForCriterion(waitForStatChange, 3000, 10, true);
 +          }
 +        }
 +      });
 +    vm1.invoke(new SerializableRunnable("Verify callback") {
 +        public void run() {
 +          assertTrue(writer.wasInvoked());
 +        }
 +      });
 +  }
 +
 +  /**
 +   * Tests that, when given a choice, a local <code>CacheWriter</code>
 +   * is invoked instead of a remote one.
 +   */
 +  public void testLocalAndRemoteCacheWriters()
 +    throws InterruptedException {
 +
 +    assertTrue(getRegionAttributes().getScope().isDistributed());
 +
 +    final String name = this.getUniqueName();
 +    final Object key = "KEY";
 +    final Object oldValue = "OLD_VALUE";
 +    final Object newValue = "NEW_VALUE";
 +
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +
 +    vm0.invoke(new CacheSerializableRunnable("Create \"Local\" Region") {
 +        public void run2() throws CacheException {
 +          Region region = createRegion(name);
 +          writer = new TestCacheWriter() {
 +              public void beforeUpdate2(EntryEvent event)
 +                throws CacheWriterException { }
 +
 +              p

<TRUNCATED>


[057/100] [abbrv] incubator-geode git commit: GEODE-831: unit test FreeListManager

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
index 12d297b..14bde59 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
@@ -55,47 +55,20 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
  * @author Kirk Lund
  * @since 9.0
  */
-public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
+public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   static final Logger logger = LogService.getLogger();
   
   public static final String FREE_OFF_HEAP_MEMORY_PROPERTY = "gemfire.free-off-heap-memory";
   
-  /**
-   * How many extra allocations to do for each actual slab allocation.
-   * Is this really a good idea?
-   */
-  public static final int BATCH_SIZE = Integer.getInteger("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE", 1);
-  /**
-   * Every allocated chunk smaller than TINY_MULTIPLE*TINY_FREE_LIST_COUNT will allocate a chunk of memory that is a multiple of this value.
-   * Sizes are always rounded up to the next multiple of this constant
-   * so internal fragmentation will be limited to TINY_MULTIPLE-1 bytes per allocation
-   * and on average will be TINY_MULTIPLE/2 given a random distribution of size requests.
-   * This does not account for the additional internal fragmentation caused by the off-heap header
-   * which currently is always 8 bytes.
-   */
-  public final static int TINY_MULTIPLE = Integer.getInteger("gemfire.OFF_HEAP_ALIGNMENT", 8);
-  /**
-   * Number of free lists to keep for tiny allocations.
-   */
-  public final static int TINY_FREE_LIST_COUNT = Integer.getInteger("gemfire.OFF_HEAP_FREE_LIST_COUNT", 16384);
-  public final static int MAX_TINY = TINY_MULTIPLE*TINY_FREE_LIST_COUNT;
-  /**
-   * How many unused bytes are allowed in a huge memory allocation.
-   */
-  public final static int HUGE_MULTIPLE = 256;
-  
-  volatile OffHeapMemoryStats stats;
+  private volatile OffHeapMemoryStats stats;
   
-  volatile OutOfOffHeapMemoryListener ooohml;
-  
-  /** The MemoryChunks that this allocator is managing by allocating smaller chunks of them.
-   * The contents of this array never change.
-   */
-  private final UnsafeMemoryChunk[] slabs;
-  private final long totalSlabSize;
-  private final int largestSlab;
+  private volatile OutOfOffHeapMemoryListener ooohml;
   
+  OutOfOffHeapMemoryListener getOutOfOffHeapMemoryListener() {
+    return this.ooohml;
+  }
+
   public final FreeListManager freeList;
 
   private MemoryInspector memoryInspector;
@@ -103,7 +76,6 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   private volatile MemoryUsageListener[] memoryUsageListeners = new MemoryUsageListener[0];
   
   private static SimpleMemoryAllocatorImpl singleton = null;
-  final ChunkFactory chunkFactory;
   
   public static SimpleMemoryAllocatorImpl getAllocator() {
     SimpleMemoryAllocatorImpl result = singleton;
@@ -118,10 +90,9 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   public static MemoryAllocator create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
       int slabCount, long offHeapMemorySize, long maxSlabSize) {
     return create(ooohml, stats, lw, slabCount, offHeapMemorySize, maxSlabSize,
-        null, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE, 
-        new UnsafeMemoryChunk.Factory() {
+        null, new AddressableMemoryChunkFactory() {
       @Override
-      public UnsafeMemoryChunk create(int size) {
+      public AddressableMemoryChunk create(int size) {
         return new UnsafeMemoryChunk(size);
       }
     });
@@ -129,15 +100,14 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   private static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
       int slabCount, long offHeapMemorySize, long maxSlabSize, 
-      UnsafeMemoryChunk[] slabs, int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple,
-      UnsafeMemoryChunk.Factory memChunkFactory) {
+      AddressableMemoryChunk[] slabs, AddressableMemoryChunkFactory memChunkFactory) {
     SimpleMemoryAllocatorImpl result = singleton;
     boolean created = false;
     try {
     if (result != null) {
       result.reuse(ooohml, lw, stats, offHeapMemorySize, slabs);
       if (lw != null) {
-        lw.config("Reusing " + result.getTotalMemory() + " bytes of off-heap memory. The maximum size of a single off-heap object is " + result.largestSlab + " bytes.");
+        lw.config("Reusing " + result.getTotalMemory() + " bytes of off-heap memory. The maximum size of a single off-heap object is " + result.freeList.getLargestSlabSize() + " bytes.");
       }
       created = true;
       LifecycleListener.invokeAfterReuse(result);
@@ -175,7 +145,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         }
       }
 
-      result = new SimpleMemoryAllocatorImpl(ooohml, stats, slabs, tinyMultiple, batchSize, tinyFreeListCount, hugeMultiple);
+      result = new SimpleMemoryAllocatorImpl(ooohml, stats, slabs);
       singleton = result;
       LifecycleListener.invokeAfterCreate(result);
       created = true;
@@ -192,19 +162,12 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     }
     return result;
   }
-  // for unit tests
-  static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
-      int slabCount, long offHeapMemorySize, long maxSlabSize, UnsafeMemoryChunk.Factory memChunkFactory) {
+  static SimpleMemoryAllocatorImpl createForUnitTest(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
+      int slabCount, long offHeapMemorySize, long maxSlabSize, AddressableMemoryChunkFactory memChunkFactory) {
     return create(ooohml, stats, lw, slabCount, offHeapMemorySize, maxSlabSize, 
-        null, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE, memChunkFactory);
-  }
-  // for unit tests
-  public static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, UnsafeMemoryChunk[] slabs) {
-    return create(oooml, stats, slabs, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE);
+        null, memChunkFactory);
   }
-  // for unit tests
-  static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, UnsafeMemoryChunk[] slabs,
-      int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple) {
+  public static SimpleMemoryAllocatorImpl createForUnitTest(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, AddressableMemoryChunk[] slabs) {
     int slabCount = 0;
     long offHeapMemorySize = 0;
     long maxSlabSize = 0;
@@ -218,11 +181,11 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         }
       }
     }
-    return create(oooml, stats, null, slabCount, offHeapMemorySize, maxSlabSize, slabs, tinyMultiple, batchSize, tinyFreeListCount, hugeMultiple, null);
+    return create(oooml, stats, null, slabCount, offHeapMemorySize, maxSlabSize, slabs, null);
   }
   
   
-  private void reuse(OutOfOffHeapMemoryListener oooml, LogWriter lw, OffHeapMemoryStats newStats, long offHeapMemorySize, UnsafeMemoryChunk[] slabs) {
+  private void reuse(OutOfOffHeapMemoryListener oooml, LogWriter lw, OffHeapMemoryStats newStats, long offHeapMemorySize, AddressableMemoryChunk[] slabs) {
     if (isClosed()) {
       throw new IllegalStateException("Can not reuse a closed off-heap memory manager.");
     }
@@ -234,83 +197,47 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         lw.warning("Using " + getTotalMemory() + " bytes of existing off-heap memory instead of the requested " + offHeapMemorySize);
       }
     }
-    if (slabs != null) {
-      // this will only happen in unit tests
-      if (slabs != this.slabs) {
-        // If the unit test gave us a different array
-        // of slabs then something is wrong because we
-        // are trying to reuse the old already allocated
-        // array which means that the new one will never
-        // be used. Note that this code does not bother
-        // comparing the contents of the arrays.
-        throw new IllegalStateException("attempted to reuse existing off-heap memory even though new off-heap memory was allocated");
-      }
+    if (!this.freeList.okToReuse(slabs)) {
+      throw new IllegalStateException("attempted to reuse existing off-heap memory even though new off-heap memory was allocated");
     }
     this.ooohml = oooml;
     newStats.initialize(this.stats);
     this.stats = newStats;
   }
 
-  private SimpleMemoryAllocatorImpl(final OutOfOffHeapMemoryListener oooml, final OffHeapMemoryStats stats, final UnsafeMemoryChunk[] slabs,
-      int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple) {
+  private SimpleMemoryAllocatorImpl(final OutOfOffHeapMemoryListener oooml, final OffHeapMemoryStats stats, final AddressableMemoryChunk[] slabs) {
     if (oooml == null) {
       throw new IllegalArgumentException("OutOfOffHeapMemoryListener is null");
     }
-    if (tinyMultiple <= 0 || (tinyMultiple & 3) != 0) {
-      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8.");
-    }
-    if (tinyMultiple > 256) {
-      // this restriction exists because of the dataSize field in the object header.
-      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be <= 256 and a multiple of 8.");
-    }
-    if (batchSize <= 0) {
-      throw new IllegalStateException("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE must be >= 1.");
-    }
-    if (tinyFreeListCount <= 0) {
-      throw new IllegalStateException("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
-    }
-    if (hugeMultiple > 256 || hugeMultiple < 0) {
-      // this restriction exists because of the dataSize field in the object header.
-      throw new IllegalStateException("HUGE_MULTIPLE must be >= 0 and <= 256 but it was " + hugeMultiple);
-    }
     
     this.ooohml = oooml;
     this.stats = stats;
-    this.slabs = slabs;
-    this.chunkFactory = new GemFireChunkFactory();
-    
+
     //OSProcess.printStacks(0, InternalDistributedSystem.getAnyInstance().getLogWriter(), false);
     this.stats.setFragments(slabs.length);
-    largestSlab = slabs[0].getSize();
-    this.stats.setLargestFragment(largestSlab);
-    long total = 0;
-    for (int i=0; i < slabs.length; i++) {
-      //debugLog("slab"+i + " @" + Long.toHexString(slabs[i].getMemoryAddress()), false);
-      //UnsafeMemoryChunk.clearAbsolute(slabs[i].getMemoryAddress(), slabs[i].getSize()); // HACK to see what this does to bug 47883
-      total += slabs[i].getSize();
-    }
-    totalSlabSize = total;
-    this.stats.incMaxMemory(this.totalSlabSize);
-    this.stats.incFreeMemory(this.totalSlabSize);
+    this.stats.setLargestFragment(slabs[0].getSize());
     
-    this.freeList = new FreeListManager(this);
+    this.freeList = new FreeListManager(this, slabs);
     this.memoryInspector = new MemoryInspectorImpl(this.freeList);
+
+    this.stats.incMaxMemory(this.freeList.getTotalMemory());
+    this.stats.incFreeMemory(this.freeList.getTotalMemory());
   }
   
-  public List<Chunk> getLostChunks() {
-    List<Chunk> liveChunks = this.freeList.getLiveChunks();
-    List<Chunk> regionChunks = getRegionLiveChunks();
-    Set<Chunk> liveChunksSet = new HashSet<>(liveChunks);
-    Set<Chunk> regionChunksSet = new HashSet<>(regionChunks);
+  public List<ObjectChunk> getLostChunks() {
+    List<ObjectChunk> liveChunks = this.freeList.getLiveChunks();
+    List<ObjectChunk> regionChunks = getRegionLiveChunks();
+    Set<ObjectChunk> liveChunksSet = new HashSet<>(liveChunks);
+    Set<ObjectChunk> regionChunksSet = new HashSet<>(regionChunks);
     liveChunksSet.removeAll(regionChunksSet);
-    return new ArrayList<Chunk>(liveChunksSet);
+    return new ArrayList<ObjectChunk>(liveChunksSet);
   }
   
   /**
    * Returns a possibly empty list that contains all the Chunks used by regions.
    */
-  private List<Chunk> getRegionLiveChunks() {
-    ArrayList<Chunk> result = new ArrayList<Chunk>();
+  private List<ObjectChunk> getRegionLiveChunks() {
+    ArrayList<ObjectChunk> result = new ArrayList<ObjectChunk>();
     RegionService gfc = GemFireCacheImpl.getInstance();
     if (gfc != null) {
       Iterator<Region<?,?>> rootIt = gfc.rootRegions().iterator();
@@ -326,7 +253,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     return result;
   }
 
-  private void getRegionLiveChunks(Region<?,?> r, List<Chunk> result) {
+  private void getRegionLiveChunks(Region<?,?> r, List<ObjectChunk> result) {
     if (r.getAttributes().getOffHeap()) {
 
       if (r instanceof PartitionedRegion) {
@@ -350,7 +277,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   }
   
-  private void basicGetRegionLiveChunks(LocalRegion r, List<Chunk> result) {
+  private void basicGetRegionLiveChunks(LocalRegion r, List<ObjectChunk> result) {
     for (Object key : r.keySet()) {
       RegionEntry re = ((LocalRegion) r).getRegionEntry(key);
       if (re != null) {
@@ -359,24 +286,34 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
          */
         @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
         Object value = re._getValue();
-        if (value instanceof Chunk) {
-          result.add((Chunk) value);
+        if (value instanceof ObjectChunk) {
+          result.add((ObjectChunk) value);
         }
       }
     }
   }
 
-  @Override
-  public MemoryChunk allocate(int size, ChunkType chunkType) {
-    //System.out.println("allocating " + size);
-    Chunk result = this.freeList.allocate(size, chunkType);
-    //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
+  private ObjectChunk allocateChunk(int size) {
+    ObjectChunk result = this.freeList.allocate(size);
+    int resultSize = result.getSize();
+    stats.incObjects(1);
+    stats.incUsedMemory(resultSize);
+    stats.incFreeMemory(-resultSize);
+    notifyListeners();
     if (ReferenceCountHelper.trackReferenceCounts()) {
       ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
     }
     return result;
   }
   
+  @Override
+  public MemoryChunk allocate(int size) {
+    //System.out.println("allocating " + size);
+    ObjectChunk result = allocateChunk(size);
+    //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
+    return result;
+  }
+  
   public static void debugLog(String msg, boolean logStack) {
     if (logStack) {
       logger.info(msg, new RuntimeException(msg));
@@ -386,22 +323,14 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   }
   
   @Override
-  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed, ChunkType chunkType) {
+  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed) {
     long addr = OffHeapRegionEntryHelper.encodeDataAsAddress(v, isSerialized, isCompressed);
     if (addr != 0L) {
       return new DataAsAddress(addr);
     }
-    if (chunkType == null) {
-      chunkType = GemFireChunk.TYPE;
-    }
-
-    Chunk result = this.freeList.allocate(v.length, chunkType);
+    ObjectChunk result = allocateChunk(v.length);
     //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()), true);
     //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()) +  "chunkSize=" + result.getSize() + " isSerialized=" + isSerialized + " v=" + Arrays.toString(v), true);
-    if (ReferenceCountHelper.trackReferenceCounts()) {
-      ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
-    }
-    assert result.getChunkType() == chunkType: "chunkType=" + chunkType + " getChunkType()=" + result.getChunkType();
     result.setSerializedValue(v);
     result.setSerialized(isSerialized);
     result.setCompressed(isCompressed);
@@ -420,7 +349,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   @Override
   public long getTotalMemory() {
-    return totalSlabSize;
+    return this.freeList.getTotalMemory();
   }
   
   @Override
@@ -445,7 +374,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   private void realClose() {
     // Removing this memory immediately can lead to a SEGV. See 47885.
     if (setClosed()) {
-      freeSlabs(this.slabs);
+      this.freeList.freeSlabs();
       this.stats.close();
       singleton = null;
     }
@@ -464,45 +393,21 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   }
   
 
-  private static void freeSlabs(final UnsafeMemoryChunk[] slabs) {
-    //debugLog("called freeSlabs", false);
-    for (int i=0; i < slabs.length; i++) {
-      slabs[i].release();
-    }
-  }
-  
-  void freeChunk(long addr) {
-    this.freeList.free(addr);
-  }
-  
-  protected UnsafeMemoryChunk[] getSlabs() {
-    return this.slabs;
+  FreeListManager getFreeListManager() {
+    return this.freeList;
   }
   
   /**
    * Return the slabId of the slab that contains the given addr.
    */
   int findSlab(long addr) {
-    for (int i=0; i < this.slabs.length; i++) {
-      UnsafeMemoryChunk slab = this.slabs[i];
-      long slabAddr = slab.getMemoryAddress();
-      if (addr >= slabAddr) {
-        if (addr < slabAddr + slab.getSize()) {
-          return i;
-        }
-      }
-    }
-    throw new IllegalStateException("could not find a slab for addr " + addr);
+    return this.freeList.findSlab(addr);
   }
   
   public OffHeapMemoryStats getStats() {
     return this.stats;
   }
   
-  public ChunkFactory getChunkFactory() {
-    return this.chunkFactory;
-  }
-
   @Override
   public void addMemoryUsageListener(final MemoryUsageListener listener) {
     synchronized (this.memoryUsageListeners) {
@@ -558,12 +463,8 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
       SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.singleton;
       if (ma != null) {
         sb.append(". Valid addresses must be in one of the following ranges: ");
-        for (int i=0; i < ma.slabs.length; i++) {
-          long startAddr = ma.slabs[i].getMemoryAddress();
-          long endAddr = startAddr + ma.slabs[i].getSize();
-          sb.append("[").append(Long.toString(startAddr, 16)).append("..").append(Long.toString(endAddr, 16)).append("] ");
-        }
-      }
+        ma.freeList.getSlabDescriptions(sb);
+     }
       throw new IllegalStateException(sb.toString());
     }
     if (addr >= 0 && addr < 1024) {
@@ -576,28 +477,19 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     if (doExpensiveValidation) {
       SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.singleton;
       if (ma != null) {
-        for (int i=0; i < ma.slabs.length; i++) {
-          if (ma.slabs[i].getMemoryAddress() <= addr && addr < (ma.slabs[i].getMemoryAddress() + ma.slabs[i].getSize())) {
-            // validate addr + size is within the same slab
-            if (size != -1) { // skip this check if size is -1
-              if (!(ma.slabs[i].getMemoryAddress() <= (addr+size-1) && (addr+size-1) < (ma.slabs[i].getMemoryAddress() + ma.slabs[i].getSize()))) {
-                throw new IllegalStateException(" address 0x" + Long.toString(addr+size-1, 16) + " does not address the original slab memory");
-              }
-            }
-            return;
-          }
+        if (!ma.freeList.validateAddressAndSizeWithinSlab(addr, size)) {
+          throw new IllegalStateException(" address 0x" + Long.toString(addr, 16) + " does not address the original slab memory");
         }
-        throw new IllegalStateException(" address 0x" + Long.toString(addr, 16) + " does not address the original slab memory");
       }
     }
   }
 
   public synchronized List<MemoryBlock> getOrphans() {
-    List<Chunk> liveChunks = this.freeList.getLiveChunks();
-    List<Chunk> regionChunks = getRegionLiveChunks();
+    List<ObjectChunk> liveChunks = this.freeList.getLiveChunks();
+    List<ObjectChunk> regionChunks = getRegionLiveChunks();
     liveChunks.removeAll(regionChunks);
     List<MemoryBlock> orphans = new ArrayList<MemoryBlock>();
-    for (Chunk chunk: liveChunks) {
+    for (ObjectChunk chunk: liveChunks) {
       orphans.add(new MemoryBlockNode(this, chunk));
     }
     Collections.sort(orphans,
@@ -615,11 +507,5 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   public MemoryInspector getMemoryInspector() {
     return this.memoryInspector;
   }
-
-  /*
-   * Set this to "true" to perform data integrity checks on allocated and reused Chunks.  This may clobber 
-   * performance so turn on only when necessary.
-   */
-  final boolean validateMemoryWithFill = Boolean.getBoolean("gemfire.validateOffHeapWithFill");
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
index 7ba28a2..99fd96f 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
@@ -42,7 +42,7 @@ public class SyncChunkStack {
     assert e != 0;
     SimpleMemoryAllocatorImpl.validateAddress(e);
     synchronized (this) {
-      Chunk.setNext(e, this.topAddr);
+      ObjectChunk.setNext(e, this.topAddr);
       this.topAddr = e;
     }
   }
@@ -51,7 +51,7 @@ public class SyncChunkStack {
     synchronized (this) {
       result = this.topAddr;
       if (result != 0L) {
-        this.topAddr = Chunk.getNext(result);
+        this.topAddr = ObjectChunk.getNext(result);
       }
     }
     return result;
@@ -85,8 +85,8 @@ public class SyncChunkStack {
       concurrentModDetected = false;
       addr = headAddr;
       while (addr != 0L) {
-        int curSize = Chunk.getSize(addr);
-        addr = Chunk.getNext(addr);
+        int curSize = ObjectChunk.getSize(addr);
+        addr = ObjectChunk.getNext(addr);
         testHookDoConcurrentModification();
         long curHead = this.topAddr;
         if (curHead != headAddr) {
@@ -113,8 +113,8 @@ public class SyncChunkStack {
       result = 0;
       addr = headAddr;
       while (addr != 0L) {
-        result += Chunk.getSize(addr);
-        addr = Chunk.getNext(addr);
+        result += ObjectChunk.getSize(addr);
+        addr = ObjectChunk.getNext(addr);
         testHookDoConcurrentModification();
         long curHead = this.topAddr;
         if (curHead != headAddr) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
index ed1c843..aebc459 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
@@ -25,7 +25,7 @@ import com.gemstone.gemfire.pdx.internal.unsafe.UnsafeWrapper;
  * 
  * @since 9.0
  */
-public class UnsafeMemoryChunk implements MemoryChunk {
+public class UnsafeMemoryChunk implements AddressableMemoryChunk {
   private static final UnsafeWrapper unsafe;
   private static final int ARRAY_BYTE_BASE_OFFSET;
   private static String reason;
@@ -70,6 +70,10 @@ public class UnsafeMemoryChunk implements MemoryChunk {
     return (int)this.size;
   }
   
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.internal.offheap.AddressableMemoryChunk#getMemoryAddress()
+   */
+  @Override
   public long getMemoryAddress() {
     return this.data;
   }
@@ -210,14 +214,4 @@ public class UnsafeMemoryChunk implements MemoryChunk {
     sb.append("}");
     return sb.toString();
   }
-  
-  /**
-   * Used to create UnsafeMemoryChunk instances.
-   */
-  public interface Factory {
-    /** Create and return an UnsafeMemoryChunk.
-     * @throws OutOfMemoryError if the create fails
-     */
-    public UnsafeMemoryChunk create(int size);
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
index 8a7d351..cfc05f2 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
@@ -31,7 +31,7 @@ import java.nio.ByteOrder;
 
 import com.gemstone.gemfire.internal.ByteBufferWriter;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
 
 /**
@@ -109,7 +109,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     public static ByteSource create(ByteBuffer bb) {
       return new ByteBufferByteSource(bb);
     }
-    public static ByteSource create(Chunk chunk) {
+    public static ByteSource create(ObjectChunk chunk) {
       // Since I found a way to create a DirectByteBuffer (using reflection) from a Chunk
       // we might not even need the ByteSource abstraction any more.
       // But it is possible that createByteBuffer will not work on a different jdk so keep it for now.
@@ -323,9 +323,9 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
   public static class OffHeapByteSource implements ByteSource {
     private int position;
     private int limit;
-    private final Chunk chunk;
+    private final ObjectChunk chunk;
 
-    public OffHeapByteSource(Chunk c) {
+    public OffHeapByteSource(ObjectChunk c) {
       this.chunk = c;
       this.position = 0;
       this.limit = capacity();
@@ -724,7 +724,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     this.buffer = copy.buffer.duplicate();
   }
 
-  public ByteBufferInputStream(Chunk blob) {
+  public ByteBufferInputStream(ObjectChunk blob) {
     this.buffer = ByteSourceFactory.create(blob);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
index 52f332f..d632158 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
@@ -18,7 +18,7 @@ package com.gemstone.gemfire.internal.tcp;
 
 import java.nio.ByteBuffer;
 
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 
 /**
  * You should only create an instance of this class if the bytes this buffer reads
@@ -67,7 +67,7 @@ public class ImmutableByteBufferInputStream extends ByteBufferInputStream {
     // for serialization
   }
   
-  public ImmutableByteBufferInputStream(Chunk blob) {
+  public ImmutableByteBufferInputStream(ObjectChunk blob) {
     super(blob);
   }
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
index 7a4840e..40015a4 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
@@ -27,7 +27,7 @@ import com.gemstone.gemfire.internal.DSCODE;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 import com.gemstone.gemfire.pdx.internal.PdxInputStream;
 
@@ -140,7 +140,7 @@ public class BlobHelper {
    * If a PdxInstance is returned then it will refer to Chunk's off-heap memory
    * with an unretained reference.
    */
-  public static @Unretained Object deserializeOffHeapBlob(Chunk blob) throws IOException, ClassNotFoundException {
+  public static @Unretained Object deserializeOffHeapBlob(ObjectChunk blob) throws IOException, ClassNotFoundException {
     Object result;
     final long start = startDeserialization();
     // For both top level and nested pdxs we just want a reference to this off-heap blob.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java b/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
index 85e078d..4a5a9df 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
@@ -26,7 +26,7 @@ import java.util.Date;
 import com.gemstone.gemfire.DataSerializer;
 import com.gemstone.gemfire.InternalGemFireException;
 import com.gemstone.gemfire.pdx.PdxSerializationException;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream;
 import com.gemstone.gemfire.internal.tcp.ImmutableByteBufferInputStream;
 
@@ -76,7 +76,7 @@ public class PdxInputStream extends ImmutableByteBufferInputStream {
     // for serialization
   }
 
-  public PdxInputStream(Chunk blob) {
+  public PdxInputStream(ObjectChunk blob) {
     super(blob);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
index 0606387..b69f82e 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
@@ -29,7 +29,7 @@ import org.junit.experimental.categories.Category;
 
 import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.ChunkValueWrapper;
 import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.Flushable;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
 import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
@@ -40,13 +40,13 @@ import com.gemstone.gemfire.test.junit.categories.UnitTest;
 public class ChunkValueWrapperJUnitTest {
 
   private static ChunkValueWrapper createChunkValueWrapper(byte[] bytes, boolean isSerialized) {
-    Chunk c = (Chunk)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false, null);
+    ObjectChunk c = (ObjectChunk)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false);
     return new ChunkValueWrapper(c);
   }
 
   @Before
   public void setUp() throws Exception {
-    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
   }
 
   @After

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
index f7d0714..690b55a 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
@@ -26,7 +26,7 @@ import org.junit.Test;
 
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.cache.EntryEventImpl.OldValueImporter;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.DataAsAddress;
 import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
 import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
@@ -110,10 +110,10 @@ public abstract class OldValueImporterTestBase {
     // off-heap DataAsAddress byte array
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         byte[] baValue = new byte[] {1,2};
-        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValue, false, false, null);
+        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValue, false, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, false);
         hdos = new HeapDataOutputStream(bytes);
@@ -127,10 +127,10 @@ public abstract class OldValueImporterTestBase {
     // off-heap Chunk byte array
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         byte[] baValue = new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
-        Chunk baValueSO = (Chunk) sma.allocateAndInitialize(baValue, false, false, null);
+        ObjectChunk baValueSO = (ObjectChunk) sma.allocateAndInitialize(baValue, false, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, false);
         hdos = new HeapDataOutputStream(bytes);
@@ -144,11 +144,11 @@ public abstract class OldValueImporterTestBase {
     // off-heap DataAsAddress String
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         String baValue = "12";
         byte[] baValueBlob = BlobHelper.serializeToBlob(baValue);
-        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValueBlob, true, false, null);
+        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValueBlob, true, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, true);
         hdos = new HeapDataOutputStream(bytes);
@@ -162,11 +162,11 @@ public abstract class OldValueImporterTestBase {
     // off-heap Chunk String
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         String baValue = "12345678";
         byte[] baValueBlob = BlobHelper.serializeToBlob(baValue);
-        Chunk baValueSO = (Chunk) sma.allocateAndInitialize(baValueBlob, true, false, null);
+        ObjectChunk baValueSO = (ObjectChunk) sma.allocateAndInitialize(baValueBlob, true, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, true);
         hdos = new HeapDataOutputStream(bytes);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java
deleted file mode 100644
index bc32367..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java
+++ /dev/null
@@ -1,64 +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 com.gemstone.gemfire.internal.offheap;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class ChunkWithHeapFormJUnitTest extends GemFireChunkJUnitTest {
-
-  @Test
-  public void getRawBytesShouldReturnCachedHeapForm() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    byte[] valueInBytes = getValueAsByteArray();
-    ChunkWithHeapForm heapForm = new ChunkWithHeapForm(chunk, valueInBytes);
-
-    assertNotNull(heapForm);
-
-    assertSame(valueInBytes, heapForm.getRawBytes());
-  }
-
-  @Test
-  public void getChunkWithoutHeapFormShouldReturnGemFireChunk() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    byte[] valueInBytes = getValueAsByteArray();
-    ChunkWithHeapForm heapForm = new ChunkWithHeapForm(chunk, valueInBytes);
-
-    Chunk chunkWithOutHeapForm = heapForm.getChunkWithoutHeapForm();
-
-    assertNotNull(chunkWithOutHeapForm);
-    assertEquals(GemFireChunk.class, chunkWithOutHeapForm.getClass());
-
-    assertEquals(chunk, heapForm.getChunkWithoutHeapForm());
-
-    assertEquals(chunk.getMemoryAddress(), chunkWithOutHeapForm.getMemoryAddress());
-    assertArrayEquals(chunk.getRawBytes(), chunkWithOutHeapForm.getRawBytes());
-    assertNotSame(valueInBytes, chunkWithOutHeapForm.getRawBytes());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
index ccc6b67..54eac9e 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
@@ -18,7 +18,6 @@
 package com.gemstone.gemfire.internal.offheap;
 
 import static org.junit.Assert.*;
-import static org.mockito.Mockito.mock;
 import static org.hamcrest.CoreMatchers.*;
 
 import java.util.Arrays;
@@ -33,19 +32,12 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 
-import com.gemstone.gemfire.LogWriter;
 import com.gemstone.gemfire.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
 public class FragmentJUnitTest {
 
-  private SimpleMemoryAllocatorImpl ma;
-  private OutOfOffHeapMemoryListener ooohml;
-  private OffHeapMemoryStats stats;
-  private LogWriter lw;
-  private UnsafeMemoryChunk.Factory umcFactory;
   private UnsafeMemoryChunk[] slabs;
-  private int numSlabs;
 
   static {
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
@@ -68,30 +60,18 @@ public class FragmentJUnitTest {
 
   @Before
   public void setUp() throws Exception {
-    ooohml = mock(OutOfOffHeapMemoryListener.class);
-    stats = mock(OffHeapMemoryStats.class);
-    lw = mock(LogWriter.class);
-    
-    numSlabs = 2;
-    umcFactory = new UnsafeMemoryChunk.Factory(){
-      @Override
-      public UnsafeMemoryChunk create(int size) {
-        return new UnsafeMemoryChunk(size);
-      }
-    };
-    slabs = allocateMemorySlabs();
+    UnsafeMemoryChunk slab1 = new UnsafeMemoryChunk((int)OffHeapStorage.MIN_SLAB_SIZE);
+    UnsafeMemoryChunk slab2 = new UnsafeMemoryChunk((int)OffHeapStorage.MIN_SLAB_SIZE);
+    slabs = new UnsafeMemoryChunk[]{slab1, slab2};
   }
 
   @After
   public void tearDown() throws Exception {
-    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+    for (int i=0; i < slabs.length; i++) {
+      slabs[i].release();
+    }
   }
   
-  private UnsafeMemoryChunk[] allocateMemorySlabs() {
-    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, numSlabs, OffHeapStorage.MIN_SLAB_SIZE * numSlabs, OffHeapStorage.MIN_SLAB_SIZE, umcFactory);
-    return ma.getSlabs();
-  }
-
   
   @Test
   public void fragmentConstructorThrowsExceptionForNon8ByteAlignedAddress() {
@@ -147,7 +127,6 @@ public class FragmentJUnitTest {
   
   @Test
   public void getStateIsAlwaysStateUNUSED() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getState()).isEqualTo(MemoryBlock.State.UNUSED);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -156,7 +135,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getFreeListIdIsAlwaysMinus1() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getFreeListId()).isEqualTo(-1);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -165,7 +143,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getRefCountIsAlwaysZero() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getRefCount()).isEqualTo(0);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -174,7 +151,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getDataTypeIsAlwaysNA() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getDataType()).isEqualTo("N/A");
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -183,7 +159,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void isSerializedIsAlwaysFalse() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.isSerialized()).isEqualTo(false);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -192,7 +167,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void isCompressedIsAlwaysFalse() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.isCompressed()).isEqualTo(false);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -201,7 +175,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getDataValueIsAlwaysNull() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getDataValue()).isNull();
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -209,17 +182,7 @@ public class FragmentJUnitTest {
   }
 
   @Test
-  public void getChunkTypeIsAlwaysNull() {
-    slabs = allocateMemorySlabs();
-    Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
-    softly.assertThat(fragment.getChunkType()).isNull();
-    fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
-    softly.assertThat(fragment.getChunkType()).isNull();
-  }
-
-  @Test
   public void fragmentEqualsComparesMemoryBlockAddresses() {
-    slabs = allocateMemorySlabs();
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment sameFragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
@@ -229,14 +192,12 @@ public class FragmentJUnitTest {
 
   @Test
   public void fragmentEqualsIsFalseForNonFragmentObjects() {
-    slabs = allocateMemorySlabs();
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     assertThat(fragment0.equals(slabs[0]), is(false));
   }
 
   @Test
   public void fragmentHashCodeIsHashCodeOfItsMemoryAddress() {
-    slabs = allocateMemorySlabs();
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
     Long fragmentAddress = fragment0.getMemoryAddress();
@@ -246,12 +207,11 @@ public class FragmentJUnitTest {
 
   @Test
   public void fragmentFillSetsAllBytesToTheSameConstantValue() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Long fragmentAddress = fragment.getMemoryAddress();
     byte[] bytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
     byte[] expectedBytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
-    Arrays.fill(expectedBytes, Chunk.FILL_BYTE);;
+    Arrays.fill(expectedBytes, ObjectChunk.FILL_BYTE);;
     fragment.fill();
     UnsafeMemoryChunk.readAbsoluteBytes(fragmentAddress, bytes, 0, (int)OffHeapStorage.MIN_SLAB_SIZE);
     assertThat(bytes, is(equalTo(expectedBytes)));
@@ -261,7 +221,6 @@ public class FragmentJUnitTest {
   public void getNextBlockThrowsExceptionForFragment() {
     expectedException.expect(UnsupportedOperationException.class);
 
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     fragment.getNextBlock();
     fail("getNextBlock failed to throw UnsupportedOperationException");
@@ -271,7 +230,6 @@ public class FragmentJUnitTest {
   public void getSlabIdThrowsExceptionForFragment() {
     expectedException.expect(UnsupportedOperationException.class);
 
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     fragment.getSlabId();
     fail("getSlabId failed to throw UnsupportedOperationException");

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
new file mode 100644
index 0000000..64032cc
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
@@ -0,0 +1,797 @@
+/*
+ * 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 com.gemstone.gemfire.internal.offheap;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+import static com.googlecode.catchexception.CatchException.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.OutOfOffHeapMemoryException;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class FreeListManagerTest {
+  static {
+    ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
+  }
+
+  private final int DEFAULT_SLAB_SIZE = 1024*1024*5;
+  private final SimpleMemoryAllocatorImpl ma = mock(SimpleMemoryAllocatorImpl.class);
+  private final OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
+  private TestableFreeListManager freeListManager;
+  
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception {
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    when(ma.getStats()).thenReturn(stats);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (this.freeListManager != null) {
+      this.freeListManager.freeSlabs();
+    }
+  }
+  
+  private static TestableFreeListManager createFreeListManager(SimpleMemoryAllocatorImpl ma, AddressableMemoryChunk[] slabs) {
+    return new TestableFreeListManager(ma, slabs);
+  }
+  
+  private void setUpSingleSlabManager() {
+    setUpSingleSlabManager(DEFAULT_SLAB_SIZE);
+  }
+  private void setUpSingleSlabManager(int slabSize) {
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(slabSize);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {slab});
+  }
+
+  @Test
+  public void usedMemoryIsZeroOnDefault() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.getUsedMemory()).isZero();
+  }
+
+  @Test
+  public void freeMemoryIsSlabSizeOnDefault() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.getFreeMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+  
+  @Test
+  public void totalMemoryIsSlabSizeOnDefault() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.getTotalMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+  
+  @Test
+  public void allocateTinyChunkHasCorrectSize() {
+    setUpSingleSlabManager();
+    int tinySize = 10;
+
+    ObjectChunk c = this.freeListManager.allocate(tinySize);
+    
+    validateChunkSizes(c, tinySize);
+  }
+  
+  private void validateChunkSizes(ObjectChunk c, int dataSize) {
+    assertThat(c).isNotNull();
+    assertThat(c.getDataSize()).isEqualTo(dataSize);
+    assertThat(c.getSize()).isEqualTo(computeExpectedSize(dataSize));
+  }
+
+  @Test
+  public void allocateTinyChunkFromFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int tinySize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(tinySize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    c = this.freeListManager.allocate(tinySize);
+
+    validateChunkSizes(c, tinySize);
+  }
+  
+  @Test
+  public void allocateTinyChunkFromEmptyFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int dataSize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    this.freeListManager.allocate(dataSize);
+    // free list will now be empty
+    c = this.freeListManager.allocate(dataSize);
+
+    validateChunkSizes(c, dataSize);
+  }
+
+  @Test
+  public void allocateHugeChunkHasCorrectSize() {
+    setUpSingleSlabManager();
+    int hugeSize = FreeListManager.MAX_TINY+1;
+
+    ObjectChunk c = this.freeListManager.allocate(hugeSize);
+
+    validateChunkSizes(c, hugeSize);
+  }
+  
+  @Test
+  public void allocateHugeChunkFromEmptyFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int dataSize = FreeListManager.MAX_TINY+1;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    this.freeListManager.allocate(dataSize);
+    // free list will now be empty
+    c = this.freeListManager.allocate(dataSize);
+    
+    validateChunkSizes(c, dataSize);
+  }
+
+  @Test
+  public void allocateHugeChunkFromFragmentWithItemInFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int dataSize = FreeListManager.MAX_TINY+1+1024;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    dataSize = FreeListManager.MAX_TINY+1;
+    c = this.freeListManager.allocate(dataSize);
+    
+    validateChunkSizes(c, dataSize);
+  }
+  @Test
+  public void freeTinyMemoryDefault() {
+    setUpSingleSlabManager();
+    
+    assertThat(this.freeListManager.getFreeTinyMemory()).isZero();
+  }
+  @Test
+  public void freeTinyMemoryEqualToChunkSize() {
+    setUpSingleSlabManager();
+    int dataSize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    
+    assertThat(this.freeListManager.getFreeTinyMemory()).isEqualTo(computeExpectedSize(dataSize));
+  }
+   
+  @Test
+  public void freeTinyMemoryWithTwoTinyFreeListsEqualToChunkSize() {
+    setUpSingleSlabManager();
+    int dataSize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    
+    int dataSize2 = 100;
+    
+    ObjectChunk c2 = this.freeListManager.allocate(dataSize2);
+    ObjectChunk.release(c2.getMemoryAddress(), this.freeListManager);
+    
+    assertThat(this.freeListManager.getFreeTinyMemory()).isEqualTo(computeExpectedSize(dataSize)+computeExpectedSize(dataSize2));
+  }
+   
+  @Test
+  public void freeHugeMemoryDefault() {
+    setUpSingleSlabManager();
+    
+    assertThat(this.freeListManager.getFreeHugeMemory()).isZero();
+  }
+  @Test
+  public void freeHugeMemoryEqualToChunkSize() {
+    setUpSingleSlabManager();
+    int dataSize = FreeListManager.MAX_TINY+1+1024;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    
+    assertThat(this.freeListManager.getFreeHugeMemory()).isEqualTo(computeExpectedSize(dataSize));
+  }
+  
+  @Test
+  public void freeFragmentMemoryDefault() {
+    setUpSingleSlabManager();
+    
+    assertThat(this.freeListManager.getFreeFragmentMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+  
+  @Test
+  public void freeFragmentMemorySomeOfFragmentAllocated() {
+    setUpSingleSlabManager();
+    ObjectChunk c = this.freeListManager.allocate(DEFAULT_SLAB_SIZE/4-8);
+    
+    assertThat(this.freeListManager.getFreeFragmentMemory()).isEqualTo((DEFAULT_SLAB_SIZE/4)*3);
+  }
+  
+  @Test
+  public void freeFragmentMemoryMostOfFragmentAllocated() {
+    setUpSingleSlabManager();
+    ObjectChunk c = this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8-8);
+    
+    assertThat(this.freeListManager.getFreeFragmentMemory()).isZero();
+  }
+  
+  private int computeExpectedSize(int dataSize) {
+    return ((dataSize + ObjectChunk.OFF_HEAP_HEADER_SIZE + 7) / 8) * 8;
+  }
+
+  @Test(expected = AssertionError.class)
+  public void allocateZeroThrowsAssertion() {
+    setUpSingleSlabManager();
+    this.freeListManager.allocate(0);
+  }
+  
+  @Test
+  public void allocateFromMultipleSlabs() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    this.freeListManager.allocate(SMALL_SLAB-8+1);
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8);
+    this.freeListManager.allocate(SMALL_SLAB-8+1);
+    assertThat(this.freeListManager.getFreeMemory()).isEqualTo(SMALL_SLAB*2+MEDIUM_SLAB-((SMALL_SLAB+8)*2));
+    assertThat(this.freeListManager.getUsedMemory()).isEqualTo(DEFAULT_SLAB_SIZE+(SMALL_SLAB+8)*2);
+    assertThat(this.freeListManager.getTotalMemory()).isEqualTo(DEFAULT_SLAB_SIZE+MEDIUM_SLAB+SMALL_SLAB*2);
+  }
+  
+  @Test
+  public void compactWithLargeChunkSizeReturnsFalse() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    ArrayList<ObjectChunk> chunks = new ArrayList<>();
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    for (ObjectChunk c: chunks) {
+      ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    }
+    this.freeListManager.firstCompact = false;
+    assertThat(this.freeListManager.compact(DEFAULT_SLAB_SIZE+1)).isFalse();
+  }
+  
+  @Test
+  public void compactWithChunkSizeOfMaxSlabReturnsTrue() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    ArrayList<ObjectChunk> chunks = new ArrayList<>();
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    for (ObjectChunk c: chunks) {
+      ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    }
+    
+    assertThat(this.freeListManager.compact(DEFAULT_SLAB_SIZE)).isTrue();
+    //assertThat(this.freeListManager.getFragmentList()).hasSize(4); // TODO intermittently fails because Fragments may be merged
+  }
+  
+  @Test
+  public void compactWithLiveChunks() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    ArrayList<ObjectChunk> chunks = new ArrayList<>();
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8);
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    this.freeListManager.allocate(SMALL_SLAB-8+1);
+    for (ObjectChunk c: chunks) {
+      ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    }
+    
+    assertThat(this.freeListManager.compact(DEFAULT_SLAB_SIZE/2)).isTrue();
+  }
+  
+  @Test
+  public void compactAfterAllocatingAll() {
+    setUpSingleSlabManager();
+    ObjectChunk c = freeListManager.allocate(DEFAULT_SLAB_SIZE-8);
+    this.freeListManager.firstCompact = false;
+    assertThat(this.freeListManager.compact(1)).isFalse();
+    // call compact twice for extra code coverage
+    assertThat(this.freeListManager.compact(1)).isFalse();
+    assertThat(this.freeListManager.getFragmentList()).isEmpty();
+  }
+  
+  @Test
+  public void afterAllocatingAllOneSizeCompactToAllocateDifferentSize() {
+    setUpSingleSlabManager();
+    ArrayList<ObjectChunk> chunksToFree = new ArrayList<>();
+    ArrayList<ObjectChunk> chunksToFreeLater = new ArrayList<>();
+    int ALLOCATE_COUNT = 1000;
+    ObjectChunk bigChunk = freeListManager.allocate(DEFAULT_SLAB_SIZE-8-(ALLOCATE_COUNT*32)-256-256);
+    for (int i=0; i < ALLOCATE_COUNT; i++) {
+      ObjectChunk c = freeListManager.allocate(24);
+      if (i%3 != 2) {
+        chunksToFree.add(c);
+      } else {
+        chunksToFreeLater.add(c);
+      }
+    }
+    ObjectChunk c1 = freeListManager.allocate(64-8);
+    ObjectChunk c2 = freeListManager.allocate(64-8);
+    ObjectChunk c3 = freeListManager.allocate(64-8);
+    ObjectChunk c4 = freeListManager.allocate(64-8);
+
+    ObjectChunk mediumChunk1 = freeListManager.allocate(128-8);
+    ObjectChunk mediumChunk2 = freeListManager.allocate(128-8);
+
+    ObjectChunk.release(bigChunk.getMemoryAddress(), freeListManager);
+    int s = chunksToFree.size();
+    for (int i=s/2; i >=0; i--) {
+      ObjectChunk c = chunksToFree.get(i);
+      ObjectChunk.release(c.getMemoryAddress(), freeListManager);
+    }
+    for (int i=(s/2)+1; i < s; i++) {
+      ObjectChunk c = chunksToFree.get(i);
+      ObjectChunk.release(c.getMemoryAddress(), freeListManager);
+    }
+    ObjectChunk.release(c3.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(c1.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(c2.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(c4.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(mediumChunk1.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(mediumChunk2.getMemoryAddress(), freeListManager);
+    this.freeListManager.firstCompact = false;
+    assertThat(freeListManager.compact(DEFAULT_SLAB_SIZE-(ALLOCATE_COUNT*32))).isFalse();
+    for (int i=0; i < ((256*2)/96); i++) {
+      ObjectChunk.release(chunksToFreeLater.get(i).getMemoryAddress(), freeListManager);
+    }
+    assertThat(freeListManager.compact(DEFAULT_SLAB_SIZE-(ALLOCATE_COUNT*32))).isTrue();
+  }
+  
+  @Test
+  public void afterAllocatingAndFreeingCompact() {
+    int slabSize = 1024*3;
+    setUpSingleSlabManager(slabSize);
+    ObjectChunk bigChunk1 = freeListManager.allocate(slabSize/3-8);
+    ObjectChunk bigChunk2 = freeListManager.allocate(slabSize/3-8);
+    ObjectChunk bigChunk3 = freeListManager.allocate(slabSize/3-8);
+    this.freeListManager.firstCompact = false;
+    assertThat(freeListManager.compact(1)).isFalse();
+    ObjectChunk.release(bigChunk3.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(bigChunk2.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(bigChunk1.getMemoryAddress(), freeListManager);
+    assertThat(freeListManager.compact(slabSize)).isTrue();
+  }
+  
+  @Test
+  public void compactWithEmptyTinyFreeList() {
+    setUpSingleSlabManager();
+    Fragment originalFragment = this.freeListManager.getFragmentList().get(0);
+    ObjectChunk c = freeListManager.allocate(16);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    c = freeListManager.allocate(16);
+    this.freeListManager.firstCompact = false;
+    assertThat(this.freeListManager.compact(1)).isTrue();
+    assertThat(this.freeListManager.getFragmentList()).hasSize(1);
+    Fragment compactedFragment = this.freeListManager.getFragmentList().get(0);
+    assertThat(compactedFragment.getSize()).isEqualTo(originalFragment.getSize()-(16+8));
+    assertThat(compactedFragment.getMemoryAddress()).isEqualTo(originalFragment.getMemoryAddress()+(16+8));
+  }
+  
+  @Test
+  public void allocationsThatLeaveLessThanMinChunkSizeFreeInAFragment() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8-(ObjectChunk.MIN_CHUNK_SIZE-1));
+    this.freeListManager.allocate(MEDIUM_SLAB-8-(ObjectChunk.MIN_CHUNK_SIZE-1));
+    
+    assertThat(this.freeListManager.compact(SMALL_SLAB)).isTrue();
+  }
+ @Test
+  public void maxAllocationUsesAllMemory() {
+    setUpSingleSlabManager();
+
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8);
+
+    assertThat(this.freeListManager.getFreeMemory()).isZero();
+    assertThat(this.freeListManager.getUsedMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+
+
+  @Test
+  public void overMaxAllocationFails() {
+    setUpSingleSlabManager();
+    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
+    when(this.ma.getOutOfOffHeapMemoryListener()).thenReturn(ooohml);
+
+    catchException(this.freeListManager).allocate(DEFAULT_SLAB_SIZE-7);
+
+    verify(ooohml).outOfOffHeapMemory(caughtException());
+  }
+  
+  @Test(expected = AssertionError.class)
+  public void allocateNegativeThrowsAssertion() {
+    setUpSingleSlabManager();
+    this.freeListManager.allocate(-123);
+  }
+  
+  @Test
+  public void hugeMultipleLessThanZeroIsIllegal() {
+    try {
+      FreeListManager.verifyHugeMultiple(-1);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("HUGE_MULTIPLE must be >= 0 and <= " + FreeListManager.HUGE_MULTIPLE + " but it was -1");
+    }
+  }
+  @Test
+  public void hugeMultipleGreaterThan256IsIllegal() {
+    try {
+      FreeListManager.verifyHugeMultiple(257);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("HUGE_MULTIPLE must be >= 0 and <= 256 but it was 257");
+    }
+  }
+  @Test
+  public void hugeMultipleof256IsLegal() {
+    FreeListManager.verifyHugeMultiple(256);
+  }
+  
+  @Test
+  public void offHeapFreeListCountLessThanZeroIsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapFreeListCount(-1);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
+    }
+  }
+  @Test
+  public void offHeapFreeListCountOfZeroIsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapFreeListCount(0);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
+    }
+  }
+  @Test
+  public void offHeapFreeListCountOfOneIsLegal() {
+    FreeListManager.verifyOffHeapFreeListCount(1);
+  }
+  @Test
+  public void offHeapAlignmentLessThanZeroIsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapAlignment(-1);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8");
+    }
+  }
+  @Test
+  public void offHeapAlignmentNotAMultipleOf8IsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapAlignment(9);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8");
+    }
+  }
+  @Test
+  public void offHeapAlignmentGreaterThan256IsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapAlignment(256+8);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_ALIGNMENT must be <= 256");
+    }
+  }
+  @Test
+  public void offHeapAlignmentOf256IsLegal() {
+    FreeListManager.verifyOffHeapAlignment(256);
+  }
+  
+  @Test
+  public void okToReuseNull() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.okToReuse(null)).isTrue();
+  }
+  
+  @Test
+  public void okToReuseSameSlabs() {
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[] {slab};
+    this.freeListManager = createFreeListManager(ma, slabs);
+    assertThat(this.freeListManager.okToReuse(slabs)).isTrue();
+  }
+  @Test
+  public void notOkToReuseDifferentSlabs() {
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[] {slab};
+    this.freeListManager = createFreeListManager(ma, slabs);
+    UnsafeMemoryChunk[] slabs2 = new UnsafeMemoryChunk[] {slab};
+    assertThat(this.freeListManager.okToReuse(slabs2)).isFalse();
+  }
+  @Test
+  public void firstSlabAlwaysLargest() {
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(10), 
+        new UnsafeMemoryChunk(100)});
+    assertThat(this.freeListManager.getLargestSlabSize()).isEqualTo(10);
+  }
+
+  @Test
+  public void findSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.findSlab(address)).isEqualTo(0);
+    assertThat(this.freeListManager.findSlab(address+9)).isEqualTo(0);
+    catchException(this.freeListManager).findSlab(address-1);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address-1));
+    catchException(this.freeListManager).findSlab(address+10);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address+10));
+  }
+  
+  @Test
+  public void findSecondSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {slab, chunk});
+    assertThat(this.freeListManager.findSlab(address)).isEqualTo(1);
+    assertThat(this.freeListManager.findSlab(address+9)).isEqualTo(1);
+    catchException(this.freeListManager).findSlab(address-1);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address-1));
+    catchException(this.freeListManager).findSlab(address+10);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address+10));
+  }
+  
+  @Test
+  public void validateAddressWithinSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address, -1)).isTrue();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address+9, -1)).isTrue();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address-1, -1)).isFalse();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address+10, -1)).isFalse();
+  }
+  
+  @Test
+  public void validateAddressAndSizeWithinSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address, 1)).isTrue();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address, 10)).isTrue();
+    catchException(this.freeListManager).validateAddressAndSizeWithinSlab(address, 0);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage(" address 0x" + Long.toString(address+0-1, 16) + " does not address the original slab memory");
+    catchException(this.freeListManager).validateAddressAndSizeWithinSlab(address, 11);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage(" address 0x" + Long.toString(address+11-1, 16) + " does not address the original slab memory");
+  }
+  
+  @Test
+  public void descriptionOfOneSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    long endAddress = address+10;
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    StringBuilder sb = new StringBuilder();
+    this.freeListManager.getSlabDescriptions(sb);
+    assertThat(sb.toString()).isEqualTo("[" + Long.toString(address, 16) + ".." + Long.toString(endAddress, 16) + "] ");
+  }
+
+  @Test
+  public void orderBlocksContainsFragment() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    List<MemoryBlock> ob = this.freeListManager.getOrderedBlocks();
+    assertThat(ob).hasSize(1);
+    assertThat(ob.get(0).getMemoryAddress()).isEqualTo(address);
+    assertThat(ob.get(0).getBlockSize()).isEqualTo(10);
+  }
+  
+  @Test
+  public void orderBlocksContainsTinyFree() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk c2 = this.freeListManager.allocate(24);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+
+    List<MemoryBlock> ob = this.freeListManager.getOrderedBlocks();
+    assertThat(ob).hasSize(3);
+  }
+
+  @Test
+  public void allocatedBlocksEmptyIfNoAllocations() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(0);
+  }
+
+  @Test
+  public void allocatedBlocksEmptyAfterFree() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(0);
+  }
+
+  @Test
+  public void allocatedBlocksHasAllocatedChunk() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(1);
+    assertThat(ob.get(0).getMemoryAddress()).isEqualTo(c.getMemoryAddress());
+  }
+  
+  @Test
+  public void allocatedBlocksHasBothAllocatedChunks() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk c2 = this.freeListManager.allocate(33);
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(2);
+  }
+  
+  @Test
+  public void allocateFromFragmentWithBadIndexesReturnsNull() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.allocateFromFragment(-1, 32)).isNull();
+    assertThat(this.freeListManager.allocateFromFragment(1, 32)).isNull();
+  }
+
+  @Test
+  public void testLogging() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(32);
+    UnsafeMemoryChunk chunk2 = new UnsafeMemoryChunk(1024*1024*5);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk, chunk2});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk c2 = this.freeListManager.allocate(1024*1024);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    ObjectChunk.release(c2.getMemoryAddress(), this.freeListManager);
+    
+    LogWriter lw = mock(LogWriter.class);
+    this.freeListManager.logOffHeapState(lw, 1024);
+  }
+  /**
+   * Just like Fragment except that the first time allocate is called
+   * it returns false indicating that the allocate failed.
+   * In a real system this would only happen if a concurrent allocate
+   * happened. This allows better code coverage.
+   */
+  private static class TestableFragment extends Fragment {
+    private boolean allocateCalled = false;
+    public TestableFragment(long addr, int size) {
+      super(addr, size);
+    }
+    @Override
+    public boolean allocate(int oldOffset, int newOffset) {
+      if (!allocateCalled) {
+        allocateCalled = true;
+        return false;
+      }
+      return super.allocate(oldOffset, newOffset);
+    }
+  }
+  private static class TestableFreeListManager extends FreeListManager {
+    private boolean firstTime = true;
+    
+    @Override
+    protected Fragment createFragment(long addr, int size) {
+      return new TestableFragment(addr, size);
+    }
+
+    @Override
+    protected SyncChunkStack createFreeListForEmptySlot(AtomicReferenceArray<SyncChunkStack> freeLists, int idx) {
+      if (this.firstTime) {
+        this.firstTime = false;
+        SyncChunkStack clq = super.createFreeListForEmptySlot(freeLists, idx);
+        if (!freeLists.compareAndSet(idx, null, clq)) {
+          fail("this should never happen. Indicates a concurrent modification");
+        }
+      }
+      return super.createFreeListForEmptySlot(freeLists, idx);
+    }
+
+    public boolean firstCompact = true;
+    @Override
+    protected void afterCompactCountFetched() {
+      if (this.firstCompact) {
+        this.firstCompact = false;
+        // Force compact into thinking a concurrent compaction happened.
+        this.compactCount.incrementAndGet();
+      }
+    }
+    
+    public TestableFreeListManager(SimpleMemoryAllocatorImpl ma, AddressableMemoryChunk[] slabs) {
+      super(ma, slabs);
+    }
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
index 93f2039..6790f6a 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
@@ -40,7 +40,7 @@ public class FreeListOffHeapRegionJUnitTest extends OffHeapRegionBase {
 
   @Override
   public int perObjectOverhead() {
-    return Chunk.OFF_HEAP_HEADER_SIZE;
+    return ObjectChunk.OFF_HEAP_HEADER_SIZE;
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java
deleted file mode 100644
index d12b823..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java
+++ /dev/null
@@ -1,129 +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 com.gemstone.gemfire.internal.offheap;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.LogWriter;
-import com.gemstone.gemfire.internal.cache.EntryEventImpl;
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class GemFireChunkFactoryJUnitTest {
-
-  private MemoryAllocator ma;
-
-  @Before
-  public void setUp() {
-    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
-    OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
-    LogWriter lw = mock(LogWriter.class);
-
-    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 1, OffHeapStorage.MIN_SLAB_SIZE * 1, OffHeapStorage.MIN_SLAB_SIZE);
-  }
-
-  @After
-  public void tearDown() {
-    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
-  }
-
-  private GemFireChunk createChunk(Object value) {
-    byte[] v = EntryEventImpl.serialize(value);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    return chunk;
-  }
-
-  @Test
-  public void factoryShouldCreateNewChunkWithGivenAddress() {
-    GemFireChunk chunk = createChunk(Long.MAX_VALUE);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    Chunk newChunk = factory.newChunk(chunk.getMemoryAddress());
-
-    assertNotNull(newChunk);
-    assertEquals(GemFireChunk.class, newChunk.getClass());
-
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-
-    chunk.release();
-  }
-
-  @Test
-  public void factoryShouldCreateNewChunkWithGivenAddressAndType() {
-    GemFireChunk chunk = createChunk(Long.MAX_VALUE);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    Chunk newChunk = factory.newChunk(chunk.getMemoryAddress(), GemFireChunk.TYPE);
-
-    assertNotNull(newChunk);
-    assertEquals(GemFireChunk.class, newChunk.getClass());
-
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-    assertThat(newChunk.getChunkType()).isEqualTo(GemFireChunk.TYPE);
-
-    chunk.release();
-  }
-
-  @Test
-  public void shouldGetChunkTypeFromAddress() {
-    byte[] v = EntryEventImpl.serialize(Long.MAX_VALUE);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    ChunkType actualType = factory.getChunkTypeForAddress(chunk.getMemoryAddress());
-
-    assertEquals(GemFireChunk.TYPE, actualType);
-
-    chunk.release();
-  }
-
-  @Test
-  public void shouldGetChunkTypeFromRawBits() {
-    byte[] v = EntryEventImpl.serialize(Long.MAX_VALUE);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    int rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + 4 /* REF_COUNT_OFFSET */);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    ChunkType actualType = factory.getChunkTypeForRawBits(rawBits);
-    assertEquals(GemFireChunk.TYPE, actualType);
-
-    chunk.release();
-  }
-}



[047/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer.java
index 9890b3b,0000000..61b925b
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer.java
@@@ -1,2007 -1,0 +1,2007 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.hdfs.internal.hoplog;
 +
 +import java.io.IOException;
 +import java.nio.ByteBuffer;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.EnumMap;
 +import java.util.Iterator;
 +import java.util.LinkedList;
 +import java.util.List;
 +import java.util.NoSuchElementException;
 +import java.util.concurrent.Callable;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentMap;
 +import java.util.concurrent.ConcurrentSkipListSet;
 +import java.util.concurrent.Future;
 +import java.util.concurrent.TimeUnit;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +import java.util.concurrent.atomic.AtomicInteger;
 +import java.util.concurrent.atomic.AtomicLong;
 +import java.util.concurrent.locks.ReadWriteLock;
 +import java.util.concurrent.locks.ReentrantReadWriteLock;
 +import java.util.regex.Matcher;
 +import java.util.regex.Pattern;
 +
++import com.gemstone.gemfire.internal.hll.CardinalityMergeException;
++import com.gemstone.gemfire.internal.hll.HyperLogLog;
++import com.gemstone.gemfire.internal.hll.ICardinality;
++import com.gemstone.gemfire.internal.hll.MurmurHash;
 +import org.apache.commons.lang.NotImplementedException;
 +import org.apache.hadoop.fs.FileStatus;
 +import org.apache.hadoop.fs.FileSystem;
 +import org.apache.hadoop.fs.Path;
 +import org.apache.hadoop.fs.PathFilter;
 +import org.apache.hadoop.ipc.RemoteException;
 +import org.apache.hadoop.util.ShutdownHookManager;
 +
 +import com.gemstone.gemfire.InternalGemFireException;
 +import com.gemstone.gemfire.cache.CacheClosedException;
 +import com.gemstone.gemfire.cache.hdfs.HDFSIOException;
 +import com.gemstone.gemfire.cache.hdfs.HDFSStore;
 +import com.gemstone.gemfire.cache.hdfs.internal.QueuedPersistentEvent;
 +import com.gemstone.gemfire.cache.hdfs.internal.SortedHoplogPersistedEvent;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.CardinalityMergeException;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.HyperLogLog;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.ICardinality;
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.MurmurHash;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSCompactionManager.CompactionRequest;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSRegionDirector.HdfsRegionManager;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.Hoplog.HoplogReader;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.Hoplog.HoplogReaderActivityListener;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.Hoplog.HoplogWriter;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.Hoplog.Meta;
 +import com.gemstone.gemfire.cache.hdfs.internal.hoplog.mapreduce.HoplogUtil;
 +import com.gemstone.gemfire.internal.HeapDataOutputStream;
 +import com.gemstone.gemfire.internal.cache.ForceReattemptException;
 +import com.gemstone.gemfire.internal.cache.PrimaryBucketException;
 +import com.gemstone.gemfire.internal.cache.execute.BucketMovedException;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.SortedOplogStatistics.IOOperation;
 +import com.gemstone.gemfire.internal.cache.persistence.soplog.TrackedReference;
 +import com.gemstone.gemfire.internal.concurrent.ConcurrentHashSet;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 +import org.apache.hadoop.hbase.util.FSUtils;
 +
 +/**
 + * Manages sorted oplog files for a bucket. An instance per bucket will exist in
 + * each PR
 + * 
 + * @author ashvina
 + */
 +public class HdfsSortedOplogOrganizer extends AbstractHoplogOrganizer<SortedHoplogPersistedEvent> {
 +  public static final int AVG_NUM_KEYS_PER_INDEX_BLOCK = 200;
 +  
 +  // all valid sorted hoplogs will follow the following name pattern
 +  public static final String SORTED_HOPLOG_REGEX = HOPLOG_NAME_REGEX + "("
 +      + FLUSH_HOPLOG_EXTENSION + "|" + MINOR_HOPLOG_EXTENSION + "|"
 +      + MAJOR_HOPLOG_EXTENSION + ")";
 +  public static final Pattern SORTED_HOPLOG_PATTERN = Pattern.compile(SORTED_HOPLOG_REGEX);
 +  
 +  //Amount of time before deleting old temporary files
 +  final long TMP_FILE_EXPIRATION_TIME_MS = Long.getLong(HoplogConfig.TMP_FILE_EXPIRATION, HoplogConfig.TMP_FILE_EXPIRATION_DEFAULT);
 +  
 +  static float RATIO = HoplogConfig.COMPACTION_FILE_RATIO_DEFAULT;
 +
 +  // Compacter for this bucket
 +  private Compactor compacter;
 +    
 +  private final HoplogReadersController hoplogReadersController;
 +  private AtomicLong previousCleanupTimestamp = new AtomicLong(Long.MIN_VALUE);
 +
 +  /**
 +   * The default HLL constant. gives an accuracy of about 3.25%
 +   * public only for testing upgrade from 1.3 to 1.4
 +   */
 +  public static double HLL_CONSTANT = 0.03;
 +  /**
 +   * This estimator keeps track of this buckets entry count. This value is
 +   * affected by flush and compaction cycles
 +   */
 +  private volatile ICardinality bucketSize = new HyperLogLog(HLL_CONSTANT);
 +  //A set of tmp files that existed when this bucket organizer was originally
 +  //created. These may still be open by the old primary, or they may be
 +  //abandoned files.
 +  private LinkedList<FileStatus> oldTmpFiles;
 +
 +  private ConcurrentMap<Hoplog, Boolean> tmpFiles = new ConcurrentHashMap<Hoplog, Boolean>();
 +
 +  protected volatile boolean organizerClosed = false;
 +
 +  /**
 +   * For the 1.4 release we are changing the HLL_CONSTANT which will make the
 +   * old persisted HLLs incompatible with the new HLLs. To fix this we will
 +   * force a major compaction when the system starts up so that we will only
 +   * have new HLLs in the system (see bug 51403)
 +   */
 +  private boolean startCompactionOnStartup = false;
 +
 +  /**
 +   * @param region
 +   *          Region manager instance. Instances of hdfs listener instance,
 +   *          stats collector, file system, etc are shared by all buckets of a
 +   *          region and provided by region manager instance
 +   * @param bucketId bucket id to be managed by this organizer
 +   * @throws IOException
 +   */
 +  public HdfsSortedOplogOrganizer(HdfsRegionManager region, int bucketId) throws IOException{
 +    super(region, bucketId);
 +    
 +    String val = System.getProperty(HoplogConfig.COMPACTION_FILE_RATIO);
 +    try {
 +      RATIO = Float.parseFloat(val);
 +    } catch (Exception e) {
 +    }
 +
 +    hoplogReadersController = new HoplogReadersController();
 +    
 +    // initialize with all the files in the directory
 +    List<Hoplog> hoplogs = identifyAndLoadSortedOplogs(true);
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}Initializing bucket with existing hoplogs, count = " + hoplogs.size(), logPrefix);
 +    }
 +    for (Hoplog hoplog : hoplogs) {
 +      addSortedOplog(hoplog, false, true);
 +    }
 +
 +    // initialize sequence to the current maximum
 +    sequence = new AtomicInteger(findMaxSequenceNumber(hoplogs));
 +    
 +    initOldTmpFiles();
 +    
 +    FileSystem fs = store.getFileSystem();
 +    Path cleanUpIntervalPath = new Path(store.getHomeDir(), HoplogConfig.CLEAN_UP_INTERVAL_FILE_NAME); 
 +    if (!fs.exists(cleanUpIntervalPath)) {
 +      long intervalDurationMillis = store.getPurgeInterval() * 60 * 1000;
 +      HoplogUtil.exposeCleanupIntervalMillis(fs, cleanUpIntervalPath, intervalDurationMillis);
 +    }
 +
 +    if (startCompactionOnStartup) {
 +      forceCompactionOnVersionUpgrade();
 +      if (logger.isInfoEnabled()) {
 +        logger.info(LocalizedStrings.HOPLOG_MAJOR_COMPACTION_SCHEDULED_FOR_BETTER_ESTIMATE);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Iterates on the input buffer and persists it in a new sorted oplog. This operation is
 +   * synchronous and blocks the thread.
 +   */
 +  @Override
 +  public void flush(Iterator<? extends QueuedPersistentEvent> iterator, final int count)
 +      throws IOException, ForceReattemptException {
 +    assert iterator != null;
 +
 +    if (logger.isDebugEnabled())
 +      logger.debug("{}Initializing flush operation", logPrefix);
 +    
 +    final Hoplog so = getTmpSortedOplog(null, FLUSH_HOPLOG_EXTENSION);
 +    HoplogWriter writer = null;
 +    ICardinality localHLL = new HyperLogLog(HLL_CONSTANT);
 +    
 +    // variables for updating stats
 +    long start = stats.getFlush().begin();
 +    int byteCount = 0;
 +    
 +    try {
 +      /**MergeGemXDHDFSToGFE changed the following statement as the code of HeapDataOutputStream is not merged */
 +      //HeapDataOutputStream out = new HeapDataOutputStream();
 +      
 +      try {
 +        writer = this.store.getSingletonWriter().runSerially(new Callable<Hoplog.HoplogWriter>() {
 +          @Override
 +          public HoplogWriter call() throws Exception {
 +            return so.createWriter(count);
 +          }
 +        });
 +      } catch (Exception e) {
 +        if (e instanceof IOException) {
 +          throw (IOException)e;
 +        }
 +        throw new IOException(e);
 +      }
 +
 +      while (iterator.hasNext() && !this.organizerClosed) {
 +        HeapDataOutputStream out = new HeapDataOutputStream(1024, null);
 +        
 +        QueuedPersistentEvent item = iterator.next();
 +        item.toHoplogEventBytes(out);
 +        byte[] valueBytes = out.toByteArray();
 +        writer.append(item.getRawKey(), valueBytes);
 +        
 +        // add key length and value length to stats byte counter
 +        byteCount += (item.getRawKey().length + valueBytes.length);
 +
 +        // increment size only if entry is not deleted
 +        if (!isDeletedEntry(valueBytes, 0)) {
 +          int hash = MurmurHash.hash(item.getRawKey());
 +          localHLL.offerHashed(hash);
 +        }
 +        /**MergeGemXDHDFSToGFE how to clear for reuse. Leaving it for Darrel to merge this change*/
 +        //out.clearForReuse();
 +      }
 +      if (organizerClosed)
 +        throw new BucketMovedException("The current bucket is moved BucketID: "+  
 +            this.bucketId + " Region name: " +  this.regionManager.getRegion().getName());
 +      
 +      // append completed. provide cardinality and close writer
 +      writer.close(buildMetaData(localHLL));
 +      writer = null;
 +    } catch (IOException e) {
 +      stats.getFlush().error(start);
 +      try {
 +        e = handleWriteHdfsIOError(writer, so, e);
 +      } finally {
 +        //Set the writer to null because handleWriteHDFSIOError has
 +        //already closed the writer.
 +        writer = null;
 +      }
 +      throw e;
 +    } catch (BucketMovedException e) {
 +      stats.getFlush().error(start);
 +      deleteTmpFile(writer, so);
 +      writer = null;
 +      throw e;
 +    } finally {
 +      if (writer != null) {
 +        writer.close();
 +      }
 +    }
 +
 +    try{
 +      
 +      // ping secondaries before making the file a legitimate file to ensure 
 +      // that in case of split brain, no other vm has taken up as primary. #50110.  
 +      pingSecondaries();
 +      
 +      // rename file and check if renaming was successful
 +      synchronized (changePrimarylockObject) {
 +        if (!organizerClosed)
 +          makeLegitimate(so);
 +        else 
 +          throw new BucketMovedException("The current bucket is moved BucketID: "+  
 +              this.bucketId + " Region name: " +  this.regionManager.getRegion().getName());
 +      }
 +      try {
 +        so.getSize();
 +      } catch (IllegalStateException e) {
 +        throw new IOException("Failed to rename hoplog file:" + so.getFileName());
 +      }
 +      
 +      //Disabling this assertion due to bug 49740
 +      // check to make sure the sequence number is correct
 +//      if (ENABLE_INTEGRITY_CHECKS) {
 +//        Assert.assertTrue(getSequenceNumber(so) == findMaxSequenceNumber(identifyAndLoadSortedOplogs(false)), 
 +//            "Invalid sequence number detected for " + so.getFileName());
 +//      }
 +      
 +      // record the file for future maintenance and reads
 +      addSortedOplog(so, false, true);
 +      stats.getFlush().end(byteCount, start);
 +      incrementDiskUsage(so.getSize());
 +    } catch (BucketMovedException e) {
 +      stats.getFlush().error(start);
 +      deleteTmpFile(writer, so);
 +      writer = null;
 +      throw e;
 +    } catch (IOException e) {
 +      stats.getFlush().error(start);
 +      logger.warn(LocalizedStrings.HOPLOG_FLUSH_OPERATION_FAILED, e);
 +      throw e;
 +    }
 +
 +    submitCompactionRequests();
 +  }
 +
 +
 +  /**
 +   * store cardinality information in metadata
 +   * @param localHLL the hll estimate for this hoplog only
 +   */
 +  private EnumMap<Meta, byte[]> buildMetaData(ICardinality localHLL) throws IOException {
 +    EnumMap<Meta, byte[]> map = new EnumMap<Hoplog.Meta, byte[]>(Meta.class);
 +    map.put(Meta.LOCAL_CARDINALITY_ESTIMATE_V2, localHLL.getBytes());
 +    return map;
 +  }
 +
 +  private void submitCompactionRequests() throws IOException {
 +    CompactionRequest req;
 +    
 +    // determine if a major compaction is needed and create a compaction request
 +    // with compaction manager
 +    if (store.getMajorCompaction()) {
 +      if (isMajorCompactionNeeded()) {
 +        req = new CompactionRequest(regionFolder, bucketId, getCompactor(), true);
 +        HDFSCompactionManager.getInstance(store).submitRequest(req);
 +      }
 +    }
 +    
 +    // submit a minor compaction task. It will be ignored if there is no work to
 +    // be done.
 +    if (store.getMinorCompaction()) {
 +      req = new CompactionRequest(regionFolder, bucketId, getCompactor(), false);
 +      HDFSCompactionManager.getInstance(store).submitRequest(req);
 +    }
 +  }
 +
 +  /**
 +   * @return true if the oldest hoplog was created 1 major compaction interval ago
 +   */
 +  private boolean isMajorCompactionNeeded() throws IOException {
 +    // major compaction interval in milliseconds
 +    
 +    long majorCInterval = ((long)store.getMajorCompactionInterval()) * 60 * 1000;
 +
 +    Hoplog oplog = hoplogReadersController.getOldestHoplog();
 +    if (oplog == null) {
 +      return false;
 +    }
 +    
 +    long oldestFileTime = oplog.getModificationTimeStamp();
 +    long now = System.currentTimeMillis();
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}Checking oldest hop " + oplog.getFileName()
 +          + " for majorCompactionInterval=" + majorCInterval
 +          + " + now=" + now, logPrefix);
 +    }
 +    if (oldestFileTime > 0l && oldestFileTime < (now - majorCInterval)) {
 +      return true;
 +    }
 +    return false;
 +  }
 +
 +  @Override
 +  public SortedHoplogPersistedEvent read(byte[] key) throws IOException {
 +    long startTime = stats.getRead().begin();
 +    String user = logger.isDebugEnabled() ? "Read" : null;
 +    
 +    // collect snapshot of hoplogs
 +    List<TrackedReference<Hoplog>> hoplogs = null;
 +    hoplogs = hoplogReadersController.getTrackedSortedOplogList(user);
 +    try {
 +      // search for the key in order starting with the youngest oplog
 +      for (TrackedReference<Hoplog> hoplog : hoplogs) {
 +        HoplogReader reader = hoplog.get().getReader();
 +        byte[] val = reader.read(key);
 +        if (val != null) {
 +          // value found in a younger hoplog. stop iteration
 +          SortedHoplogPersistedEvent eventObj = deserializeValue(val);
 +          stats.getRead().end(val.length, startTime);
 +          return eventObj;
 +        }
 +      }
 +    } catch (IllegalArgumentException e) {
 +      if (IOException.class.isAssignableFrom(e.getCause().getClass())) {
 +        throw handleIOError((IOException) e.getCause());
 +      } else {
 +        throw e;
 +      }
 +    } catch (IOException e) {
 +      throw handleIOError(e);
 +    } catch (HDFSIOException e) {
 +        throw handleIOError(e);
 +    } finally {
 +      hoplogReadersController.releaseHoplogs(hoplogs, user);
 +    }
 +    
 +    stats.getRead().end(0, startTime);
 +    return null;
 +  }
 +
 +  protected IOException handleIOError(IOException e) {
 +    // expose the error wrapped inside remote exception
 +    if (e instanceof RemoteException) {
 +      return ((RemoteException) e).unwrapRemoteException();
 +    } 
 +    
 +    checkForSafeError(e);
 +    
 +    // it is not a safe error. let the caller handle it
 +    return e;
 +  }
 +  
 +  protected HDFSIOException handleIOError(HDFSIOException e) {
 +    checkForSafeError(e);
 +    return e;
 +  }
 +
 +  protected void checkForSafeError(Exception e) {
 +    boolean safeError = ShutdownHookManager.get().isShutdownInProgress();
 +    if (safeError) {
 +      // IOException because of closed file system. This happens when member is
 +      // shutting down
 +      if (logger.isDebugEnabled())
 +        logger.debug("IO error caused by filesystem shutdown", e);
 +      throw new CacheClosedException("IO error caused by filesystem shutdown", e);
 +    } 
 +
 +    if(isClosed()) {
 +      //If the hoplog organizer is closed, throw an exception to indicate the 
 +      //caller should retry on the new primary.
 +      throw new PrimaryBucketException(e);
 +    }
 +  }
 +  
 +  protected IOException handleWriteHdfsIOError(HoplogWriter writer, Hoplog so, IOException e)
 +      throws IOException {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}Handle write error:" + so, logPrefix);
 +    }
 +    
 +    closeWriter(writer);
 +    // add to the janitor queue
 +    tmpFiles.put(so, Boolean.TRUE);
 +
 +    return handleIOError(e);
 +  }
 +
 +  private void deleteTmpFile(HoplogWriter writer, Hoplog so) {
 +    closeWriter(writer);
 +    
 +    // delete the temporary hoplog
 +    try {
 +      if (so != null) {
 +        so.delete();
 +      }
 +    } catch (IOException e1) {
 +      logger.info(e1);
 +    }
 +  }
 +
 +  private void closeWriter(HoplogWriter writer) {
 +    if (writer != null) {
 +      // close writer before deleting it
 +      try {
 +        writer.close();
 +      } catch (Throwable e1) {
 +        // error to close hoplog will happen if no connections to datanode are
 +        // available. Try to delete the file on namenode
 +        if(!isClosed()) {
 +          logger.info(e1);
 +        }
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Closes hoplog and suppresses IO during reader close. Suppressing IO errors
 +   * when the organizer is closing or an hoplog becomes inactive lets the system
 +   * continue freeing other resources. It could potentially lead to socket
 +   * leaks though.
 +   */
 +  private void closeReaderAndSuppressError(Hoplog hoplog, boolean clearCache) {
 +    try {
 +      hoplog.close();
 +    } catch (IOException e) {
 +      // expose the error wrapped inside remote exception
 +      if (e instanceof RemoteException) {
 +        e = ((RemoteException) e).unwrapRemoteException();
 +      } 
 +      logger.info(e);
 +    }
 +  }
 +
 +  @Override
 +  public BucketIterator scan() throws IOException {
 +    String user = logger.isDebugEnabled() ? "Scan" : null;
 +    List<TrackedReference<Hoplog>> hoplogs = null;
 +    BucketIterator iter = null;
 +    try {
 +      hoplogs = hoplogReadersController.getTrackedSortedOplogList(user);
 +      iter = new BucketIterator(hoplogs);
 +      return iter;
 +    }  finally {
 +      // Normally the hoplogs will be released when the iterator is closed. The
 +      // hoplogs must be released only if creating the iterator has failed.
 +      if (iter == null) {
 +        hoplogReadersController.releaseHoplogs(hoplogs, user);
 +      }
 +    }
 +  }
 +
 +  @Override
 +  public BucketIterator scan(byte[] from, byte[] to) throws IOException {
 +    throw new NotImplementedException();
 +  }
 +
 +  @Override
 +  public BucketIterator scan(byte[] from, boolean fromInclusive, byte[] to, boolean toInclusive) throws IOException {
 +    throw new NotImplementedException();
 +  }
 +
 +  @Override
 +  public HoplogIterator<byte[], SortedHoplogPersistedEvent> scan(
 +      long startOffset, long length) throws IOException {
 +    throw new UnsupportedOperationException("Not supported for " + this.getClass().getSimpleName());
 +  }
 +
 +  @Override
 +  public void close() throws IOException {
 +    super.close();
 +    
 +    synchronized (changePrimarylockObject) {
 +      organizerClosed = true;
 +    }
 +    //Suspend compaction
 +    getCompactor().suspend();
 +    
 +    //Close the readers controller.
 +    hoplogReadersController.close();
 +    
 +    previousCleanupTimestamp.set(Long.MIN_VALUE);
 +    
 +  }
 +
 +  /**
 +   * This method call will happen on secondary node. The secondary node needs to update its data
 +   * structures
 +   */
 +  @Override
 +  public void hoplogCreated(String region, int bucketId, Hoplog... oplogs)
 +      throws IOException {
 +    for (Hoplog oplog : oplogs) {
 +      addSortedOplog(oplog, false, true);
 +    }
 +  }
 +
 +  @Override
 +  public long sizeEstimate() {
 +    return this.bucketSize.cardinality();
 +  }
 +
 +  private void addSortedOplog(Hoplog so, boolean notify, boolean addsToBucketSize)
 +  throws IOException {
 +    if (!hoplogReadersController.addSortedOplog(so)) {
 +      so.close();
 +      throw new InternalGemFireException("Failed to add " + so);
 +    }
 +
 +    String user = logger.isDebugEnabled() ? "Add" : null;
 +    if (addsToBucketSize) {
 +      TrackedReference<Hoplog> ref = null;
 +      try {
 +        ref = hoplogReadersController.trackHoplog(so, user);
 +        synchronized (bucketSize) {
 +          ICardinality localHLL = ref.get().getEntryCountEstimate();
 +          if (localHLL != null) {
 +            bucketSize = mergeHLL(bucketSize, localHLL);
 +          }
 +        }
 +      } finally {
 +        if (ref != null) {
 +          hoplogReadersController.releaseHoplog(ref, user);
 +        }
 +      }
 +    }
 +
 +    if (notify && listener != null) {
 +      listener.hoplogCreated(regionFolder, bucketId, so);
 +    }
 +  }
 +
 +  private void reEstimateBucketSize() throws IOException {
 +    ICardinality global = null;
 +    String user = logger.isDebugEnabled() ? "HLL" : null;
 +    List<TrackedReference<Hoplog>> hoplogs = null;
 +    try {
 +      hoplogs = hoplogReadersController.getTrackedSortedOplogList(user);
 +      global = new HyperLogLog(HLL_CONSTANT);
 +      for (TrackedReference<Hoplog> hop : hoplogs) {
 +        global = mergeHLL(global, hop.get().getEntryCountEstimate());
 +      }
 +    } finally {
 +      hoplogReadersController.releaseHoplogs(hoplogs, user);
 +    }
 +    bucketSize = global;
 +  }
 +
 +  protected ICardinality mergeHLL(ICardinality global, ICardinality local)
 +  /*throws IOException*/ {
 +    try {
 +      return global.merge(local);
 +    } catch (CardinalityMergeException e) {
 +      // uncomment this after the 1.4 release
 +      //throw new InternalGemFireException(e.getLocalizedMessage(), e);
 +      startCompactionOnStartup = true;
 +      return global;
 +    }
 +  }
 +
 +  private void removeSortedOplog(TrackedReference<Hoplog> so, boolean notify) throws IOException {
 +    hoplogReadersController.removeSortedOplog(so);
 +    
 +    // release lock before notifying listeners
 +    if (notify && listener != null) {
 +      listener.hoplogDeleted(regionFolder, bucketId, so.get());
 +    }
 +  }
 +  
 +  private void notifyCompactionListeners(boolean isMajor) {
 +    listener.compactionCompleted(regionFolder, bucketId, isMajor);
 +  }
 +  
 +  /**
 +   * This method call will happen on secondary node. The secondary node needs to update its data
 +   * structures
 +   * @throws IOException 
 +   */
 +  @Override
 +  public void hoplogDeleted(String region, int bucketId, Hoplog... oplogs) throws IOException {
 +    throw new NotImplementedException();
 +  }
 +
 +  @Override
 +  public synchronized Compactor getCompactor() {
 +    if (compacter == null) {
 +      compacter = new HoplogCompactor();
 +    }
 +    return compacter;
 +  }
 +
 +  @Override
 +  protected Hoplog getHoplog(Path hoplogPath) throws IOException {
 +    Hoplog so = new HFileSortedOplog(store, hoplogPath, store.getBlockCache(), stats, store.getStats());
 +    return so;
 +  }
 +
 +  /**
 +   * locks sorted oplogs collection, removes oplog and renames for deletion later
 +   * @throws IOException 
 +   */
 +  void markSortedOplogForDeletion(List<TrackedReference<Hoplog>> targets, boolean notify) throws IOException {
 +    for (int i = targets.size(); i > 0; i--) {
 +      TrackedReference<Hoplog> so = targets.get(i - 1);
 +      removeSortedOplog(so, true);
 +      if (!store.getFileSystem().exists(new Path(bucketPath, so.get().getFileName()))) {
 +        // the hoplog does not even exist on file system. Skip remaining steps
 +        continue;
 +      }
 +      addExpiryMarkerForAFile(so.get());
 +    }
 +  }
 +  
 +  /**
 +   * Deletes expired hoplogs and expiry markers from the file system. Calculates
 +   * a target timestamp based on cleanup interval. Then gets list of target
 +   * hoplogs. It also updates the disk usage state
 +   * 
 +   * @return number of files deleted
 +   */
 +   synchronized int initiateCleanup() throws IOException {
 +    int conf = store.getPurgeInterval();
 +    // minutes to milliseconds
 +    long intervalDurationMillis = conf * 60 * 1000;
 +    // Any expired hoplog with timestamp less than targetTS is a delete
 +    // candidate.
 +    long targetTS = System.currentTimeMillis() - intervalDurationMillis;
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("Target timestamp for expired hoplog deletion " + targetTS, logPrefix);
 +    }
 +    // avoid too frequent cleanup invocations. Exit cleanup invocation if the
 +    // previous cleanup was executed within 10% range of cleanup interval
 +    if (previousCleanupTimestamp.get() > targetTS
 +        && (previousCleanupTimestamp.get() - targetTS) < (intervalDurationMillis / 10)) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Skip cleanup, previous " + previousCleanupTimestamp.get(), logPrefix);
 +      }
 +      return 0;
 +    }
 +
 +    List<FileStatus> targets = getOptimizationTargets(targetTS);
 +    return deleteExpiredFiles(targets);
 +  }
 +
 +  protected int deleteExpiredFiles(List<FileStatus> targets) throws IOException {
 +    if (targets == null) {
 +      return 0;
 +    }
 +
 +    for (FileStatus file : targets) {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Deleting file: " + file.getPath(), logPrefix);
 +      }
 +      store.getFileSystem().delete(file.getPath(), false);
 +      
 +      if (isClosed()) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}Expiry file cleanup interupted by bucket close", logPrefix);
 +        return 0;
 +      }
 +      incrementDiskUsage(-1 * file.getLen());
 +    }
 +
 +    previousCleanupTimestamp.set(System.currentTimeMillis());
 +    return targets.size();
 +  }
 +
 +  /**
 +   * @param ts
 +   *          target timestamp
 +   * @return list of hoplogs, whose expiry markers were created before target
 +   *         timestamp, and the expiry marker itself.
 +   * @throws IOException
 +   */
 +  protected List<FileStatus> getOptimizationTargets(long ts) throws IOException {
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}Identifying optimization targets " + ts, logPrefix);
 +    }
 +
 +    List<FileStatus> deleteTargets = new ArrayList<FileStatus>();
 +    FileStatus[] markers = getExpiryMarkers();
 +    if (markers != null) {
 +      for (FileStatus marker : markers) {
 +        String name = truncateExpiryExtension(marker.getPath().getName());
 +        long timestamp = marker.getModificationTime();
 +
 +        // expired minor compacted files are not being used anywhere. These can
 +        // be removed immediately. All the other expired files should be removed
 +        // when the files have aged
 +        boolean isTarget = false;
 +        
 +        if (name.endsWith(MINOR_HOPLOG_EXTENSION)) {
 +          isTarget = true;
 +        } else if (timestamp < ts && name.endsWith(FLUSH_HOPLOG_EXTENSION)) {
 +          isTarget = true;
 +        } else if (timestamp < ts && name.endsWith(MAJOR_HOPLOG_EXTENSION)) {
 +          long majorCInterval = ((long)store.getMajorCompactionInterval()) * 60 * 1000;
 +          if (timestamp < (System.currentTimeMillis() - majorCInterval)) {
 +            isTarget = true;
 +          }
 +        }
 +        if (!isTarget) {
 +          continue;
 +        }
 +        
 +        // if the file is still being read, do not delete or rename it
 +        TrackedReference<Hoplog> used = hoplogReadersController.getInactiveHoplog(name);
 +        if (used != null) {
 +          if (used.inUse() && logger.isDebugEnabled()) {
 +            logger.debug("{}Optimizer: found active expired hoplog:" + name, logPrefix);
 +          } else if (logger.isDebugEnabled()) {
 +            logger.debug("{}Optimizer: found open expired hoplog:" + name, logPrefix);
 +          }
 +          continue;
 +        }
 +        
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("{}Delete target identified " + marker.getPath(), logPrefix);
 +        }
 +        
 +        deleteTargets.add(marker);
 +        Path hoplogPath = new Path(bucketPath, name);
 +        if (store.getFileSystem().exists(hoplogPath)) {
 +          FileStatus hoplog = store.getFileSystem().getFileStatus(hoplogPath);
 +          deleteTargets.add(hoplog);
 +        }
 +      }
 +    }
 +    return deleteTargets;
 +  }
 +
 +  /**
 +   * Returns a list of of hoplogs present in the bucket's directory, expected to be called during
 +   * hoplog set initialization
 +   */
 +  List<Hoplog> identifyAndLoadSortedOplogs(boolean countSize) throws IOException {
 +    FileSystem fs = store.getFileSystem();
 +    if (! fs.exists(bucketPath)) {
 +      return new ArrayList<Hoplog>();
 +    }
 +    
 +    FileStatus allFiles[] = fs.listStatus(bucketPath);
 +    ArrayList<FileStatus> validFiles = new ArrayList<FileStatus>();
 +    for (FileStatus file : allFiles) {
 +      // All hoplog files contribute to disk usage
 +      Matcher matcher = HOPLOG_NAME_PATTERN.matcher(file.getPath().getName());
 +      if (! matcher.matches()) {
 +        // not a hoplog
 +        continue;
 +      }
 +      
 +      // account for the disk used by this file
 +      if (countSize) {
 +        incrementDiskUsage(file.getLen());
 +      }
 +      
 +      // All valid hoplog files must match the regex
 +      matcher = SORTED_HOPLOG_PATTERN.matcher(file.getPath().getName());
 +      if (matcher.matches()) {
 +        validFiles.add(file);
 +      }
 +    }
 +    
 +    FileStatus[] markers = getExpiryMarkers();
 +    FileStatus[] validHoplogs = filterValidHoplogs(
 +        validFiles.toArray(new FileStatus[validFiles.size()]), markers);
 +
 +    ArrayList<Hoplog> results = new ArrayList<Hoplog>();
 +    if (validHoplogs == null || validHoplogs.length == 0) {
 +      return results;
 +    }
 +
 +    for (int i = 0; i < validHoplogs.length; i++) {
 +      // Skip directories
 +      if (validHoplogs[i].isDirectory()) {
 +        continue;
 +      }
 +
 +      final Path p = validHoplogs[i].getPath();
 +      // skip empty file
 +      if (fs.getFileStatus(p).getLen() <= 0) {
 +        continue;
 +      }
 +
 +      Hoplog hoplog = new HFileSortedOplog(store, p, store.getBlockCache(), stats, store.getStats());
 +      results.add(hoplog);
 +    }
 +
 +    return results;
 +  }
 +
 +  private static int findMaxSequenceNumber(List<Hoplog> hoplogs) throws IOException {
 +    int maxSeq = 0;
 +    for (Hoplog hoplog : hoplogs) {
 +      maxSeq = Math.max(maxSeq, getSequenceNumber(hoplog));
 +    }
 +    return maxSeq;
 +  }
 +
 +  /**
 +   * @return the sequence number associate with a hoplog file
 +   */
 +  static int getSequenceNumber(Hoplog hoplog) {
 +    Matcher matcher = SORTED_HOPLOG_PATTERN.matcher(hoplog.getFileName());
 +    boolean matched = matcher.find();
 +    assert matched;
 +    return Integer.valueOf(matcher.group(3));
 +  }
 +
 +  protected FileStatus[] getExpiryMarkers() throws IOException {
 +    FileSystem fs = store.getFileSystem();
 +    if (hoplogReadersController.hoplogs == null
 +        || hoplogReadersController.hoplogs.size() == 0) {
 +      // there are no hoplogs in the system. May be the bucket is not existing
 +      // at all.
 +      if (!fs.exists(bucketPath)) {
 +        if (logger.isDebugEnabled())
 +          logger.debug("{}This bucket is unused, skipping expired hoplog check", logPrefix);
 +        return null;
 +      }
 +    }
 +    
 +    FileStatus files[] = FSUtils.listStatus(fs, bucketPath, new PathFilter() {
 +      @Override
 +      public boolean accept(Path file) {
 +        // All expired hoplog end with expire extension and must match the valid file regex
 +        String fileName = file.getName();
 +        if (! fileName.endsWith(EXPIRED_HOPLOG_EXTENSION)) {
 +          return false;
 +        }
 +        fileName = truncateExpiryExtension(fileName);
 +        Matcher matcher = SORTED_HOPLOG_PATTERN.matcher(fileName);
 +        return matcher.find();
 +      }
 +
 +    });
 +    return files;
 +  }
 +  
 +  @Override
 +  public void clear() throws IOException {
 +    //Suspend compaction while we are doing the clear. This
 +    //aborts the currently in progress compaction.
 +    getCompactor().suspend();
 +    
 +    // while compaction is suspended, clear method marks hoplogs for deletion
 +    // only. Files will be removed by cleanup thread after active gets and
 +    // iterations are completed
 +    String user = logger.isDebugEnabled() ? "clear" : null;
 +    List<TrackedReference<Hoplog>> oplogs = null;
 +    try {
 +      oplogs = hoplogReadersController.getTrackedSortedOplogList(user);
 +      markSortedOplogForDeletion(oplogs, true);
 +    } finally {
 +      if (oplogs != null) {
 +        hoplogReadersController.releaseHoplogs(oplogs, user);
 +      }
 +      //Resume compaction
 +      getCompactor().resume();
 +    }
 +  }
 +
 +  /**
 +   * Performs the following activities
 +   * <UL>
 +   * <LI>Submits compaction requests as needed
 +   * <LI>Deletes tmp files which the system failed to removed earlier
 +   */
 +  @Override
 +  public void performMaintenance() throws IOException {
 +    long startTime = System.currentTimeMillis();
 +    
 +    if (logger.isDebugEnabled())
 +      logger.debug("{}Executing bucket maintenance", logPrefix);
 +
 +    submitCompactionRequests();
 +    hoplogReadersController.closeInactiveHoplogs();
 +    initiateCleanup();
 +    
 +    cleanupTmpFiles();
 +    
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}Time spent in bucket maintenance (in ms): "
 +          + (System.currentTimeMillis() - startTime), logPrefix);
 +    }
 +  }
 +
 +  @Override
 +  public Future<CompactionStatus> forceCompaction(boolean isMajor) {
 +    CompactionRequest request = new CompactionRequest(regionFolder, bucketId,
 +        getCompactor(), isMajor, true/*force*/);
 +    return HDFSCompactionManager.getInstance(store).submitRequest(request);
 +  }
 +
 +  private Future<CompactionStatus> forceCompactionOnVersionUpgrade() {
 +    CompactionRequest request = new CompactionRequest(regionFolder, bucketId, getCompactor(), true, true, true);
 +    return HDFSCompactionManager.getInstance(store).submitRequest(request);
 +  }
 +
 +  @Override
 +  public long getLastMajorCompactionTimestamp() {
 +    long ts = 0;
 +    String user = logger.isDebugEnabled() ? "StoredProc" : null;
 +    List<TrackedReference<Hoplog>> hoplogs = hoplogReadersController.getTrackedSortedOplogList(user);
 +    try {
 +      for (TrackedReference<Hoplog> hoplog : hoplogs) {
 +        String fileName = hoplog.get().getFileName();
 +        Matcher file = HOPLOG_NAME_PATTERN.matcher(fileName);
 +        if (file.matches() && fileName.endsWith(MAJOR_HOPLOG_EXTENSION)) {
 +          ts = getHoplogTimestamp(file);
 +          break;
 +        }
 +      }
 +    } finally {
 +      hoplogReadersController.releaseHoplogs(hoplogs, user);
 +    }
 +    if (logger.isDebugEnabled()) {
 +      logger.debug("{}HDFS: for bucket:"+getRegionBucketStr()+" returning last major compaction timestamp "+ts, logPrefix);
 +    }
 +    return ts;
 +  }
 +
 +  private void initOldTmpFiles() throws IOException {
 +    FileSystem fs = store.getFileSystem();
 +    if (! fs.exists(bucketPath)) {
 +      return;
 +    }
 +    
 +    oldTmpFiles = new LinkedList<FileStatus>(Arrays.asList(fs.listStatus(bucketPath, new TmpFilePathFilter())));
 +  }
 +  
 +  private void cleanupTmpFiles() throws IOException {
 +    if(oldTmpFiles == null && tmpFiles == null) {
 +      return;
 +    }
 +    
 +    if (oldTmpFiles != null) {
 +      FileSystem fs = store.getFileSystem();
 +      long now = System.currentTimeMillis();
 +      for (Iterator<FileStatus> itr = oldTmpFiles.iterator(); itr.hasNext();) {
 +        FileStatus file = itr.next();
 +        if(file.getModificationTime() + TMP_FILE_EXPIRATION_TIME_MS > now) {
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("{}Deleting temporary file:" + file.getPath(), logPrefix);
 +          }
 +          fs.delete(file.getPath(), false);
 +          itr.remove();
 +        }
 +      }
 +    }
 +    if (tmpFiles != null) {
 +      for (Hoplog so : tmpFiles.keySet()) {
 +        if (logger.isDebugEnabled()) {
 +          logger.debug("{}Deleting temporary file:" + so.getFileName(), logPrefix);
 +        }
 +        deleteTmpFile(null, so);
 +      }
 +    }
 +  }
 +  
 +  /**
 +   * Executes tiered compaction of hoplog files. One instance of compacter per bucket will exist
 +   */
 +  protected class HoplogCompactor implements Compactor {
 +    private volatile boolean suspend = false;
 +    
 +    // the following boolean will be used to synchronize minor compaction
 +    private AtomicBoolean isMinorCompactionActive = new AtomicBoolean(false);
 +    // the following boolean will be used to synchronize major compaction
 +    private AtomicBoolean isMajorCompactionActive = new AtomicBoolean(false);
 +    // the following integer tracks the max sequence number amongst the
 +    // target files being major compacted. This value will be used to prevent
 +    // concurrent MajorC and minorC. MinorC is preempted in case of an
 +    // overlap. This object is also used as a lock. The lock is acquired before
 +    // identifying compaction targets and before marking targets for expiry
 +    final AtomicInteger maxMajorCSeqNum = new AtomicInteger(-1);
 +
 +    @Override
 +    public void suspend() {
 +      long wait = Long.getLong(HoplogConfig.SUSPEND_MAX_WAIT_MS, HoplogConfig.SUSPEND_MAX_WAIT_MS_DEFAULT);
 +      this.suspend=true;
 +      //this forces the compact method to finish.
 +      while (isMajorCompactionActive.get() || isMinorCompactionActive.get()) {
 +        if (wait < 0) {
 +          wait = Long.getLong(HoplogConfig.SUSPEND_MAX_WAIT_MS, HoplogConfig.SUSPEND_MAX_WAIT_MS_DEFAULT);
 +          String act = isMajorCompactionActive.get() ? "MajorC" : "MinorC";
 +          logger.warn(LocalizedMessage.create(LocalizedStrings.HOPLOG_SUSPEND_OF_0_FAILED_IN_1, new Object[] {act, wait}));
 +          break;
 +        }
 +        try {
 +          TimeUnit.MILLISECONDS.sleep(50);
 +          wait -= 50;
 +        } catch (InterruptedException e) {
 +          break;
 +        }
 +      }
 +    }
 +    
 +    @Override
 +    public void resume() {
 +      this.suspend = false;
 +    }
 +    
 +    @Override
 +    public boolean isBusy(boolean isMajor) {
 +      if (isMajor) {
 +        return isMajorCompactionActive.get();
 +      } else {
 +        return isMinorCompactionActive.get();
 +      }
 +    }
 +    
 +    /**
 +     * compacts hoplogs. The method takes a minor or major compaction "lock" to
 +     * prevent concurrent execution of compaction cycles. A possible improvement
 +     * is to allow parallel execution of minor compaction if the sets of
 +     * hoplogs being compacted are disjoint.
 +     */
 +    @Override
 +    public boolean compact(boolean isMajor, boolean isForced) throws IOException {
 +      if(suspend) {
 +        return false;
 +      }
 +
 +      String extension = null;
 +      IOOperation compactionStats = null;
 +      long startTime = 0; 
 +      final AtomicBoolean lock;
 +      Hoplog compactedHoplog = null;
 +      List<TrackedReference<Hoplog>> targets = null;
 +      String user = logger.isDebugEnabled() ? (isMajor ? "MajorC" : "MinorC") : null;
 +      
 +      if (isMajor) {
 +        lock = isMajorCompactionActive;
 +        extension = MAJOR_HOPLOG_EXTENSION;
 +        compactionStats = stats.getMajorCompaction();
 +      } else {
 +        lock = isMinorCompactionActive;
 +        extension = MINOR_HOPLOG_EXTENSION;
 +        compactionStats = stats.getMinorCompaction();
 +      }
 +
 +      // final check before beginning compaction. Return if compaction is active
 +      if (! lock.compareAndSet(false, true)) {
 +        if (isMajor) {
 +          if (logger.isDebugEnabled())
 +            logger.debug("{}Major compaction already active. Ignoring new request", logPrefix);
 +        } else {
 +          if (logger.isDebugEnabled())
 +            logger.debug("Minor compaction already active. Ignoring new request", logPrefix);
 +        }
 +        return false;
 +      }
 +      
 +      try {
 +        if(suspend) {
 +          return false;
 +        }
 +        
 +        // variables for updating stats
 +        startTime = compactionStats.begin();
 +        
 +        int seqNum = -1;
 +        int lastKnownMajorCSeqNum;
 +        synchronized (maxMajorCSeqNum) {
 +          lastKnownMajorCSeqNum = maxMajorCSeqNum.get();
 +          targets = hoplogReadersController.getTrackedSortedOplogList(user);
 +          getCompactionTargets(isMajor, targets, lastKnownMajorCSeqNum);
 +          if (targets != null && targets.size() > 0) {
 +            targets = Collections.unmodifiableList(targets);
 +            seqNum = getSequenceNumber(targets.get(0).get());
 +            if (isMajor) {
 +              maxMajorCSeqNum.set(seqNum);
 +            }
 +          }
 +        }
 +        
 +        if (targets == null || targets.isEmpty() || (!isMajor && targets.size() == 1 && !isForced)) {
 +          if (logger.isDebugEnabled()){
 +            logger.debug("{}Skipping compaction, too few hoplops to compact. Major?" + isMajor, logPrefix);
 +          }
 +            
 +          compactionStats.end(0, startTime);
 +          return true;
 +        }
 +        
 +        //In case that we only have one major compacted file, we don't need to run major compaction to
 +        //generate a copy of the same content
 +        if (targets.size() == 1 && !isForced) {
 +        String hoplogName = targets.get(0).get().getFileName();
 +          if (hoplogName.endsWith(MAJOR_HOPLOG_EXTENSION)){
 +            if (logger.isDebugEnabled()){
 +              logger.debug("{}Skipping compaction, no need to compact a major compacted file. Major?" + isMajor, logPrefix);
 +            }
 +            compactionStats.end(0, startTime);
 +            return true;
 +          }
 +        }
 +        
 +        if (logger.isDebugEnabled()) {
 +          for (TrackedReference<Hoplog> target : targets) {
 +            if (logger.isDebugEnabled()) {
 +              fineLog("Target:", target, " size:", target.get().getSize());
 +            }
 +          }
 +        }
 +        
 +        // Create a temporary hoplog for compacted hoplog. The compacted hoplog
 +        // will have the seq number same as that of youngest target file. Any
 +        // hoplog younger than target hoplogs will have a higher sequence number
 +        compactedHoplog = getTmpSortedOplog(seqNum, extension);
 +        
 +        long byteCount;
 +        try {
 +          byteCount = fillCompactionHoplog(isMajor, targets, compactedHoplog, lastKnownMajorCSeqNum);
 +          compactionStats.end(byteCount, startTime);
 +        } catch (InterruptedException e) {
 +          if (logger.isDebugEnabled())
 +            logger.debug("{}Compaction execution suspended", logPrefix);
 +          compactionStats.error(startTime);
 +          return false;
 +        } catch (ForceReattemptException e) {
 +          if (logger.isDebugEnabled())
 +            logger.debug("{}Compaction execution suspended", logPrefix);
 +          compactionStats.error(startTime);
 +          return false;
 +        }
 +        
 +        // creation of compacted hoplog completed, its time to use it for
 +        // reading. Before using it, make sure minorC and mojorC were not
 +        // executing on overlapping sets of files. All targets can be marked for
 +        // expiration. Notify listener if configured. Update bucket size
 +        synchronized (maxMajorCSeqNum) {
 +          if (!isMajor && isMinorMajorOverlap(targets, maxMajorCSeqNum.get())) {
 +            // MajorC is higher priority. In case of any overlap kill minorC
 +            if (logger.isDebugEnabled())
 +              logger.debug("{}Interrupting MinorC for a concurrent MajorC", logPrefix);
 +            compactionStats.error(startTime);
 +            return false;
 +          }
 +          addSortedOplog(compactedHoplog, true, false);
 +          markSortedOplogForDeletion(targets, true);
 +        }
 +      } catch (IOException e) {
 +        compactionStats.error(startTime);
 +        throw e;
 +      } finally {
 +        if (isMajor) {
 +          maxMajorCSeqNum.set(-1);
 +        }
 +        lock.set(false);
 +        hoplogReadersController.releaseHoplogs(targets, user);
 +      }
 +      
 +      incrementDiskUsage(compactedHoplog.getSize());
 +      reEstimateBucketSize();
 +      
 +      notifyCompactionListeners(isMajor);
 +      return true;
 +    }
 +
 +    /**
 +     * Major compaction compacts all files. Seq number of the youngest file
 +     * being MajorCed is known. If MinorC is operating on any file with a seq
 +     * number less than this number, there is a overlap
 +     * @param num 
 +     */
 +    boolean isMinorMajorOverlap(List<TrackedReference<Hoplog>> targets, int num) {
 +      if (num < 0 || targets == null || targets.isEmpty()) {
 +        return false;
 +      }
 +
 +      for (TrackedReference<Hoplog> hop : targets) {
 +        if (getSequenceNumber(hop.get()) <= num) {
 +          return true;
 +        }
 +      }
 +      
 +      return false;
 +    }
 +
 +    /**
 +     * Iterates over targets and writes eligible targets to the output hoplog.
 +     * Handles creation of iterators and writer and closing it in case of
 +     * errors.
 +     */
 +    public long fillCompactionHoplog(boolean isMajor,
 +        List<TrackedReference<Hoplog>> targets, Hoplog output, int majorCSeqNum)
 +        throws IOException, InterruptedException, ForceReattemptException {
 +
 +      HoplogWriter writer = null;
 +      ICardinality localHLL = new HyperLogLog(HLL_CONSTANT);
 +      HoplogSetIterator mergedIter = null;
 +      int byteCount = 0;
 +      
 +      try {
 +        // create a merged iterator over the targets and write entries into
 +        // output hoplog
 +        mergedIter = new HoplogSetIterator(targets);
 +        writer = output.createWriter(mergedIter.getRemainingEntryCount());
 +
 +        boolean interrupted = false;
 +        for (; mergedIter.hasNext(); ) {
 +          if (suspend) {
 +            interrupted = true;
 +            break;
 +          } else if (!isMajor &&  maxMajorCSeqNum.get() > majorCSeqNum) {
 +            // A new major compaction cycle is starting, quit minorC to avoid
 +            // duplicate work and missing deletes
 +            if (logger.isDebugEnabled())
 +              logger.debug("{}Preempting MinorC, new MajorC cycle detected ", logPrefix);
 +            interrupted = true;
 +            break;
 +          }
 +
 +          mergedIter.nextBB();
 +          
 +          ByteBuffer k = mergedIter.getKeyBB();
 +          ByteBuffer v = mergedIter.getValueBB();
 +          
 +          boolean isDeletedEntry = isDeletedEntry(v.array(), v.arrayOffset());
 +          if (isMajor && isDeletedEntry) {
 +            // its major compaction, time to ignore deleted entries
 +            continue;
 +          }
 +
 +          if (!isDeletedEntry) {
 +            int hash = MurmurHash.hash(k.array(), k.arrayOffset(), k.remaining(), -1);
 +            localHLL.offerHashed(hash);
 +          }
 +
 +          writer.append(k, v);
 +          byteCount += (k.remaining() + v.remaining());
 +        }
 +
 +        mergedIter.close();
 +        mergedIter = null;
 +
 +        writer.close(buildMetaData(localHLL));
 +        writer = null;
 +
 +        if (interrupted) {
 +          // If we suspended compaction operations, delete the partially written
 +          // file and return.
 +          output.delete();
 +          throw new InterruptedException();
 +        }
 +        
 +        // ping secondaries before making the file a legitimate file to ensure 
 +        // that in case of split brain, no other vm has taken up as primary. #50110. 
 +        pingSecondaries();
 +        
 +        makeLegitimate(output);
 +        return byteCount;
 +      } catch (IOException e) {
 +        e = handleWriteHdfsIOError(writer, output, e);
 +        writer = null;
 +        throw e;
 +      } catch (ForceReattemptException e) {
 +        output.delete();
 +        throw e;
 +      }finally {
 +        if (mergedIter != null) {
 +          mergedIter.close();
 +        }
 +
 +        if (writer != null) {
 +          writer.close();
 +        }
 +      }
 +    }
 +
 +    /**
 +     * identifies targets. For major compaction all sorted oplogs will be
 +     * iterated on. For minor compaction, policy driven fewer targets will take
 +     * place.
 +     */
 +    protected void getCompactionTargets(boolean major,
 +        List<TrackedReference<Hoplog>> targets, int majorCSeqNum) {
 +      if (!major) {
 +        getMinorCompactionTargets(targets, majorCSeqNum);
 +      }
 +    }
 +
 +    /**
 +     * list of oplogs most suitable for compaction. The alogrithm selects m
 +     * smallest oplogs which are not bigger than X in size. Null if valid
 +     * candidates are not found
 +     */
 +    void getMinorCompactionTargets(List<TrackedReference<Hoplog>> targets, int majorCSeqNum) 
 +    {
 +      List<TrackedReference<Hoplog>> omittedHoplogs = new ArrayList<TrackedReference<Hoplog>>();
 +
 +      // reverse the order of hoplogs in list. the oldest file becomes the first file.
 +      Collections.reverse(targets);
 +
 +      // hoplog greater than this size will not be minor-compacted
 +      final long MAX_COMPACTION_FILE_SIZE;
 +      // maximum number of files to be included in any compaction cycle
 +      final int MAX_FILE_COUNT_COMPACTION;
 +      // minimum number of files that must be present for compaction to be worth
 +      final int MIN_FILE_COUNT_COMPACTION;
 +      
 +      MAX_COMPACTION_FILE_SIZE = ((long)store.getInputFileSizeMax()) * 1024 *1024;
 +      MAX_FILE_COUNT_COMPACTION = store.getInputFileCountMax();
 +      MIN_FILE_COUNT_COMPACTION = store.getInputFileCountMin();
 +
 +      try {
 +        // skip till first file smaller than the max compaction file size is
 +        // found. And if MajorC is active, move to a file which is also outside
 +        // scope of MajorC
 +        for (Iterator<TrackedReference<Hoplog>> iterator = targets.iterator(); iterator.hasNext();) {
 +          TrackedReference<Hoplog> oplog = iterator.next();
 +          if (majorCSeqNum >= getSequenceNumber(oplog.get())) {
 +            iterator.remove();
 +            omittedHoplogs.add(oplog);
 +            if (logger.isDebugEnabled()){
 +              fineLog("Overlap with MajorC, excluding hoplog " + oplog.get());
 +            }
 +            continue;
 +          }
 +          
 +          if (oplog.get().getSize() > MAX_COMPACTION_FILE_SIZE || oplog.get().getFileName().endsWith(MAJOR_HOPLOG_EXTENSION)) {
 +          // big file will not be included for minor compaction
 +          // major compacted file will not be converted to minor compacted file
 +            iterator.remove();
 +            omittedHoplogs.add(oplog);
 +            if (logger.isDebugEnabled()) {
 +              fineLog("Excluding big hoplog from minor cycle:",
 +                  oplog.get(), " size:", oplog.get().getSize(), " limit:",
 +                  MAX_COMPACTION_FILE_SIZE);
 +            }
 +          } else {
 +            // first small hoplog found, skip the loop
 +            break;
 +          }
 +        }
 +
 +        // If there are too few files no need to perform compaction
 +        if (targets.size() < MIN_FILE_COUNT_COMPACTION) {
 +          if (logger.isDebugEnabled()){
 +            logger.debug("{}Too few hoplogs for minor cycle:" + targets.size(), logPrefix);
 +          }
 +          omittedHoplogs.addAll(targets);
 +          targets.clear();
 +          return;
 +        }
 +        
 +        float maxGain = Float.MIN_VALUE;
 +        int bestFrom = -1; 
 +        int bestTo = -1; 
 +        
 +        // for listSize=5 list, minFile=3; maxIndex=5-3. 
 +        // so from takes values 0,1,2
 +        int maxIndexForFrom = targets.size() - MIN_FILE_COUNT_COMPACTION;
 +        for (int from = 0; from <= maxIndexForFrom ; from++) {
 +          // for listSize=6 list, minFile=3, maxFile=5; minTo=0+3-1, maxTo=0+5-1
 +          // so to takes values 2,3,4
 +          int minIndexForTo = from + MIN_FILE_COUNT_COMPACTION - 1;
 +          int maxIndexForTo = Math.min(from + MAX_FILE_COUNT_COMPACTION, targets.size());
 +          
 +          for (int i = minIndexForTo; i < maxIndexForTo; i++) {
 +            Float gain = computeGain(from, i, targets);
 +            if (gain == null) {
 +              continue;
 +            }
 +            
 +            if (gain > maxGain) {
 +              maxGain = gain;
 +              bestFrom = from;
 +              bestTo = i;
 +            }
 +          }
 +        }
 +        
 +        if (bestFrom == -1) {
 +          if (logger.isDebugEnabled())
 +            logger.debug("{}Failed to find optimal target set for MinorC", logPrefix);
 +          omittedHoplogs.addAll(targets);
 +          targets.clear();
 +          return;
 +        }
 +
 +        if (logger.isDebugEnabled()) {
 +          fineLog("MinorCTarget optimal result from:", bestFrom, " to:", bestTo);
 +        }
 +
 +        // remove hoplogs they do not fall in the bestFrom-bestTo range
 +        int i = 0;
 +        for (Iterator<TrackedReference<Hoplog>> iter = targets.iterator(); iter.hasNext();) {
 +          TrackedReference<Hoplog> hop = iter.next();
 +          if (i < bestFrom || i > bestTo) {
 +            iter.remove();
 +            omittedHoplogs.add(hop);
 +          }
 +          i++;
 +        }
 +      } finally {
 +        // release readers of targets not included in the compaction cycle 
 +        String user = logger.isDebugEnabled() ? "MinorC" : null;
 +        hoplogReadersController.releaseHoplogs(omittedHoplogs, user);
 +      }
 +      
 +      // restore the order, youngest file is the first file again
 +      Collections.reverse(targets);
 +    }
 +
 +    @Override
 +    public HDFSStore getHdfsStore() {
 +      return store;
 +    }
 +  }
 +  
 +  Float computeGain(int from, int to, List<TrackedReference<Hoplog>> targets) {
 +    double SIZE_64K = 64.0 * 1024;
 +    // TODO the base for log should depend on the average number of keys a index block will contain
 +    double LOG_BASE = Math.log(AVG_NUM_KEYS_PER_INDEX_BLOCK);
 +    
 +    long totalSize = 0;
 +    double costBefore = 0f;
 +    for (int i = from; i <= to; i++) {
 +      long size = targets.get(i).get().getSize();
 +      if (size == 0) {
 +        continue;
 +      }
 +      totalSize += size;
 +      
 +      // For each hoplog file, read cost is number of index block reads and 1
 +      // data block read. Index blocks on an average contain N keys and are
 +      // organized in a N-ary tree structure. Hence the number of index block
 +      // reads will be logBaseN(number of data blocks)
 +      costBefore += Math.ceil(Math.max(1.0, Math.log(size / SIZE_64K) / LOG_BASE)) + 1;
 +    }
 +    
 +    // if the first file is relatively too large this set is bad for compaction
 +    long firstFileSize = targets.get(from).get().getSize();
 +    if (firstFileSize > (totalSize - firstFileSize) * RATIO) {
 +      if (logger.isDebugEnabled()){
 +        fineLog("First file too big:", firstFileSize, " totalSize:", totalSize);
 +      }
 +      return null;
 +    }
 +        
 +    // compute size in mb so that the value of gain is in few decimals
 +    long totalSizeInMb = totalSize / 1024 / 1024;
 +    if (totalSizeInMb == 0) {
 +      // the files are tooooo small, just return the count. The more we compact
 +      // the better it is
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Total size too small:" +totalSize, logPrefix);
 +      }
 +      return (float) costBefore;
 +    }
 +    
 +    double costAfter = Math.ceil(Math.log(totalSize / SIZE_64K) / LOG_BASE) + 1;
 +    return (float) ((costBefore - costAfter) / totalSizeInMb);
 +  }
 +  
 +  /**
 +   * Hoplog readers are accessed asynchronously. There could be a window in
 +   * which, while a hoplog is being iterated on, it gets compacted and becomes
 +   * expired or inactive. The reader of the hoplog must not be closed till the
 +   * iterator completes. All such scenarios will be managed by this class. It
 +   * will keep all the reader, active and inactive, and reference counter to the
 +   * readers. An inactive reader will be closed if the reference count goes down
 +   * to 0.
 +   * 
 +   * One important point, only compaction process makes a hoplog inactive.
 +   * Compaction process in a bucket is single threaded. So compaction itself
 +   * will not face race condition. Read and scan operations on the bucket will
 +   * be affected. So reference counter is incremented for each read and scan.
 +   * 
 +   * @author ashvina
 +   */
 +  private class HoplogReadersController implements HoplogReaderActivityListener {
 +    private Integer maxOpenFilesLimit;
 +
 +    // sorted collection of all the active oplog files associated with this bucket. Instead of a
 +    // queue, a set is used. New files created as part of compaction may be inserted after a few
 +    // hoplogs were created. The compacted file is such a case but should not be treated newest.
 +    private final ConcurrentSkipListSet<TrackedReference<Hoplog>> hoplogs;
 +    
 +    // list of all the hoplogs that have been compacted and need to be closed
 +    // once the reference count reduces to 0
 +    private final ConcurrentHashSet<TrackedReference<Hoplog>> inactiveHoplogs;
 +    
 +    // ReadWriteLock on list of oplogs to allow for consistent reads and scans
 +    // while hoplog set changes. A write lock is needed on completion of
 +    // compaction, addition of a new hoplog or on receiving updates message from
 +    // other GF nodes
 +    private final ReadWriteLock hoplogRWLock = new ReentrantReadWriteLock(true);
 +
 +    // tracks the number of active readers for hoplogs of this bucket
 +    private AtomicInteger activeReaderCount = new AtomicInteger(0);
 +    
 +    public HoplogReadersController() {
 +      HoplogComparator comp = new HoplogComparator();
 +      hoplogs = new ConcurrentSkipListSet<TrackedReference<Hoplog>>(comp) {
 +        private static final long serialVersionUID = 1L;
 +
 +        @Override
 +        public boolean add(TrackedReference<Hoplog> e) {
 +          // increment number of hoplogs active for this bucket
 +          boolean result =  super.add(e);
 +          if (result)
 +            stats.incActiveFiles(1);
 +          return result;
 +        }
 +        
 +        @Override
 +        public boolean remove(Object o) {
 +          // decrement the number of hoplogs active for this bucket
 +          boolean result =  super.remove(o);
 +          if (result)
 +            stats.incActiveFiles(-1);
 +          return result;
 +        }
 +      };
 +      
 +      inactiveHoplogs = new ConcurrentHashSet<TrackedReference<Hoplog>>() {
 +        private static final long serialVersionUID = 1L;
 +        
 +        @Override
 +        public boolean add(TrackedReference<Hoplog> e) {
 +          boolean result =  super.add(e);
 +          if (result)
 +            stats.incInactiveFiles(1);
 +          return result;
 +        }
 +        
 +        @Override
 +        public boolean remove(Object o) {
 +          boolean result =  super.remove(o);
 +          if (result)
 +            stats.incInactiveFiles(-1);
 +          return result;
 +        }
 +      };
 +      
 +      maxOpenFilesLimit = Integer.getInteger(
 +          HoplogConfig.BUCKET_MAX_OPEN_HFILES_CONF,
 +          HoplogConfig.BUCKET_MAX_OPEN_HFILES_DEFAULT);
 +    }
 +    
 +    Hoplog getOldestHoplog() {
 +      if (hoplogs.isEmpty()) {
 +        return null;
 +      }
 +      return hoplogs.last().get();
 +    }
 +
 +    /**
 +     * locks sorted oplogs collection and performs add operation
 +     * @return if addition was successful
 +     */
 +    private boolean addSortedOplog(Hoplog so) throws IOException {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Try add " + so, logPrefix);
 +      }
 +      hoplogRWLock.writeLock().lock();
 +      try {
 +        int size = hoplogs.size();
 +        boolean result = hoplogs.add(new TrackedReference<Hoplog>(so));
 +        so.setReaderActivityListener(this);
 +        if (logger.isDebugEnabled()){
 +          fineLog("Added: ", so, " Before:", size, " After:", hoplogs.size());
 +        }
 +        return result;
 +      } finally {
 +        hoplogRWLock.writeLock().unlock();
 +      }
 +    }
 +    
 +    /**
 +     * locks sorted oplogs collection and performs remove operation and updates readers also
 +     */
 +    private void removeSortedOplog(TrackedReference<Hoplog> so) throws IOException {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("Try remove " + so, logPrefix);
 +      }
 +      hoplogRWLock.writeLock().lock();
 +      try {
 +        int size = hoplogs.size();
 +        boolean result = hoplogs.remove(so);
 +        if (result) {
 +          inactiveHoplogs.add(so);
 +          if (logger.isDebugEnabled()) {
 +            fineLog("Removed: ", so, " Before:", size, " After:", hoplogs.size());
 +          }
 +        } else {
 +          if (inactiveHoplogs.contains(so)) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}Found a missing active hoplog in inactive list." + so, logPrefix);
 +            }
 +          } else {
 +            so.get().close();
 +            logger.warn(LocalizedMessage.create(LocalizedStrings.HOPLOG_MISSING_IN_BUCKET_FORCED_CLOSED, so.get()));
 +          }
 +        }
 +      } finally {
 +        hoplogRWLock.writeLock().unlock();
 +      }
 +    }
 +    
 +    private  void closeInactiveHoplogs() throws IOException {
 +      hoplogRWLock.writeLock().lock();
 +      try {
 +        for (TrackedReference<Hoplog> hoplog : inactiveHoplogs) {
 +          if (logger.isDebugEnabled()){
 +            logger.debug("{}Try close inactive " + hoplog, logPrefix);
 +          }
 +
 +          if (!hoplog.inUse()) {
 +            int size = inactiveHoplogs.size();            
 +            inactiveHoplogs.remove(hoplog);
 +            closeReaderAndSuppressError(hoplog.get(), true);
 +            if (logger.isDebugEnabled()){
 +              fineLog("Closed inactive: ", hoplog.get(), " Before:", size,
 +                  " After:", inactiveHoplogs.size());
 +            }
 +          }
 +        }
 +      } finally {
 +        hoplogRWLock.writeLock().unlock();
 +      }
 +    }
 +    
 +    /**
 +     * @param target
 +     *          name of the hoplog file
 +     * @return trackedReference if target exists in inactive hoplog list.
 +     * @throws IOException
 +     */
 +    TrackedReference<Hoplog> getInactiveHoplog(String target) throws IOException {
 +      hoplogRWLock.writeLock().lock();
 +      try {
 +        for (TrackedReference<Hoplog> hoplog : inactiveHoplogs) {
 +          if (hoplog.get().getFileName().equals(target)) {
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}Target found in inactive hoplogs list: " + hoplog, logPrefix);
 +            }
 +            return hoplog;
 +          }
 +        }
 +        if (logger.isDebugEnabled()){
 +          logger.debug("{}Target not found in inactive hoplogs list: " + target, logPrefix);
 +        }
 +        return null;
 +      } finally {
 +        hoplogRWLock.writeLock().unlock();
 +      }
 +    }
 +    
 +    /**
 +     * force closes all readers
 +     */
 +    public void close() throws IOException {
 +      hoplogRWLock.writeLock().lock();
 +      try {
 +        for (TrackedReference<Hoplog> hoplog : hoplogs) {
 +          closeReaderAndSuppressError(hoplog.get(), true);
 +        }
 +        
 +        for (TrackedReference<Hoplog> hoplog : inactiveHoplogs) {
 +          closeReaderAndSuppressError(hoplog.get(), true);
 +        }
 +      } finally {
 +        hoplogs.clear();
 +        inactiveHoplogs.clear();
 +        hoplogRWLock.writeLock().unlock();
 +      }
 +    }
 +    
 +    /**
 +     * locks hoplogs to create a snapshot of active hoplogs. reference of each
 +     * reader is incremented to keep it from getting closed
 +     * 
 +     * @return ordered list of sorted oplogs
 +     */
 +    private List<TrackedReference<Hoplog>> getTrackedSortedOplogList(String user) {
 +      List<TrackedReference<Hoplog>> oplogs = new ArrayList<TrackedReference<Hoplog>>();
 +      hoplogRWLock.readLock().lock();
 +      try {
 +        for (TrackedReference<Hoplog> oplog : hoplogs) {
 +          oplog.increment(user);
 +          oplogs.add(oplog);
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("{}Track ref " + oplog, logPrefix);
 +          }
 +        }
 +      } finally {
 +        hoplogRWLock.readLock().unlock();
 +      }
 +      return oplogs;
 +    }
 +
 +    private TrackedReference<Hoplog> trackHoplog(Hoplog hoplog, String user) {
 +      hoplogRWLock.readLock().lock();
 +      try {
 +        for (TrackedReference<Hoplog> oplog : hoplogs) {
 +          if (oplog.get().getFileName().equals(hoplog.getFileName())) {
 +            oplog.increment(user);
 +            if (logger.isDebugEnabled()) {
 +              logger.debug("{}Track " + oplog, logPrefix);
 +            }
 +            return oplog;
 +          }
 +        }
 +      } finally {
 +        hoplogRWLock.readLock().unlock();
 +      }
 +      throw new NoSuchElementException(hoplog.getFileName());
 +    }
 +    
 +    public void releaseHoplogs(List<TrackedReference<Hoplog>> targets, String user) {
 +      if (targets == null) {
 +        return;
 +      }
 +      
 +      for (int i = targets.size() - 1; i >= 0; i--) {
 +        TrackedReference<Hoplog> hoplog = targets.get(i);
 +        releaseHoplog(hoplog, user);
 +      }
 +    }
 +
 +    public void releaseHoplog(TrackedReference<Hoplog> target, String user) {
 +      if (target ==  null) {
 +        return;
 +      }
 +      
 +      target.decrement(user);
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Try release " + target, logPrefix);
 +      }
 +      if (target.inUse()) {
 +        return;
 +      }
 +      
 +      // there are no users of this hoplog. if it is inactive close it.
 +      hoplogRWLock.writeLock().lock();
 +      try {
 +        if (!target.inUse()) {
 +          if (inactiveHoplogs.contains(target) ) {
 +            int sizeBefore = inactiveHoplogs.size();
 +            inactiveHoplogs.remove(target);
 +            closeReaderAndSuppressError(target.get(), true);
 +            if (logger.isDebugEnabled()) {
 +              fineLog("Closed inactive: ", target, " totalBefore:", sizeBefore,
 +                  " totalAfter:", inactiveHoplogs.size());
 +            }
 +          } else if (hoplogs.contains(target)) {
 +            closeExcessReaders();              
 +          }
 +        }
 +      } catch (IOException e) {
 +        logger.warn(LocalizedMessage.create(LocalizedStrings.HOPLOG_IO_ERROR, 
 +            "Close reader: " + target.get().getFileName()), e);
 +      } finally {
 +        hoplogRWLock.writeLock().unlock();
 +      }
 +    }
 +
 +    /*
 +     * detects if the total number of open hdfs readers is more than configured
 +     * max file limit. In case the limit is exceeded, some readers need to be
 +     * closed to avoid dadanode receiver overflow error.
 +     */
 +    private void closeExcessReaders() throws IOException {
 +      if (logger.isDebugEnabled()) {
 +        logger.debug("{}Close excess readers. Size:" + hoplogs.size()
 +            + " activeReaders:" + activeReaderCount.get() + " limit:"
 +            + maxOpenFilesLimit, logPrefix);
 +      }
 +
 +      if (hoplogs.size() <= maxOpenFilesLimit) {
 +        return;
 +      }
 +      
 +      if (activeReaderCount.get() <= maxOpenFilesLimit) {
 +        return;
 +      }
 +      
 +      for (TrackedReference<Hoplog> hoplog : hoplogs.descendingSet()) {
 +        if (!hoplog.inUse() && !hoplog.get().isClosed()) {
 +          hoplog.get().close(false);
 +          if (logger.isDebugEnabled()) {
 +            logger.debug("{}Excess reader closed " + hoplog, logPrefix);
 +          }
 +        }
 +        
 +        if (activeReaderCount.get() <= maxOpenFilesLimit) {
 +          return;
 +        }
 +      }
 +    }
 +
 +    @Override
 +    public void readerCreated() {
 +      activeReaderCount.incrementAndGet();
 +      stats.incActiveReaders(1);
 +      if (logger.isDebugEnabled())
 +        logger.debug("{}ActiveReader++", logPrefix);
 +    }
 +
 +    @Override
 +    public void readerClosed() {
 +      activeReaderCount.decrementAndGet(); 
 +      stats.incActiveReaders(-1);
 +      if (logger.isDebugEnabled())
 +        logger.debug("{}ActiveReader--", logPrefix);
 +    }
 +  }
 +
 +  /**
 +   * returns an ordered list of oplogs, FOR TESTING ONLY
 +   */
 +  public List<TrackedReference<Hoplog>> getSortedOplogs() throws IOException {
 +    List<TrackedReference<Hoplog>> oplogs = new ArrayList<TrackedReference<Hoplog>>();
 +    for (TrackedReference<Hoplog> oplog : hoplogReadersController.hoplogs) {
 +        oplogs.add(oplog);
 +    }
 +    return oplogs;
 +  }
 +
 +  /**
 +   * Merged iterator on a list of hoplogs. 
 +   */
 +  public class BucketIterator implements HoplogIterator<byte[], SortedHoplogPersistedEvent> {
 +    // list of hoplogs to be iterated on.
 +    final List<TrackedReference<Hoplog>> hoplogList;
 +    HoplogSetIterator mergedIter;
 +
 +    public BucketIterator(List<TrackedReference<Hoplog>> hoplogs) throws IOException {
 +      this.hoplogList = hoplogs;
 +      try {
 +        mergedIter = new HoplogSetIterator(this.hoplogList);
 +        if (logger.isDebugEnabled()) {
 +          for (TrackedReference<Hoplog> hoplog : hoplogs) {
 +            logger.debug("{}BucketIter target hop:" + hoplog.get().getFileName(), logPrefix);
 +          }
 +        }
 +      } catch (IllegalArgumentException e) {
 +        if (IOException.class.isAssignableFrom(e.getCause().getClass())) {
 +          throw handleIOError((IOException) e.getCause());
 +        } else {
 +          throw e;
 +        }
 +      } catch (IOException e) {
 +        throw handleIOError(e);
 +      } catch (HDFSIOException e) {
 +        throw handleIOError(e);
 +      } 
 +    }
 +
 +    @Override
 +    public boolean hasNext() {
 +      return mergedIter.hasNext();
 +    }
 +
 +    @Override
 +    public byte[] next() throws IOException {
 +      try {
 +        return HFileSortedOplog.byteBufferToArray(mergedIter.next());
 +      } catch (IllegalArgumentException e) {
 +        if (IOException.class.isAssignableFrom(e.getCause().getClass())) {
 +          throw handleIOError((IOException) e.getCause());
 +        } else {
 +          throw e;
 +        }
 +      } catch (IOException e) {
 +        throw handleIOError(e);
 +      }  
 +    }
 +
 +    @Override
 +    public byte[] getKey() {
 +      // merged iterator returns a byte[]. This needs to be deserialized to the object which was
 +      // provided during flush operation
 +      return HFileSortedOplog.byteBufferToArray(mergedIter.getKey());
 +    }
 +
 +    @Override
 +    public SortedHoplogPersistedEvent getValue() {
 +      // merged iterator returns a byte[]. This needs to be deserialized to the
 +      // object which was provided during flush operation
 +      try {
 +        return deserializeValue(HFileSortedOplog.byteBufferToArray(mergedIter.getValue()));
 +      } catch (IOException e) {
 +        throw new HDFSIOException("Failed to deserialize byte while iterating on partition", e);
 +      }
 +    }
 +
 +    @Override
 +    public void remove() {
 +      mergedIter.remove();
 +    }
 +
 +    @Override
 +    public void close() {
 +      // TODO release the closed iterators early
 +      String user = logger.isDebugEnabled() ? "Scan" : null;
 +      hoplogReadersController.releaseHoplogs(hoplogList, user);
 +    }
 +  }
 +  
 +  /**
 +   * This utility class is used to filter temporary hoplogs in a bucket
 +   * directory
 +   * 
 +   * @author ashvina
 +   */
 +  private static class TmpFilePathFilter implements PathFilter {
 +    @Override
 +    public boolean accept(Path path) {
 +      Matcher matcher = HOPLOG_NAME_PATTERN.matcher(path.getName());
 +      if (matcher.matches() && path.getName().endsWith(TEMP_HOPLOG_EXTENSION)) {
 +        return true;
 +      }
 +      return false;
 +    }
 +  }
 +
 +  private void fineLog(Object... strings) {
 +    if (logger.isDebugEnabled()) {
 +      StringBuffer sb = concatString(strings);
 +      logger.debug(logPrefix + sb.toString());
 +    }
 +  }
 +
 +  private StringBuffer concatString(Object... strings) {
 +    StringBuffer sb = new StringBuffer();
 +    for (Object str : strings) {
 +      sb.append(str.toString());
 +    }
 +    return sb;
 +  }
 +
 +  @Override
 +  public void compactionCompleted(String region, int bucket, boolean isMajor) {
 +    // do nothing for compaction events. Hoplog Organizer depends on addition
 +    // and deletion of hoplogs only
 +  }
 +}
 +

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/Hoplog.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/Hoplog.java
index 113e49b,0000000..a5030ae
mode 100644,000000..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/Hoplog.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/hdfs/internal/hoplog/Hoplog.java
@@@ -1,263 -1,0 +1,264 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.hdfs.internal.hoplog;
 +
++import com.gemstone.gemfire.internal.hll.ICardinality;
++
 +import java.io.Closeable;
 +import java.io.IOException;
 +import java.nio.ByteBuffer;
 +import java.util.EnumMap;
 +
- import com.gemstone.gemfire.cache.hdfs.internal.cardinality.ICardinality;
 +
 +/**
 + * Ordered sequence file
 + */
 +public interface Hoplog extends Closeable, Comparable<Hoplog>  {
 +  public static final boolean NOP_WRITE = Boolean.getBoolean("Hoplog.NOP_WRITE");
 +  
 +  /** the gemfire magic number for sorted oplogs */
 +  public static final byte[] MAGIC = new byte[] { 0x47, 0x53, 0x4F, 0x50 };
 +
 +  /**
 +   * @return an instance of cached reader, creates one if does not exist
 +   * @throws IOException
 +   */
 +  HoplogReader getReader() throws IOException;
 +
 +  /**
 +   * Creates a new sorted writer.
 +   * 
 +   * @param keys
 +   *          an estimate of the number of keys to be written
 +   * @return the writer
 +   * @throws IOException
 +   *           error creating writer
 +   */
 +  HoplogWriter createWriter(int keys) throws IOException;
 +
 +  /**
 +   * @param listener listener of reader's activity
 +   */
 +  void setReaderActivityListener(HoplogReaderActivityListener listener);
 +  
 +  /**
 +   * @return file name
 +   */
 +  String getFileName();
 +
 +  /**
 +   * @return Entry count estimate for this hoplog
 +   */
 +  public ICardinality getEntryCountEstimate() throws IOException;
 +
 +  /**
 +   * renames the file to the input name
 +   * 
 +   * @throws IOException
 +   */
 +  void rename(String name) throws IOException;
 +
 +  /**
 +   * Deletes the sorted oplog file
 +   */
 +  void delete() throws IOException;
 +  
 +  /**
 +   * Returns true if the hoplog is closed for reads.
 +   * @return true if closed
 +   */
 +  boolean isClosed();
 +  
 +  /**
 +   * @param clearCache clear this sorted oplog's cache if true
 +   * @throws IOException 
 +   */
 +  void close(boolean clearCache) throws IOException;
 +  
 +  /**
 +   * @return the modification timestamp of the file
 +   */
 +  long getModificationTimeStamp();
 +  
 +  /**
 +   * @return the size of file
 +   */
 +  long getSize();
 +
 +  /**
 +   * Reads sorted oplog file.
 +   */
 +  public interface HoplogReader extends HoplogSetReader<byte[], byte[]> {
 +    /**
 +     * Returns a byte buffer based view of the value linked to the key
 +     */
 +    ByteBuffer get(byte[] key) throws IOException;
 +
 +    /**
 +     * @return Returns the bloom filter associated with this sorted oplog file.
 +     */
 +    BloomFilter getBloomFilter() throws IOException;
 +
 +    /**
 +     * @return number of KV pairs in the file, including tombstone entries
 +     */
 +    long getEntryCount();
 +
 +    /**
 +     * Returns the {@link ICardinality} implementation that is useful for
 +     * estimating the size of this Hoplog.
 +     * 
 +     * @return the cardinality estimator
 +     */
 +    ICardinality getCardinalityEstimator();
 +  }
 +
 +  /**
 +   * Provides hoplog's reader's activity related events to owners
 +   * 
 +   * @author ashvina
 +   */
 +  public interface HoplogReaderActivityListener {
 +    /**
 +     * Invoked when a reader is created and an active reader did not exist
 +     * earlier
 +     */
 +    public void readerCreated();
 +    
 +    /**
 +     * Invoked when an active reader is closed
 +     */
 +    public void readerClosed();
 +  }
 +
 +  /**
 +   * Writes key/value pairs in a sorted oplog file. Each entry that is appended must have a key that
 +   * is greater than or equal to the previous key.
 +   */
 +  public interface HoplogWriter extends Closeable {
 +    /**
 +     * Appends another key and value. The key is expected to be greater than or equal to the last
 +     * key that was appended.
 +     * @param key
 +     * @param value
 +     */
 +    void append(byte[] key, byte[] value) throws IOException;
 +
 +    /**
 +     * Appends another key and value. The key is expected to be greater than or equal to the last
 +     * key that was appended.
 +     */
 +    void append(ByteBuffer key, ByteBuffer value) throws IOException;
 +
 +    void close(EnumMap<Meta, byte[]> metadata) throws IOException;
 +    
 +    /**
 +     * flushes all outstanding data into the OS buffers on all DN replicas 
 +     * @throws IOException
 +     */
 +    void hsync() throws IOException;
 +    
 +    /**
 +     * Gets the size of the data that has already been written
 +     * to the writer.  
 +     * 
 +     * @return number of bytes already written to the writer
 +     */
 +    public long getCurrentSize() throws IOException; 
 +  }
 +
 +  /**
 +   * Identifies the gemfire sorted oplog versions.
 +   */
 +  public enum HoplogVersion {
 +    V1;
 +
 +    /**
 +     * Returns the version string as bytes.
 +     * 
 +     * @return the byte form
 +     */
 +    public byte[] toBytes() {
 +      return name().getBytes();
 +    }
 +
 +    /**
 +     * Constructs the version from a byte array.
 +     * 
 +     * @param version
 +     *          the byte form of the version
 +     * @return the version enum
 +     */
 +    public static HoplogVersion fromBytes(byte[] version) {
 +      return HoplogVersion.valueOf(new String(version));
 +    }
 +  }
 +
 +  /**
 +   * Names the available metadata keys that will be stored in the sorted oplog.
 +   */
 +  public enum Meta {
 +    /** identifies the soplog as a gemfire file, required */
 +    GEMFIRE_MAGIC,
 +
 +    /** identifies the soplog version, required */
 +    SORTED_OPLOG_VERSION,
 +    
 +    /** identifies the gemfire version the soplog was created with */
 +    GEMFIRE_VERSION,
 +
 +    /** identifies the statistics data */
 +    STATISTICS,
 +
 +    /** identifies the embedded comparator types */
 +    COMPARATORS,
 +    
 +    /** identifies the pdx type data, optional */
 +    PDX,
 +
 +    /**
 +     * identifies the hyperLogLog byte[] which estimates the cardinality for
 +     * only one hoplog
 +     */
 +    LOCAL_CARDINALITY_ESTIMATE,
 +
 +    /**
 +     * represents the hyperLogLog byte[] after upgrading the constant from
 +     * 0.1 to 0.03 (in gfxd 1.4)
 +     */
 +    LOCAL_CARDINALITY_ESTIMATE_V2
 +    ;
 +
 +    /**
 +     * Converts the metadata name to bytes.
 +     */
 +    public byte[] toBytes() {
 +      return ("gemfire." + name()).getBytes();
 +    }
 +
 +    /**
 +     * Converts the byte form of the name to an enum.
 +     * 
 +     * @param key
 +     *          the key as bytes
 +     * @return the enum form
 +     */
 +    public static Meta fromBytes(byte[] key) {
 +      return Meta.valueOf(new String(key).substring("gemfire.".length()));
 +    }
 +  }
 +}


[068/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
index 0000000,2d86296..630ae22
mode 000000,100755..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java
@@@ -1,0 -1,540 +1,540 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertFalse;
+ import static org.junit.Assert.assertNotNull;
+ import static org.junit.Assert.assertNull;
+ import static org.junit.Assert.assertTrue;
+ import static org.junit.Assert.fail;
+ 
+ import java.io.IOException;
+ import java.io.Serializable;
+ import java.sql.Timestamp;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.Date;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Hashtable;
+ import java.util.IdentityHashMap;
+ import java.util.LinkedHashSet;
+ import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Properties;
+ import java.util.Stack;
+ import java.util.TreeMap;
+ import java.util.TreeSet;
+ import java.util.UUID;
+ import java.util.Vector;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionShortcut;
+ import com.gemstone.gemfire.compression.SnappyCompressor;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+ 
+ /**
+  * Basic integration tests for validating the off-heap implementation. 
+  * 
+  * @author Kirk Lund
+  */
+ @Category(IntegrationTest.class)
+ public class OffHeapValidationJUnitTest {
+ 
+   private GemFireCacheImpl cache;
+   
+   @Before
+   public void setUp() throws Exception {
+     this.cache = createCache();
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+     closeCache(this.cache);
+   }
+ 
+   protected GemFireCacheImpl createCache() {
+     Properties props = new Properties();
+     props.setProperty("locators", "");
+     props.setProperty("mcast-port", "0");
+     props.setProperty("off-heap-memory-size", getOffHeapMemorySize());
+     GemFireCacheImpl result = (GemFireCacheImpl) new CacheFactory(props).create();
+     return result;
+   }
+   
+   protected void closeCache(GemFireCacheImpl gfc) {
+     gfc.close();
+   }
+   
+   protected String getOffHeapMemorySize() {
+     return "2m";
+   }
+   
+   protected RegionShortcut getRegionShortcut() {
+     return RegionShortcut.REPLICATE;
+   }
+   
+   protected String getRegionName() {
+     return "region1";
+   }
+   
+   @Test
+   public void testMemoryInspection() throws IOException {
+     // validate initial state
+     MemoryAllocator allocator = this.cache.getOffHeapStore();
+     assertNotNull(allocator);
+     MemoryInspector inspector = allocator.getMemoryInspector();
+     assertNotNull(inspector);
+     inspector.createSnapshot();
+     try {
+       MemoryBlock firstBlock = inspector.getFirstBlock();
+       assertNotNull(firstBlock);
+       assertEquals(1024*1024*2, firstBlock.getBlockSize());
+       assertEquals("N/A", firstBlock.getDataType());
+       assertEquals(-1, firstBlock.getFreeListId());
+       assertTrue(firstBlock.getMemoryAddress() > 0);
+       assertNull(firstBlock.getNextBlock());
+       assertEquals(0, firstBlock.getRefCount());
+       assertEquals(0, firstBlock.getSlabId());
+       assertEquals(MemoryBlock.State.UNUSED, firstBlock.getState());
+       assertFalse(firstBlock.isCompressed());
+       assertFalse(firstBlock.isSerialized());
+     } finally {
+       inspector.clearSnapshot();
+     }
+     
+     // create off-heap region
+     Region<Object, Object> region = this.cache.createRegionFactory(getRegionShortcut()).setOffHeap(true).create(getRegionName());
+     Region<Object, Object> compressedRegion = this.cache.createRegionFactory(getRegionShortcut()).setOffHeap(true).setCompressor(SnappyCompressor.getDefaultInstance()).create(getRegionName()+"Compressed");
+     
+     // perform some ops
+     List<ExpectedValues> expected = new ArrayList<ExpectedValues>();
+ 
+     // Chunk.OFF_HEAP_HEADER_SIZE + 4 ?
+     
+     putString(region, expected);
+     putCompressedString(compressedRegion, expected);
+     putDate(region, expected);
+     putByteArray(region, expected);
+     putCompressedByteArray(compressedRegion, expected);
+     putByteArrayArray(region, expected);
+     putShortArray(region, expected);
+     putStringArray(region, expected);
+     putObjectArray(region, expected);
+     putArrayList(region, expected);
+     putLinkedList(region, expected);
+     putHashSet(region, expected);
+     putLinkedHashSet(region, expected);
+     putHashMap(region, expected);
+     putIdentityHashMap(region, expected);
+     putHashtable(region, expected);
+     putProperties(region, expected);
+     putVector(region, expected);
+     putStack(region, expected);
+     putTreeMap(region, expected);
+     putTreeSet(region, expected);
+     putClass(region, expected);
+     putUUID(region, expected);
+     putTimestamp(region, expected);
+     putSerializableClass(region, expected);
+     
+     // TODO: USER_DATA_SERIALIZABLE
+     
+     // TODO: PDX
+     
+     // TODO: PDX_ENUM
+     
+     // TODO: GEMFIRE_ENUM
+     
+     // TODO: PDX_INLINE_ENUM
+     
+     // validate inspection
+     inspector.createSnapshot();
+     try {
+     MemoryBlock firstBlock = inspector.getFirstBlock();
+     assertEquals(MemoryBlock.State.UNUSED, firstBlock.getState());
+     
+     //System.out.println(((SimpleMemoryAllocatorImpl)inspector).getSnapshot());
+     
+     // sort the ExpectedValues into the same order as the MemberBlocks from inspector
+     Collections.sort(expected, 
+         new Comparator<ExpectedValues>() {
+           @Override
+           public int compare(ExpectedValues o1, ExpectedValues o2) {
+             return Long.valueOf(o1.memoryAddress).compareTo(o2.memoryAddress);
+           }
+     });
+     
+     int i = 0;
+     MemoryBlock block = firstBlock.getNextBlock();
+     while (block != null) {
+       ExpectedValues values = expected.get(i);
+       assertEquals(i + ":" + values.dataType, values.blockSize, block.getBlockSize());
+       assertEquals(i + ":" + values.dataType, values.dataType, block.getDataType());
+       assertEquals(i + ":" + values.dataType, values.freeListId, block.getFreeListId());
+       assertEquals(i + ":" + values.dataType, values.memoryAddress, block.getMemoryAddress());
+       assertEquals(i + ":" + values.dataType, values.refCount, block.getRefCount());
+       assertEquals(i + ":" + values.dataType, values.slabId, block.getSlabId());
+       assertEquals(i + ":" + values.dataType, values.isCompressed, block.isCompressed());
+       assertEquals(i + ":" + values.dataType, values.isSerialized, block.isSerialized());
+       // compare block.getDataValue() but only for String types
+       if (values.dataType.equals("java.lang.String")) {
+         Object obj = block.getDataValue();
+         assertNotNull(block.toString(), obj);
+         assertTrue(obj instanceof String);
+         assertEquals("this is a string", (String)obj);
+       }
+       if ((values.dataType.contains("byte [") && values.dataType.lastIndexOf('[') == values.dataType.indexOf('[')) || values.dataType.startsWith("compressed")) {
+         assertTrue("for dataType=" + values.dataType + " expected " + Arrays.toString((byte[])values.dataValue) + " but was " + Arrays.toString((byte[])block.getDataValue()),
+             Arrays.equals((byte[])values.dataValue, (byte[])block.getDataValue()));
+       } else if (values.dataType.contains("[")) {
+         // TODO: multiple dimension arrays or non-byte arrays
+       } else if (values.dataValue instanceof Collection) {
+         int diff = joint((Collection<?>)values.dataValue, (Collection<?>)block.getDataValue());
+         assertEquals(i + ":" + values.dataType, 0, diff);
+       } else if (values.dataValue instanceof IdentityHashMap) {
+         // TODO
+       } else if (values.dataValue instanceof Map) {
+         int diff = joint((Map<?,?>)values.dataValue, (Map<?,?>)block.getDataValue());
+         assertEquals(i + ":" + values.dataType, 0, diff);
+       } else {
+         assertEquals(i + ":" + values.dataType, values.dataValue, block.getDataValue());
+       }
+       block = block.getNextBlock();
+       i++;
+     }
+     assertEquals("All blocks: "+inspector.getAllBlocks(), expected.size(), i);
+     } finally {
+       inspector.clearSnapshot();
+     }
+     
+     // perform more ops
+ 
+     // validate more inspection
+     
+   }
+   
+   /**
+    * Returns -1 if c1 is missing an element in c2, 1 if c2 is missing an element
+    * in c1, or 0 is they contain the exact same elements.
+    * @throws NullPointerException if either c1 or c2 is null
+    */
+   private static int joint(Collection<?> c1, Collection<?> c2) {
+     if (c1.size() < c2.size()) {
+       return -1;
+     } else if (c2.size() < c1.size()) {
+       return 1;
+     }
+     Collection<Object> c3 = new ArrayList<Object>();
+     c3.addAll(c1);
+     c3.removeAll(c2);
+     if (c3.size() > 0) {
+       return -1;
+     }
+     c3.addAll(c2);
+     c3.removeAll(c1);
+     if (c3.size() > 0) {
+       return 1;
+     }
+     return 0;
+   }
+   
+   /**
+    * Returns -1 if m1 is missing a key in m2, 1 if m2 is missing a key
+    * in m1, or 0 is they contain the exact same keys.
+    * @throws NullPointerException if either c1 or c2 is null
+    */
+   private static int joint(Map<?, ?> m1, Map<?, ?> m2) {
+     if (m1.size() < m2.size()) {
+       return -1;
+     } else if (m2.size() < m1.size()) {
+       return 1;
+     }
+     Collection<Object> c3 = new ArrayList<Object>();
+     c3.addAll(m1.keySet());
+     c3.removeAll(m2.keySet());
+     if (c3.size() > 0) {
+       return -1;
+     }
+     c3.addAll(m2.keySet());
+     c3.removeAll(m1.keySet());
+     if (c3.size() > 0) {
+       return 1;
+     }
+     return 0;
+   }
+   
+   private long getMemoryAddress(Region region, String key) {
+     Object entry = ((LocalRegion) region).getRegionEntry(key)._getValue();
 -    assertTrue(entry instanceof Chunk);
 -    long memoryAddress = ((Chunk)entry).getMemoryAddress();
++    assertTrue(entry instanceof ObjectChunk);
++    long memoryAddress = ((ObjectChunk)entry).getMemoryAddress();
+     assertTrue(memoryAddress > 0);
+     return memoryAddress;
+   }
+   
+   private void putString(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyString";
+     String value = "this is a string";
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, value.length()*2, "java.lang.String", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putCompressedString(Region<Object, Object> region, List<ExpectedValues> expected) throws IOException {
+     String key = "keyString";
+     String value = "this is a string";
+     region.put(key, value);
+     HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+     DataSerializer.writeObject(value, hdos);
+     byte[] uncompressedBytes = hdos.toByteArray();
+     byte[] expectedValue = SnappyCompressor.getDefaultInstance().compress(uncompressedBytes);
+     expected.add(new ExpectedValues(expectedValue, 32, "compressed object of size " + expectedValue.length, -1, getMemoryAddress(region, key), 1, 0, true, true));
+   }
+ 
+   private void putDate(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyDate";
+     Date value = new Date();
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 24, "java.util.Date", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putByteArray(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyByteArray";
+     byte[] value = new byte[10];
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 24, "byte[10]", -1, getMemoryAddress(region, key), 1, 0, false, false));
+   }
+   private void putCompressedByteArray(Region<Object, Object> region, List<ExpectedValues> expected) throws IOException {
+     String key = "keyByteArray";
+     byte[] value = new byte[10];
+     region.put(key, value);
+     byte[] expectedValue = SnappyCompressor.getDefaultInstance().compress(value);
+     expected.add(new ExpectedValues(expectedValue, 24, "compressed byte[" + expectedValue.length + "]", -1, getMemoryAddress(region, key), 1, 0, true, false));
+   }
+   
+   private void putByteArrayArray(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyByteArrayArray";
+     byte[][] value = new byte[10][10];
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 120, "byte[][]", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putShortArray(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyShortArray(";
+     short[] value = new short[10];
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "short[]", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putStringArray(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyStringArray";
+     String[] value = new String[10];
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 24, "java.lang.String[]", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putObjectArray(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyObjectArray";
+     Object[] value = new Object[10];
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 40, "java.lang.Object[]", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putArrayList(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyArrayList";
+     ArrayList<Object> value = new ArrayList<Object>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.ArrayList", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putLinkedList(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyLinkedList";
+     LinkedList<Object> value = new LinkedList<Object>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.LinkedList", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putHashSet(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyHashSet";
+     HashSet<Object> value = new HashSet<Object>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.HashSet", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putLinkedHashSet(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyLinkedHashSet";
+     LinkedHashSet<Object> value = new LinkedHashSet<Object>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.LinkedHashSet", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putHashMap(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyHashMap";
+     HashMap<Object,Object> value = new HashMap<Object,Object>();
+     value.put("1", "string 1");
+     value.put("2", "string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 40, "java.util.HashMap", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+ 
+   private void putIdentityHashMap(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyIdentityHashMap";
+     IdentityHashMap<Object,Object> value = new IdentityHashMap<Object,Object>();
+     value.put("1", "string 1");
+     value.put("2", "string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 40, "java.util.IdentityHashMap", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putHashtable(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyHashtable";
+     Hashtable<Object,Object> value = new Hashtable<Object,Object>();
+     value.put("1", "string 1");
+     value.put("2", "string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 40, "java.util.Hashtable", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putProperties(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyProperties";
+     Properties value = new Properties();
+     value.put("1", "string 1");
+     value.put("2", "string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 40, "java.util.Properties", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putVector(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyVector";
+     Vector<String> value = new Vector<String>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.Vector", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putStack(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyStack";
+     Stack<String> value = new Stack<String>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.Stack", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putTreeMap(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyTreeMap";
+     TreeMap<String, String> value = new TreeMap<String, String>();
+     value.put("1", "string 1");
+     value.put("2", "string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 48, "java.util.TreeMap", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putTreeSet(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyTreeSet";
+     TreeSet<String> value = new TreeSet<String>();
+     value.add("string 1");
+     value.add("string 2");
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 40, "java.util.TreeSet", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+ 
+   private void putClass(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyClass";
+     Class<String> value = String.class;
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.lang.Class", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putUUID(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyUUID";
+     UUID value = UUID.randomUUID(); 
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 32, "java.util.UUID", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   private void putTimestamp(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keyTimestamp";
+     Timestamp value = new Timestamp(System.currentTimeMillis());
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 24, "java.sql.Timestamp", -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+ 
+   private void putSerializableClass(Region<Object, Object> region, List<ExpectedValues> expected) {
+     String key = "keySerializableClass";
+     SerializableClass value = new SerializableClass();
+     region.put(key, value);
+     expected.add(new ExpectedValues(value, 112, "java.io.Serializable:" + SerializableClass.class.getName(), -1, getMemoryAddress(region, key), 1, 0, false, true));
+   }
+   
+   static class ExpectedValues {
+     final Object dataValue;
+     final int blockSize;
+     final String dataType;
+     final int freeListId;
+     final long memoryAddress;
+     final int refCount;
+     final int slabId;
+     final boolean isCompressed;
+     final boolean isSerialized;
+     ExpectedValues(Object dataValue, int blockSize, String dataType, int freeListId, long memoryAddress, int refCount, int slabId, boolean isCompressed, boolean isSerialized) {
+       this.dataValue = dataValue;
+       this.blockSize = blockSize;
+       this.dataType = dataType;
+       this.freeListId = freeListId;
+       this.memoryAddress = memoryAddress;
+       this.refCount = refCount;
+       this.slabId = slabId;
+       this.isCompressed = isCompressed;
+       this.isSerialized = isSerialized;
+     }
+   }
+   
+   @SuppressWarnings("serial")
+   public static class SerializableClass implements Serializable {
+     public boolean equals(Object obj) {
+       return obj instanceof SerializableClass;
+     }
+     public int hashCode() {
+       return 42;
+     }
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
index 0000000,daebefa..9c83f5b
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java
@@@ -1,0 -1,115 +1,115 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ 
+ import java.io.ByteArrayInputStream;
+ import java.io.DataInput;
+ import java.io.DataInputStream;
+ import java.io.IOException;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.internal.HeapDataOutputStream;
+ import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+ import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
+ import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
+ import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class OffHeapWriteObjectAsByteArrayJUnitTest {
+ 
+   @Before
+   public void setUp() throws Exception {
 -    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
++    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+   }
+ 
+   @After
+   public void tearDown() throws Exception {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+   }
+   
+   private StoredObject createStoredObject(byte[] bytes, boolean isSerialized, boolean isCompressed) {
 -    return SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, isCompressed, null);
++    return SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, isCompressed);
+   }
+   
+   private DataInputStream createInput(HeapDataOutputStream hdos) {
+     ByteArrayInputStream bais = new ByteArrayInputStream(hdos.toByteArray());
+     return new DataInputStream(bais);
+   }
+   
+   @Test
+   public void testByteArrayChunk() throws IOException, ClassNotFoundException {
+     byte[] expected = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+     StoredObject so = createStoredObject(expected, false, false);
 -    assertTrue(so instanceof Chunk);
++    assertTrue(so instanceof ObjectChunk);
+     HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]);
+     DataSerializer.writeObjectAsByteArray(so, hdos);
+     DataInputStream in = createInput(hdos);
+     byte[] actual = DataSerializer.readByteArray(in);
+     assertArrayEquals(expected, actual);
+   }
+   
+   @Test
+   public void testByteArrayDataAsAddress() throws IOException, ClassNotFoundException {
+     byte[] expected = new byte[] {1, 2, 3};
+     StoredObject so = createStoredObject(expected, false, false);
+     assertTrue(so instanceof DataAsAddress);
+     HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]);
+     DataSerializer.writeObjectAsByteArray(so, hdos);
+     DataInputStream in = createInput(hdos);
+     byte[] actual = DataSerializer.readByteArray(in);
+     assertArrayEquals(expected, actual);
+   }
+   
+   @Test
+   public void testStringChunk() throws IOException, ClassNotFoundException {
+     byte[] expected = EntryEventImpl.serialize("1234567890");
+     StoredObject so = createStoredObject(expected, true, false);
 -    assertTrue(so instanceof Chunk);
++    assertTrue(so instanceof ObjectChunk);
+     HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]);
+     DataSerializer.writeObjectAsByteArray(so, hdos);
+     DataInputStream in = createInput(hdos);
+     byte[] actual = DataSerializer.readByteArray(in);
+     assertArrayEquals(expected, actual);
+     assertNoMoreInput(in);
+   }
+   
+   @Test
+   public void testStringDataAsAddress() throws IOException, ClassNotFoundException {
+     byte[] expected = EntryEventImpl.serialize("1234");
+     StoredObject so = createStoredObject(expected, true, false);
+     assertTrue(so instanceof DataAsAddress);
+     HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]);
+     DataSerializer.writeObjectAsByteArray(so, hdos);
+     DataInputStream in = createInput(hdos);
+     byte[] actual = DataSerializer.readByteArray(in);
+     assertArrayEquals(expected, actual);
+   }
+   
+   private void assertNoMoreInput(DataInputStream in) throws IOException {
+     assertEquals(0, in.available());
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
index 0000000,6e26b2f..d8c35b8
mode 000000,100755..100755
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java
@@@ -1,0 -1,47 +1,47 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+ 
+ @Category(IntegrationTest.class)
+ public class OldFreeListOffHeapRegionJUnitTest extends OffHeapRegionBase {
+ 
+   @Override
+   protected String getOffHeapMemorySize() {
+     return "20m";
+   }
+   
+   @Override
+   public void configureOffHeapStorage() {
+     System.setProperty("gemfire.OFF_HEAP_SLAB_SIZE", "1m");
+   }
+ 
+   @Override
+   public void unconfigureOffHeapStorage() {
+     System.clearProperty("gemfire.OFF_HEAP_TOTAL_SIZE");
+     System.clearProperty("gemfire.OFF_HEAP_SLAB_SIZE");
+   }
+ 
+   @Override
+   public int perObjectOverhead() {
 -    return Chunk.OFF_HEAP_HEADER_SIZE;
++    return ObjectChunk.OFF_HEAP_HEADER_SIZE;
+   }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
index 0000000,239cbc8..51f46a1
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java
@@@ -1,0 -1,246 +1,246 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ 
+ import java.util.Collections;
+ import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Random;
+ import java.util.concurrent.CountDownLatch;
+ import java.util.concurrent.ThreadLocalRandom;
+ import java.util.concurrent.TimeUnit;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+ 
+ /**
+  * Tests fill pattern validation for the {@link SimpleMemoryAllocatorImpl}.
+  */
+ @Category(IntegrationTest.class)
+ public class SimpleMemoryAllocatorFillPatternIntegrationTest {
+   private static Random random = ThreadLocalRandom.current();
+ 
+   /**
+    * Chunk operation types.
+    */
+   static enum Operation {
+     ALLOCATE,
+     FREE,
+     WRITE;
+     
+     // Holds all Operation values
+     private static Operation[] values = Operation.values(); 
+     
+     static Operation randomOperation() {
+       return values[random.nextInt(values.length)];
+     }
+   };
+   
+   /** Number of worker threads for advanced tests. */
+   private static final int WORKER_THREAD_COUNT = 5;
+   
+   /** Size of single test slab.*/
+   private static final int SLAB_SIZE = 1024 * 1024 * 50;
+   
+   /** Maximum number of bytes a worker thread can allocate during advanced tests.  */
+   private static final int MAX_WORKER_ALLOCATION_TOTAL_SIZE = SLAB_SIZE / WORKER_THREAD_COUNT / 2;
+   
+   /** Maximum allocation for a single Chunk.  */
+   private static final int MAX_WORKER_ALLOCATION_SIZE = 512;
+   
+   /** Canned data for write operations. */
+   private static final byte[] WRITE_BYTES = new String("Some string data.").getBytes();
+   
+   /** Minimum size for write operations. */
+   private static final int MIN_WORKER_ALLOCATION_SIZE = WRITE_BYTES.length;
+ 
+   /** Runtime for worker threads. */
+   private static final long RUN_TIME_IN_MILLIS = 1 * 1000 * 5;
+   
+   /** Chunk size for basic huge allocation test. */
+   private static final int HUGE_CHUNK_SIZE = 1024 * 200;
+   
+   /** Our test victim. */
+   private SimpleMemoryAllocatorImpl allocator = null;
+   
+   /** Our test victim's memory slab. */
+   private UnsafeMemoryChunk slab = null;
+ 
+   /**
+    * Enables fill validation and creates the test victim.
+    */
+   @Before
+   public void setUp() throws Exception {
+     System.setProperty("gemfire.validateOffHeapWithFill", "true");
+     this.slab = new UnsafeMemoryChunk(SLAB_SIZE);
 -    this.allocator = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
++    this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
+   }
+ 
+   /**
+    * Frees off heap memory.
+    */
+   @After
+   public void tearDown() throws Exception {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     System.clearProperty("gemfire.validateOffHeapWithFill");
+   }
+   
+   /**
+    * This test hammers a SimpleMemoryAllocatorImpl with multiple threads exercising
+    * the fill validation of tiny Chunks for one minute.  This, of course, exercises many aspects of
+    * the SimpleMemoryAllocatorImpl and its helper classes.
+    * @throws Exception
+    */
+   @Test
+   public void testFillPatternAdvancedForTinyAllocations() throws Exception { 
+     doFillPatternAdvancedTest(new ChunkSizer() {
+       @Override
+       public int allocationSize() {
+         int allocation = random.nextInt(MAX_WORKER_ALLOCATION_SIZE+1);
+         
+         while(allocation < MIN_WORKER_ALLOCATION_SIZE) {
+           allocation = random.nextInt(MAX_WORKER_ALLOCATION_SIZE+1);
+         }
+         return allocation;
+       }
+     });
+   }
+ 
+   /**
+    * This test hammers a SimpleMemoryAllocatorImpl with multiple threads exercising
+    * the fill validation of huge Chunks for one minute.  This, of course, exercises many aspects of
+    * the SimpleMemoryAllocatorImpl and its helper classes.
+    * @throws Exception
+    */
+   @Test
+   public void testFillPatternAdvancedForHugeAllocations() throws Exception {
+     doFillPatternAdvancedTest(new ChunkSizer() {
+       @Override
+       public int allocationSize() {
+         return HUGE_CHUNK_SIZE;
+       }
+     });
+   }
+   
+   private interface ChunkSizer {
+     int allocationSize();
+   }
+   
+   private void doFillPatternAdvancedTest(final ChunkSizer chunkSizer) throws InterruptedException {
+     // Used to manage worker thread completion
+     final CountDownLatch latch = new CountDownLatch(WORKER_THREAD_COUNT);
+     
+     // Use to track any errors the worker threads will encounter
+     final List<Throwable> threadErrorList = Collections.synchronizedList(new LinkedList<Throwable>());
+     
+     /*
+      * Start up a number of worker threads.  These threads will randomly allocate, free,
+      * and write to Chunks.
+      */
+     for(int i = 0;i < WORKER_THREAD_COUNT;++i) {
+       new Thread(new Runnable() {
+         // Total allocation in bytes for this thread
+         private int totalAllocation = 0;
+         
+         // List of Chunks allocated by this thread
 -        private List<Chunk> chunks = new LinkedList<Chunk>();
++        private List<ObjectChunk> chunks = new LinkedList<ObjectChunk>();
+         
+         // Time to end thread execution
+         private long endTime = System.currentTimeMillis() + RUN_TIME_IN_MILLIS;
+         
+         /**
+          * Allocates a chunk and adds it to the thread's Chunk list.
+          */
+         private void allocate() {          
+           int allocation = chunkSizer.allocationSize();
 -          Chunk chunk = (Chunk) allocator.allocate(allocation, null);
++          ObjectChunk chunk = (ObjectChunk) allocator.allocate(allocation);
+           
+           // This should always work just after allocation
+           chunk.validateFill();
+           
+           chunks.add(chunk);
+           totalAllocation += chunk.getSize();
+         }
+         
+         /**
+          * Frees a random chunk from the Chunk list.
+          */
+         private void free() {
 -          Chunk chunk = chunks.remove(random.nextInt(chunks.size()));
++          ObjectChunk chunk = chunks.remove(random.nextInt(chunks.size()));
+           totalAllocation -= chunk.getSize();
+           
+           /*
+            * Chunk is filled here but another thread may have already grabbed it so we
+            * cannot validate the fill.
+            */
+           chunk.release(); 
+         }
+         
+         /**
+          * Writes canned data to a random Chunk from the Chunk list.
+          */
+         private void write() {
 -          Chunk chunk = chunks.get(random.nextInt(chunks.size()));
++          ObjectChunk chunk = chunks.get(random.nextInt(chunks.size()));
+           chunk.writeBytes(0, WRITE_BYTES);
+         }
+         
+         /**
+          * Randomly selects Chunk operations and executes them
+          * for a period of time.  Collects any error thrown during execution.
+          */
+         @Override
+         public void run() {
+           try {
+             for(long currentTime = System.currentTimeMillis();currentTime < endTime;currentTime = System.currentTimeMillis()) {
+               Operation op = (totalAllocation == 0 ? Operation.ALLOCATE : (totalAllocation >= MAX_WORKER_ALLOCATION_TOTAL_SIZE ? Operation.FREE : Operation.randomOperation()));
+               switch(op) {
+               case ALLOCATE:
+                 allocate();
+                 break;
+               case FREE:
+                 free();
+                 break;
+               case WRITE:
+                 write();
+                 break;
+               }
+             }
+           } catch (Throwable t) {
+             threadErrorList.add(t);
+           } finally {
+             latch.countDown();
+           }
+        }        
+       }).start();
+     }
+     
+     // Make sure each thread ended cleanly
+     assertTrue(latch.await(2, TimeUnit.MINUTES));
+     
+     // Fail on the first error we find
+     if(!threadErrorList.isEmpty()) {
+       fail(threadErrorList.get(0).getMessage());
+     }
+   }
+   
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
index 0000000,21c9835..7c26f86
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java
@@@ -1,0 -1,183 +1,183 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ import static com.googlecode.catchexception.CatchException.*;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ import junit.framework.TestCase;
+ 
+ /**
+  * Tests fill pattern validation for the {@link SimpleMemoryAllocatorImpl}.
+  * @author rholmes
+  */
+ @Category(UnitTest.class)
+ public class SimpleMemoryAllocatorFillPatternJUnitTest {
+   
+   /** Size of single test slab.*/
+   private static final int SLAB_SIZE = 1024 * 1024 * 50;
+   
+   /** Canned data for write operations. */
+   private static final byte[] WRITE_BYTES = new String("Some string data.").getBytes();
+   
+   /** Chunk size for basic huge allocation test. */
+   private static final int HUGE_CHUNK_SIZE = 1024 * 200;
+   
+   /** The number of chunks to allocate in order to force compaction. */
+   private static final int COMPACTION_CHUNKS = 3;
+   
+   /** Our slab size divided in three (with some padding for safety). */
+   private static final int COMPACTION_CHUNK_SIZE = (SLAB_SIZE / COMPACTION_CHUNKS) - 1024;
+   
+   /** This should force compaction when allocated. */
+   private static final int FORCE_COMPACTION_CHUNK_SIZE = COMPACTION_CHUNK_SIZE * 2;
+ 
+   /** Our test victim. */
+   private SimpleMemoryAllocatorImpl allocator = null;
+   
+   /** Our test victim's memory slab. */
+   private UnsafeMemoryChunk slab = null;
+ 
+   /**
+    * Enables fill validation and creates the test victim.
+    */
+   @Before
+   public void setUp() throws Exception {
+     System.setProperty("gemfire.validateOffHeapWithFill", "true");
+     this.slab = new UnsafeMemoryChunk(SLAB_SIZE);
 -    this.allocator = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
++    this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab});
+   }
+ 
+   /**
+    * Frees off heap memory.
+    */
+   @After
+   public void tearDown() throws Exception {
+     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     System.clearProperty("gemfire.validateOffHeapWithFill");
+   }
+ 
+   /**
+    * This tests the fill pattern for a single tiny Chunk allocation.
+    * @throws Exception
+    */
+   @Test
+   public void testFillPatternBasicForTinyAllocations() throws Exception {
+     doFillPatternBasic(1024);
+   }
+   
+   /**
+    * This tests the fill pattern for a single huge Chunk allocation.
+    * @throws Exception
+    */
+   @Test
+   public void testFillPatternBasicForHugeAllocations() throws Exception {
+     doFillPatternBasic(HUGE_CHUNK_SIZE);
+   }
+   
+   private void doFillPatternBasic(final int chunkSize) {
+     /*
+      * Pull a chunk off the fragment.  This will have no fill because
+      * it is a "fresh" chunk.
+      */
 -    Chunk chunk = (Chunk) this.allocator.allocate(chunkSize, null);
++    ObjectChunk chunk = (ObjectChunk) this.allocator.allocate(chunkSize);
+ 
+     /*
+      * Chunk should have valid fill from initial fragment allocation.
+      */
+     chunk.validateFill();
+          
+     // "Dirty" the chunk so the release has something to fill over
 -    chunk.writeBytes(Chunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
++    chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
+ 
+     // This should free the Chunk (ref count == 1)
+     chunk.release();
+ 
+     /*
+      * This chunk should have a fill because it was reused from the
+      * free list (assuming no fragmentation at this point...)
+      */
 -    chunk = (Chunk) this.allocator.allocate(chunkSize, null);
++    chunk = (ObjectChunk) this.allocator.allocate(chunkSize);
+     
+     // Make sure we have a fill this time
+     chunk.validateFill();
+     
+     // Give the fill code something to write over during the release
 -    chunk.writeBytes(Chunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
++    chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
+     chunk.release();
+ 
+     // Again, make sure the release implemented the fill
+     chunk.validateFill();
+ 
+     // "Dirty up" the free chunk
 -    chunk.writeBytes(Chunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
++    chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES);
+     
+     catchException(chunk).validateFill();
+     assertTrue(caughtException() instanceof IllegalStateException);
+     assertEquals("Fill pattern violated for chunk " + chunk.getMemoryAddress() + " with size " + chunk.getSize(), caughtException().getMessage());
+     
+   }
+ 
+   /**
+    * This tests that fill validation is working properly on newly created fragments after
+    * a compaction.
+    * @throws Exception
+    */
+   @Test
+   public void testFillPatternAfterCompaction() throws Exception {
+     /*
+      * Stores our allocated memory.
+      */
 -    Chunk[] allocatedChunks = new Chunk[COMPACTION_CHUNKS];
++    ObjectChunk[] allocatedChunks = new ObjectChunk[COMPACTION_CHUNKS];
+     
+     /*
+      * Use up most of our memory
+      * Our memory looks like [      ][      ][      ]
+      */
+     for(int i =0;i < allocatedChunks.length;++i) {
 -      allocatedChunks[i] = (Chunk) this.allocator.allocate(COMPACTION_CHUNK_SIZE, null);
++      allocatedChunks[i] = (ObjectChunk) this.allocator.allocate(COMPACTION_CHUNK_SIZE);
+       allocatedChunks[i].validateFill();
+     }
+ 
+     /*
+      * Release some of our allocated chunks.
+      */
+     for(int i=0;i < 2;++i) {
+       allocatedChunks[i].release();
+       allocatedChunks[i].validateFill();      
+     }
+     
+     /*
+      * Now, allocate another chunk that is slightly larger than one of
+      * our initial chunks.  This should force a compaction causing our
+      * memory to look like [            ][      ].
+      */
 -    Chunk slightlyLargerChunk = (Chunk) this.allocator.allocate(FORCE_COMPACTION_CHUNK_SIZE, null);
++    ObjectChunk slightlyLargerChunk = (ObjectChunk) this.allocator.allocate(FORCE_COMPACTION_CHUNK_SIZE);
+     
+     /*
+      * Make sure the compacted memory has the fill validation.
+      */
+     slightlyLargerChunk.validateFill();
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
index 0000000,d9979cc..1f17f9b
mode 000000,100644..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java
@@@ -1,0 -1,675 +1,631 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.offheap;
+ 
+ import static org.junit.Assert.*;
+ 
+ import java.nio.ByteBuffer;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.concurrent.atomic.AtomicReference;
+ 
+ import org.junit.Rule;
+ import org.junit.Test;
+ import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+ import org.junit.experimental.categories.Category;
+ 
+ import com.gemstone.gemfire.OutOfOffHeapMemoryException;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.internal.logging.NullLogWriter;
 -import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk.Factory;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+ 
+ @Category(UnitTest.class)
+ public class SimpleMemoryAllocatorJUnitTest {
+   @Rule
+   public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+ 
+   private static int round(int multiple, int v) {
+     return ((v+multiple-1)/multiple)*multiple;
+   }
+   @Test
+   public void testNullGetAllocator() {
+     try {
+       SimpleMemoryAllocatorImpl.getAllocator();
+       fail("expected CacheClosedException");
+     } catch (CacheClosedException expected) {
+     }
+   }
+   @Test
+   public void testConstructor() {
+     try {
 -      SimpleMemoryAllocatorImpl.create(null, null, null);
++      SimpleMemoryAllocatorImpl.createForUnitTest(null, null, null);
+       fail("expected IllegalArgumentException");
+     } catch (IllegalArgumentException expected) {
+     }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, -1, 0, 0, 0);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8"));
 -    }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 9, 0, 0, 0);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8"));
 -    }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 256+8, 0, 0, 0);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_ALIGNMENT must be <= 256"));
 -    }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 0, 0, 0);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE must be >= 1."));
 -    }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 1, 0, 0);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1."));
 -    }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 1, 1, -1);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("HUGE_MULTIPLE must be >= 0 and <= 256 but it was -1"));
 -    }
 -    try {
 -      SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), null, null, 8, 1, 1, 257);
 -      fail("expected IllegalStateException");
 -    } catch (IllegalStateException expected) {
 -      assertEquals(true, expected.getMessage().contains("HUGE_MULTIPLE must be >= 0 and <= 256 but it was 257"));
 -    }
 -     
+   }
+   /**
+    * Logger that remembers the last severe message
+    */
+   private static class LastSevereLogger extends NullLogWriter {
+     private String lastSevereMessage;
+     private Throwable lastSevereThrowable;
+     
+     private void setLastSevere(String msg, Throwable ex) {
+       this.lastSevereMessage = msg;
+       this.lastSevereThrowable = ex;
+     }
+     public String getLastSevereMessage() {
+       return this.lastSevereMessage;
+     }
+     public Throwable getLastSevereThrowable() {
+       return this.lastSevereThrowable;
+     }
+     @Override
+     public void severe(String msg, Throwable ex) {
+       setLastSevere(msg, ex);
+     }
+     @Override
+     public void severe(String msg) {
+       setLastSevere(msg, null);
+     }
+     @Override
+     public void severe(Throwable ex) {
+       setLastSevere(null, ex);
+     }
+   }
+   @Test
+   public void testCreate() {
+     System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "false");
+     {
+       NullOutOfOffHeapMemoryListener listener = new NullOutOfOffHeapMemoryListener();
+       NullOffHeapMemoryStats stats = new NullOffHeapMemoryStats();
+       LastSevereLogger logger = new LastSevereLogger();
+       try {
 -        SimpleMemoryAllocatorImpl.create(listener, stats, logger, 10, 950, 100,
 -            new UnsafeMemoryChunk.Factory() {
++        SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, logger, 10, 950, 100,
++            new AddressableMemoryChunkFactory() {
+           @Override
 -          public UnsafeMemoryChunk create(int size) {
++          public AddressableMemoryChunk create(int size) {
+             throw new OutOfMemoryError("expected");
+           }
+         });
+       } catch (OutOfMemoryError expected) {
+       }
+       assertTrue(listener.isClosed());
+       assertTrue(stats.isClosed());
+       assertEquals(null, logger.getLastSevereThrowable());
+       assertEquals(null, logger.getLastSevereMessage());
+      }
+     {
+       NullOutOfOffHeapMemoryListener listener = new NullOutOfOffHeapMemoryListener();
+       NullOffHeapMemoryStats stats = new NullOffHeapMemoryStats();
+       LastSevereLogger logger = new LastSevereLogger();
+       int MAX_SLAB_SIZE = 100;
+       try {
 -        Factory factory = new UnsafeMemoryChunk.Factory() {
++        AddressableMemoryChunkFactory factory = new AddressableMemoryChunkFactory() {
+           private int createCount = 0;
+           @Override
 -          public UnsafeMemoryChunk create(int size) {
++          public AddressableMemoryChunk create(int size) {
+             createCount++;
+             if (createCount == 1) {
+               return new UnsafeMemoryChunk(size);
+             } else {
+               throw new OutOfMemoryError("expected");
+             }
+           }
+         };
 -        SimpleMemoryAllocatorImpl.create(listener, stats, logger, 10, 950, MAX_SLAB_SIZE, factory);
++        SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, logger, 10, 950, MAX_SLAB_SIZE, factory);
+       } catch (OutOfMemoryError expected) {
+       }
+       assertTrue(listener.isClosed());
+       assertTrue(stats.isClosed());
+       assertEquals(null, logger.getLastSevereThrowable());
+       assertEquals("Off-heap memory creation failed after successfully allocating " + MAX_SLAB_SIZE + " bytes of off-heap memory.", logger.getLastSevereMessage());
+     }
+     {
+       NullOutOfOffHeapMemoryListener listener = new NullOutOfOffHeapMemoryListener();
+       NullOffHeapMemoryStats stats = new NullOffHeapMemoryStats();
 -      Factory factory = new UnsafeMemoryChunk.Factory() {
++      AddressableMemoryChunkFactory factory = new AddressableMemoryChunkFactory() {
+         @Override
 -        public UnsafeMemoryChunk create(int size) {
++        public AddressableMemoryChunk create(int size) {
+           return new UnsafeMemoryChunk(size);
+         }
+       };
+       MemoryAllocator ma = 
 -        SimpleMemoryAllocatorImpl.create(listener, stats, new NullLogWriter(), 10, 950, 100, factory);
++        SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, new NullLogWriter(), 10, 950, 100, factory);
+       try {
+         assertFalse(listener.isClosed());
+         assertFalse(stats.isClosed());
+         ma.close();
+         assertTrue(listener.isClosed());
+         assertFalse(stats.isClosed());
+         listener = new NullOutOfOffHeapMemoryListener();
+         NullOffHeapMemoryStats stats2 = new NullOffHeapMemoryStats();
+         {
+           UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024);
+           try {
 -            SimpleMemoryAllocatorImpl.create(listener, stats2, new UnsafeMemoryChunk[]{slab});
++            SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats2, new UnsafeMemoryChunk[]{slab});
+           } catch (IllegalStateException expected) {
+             assertTrue("unexpected message: " + expected.getMessage(), 
+                 expected.getMessage().equals("attempted to reuse existing off-heap memory even though new off-heap memory was allocated"));
+           } finally {
+             slab.release();
+           }
+           assertFalse(stats.isClosed());
+           assertTrue(listener.isClosed());
+           assertTrue(stats2.isClosed());
+         }
+         listener = new NullOutOfOffHeapMemoryListener();
+         stats2 = new NullOffHeapMemoryStats();
 -        MemoryAllocator ma2 = SimpleMemoryAllocatorImpl.create(listener, stats2, new NullLogWriter(), 10, 950, 100, factory);
++        MemoryAllocator ma2 = SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats2, new NullLogWriter(), 10, 950, 100, factory);
+         assertSame(ma, ma2);
+         assertTrue(stats.isClosed());
+         assertFalse(listener.isClosed());
+         assertFalse(stats2.isClosed());
+         stats = stats2;
+         ma.close();
+         assertTrue(listener.isClosed());
+         assertFalse(stats.isClosed());
+       } finally {
+         SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+       }
+       assertTrue(stats.isClosed());
+     }
+   }
+   @Test
+   public void testBasics() {
 -    int BATCH_SIZE = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.BATCH_SIZE;
 -    int TINY_MULTIPLE = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.TINY_MULTIPLE;
 -    int HUGE_MULTIPLE = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.HUGE_MULTIPLE;
 -    int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
 -    int maxTiny = com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.MAX_TINY-perObjectOverhead;
++    int BATCH_SIZE = 1;
++    int TINY_MULTIPLE = com.gemstone.gemfire.internal.offheap.FreeListManager.TINY_MULTIPLE;
++    int HUGE_MULTIPLE = com.gemstone.gemfire.internal.offheap.FreeListManager.HUGE_MULTIPLE;
++    int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
++    int maxTiny = com.gemstone.gemfire.internal.offheap.FreeListManager.MAX_TINY-perObjectOverhead;
+     int minHuge = maxTiny+1;
+     int TOTAL_MEM = (maxTiny+perObjectOverhead)*BATCH_SIZE /*+ (maxBig+perObjectOverhead)*BATCH_SIZE*/ + round(TINY_MULTIPLE, minHuge+1+perObjectOverhead)*BATCH_SIZE + (TINY_MULTIPLE+perObjectOverhead)*BATCH_SIZE /*+ (MIN_BIG_SIZE+perObjectOverhead)*BATCH_SIZE*/ + round(TINY_MULTIPLE, minHuge+perObjectOverhead+1);
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       assertEquals(TOTAL_MEM, ma.getFreeMemory());
+       assertEquals(TOTAL_MEM, ma.freeList.getFreeFragmentMemory());
+       assertEquals(0, ma.freeList.getFreeTinyMemory());
+       assertEquals(0, ma.freeList.getFreeHugeMemory());
 -      MemoryChunk tinymc = ma.allocate(maxTiny, null);
++      MemoryChunk tinymc = ma.allocate(maxTiny);
+       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeTinyMemory());
 -      MemoryChunk hugemc = ma.allocate(minHuge, null);
++      MemoryChunk hugemc = ma.allocate(minHuge);
+       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, minHuge+perObjectOverhead)/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       long freeSlab = ma.freeList.getFreeFragmentMemory();
+       long oldFreeHugeMemory = ma.freeList.getFreeHugeMemory();
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), oldFreeHugeMemory);
+       hugemc.release();
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead), ma.freeList.getFreeHugeMemory()-oldFreeHugeMemory);
+       assertEquals(TOTAL_MEM/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       long oldFreeTinyMemory = ma.freeList.getFreeTinyMemory();
+       tinymc.release();
+       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.freeList.getFreeTinyMemory()-oldFreeTinyMemory);
+       assertEquals(TOTAL_MEM, ma.getFreeMemory());
+       // now lets reallocate from the free lists
 -      tinymc = ma.allocate(maxTiny, null);
++      tinymc = ma.allocate(maxTiny);
+       assertEquals(oldFreeTinyMemory, ma.freeList.getFreeTinyMemory());
+       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
 -      hugemc = ma.allocate(minHuge, null);
++      hugemc = ma.allocate(minHuge);
+       assertEquals(oldFreeHugeMemory, ma.freeList.getFreeHugeMemory());
+       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, minHuge+perObjectOverhead)/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       hugemc.release();
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead), ma.freeList.getFreeHugeMemory()-oldFreeHugeMemory);
+       assertEquals(TOTAL_MEM/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory());
+       tinymc.release();
+       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.freeList.getFreeTinyMemory()-oldFreeTinyMemory);
+       assertEquals(TOTAL_MEM, ma.getFreeMemory());
+       // None of the reallocates should have come from the slab.
+       assertEquals(freeSlab, ma.freeList.getFreeFragmentMemory());
 -      tinymc = ma.allocate(1, null);
++      tinymc = ma.allocate(1);
+       assertEquals(round(TINY_MULTIPLE, 1+perObjectOverhead), tinymc.getSize());
+       assertEquals(freeSlab-(round(TINY_MULTIPLE, 1+perObjectOverhead)*BATCH_SIZE), ma.freeList.getFreeFragmentMemory());
+       freeSlab = ma.freeList.getFreeFragmentMemory();
+       tinymc.release();
+       assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead)+(round(TINY_MULTIPLE, 1+perObjectOverhead)*BATCH_SIZE), ma.freeList.getFreeTinyMemory()-oldFreeTinyMemory);
+       
 -      hugemc = ma.allocate(minHuge+1, null);
++      hugemc = ma.allocate(minHuge+1);
+       assertEquals(round(TINY_MULTIPLE, minHuge+1+perObjectOverhead), hugemc.getSize());
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory());
+       hugemc.release();
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*BATCH_SIZE, ma.freeList.getFreeHugeMemory());
 -      hugemc = ma.allocate(minHuge, null);
++      hugemc = ma.allocate(minHuge);
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory());
+       if (BATCH_SIZE > 1) {
 -        MemoryChunk hugemc2 = ma.allocate(minHuge, null);
++        MemoryChunk hugemc2 = ma.allocate(minHuge);
+         assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-2), ma.freeList.getFreeHugeMemory());
+         hugemc2.release();
+         assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory());
+       }
+       hugemc.release();
+       assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*BATCH_SIZE, ma.freeList.getFreeHugeMemory());
+       // now that we do compaction the following allocate works.
 -      hugemc = ma.allocate(minHuge + HUGE_MULTIPLE + HUGE_MULTIPLE-1, null);
++      hugemc = ma.allocate(minHuge + HUGE_MULTIPLE + HUGE_MULTIPLE-1);
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   
+   @Test
+   public void testChunkCreateDirectByteBuffer() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       ByteBuffer bb = ByteBuffer.allocate(1024);
+       for (int i=0; i < 1024; i++) {
+         bb.put((byte) i);
+       }
+       bb.position(0);
 -      Chunk c = (Chunk) ma.allocateAndInitialize(bb.array(), false, false, null);
++      ObjectChunk c = (ObjectChunk) ma.allocateAndInitialize(bb.array(), false, false);
+       assertEquals(1024, c.getDataSize());
+       if (!Arrays.equals(bb.array(), c.getRawBytes())) {
+         fail("arrays are not equal. Expected " + Arrays.toString(bb.array()) + " but found: " + Arrays.toString(c.getRawBytes()));
+       }
+       ByteBuffer dbb = c.createDirectByteBuffer();
+       assertEquals(true, dbb.isDirect());
+       assertEquals(bb, dbb);
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   
+   @Test
+   public void testDebugLog() {
+     SimpleMemoryAllocatorImpl.debugLog("test debug log", false);
+     SimpleMemoryAllocatorImpl.debugLog("test debug log", true);
+   }
+   @Test
+   public void testGetLostChunks() {
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       assertEquals(Collections.emptyList(), ma.getLostChunks());
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   @Test
+   public void testFindSlab() {
+     final int SLAB_SIZE = 1024*1024;
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       assertEquals(0, ma.findSlab(slab.getMemoryAddress()));
+       assertEquals(0, ma.findSlab(slab.getMemoryAddress()+SLAB_SIZE-1));
+       try {
+         ma.findSlab(slab.getMemoryAddress()-1);
+         fail("expected IllegalStateException");
+       } catch (IllegalStateException expected) {
+       }
+       try {
+         ma.findSlab(slab.getMemoryAddress()+SLAB_SIZE);
+         fail("expected IllegalStateException");
+       } catch (IllegalStateException expected) {
+       }
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   @Test
+   public void testValidateAddressAndSize() {
+     final int SLAB_SIZE = 1024*1024;
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       try {
+         SimpleMemoryAllocatorImpl.validateAddress(0L);
+         fail("expected IllegalStateException");
+       } catch (IllegalStateException expected) {
+         assertEquals("Unexpected exception message: " + expected.getMessage(), true, expected.getMessage().contains("addr was smaller than expected"));
+       }
+       try {
+         SimpleMemoryAllocatorImpl.validateAddress(1L);
+         fail("expected IllegalStateException");
+       } catch (IllegalStateException expected) {
+         assertEquals("Unexpected exception message: " + expected.getMessage(), true, expected.getMessage().contains("Valid addresses must be in one of the following ranges:"));
+       }
+       SimpleMemoryAllocatorImpl.validateAddressAndSizeWithinSlab(slab.getMemoryAddress(), SLAB_SIZE, false);
+       SimpleMemoryAllocatorImpl.validateAddressAndSizeWithinSlab(slab.getMemoryAddress(), SLAB_SIZE, true);
+       SimpleMemoryAllocatorImpl.validateAddressAndSizeWithinSlab(slab.getMemoryAddress(), -1, true);
+       try {
+         SimpleMemoryAllocatorImpl.validateAddressAndSizeWithinSlab(slab.getMemoryAddress()-1, SLAB_SIZE, true);
+         fail("expected IllegalStateException");
+       } catch (IllegalStateException expected) {
+         assertEquals("Unexpected exception message: " + expected.getMessage(), true, expected.getMessage().equals(" address 0x" + Long.toString(slab.getMemoryAddress()-1, 16) + " does not address the original slab memory"));
+       }
+       try {
+         SimpleMemoryAllocatorImpl.validateAddressAndSizeWithinSlab(slab.getMemoryAddress(), SLAB_SIZE+1, true);
+         fail("expected IllegalStateException");
+       } catch (IllegalStateException expected) {
+         assertEquals("Unexpected exception message: " + expected.getMessage(), true, expected.getMessage().equals(" address 0x" + Long.toString(slab.getMemoryAddress()+SLAB_SIZE, 16) + " does not address the original slab memory"));
+       }
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   @Test
+   public void testMemoryInspection() {
+     final int SLAB_SIZE = 1024*1024;
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       MemoryInspector inspector = ma.getMemoryInspector();
+       assertNotNull(inspector);
+       assertEquals(null, inspector.getFirstBlock());
+       assertEquals(Collections.emptyList(), inspector.getSnapshot());
+       assertEquals(Collections.emptyList(), inspector.getAllocatedBlocks());
+       assertEquals(null, inspector.getBlockAfter(null));
+       inspector.createSnapshot();
+       // call this twice for code coverage
+       inspector.createSnapshot();
+       try {
+         assertEquals(inspector.getAllBlocks(), inspector.getSnapshot());
+         MemoryBlock firstBlock = inspector.getFirstBlock();
+         assertNotNull(firstBlock);
+         assertEquals(1024*1024, firstBlock.getBlockSize());
+         assertEquals("N/A", firstBlock.getDataType());
+         assertEquals(-1, firstBlock.getFreeListId());
+         assertTrue(firstBlock.getMemoryAddress() > 0);
+         assertNull(firstBlock.getNextBlock());
+         assertEquals(0, firstBlock.getRefCount());
+         assertEquals(0, firstBlock.getSlabId());
+         assertEquals(MemoryBlock.State.UNUSED, firstBlock.getState());
+         assertFalse(firstBlock.isCompressed());
+         assertFalse(firstBlock.isSerialized());
+         assertEquals(null, inspector.getBlockAfter(firstBlock));
+       } finally {
+         inspector.clearSnapshot();
+       }
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ 
+   @Test
+   public void testClose() {
+     System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "false");
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024);
+     boolean freeSlab = true;
+     UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[]{slab};
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
+       ma.close();
+       ma.close();
+       System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
+       try {
 -        ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
++        ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs);
+         ma.close();
+         freeSlab = false;
+         ma.close();
+       } finally {
+         System.clearProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY);
+       }
+     } finally {
+       if (freeSlab) {
+         SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+       }
+     }
+     
+   }
+   
+   @Test
+   public void testCompaction() {
 -    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
++    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
+     final int BIG_ALLOC_SIZE = 150000;
+     final int SMALL_ALLOC_SIZE = BIG_ALLOC_SIZE/2;
+     final int TOTAL_MEM = BIG_ALLOC_SIZE;
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
 -      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
+       try {
 -        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
++        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+         fail("Expected out of memory");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       bmc.release();
+       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
 -      MemoryChunk smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
 -      MemoryChunk smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
++      MemoryChunk smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
++      MemoryChunk smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+       smc2.release();
+       assertEquals(TOTAL_MEM-SMALL_ALLOC_SIZE, ma.freeList.getFreeMemory());
+       try {
 -        bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
++        bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
+         fail("Expected out of memory");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       smc1.release();
+       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
 -      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
++      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
+       bmc.release();
+       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
+       ArrayList<MemoryChunk> mcs = new ArrayList<MemoryChunk>();
+       for (int i=0; i < BIG_ALLOC_SIZE/(8+perObjectOverhead); i++) {
 -        mcs.add(ma.allocate(8, null));
++        mcs.add(ma.allocate(8));
+       }
+       checkMcs(mcs);
+       assertEquals(0, ma.freeList.getFreeMemory());
+       try {
 -        ma.allocate(8, null);
++        ma.allocate(8);
+         fail("expected out of memory");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       mcs.remove(0).release(); // frees 8+perObjectOverhead
+       assertEquals(8+perObjectOverhead, ma.freeList.getFreeMemory());
+       mcs.remove(0).release(); // frees 8+perObjectOverhead
+       assertEquals((8+perObjectOverhead)*2, ma.freeList.getFreeMemory());
 -      ma.allocate(16, null).release(); // allocates and frees 16+perObjectOverhead; still have perObjectOverhead
++      ma.allocate(16).release(); // allocates and frees 16+perObjectOverhead; still have perObjectOverhead
+       assertEquals((8+perObjectOverhead)*2, ma.freeList.getFreeMemory());
+       mcs.remove(0).release(); // frees 8+perObjectOverhead
+       assertEquals((8+perObjectOverhead)*3, ma.freeList.getFreeMemory());
+       mcs.remove(0).release(); // frees 8+perObjectOverhead
+       assertEquals((8+perObjectOverhead)*4, ma.freeList.getFreeMemory());
+       // At this point I should have 8*4 + perObjectOverhead*4 of free memory
 -      ma.allocate(8*4+perObjectOverhead*3, null).release();
++      ma.allocate(8*4+perObjectOverhead*3).release();
+       assertEquals((8+perObjectOverhead)*4, ma.freeList.getFreeMemory());
+       mcs.remove(0).release(); // frees 8+perObjectOverhead
+       assertEquals((8+perObjectOverhead)*5, ma.freeList.getFreeMemory());
+       // At this point I should have 8*5 + perObjectOverhead*5 of free memory
+       try {
 -        ma.allocate((8*5+perObjectOverhead*4)+1, null);
++        ma.allocate((8*5+perObjectOverhead*4)+1);
+         fail("expected out of memory");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       mcs.remove(0).release(); // frees 8+perObjectOverhead
+       assertEquals((8+perObjectOverhead)*6, ma.freeList.getFreeMemory());
+       checkMcs(mcs);
+       // At this point I should have 8*6 + perObjectOverhead*6 of free memory
 -      MemoryChunk mc24 = ma.allocate(24, null);
++      MemoryChunk mc24 = ma.allocate(24);
+       checkMcs(mcs);
+       assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead), ma.freeList.getFreeMemory());
+       // At this point I should have 8*3 + perObjectOverhead*5 of free memory
 -      MemoryChunk mc16 = ma.allocate(16, null);
++      MemoryChunk mc16 = ma.allocate(16);
+       checkMcs(mcs);
+       assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead) - (16+perObjectOverhead), ma.freeList.getFreeMemory());
+       // At this point I should have 8*1 + perObjectOverhead*4 of free memory
 -      mcs.add(ma.allocate(8, null));
++      mcs.add(ma.allocate(8));
+       checkMcs(mcs);
+       assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead) - (16+perObjectOverhead) - (8+perObjectOverhead), ma.freeList.getFreeMemory());
+       // At this point I should have 8*0 + perObjectOverhead*3 of free memory
 -      MemoryChunk mcDO = ma.allocate(perObjectOverhead*2, null);
++      MemoryChunk mcDO = ma.allocate(perObjectOverhead*2);
+       checkMcs(mcs);
+       // At this point I should have 8*0 + perObjectOverhead*0 of free memory
+       assertEquals(0, ma.freeList.getFreeMemory());
+       try {
 -        ma.allocate(1, null);
++        ma.allocate(1);
+         fail("expected out of memory");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       checkMcs(mcs);
+       assertEquals(0, ma.freeList.getFreeMemory());
+       mcDO.release();
+       assertEquals((perObjectOverhead*3), ma.freeList.getFreeMemory());
+       mcs.remove(mcs.size()-1).release();
+       assertEquals((perObjectOverhead*3)+(8+perObjectOverhead), ma.freeList.getFreeMemory());
+       mc16.release();
+       assertEquals((perObjectOverhead*3)+(8+perObjectOverhead)+(16+perObjectOverhead), ma.freeList.getFreeMemory());
+       mc24.release();
+       assertEquals((perObjectOverhead*3)+(8+perObjectOverhead)+(16+perObjectOverhead)+(24+perObjectOverhead), ma.freeList.getFreeMemory());
+       
+       long freeMem = ma.freeList.getFreeMemory();
+       for (MemoryChunk mc: mcs) {
+         mc.release();
+         assertEquals(freeMem+(8+perObjectOverhead), ma.freeList.getFreeMemory());
+         freeMem += (8+perObjectOverhead);
+       }
+       mcs.clear();
+       assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory());
 -      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
++      bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
+       bmc.release();
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   
+   long expectedMemoryUsage;
+   boolean memoryUsageEventReceived;
+   @Test
+   public void testUsageEventListener() {
 -    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
++    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
+     final int SMALL_ALLOC_SIZE = 1000;
+     UnsafeMemoryChunk slab = new UnsafeMemoryChunk(3000);
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       MemoryUsageListener listener = new MemoryUsageListener() {
+         @Override
+         public void updateMemoryUsed(final long bytesUsed) {
+           SimpleMemoryAllocatorJUnitTest.this.memoryUsageEventReceived = true;
+           assertEquals(SimpleMemoryAllocatorJUnitTest.this.expectedMemoryUsage, bytesUsed);
+         }
+       };
+       ma.addMemoryUsageListener(listener);
+       
+       this.expectedMemoryUsage = SMALL_ALLOC_SIZE;
+       this.memoryUsageEventReceived = false;
 -      MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
++      MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+       assertEquals(true, this.memoryUsageEventReceived);
+       
+       this.expectedMemoryUsage = SMALL_ALLOC_SIZE * 2;
+       this.memoryUsageEventReceived = false;
 -      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
++      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+       assertEquals(true, this.memoryUsageEventReceived);
+       
+       MemoryUsageListener unaddedListener = new MemoryUsageListener() {
+         @Override
+         public void updateMemoryUsed(final long bytesUsed) {
+           throw new IllegalStateException("Should never be called");
+         }
+       };
+       ma.removeMemoryUsageListener(unaddedListener);
+       
+       ma.removeMemoryUsageListener(listener);
+       
+       ma.removeMemoryUsageListener(unaddedListener);
+ 
+       this.expectedMemoryUsage = SMALL_ALLOC_SIZE * 2;
+       this.memoryUsageEventReceived = false;
 -      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
++      smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+       assertEquals(false, this.memoryUsageEventReceived);
+       
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+   private void checkMcs(ArrayList<MemoryChunk> mcs) {
+     for (MemoryChunk mc: mcs) {
+       assertEquals(8+8, mc.getSize());
+     }
+   }
+   
+   @Test
+   public void testOutOfOffHeapMemory() {
 -    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.Chunk.OFF_HEAP_HEADER_SIZE;
++    final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE;
+     final int BIG_ALLOC_SIZE = 150000;
+     final int SMALL_ALLOC_SIZE = BIG_ALLOC_SIZE/2;
+     final int TOTAL_MEM = BIG_ALLOC_SIZE;
+     final UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM);
+     final AtomicReference<OutOfOffHeapMemoryException> ooom = new AtomicReference<OutOfOffHeapMemoryException>();
+     final OutOfOffHeapMemoryListener oooml = new OutOfOffHeapMemoryListener() {
+       @Override
+       public void outOfOffHeapMemory(OutOfOffHeapMemoryException cause) {
+         ooom.set(cause);
+       }
+       @Override
+       public void close() {
+       }
+     };
+     try {
 -      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(oooml, new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
++      SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(oooml, new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab});
+       // make a big allocation
 -      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null);
++      MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead);
+       assertNull(ooom.get());
+       // drive the ma to ooom with small allocations
+       try {
 -        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null);
++        MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead);
+         fail("Expected out of memory");
+       } catch (OutOfOffHeapMemoryException expected) {
+       }
+       assertNotNull(ooom.get());
+       assertTrue(ooom.get().getMessage().contains("Out of off-heap memory. Could not allocate size of "));
+     } finally {
+       SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+     }
+   }
+ }



[065/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
----------------------------------------------------------------------
diff --cc geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
index 0000000,3747416..f3c1c5d
mode 000000,100644..100644
--- a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
+++ b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
@@@ -1,0 -1,826 +1,827 @@@
+ com/gemstone/gemfire/CancelException,false
+ com/gemstone/gemfire/CopyException,true,-1143711608610323585
+ com/gemstone/gemfire/DeltaSerializationException,false
+ com/gemstone/gemfire/ForcedDisconnectException,true,4977003259880566257
+ com/gemstone/gemfire/GemFireCacheException,true,-2844020916351682908
+ com/gemstone/gemfire/GemFireCheckedException,false
+ com/gemstone/gemfire/GemFireConfigException,true,7791789785331120991
+ com/gemstone/gemfire/GemFireException,false
+ com/gemstone/gemfire/GemFireIOException,true,5694009444435264497
+ com/gemstone/gemfire/GemFireRethrowable,true,8349791552668922571
+ com/gemstone/gemfire/IncompatibleSystemException,true,-6852188720149734350
+ com/gemstone/gemfire/InternalGemFireError,true,6390043490679349593
+ com/gemstone/gemfire/InternalGemFireException,true,-6912843691545178619
+ com/gemstone/gemfire/InvalidDeltaException,false
+ com/gemstone/gemfire/InvalidValueException,true,6186767885369527709
+ com/gemstone/gemfire/InvalidVersionException,true,6342040462194322698
+ com/gemstone/gemfire/LicenseException,true,-1178557127300465801
+ com/gemstone/gemfire/NoSystemException,true,-101890149467219630
+ com/gemstone/gemfire/OutOfOffHeapMemoryException,true,4111959438738739010
+ com/gemstone/gemfire/SerializationException,true,7783018024920098997
+ com/gemstone/gemfire/SystemConnectException,true,-7378174428634468238
+ com/gemstone/gemfire/SystemIsRunningException,true,3516268055878767189
+ com/gemstone/gemfire/ThreadInterruptedException,true,6169940883541267514
+ com/gemstone/gemfire/ToDataException,true,-2329606027453879918
+ com/gemstone/gemfire/UncreatedSystemException,true,5424354567878425435
+ com/gemstone/gemfire/UnmodifiableException,true,-1043243260052395455
+ com/gemstone/gemfire/UnstartedSystemException,true,-4285897556527521788
+ com/gemstone/gemfire/admin/AdminException,true,879398950879472021
+ com/gemstone/gemfire/admin/AdminXmlException,true,-6848726449157550169
+ com/gemstone/gemfire/admin/AlertLevel,true,-4752438966587392126,ordinal:int
+ com/gemstone/gemfire/admin/CacheDoesNotExistException,true,-1639933911265729978
+ com/gemstone/gemfire/admin/GemFireHealth$Health,true,3039539430412151801,healthString:java/lang/String
+ com/gemstone/gemfire/admin/GemFireMemberStatus,true,3389997790525991310,_bindAddress:java/lang/String,_clientHealthStats:java/util/Map,_clientHostNames:java/util/Map,_clientQueueSizes:java/util/Map,_connectedClients:java/util/Set,_connectedIncomingGateways:java/util/Map,_connectedPeers:java/util/Set,_connectedServers:java/util/Set,_freeHeapSize:long,_gatewayHubStatus:java/lang/Object,_gatewayQueueSizes:java/util/Map,_hostAddress:java/net/InetAddress,_isClient:boolean,_isConnected:boolean,_isGatewayHub:boolean,_isLocator:boolean,_isPrimaryGatewayHub:boolean,_isServer:boolean,_locators:java/lang/String,_maximumHeapSize:long,_mcastAddress:java/net/InetAddress,_mcastPort:int,_memberId:java/io/Serializable,_memberName:java/lang/String,_outgoingGateways:java/util/Map,_regionStatuses:java/util/Map,_serverPort:int,_unconnectedServers:java/util/Set,upTime:long
+ com/gemstone/gemfire/admin/OperationCancelledException,true,5474068770227602546
+ com/gemstone/gemfire/admin/RegionNotFoundException,true,1758668137691463909
+ com/gemstone/gemfire/admin/RuntimeAdminException,true,-7512771113818634005
+ com/gemstone/gemfire/admin/SystemMemberType,true,3284366994485749302,ordinal:int
+ com/gemstone/gemfire/admin/UnmodifiableConfigurationException,true,-7653547392992060646
+ com/gemstone/gemfire/admin/internal/BackupStatusImpl,true,3704162840296921840,backedUpDiskStores:java/util/Map,offlineDiskStores:java/util/Set
+ com/gemstone/gemfire/admin/internal/CacheHealthConfigImpl,false,maxEventQueueSize:long,maxLoadTime:long,maxNetSearchTime:long,minHitRatio:double
+ com/gemstone/gemfire/admin/internal/GemFireHealthConfigImpl,true,-6797673296902808018,hostName:java/lang/String,interval:int
+ com/gemstone/gemfire/admin/internal/MemberHealthConfigImpl,true,3966032573073580490,maxMessageQueueSize:long,maxReplyTimeouts:long,maxRetransmissionRatio:double,maxVMProcessSize:long
+ com/gemstone/gemfire/admin/internal/StatisticImpl,true,3899296873901634399,internalStat:com/gemstone/gemfire/internal/admin/Stat
+ com/gemstone/gemfire/admin/jmx/internal/AgentImpl$StartupException,true,6614145962199330348
+ com/gemstone/gemfire/admin/jmx/internal/AgentLauncher$Status,true,-7758402454664266174,baseName:java/lang/String,exception:java/lang/Throwable,msg:java/lang/String,pid:int,state:int
+ com/gemstone/gemfire/admin/jmx/internal/ConfigAttributeInfo,true,-1918437700841687078,config:com/gemstone/gemfire/admin/jmx/internal/ConfigurationParameterJmxImpl
+ com/gemstone/gemfire/admin/jmx/internal/ConfigurationParameterJmxImpl,true,-7822171853906772375,deserialized:boolean
+ com/gemstone/gemfire/admin/jmx/internal/ConnectionNotificationFilterImpl,true,1
+ com/gemstone/gemfire/admin/jmx/internal/DynamicManagedBean,true,4051924500150228160
+ com/gemstone/gemfire/admin/jmx/internal/GemFireHealthConfigJmxImpl,true,1482719647163239953,delegate:com/gemstone/gemfire/admin/GemFireHealthConfig,health:com/gemstone/gemfire/admin/GemFireHealth,mbeanName:java/lang/String,modelMBean:javax/management/modelmbean/ModelMBean,objectName:javax/management/ObjectName
+ com/gemstone/gemfire/admin/jmx/internal/ManagedResourceType,true,3752874768667480449,ordinal:int
+ com/gemstone/gemfire/admin/jmx/internal/RefreshNotificationType,true,4376763592395613794,ordinal:int
+ com/gemstone/gemfire/admin/jmx/internal/StatisticAttributeInfo,true,28022387514935560,stat:com/gemstone/gemfire/admin/Statistic
+ com/gemstone/gemfire/cache/AttributesFactory$RegionAttributesImpl,true,-3663000883567530374,asyncEventQueueIds:java/util/Set,cacheListeners:java/util/ArrayList,cacheLoader:com/gemstone/gemfire/cache/CacheLoader,cacheWriter:com/gemstone/gemfire/cache/CacheWriter,compressor:com/gemstone/gemfire/compression/Compressor,concurrencyChecksEnabled:boolean,concurrencyLevel:int,customEntryIdleTimeout:com/gemstone/gemfire/cache/CustomExpiry,customEntryTimeToLive:com/gemstone/gemfire/cache/CustomExpiry,dataPolicy:com/gemstone/gemfire/cache/DataPolicy,diskDirs:java/io/File[],diskSizes:int[],diskStoreName:java/lang/String,diskSynchronous:boolean,diskWriteAttributes:com/gemstone/gemfire/cache/DiskWriteAttributes,earlyAck:boolean,enableAsyncConflation:boolean,enableSubscriptionConflation:boolean,entryIdleTimeout:int,entryIdleTimeoutExpirationAction:com/gemstone/gemfire/cache/ExpirationAction,entryTimeToLive:int,entryTimeToLiveExpirationAction:com/gemstone/gemfire/cache/ExpirationAction,evictionAtt
 ributes:com/gemstone/gemfire/internal/cache/EvictionAttributesImpl,gatewaySenderIds:java/util/Set,hdfsStoreName:java/lang/String,hdfsWriteOnly:boolean,ignoreJTA:boolean,indexMaintenanceSynchronous:boolean,initialCapacity:int,isBucketRegion:boolean,isCloningEnabled:boolean,isLockGrantor:boolean,keyConstraint:java/lang/Class,loadFactor:float,membershipAttributes:com/gemstone/gemfire/cache/MembershipAttributes,multicastEnabled:boolean,offHeap:boolean,partitionAttributes:com/gemstone/gemfire/cache/PartitionAttributes,poolName:java/lang/String,publisher:boolean,regionIdleTimeout:int,regionIdleTimeoutExpirationAction:com/gemstone/gemfire/cache/ExpirationAction,regionTimeToLive:int,regionTimeToLiveExpirationAction:com/gemstone/gemfire/cache/ExpirationAction,scope:com/gemstone/gemfire/cache/Scope,statisticsEnabled:boolean,subscriptionAttributes:com/gemstone/gemfire/cache/SubscriptionAttributes,valueConstraint:java/lang/Class
+ com/gemstone/gemfire/cache/CacheClosedException,true,-6479561694497811262
+ com/gemstone/gemfire/cache/CacheException,false
+ com/gemstone/gemfire/cache/CacheExistsException,true,4090002289325418100
+ com/gemstone/gemfire/cache/CacheLoaderException,true,-3383072059406642140
+ com/gemstone/gemfire/cache/CacheRuntimeException,false
+ com/gemstone/gemfire/cache/CacheWriterException,true,-2872212342970454458
+ com/gemstone/gemfire/cache/CacheXmlException,true,-4343870964883131754
+ com/gemstone/gemfire/cache/CommitConflictException,true,-1491184174802596675
+ com/gemstone/gemfire/cache/CommitDistributionException,true,-3517820638706581823,regionDistributionExceptions:java/util/Set
+ com/gemstone/gemfire/cache/CommitIncompleteException,true,1017741483744420800
+ com/gemstone/gemfire/cache/DataPolicy,true,2095573273889467233,ordinal:byte
+ com/gemstone/gemfire/cache/DiskAccessException,true,5799100281147167888
+ com/gemstone/gemfire/cache/DiskWriteAttributesFactory,true,-4077746249663727235,props:java/util/Properties
+ com/gemstone/gemfire/cache/DuplicatePrimaryPartitionException,true,1
+ com/gemstone/gemfire/cache/EntryDestroyedException,true,831865939772672542
+ com/gemstone/gemfire/cache/EntryExistsException,true,2925082493103537925,oldValue:java/lang/Object
+ com/gemstone/gemfire/cache/EntryNotFoundException,true,-2404101631744605659
+ com/gemstone/gemfire/cache/EntryNotFoundInRegion,true,5572550909947420405
+ com/gemstone/gemfire/cache/EvictionAction,true,-98840597493242980
+ com/gemstone/gemfire/cache/EvictionAlgorithm,true,5778669432033106789
+ com/gemstone/gemfire/cache/ExpirationAction,true,658925707882047900,ordinal:int
+ com/gemstone/gemfire/cache/FailedSynchronizationException,true,-6225053492344591496
+ com/gemstone/gemfire/cache/GatewayConfigurationException,false
+ com/gemstone/gemfire/cache/GatewayException,true,8090143153569084886
+ com/gemstone/gemfire/cache/IncompatibleVersionException,true,668812986092856749
+ com/gemstone/gemfire/cache/InterestPolicy,true,1567179436331385968,ordinal:byte
+ com/gemstone/gemfire/cache/InterestResultPolicy,true,-4993765891973030160,ordinal:byte
+ com/gemstone/gemfire/cache/LossAction,true,-832035480397447797,ordinal:byte
+ com/gemstone/gemfire/cache/LowMemoryException,true,6585765466722883168,critMems:java/util/Set
+ com/gemstone/gemfire/cache/MirrorType,true,-6632651349646672540,ordinal:int
+ com/gemstone/gemfire/cache/NoQueueServersAvailableException,true,8484086019155762365
+ com/gemstone/gemfire/cache/NoSubscriptionServersAvailableException,true,8484086019155762365
+ com/gemstone/gemfire/cache/Operation,true,-7521751729852504238,ordinal:byte
+ com/gemstone/gemfire/cache/OperationAbortedException,false
+ com/gemstone/gemfire/cache/PartitionedRegionDistributionException,true,-3004093739855972548
+ com/gemstone/gemfire/cache/PartitionedRegionStorageException,true,5905463619475329732
+ com/gemstone/gemfire/cache/RegionAccessException,true,3142958723089038406
+ com/gemstone/gemfire/cache/RegionDestroyedException,true,319804842308010754,regionFullPath:java/lang/String
+ com/gemstone/gemfire/cache/RegionDistributionException,true,-5950359426786805646
+ com/gemstone/gemfire/cache/RegionExistsException,true,-5643670216230359426
+ com/gemstone/gemfire/cache/RegionReinitializedException,true,8532904304288670752
+ com/gemstone/gemfire/cache/RegionRoleException,false,regionFullPath:java/lang/String
+ com/gemstone/gemfire/cache/RegionShortcut,false
+ com/gemstone/gemfire/cache/RemoteTransactionException,true,-2217135580436381984
+ com/gemstone/gemfire/cache/ResourceException,false
+ com/gemstone/gemfire/cache/ResumptionAction,true,6632254151314915610,ordinal:byte
+ com/gemstone/gemfire/cache/RoleException,true,-7521056108445887394
+ com/gemstone/gemfire/cache/Scope,true,5534399159504301602,ordinal:int
+ com/gemstone/gemfire/cache/StatisticsDisabledException,true,-2987721454129719551
+ com/gemstone/gemfire/cache/SynchronizationCommitConflictException,true,2619806460255259492
+ com/gemstone/gemfire/cache/TimeoutException,true,-6260761691185737442
+ com/gemstone/gemfire/cache/TransactionDataNodeHasDepartedException,true,-2217135580436381984
+ com/gemstone/gemfire/cache/TransactionDataNotColocatedException,true,-2217135580436381984
+ com/gemstone/gemfire/cache/TransactionDataRebalancedException,true,-2217135580436381984
+ com/gemstone/gemfire/cache/TransactionException,true,-8400774340264221993
+ com/gemstone/gemfire/cache/TransactionInDoubtException,true,4895453685211922512
+ com/gemstone/gemfire/cache/TransactionWriterException,true,-5557392877576634835
+ com/gemstone/gemfire/cache/UnsupportedOperationInTransactionException,false
+ com/gemstone/gemfire/cache/UnsupportedVersionException,true,1152280300663399399
+ com/gemstone/gemfire/cache/VersionException,false
+ com/gemstone/gemfire/cache/client/AllConnectionsInUseException,true,7304243507881787071
+ com/gemstone/gemfire/cache/client/ClientNotReadyException,true,-315765802919271588
+ com/gemstone/gemfire/cache/client/ClientRegionShortcut,false
+ com/gemstone/gemfire/cache/client/NoAvailableLocatorsException,true,-8212446737778234890
+ com/gemstone/gemfire/cache/client/NoAvailableServersException,true,-8212446737778234890
+ com/gemstone/gemfire/cache/client/ServerConnectivityException,true,-5205644901262051330
+ com/gemstone/gemfire/cache/client/ServerOperationException,true,-3106323103325266219
+ com/gemstone/gemfire/cache/client/ServerRefusedConnectionException,true,1794959225832197946
+ com/gemstone/gemfire/cache/client/SubscriptionNotEnabledException,true,-8212446737778234890
+ com/gemstone/gemfire/cache/client/internal/ContainsKeyOp$MODE,false
+ com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp$CompletionType,false
+ com/gemstone/gemfire/cache/client/internal/pooling/ConnectionDestroyedException,true,-6918516787578041316
+ com/gemstone/gemfire/cache/execute/EmtpyRegionFunctionException,true,1
+ com/gemstone/gemfire/cache/execute/FunctionAdapter,false
+ com/gemstone/gemfire/cache/execute/FunctionException,true,4893171227542647452
+ com/gemstone/gemfire/cache/execute/FunctionInvocationTargetException,true,1,id:com/gemstone/gemfire/distributed/DistributedMember
+ com/gemstone/gemfire/cache/hdfs/HDFSIOException,false
+ com/gemstone/gemfire/cache/hdfs/StoreExistsException,true,1
+ com/gemstone/gemfire/cache/hdfs/internal/HDFSStoreConfigHolder,false,autoMajorCompact:boolean,batchIntervalMillis:int,batchSize:int,blockCacheSize:float,clientConfigFile:java/lang/String,diskStoreName:java/lang/String,diskSynchronous:boolean,dispatcherThreads:int,fileRolloverInterval:int,homeDir:java/lang/String,isAutoCompact:boolean,isPersistenceEnabled:boolean,logPrefix:java/lang/String,majorCompactionConcurrency:int,majorCompactionIntervalMins:int,maxConcurrency:int,maxFileSize:int,maxInputFileCount:int,maxInputFileSizeMB:int,maximumQueueMemory:int,minInputFileCount:int,name:java/lang/String,namenodeURL:java/lang/String,oldFileCleanupIntervalMins:int
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/HDFSCompactionManager$CompactionIsDisabled,true,1
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/HDFSFlushQueueFunction,false
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/HDFSForceCompactionFunction,false
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/HDFSLastCompactionTimeFunction,false
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer$HoplogReadersController$1,true,1,this$1:com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer$HoplogReadersController,val$this$0:com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer$HoplogReadersController$2,true,1,this$1:com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer$HoplogReadersController,val$this$0:com/gemstone/gemfire/cache/hdfs/internal/hoplog/HdfsSortedOplogOrganizer
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/Hoplog$HoplogVersion,false
+ com/gemstone/gemfire/cache/hdfs/internal/hoplog/Hoplog$Meta,false
+ com/gemstone/gemfire/cache/hdfs/internal/org/apache/hadoop/io/SequenceFile$CompressionType,false
+ com/gemstone/gemfire/cache/operations/PutAllOperationContext$UpdateOnlyMap,true,-1034234728574286014,m:java/util/Map
+ com/gemstone/gemfire/cache/partition/PartitionNotAvailableException,true,1
+ com/gemstone/gemfire/cache/persistence/ConflictingPersistentDataException,true,-2629287782021455875
+ com/gemstone/gemfire/cache/persistence/PartitionOfflineException,true,-6471045959318795870,offlineMembers:java/util/Set
+ com/gemstone/gemfire/cache/persistence/PersistentReplicatesOfflineException,true,6209644027346609970
+ com/gemstone/gemfire/cache/persistence/RevokeFailedException,true,-2629287782021455875
+ com/gemstone/gemfire/cache/persistence/RevokedPersistentDataException,true,0
+ com/gemstone/gemfire/cache/query/AmbiguousNameException,true,5635771575414148564
+ com/gemstone/gemfire/cache/query/CqAttributesFactory$CqAttributesImpl,true,-959395592883099100,clSync:java/lang/Object,cqListeners:java/util/ArrayList,dataPolicyHasBeenSet:boolean
+ com/gemstone/gemfire/cache/query/CqClosedException,true,-3793993436374495840
+ com/gemstone/gemfire/cache/query/CqException,true,-5905461592471139171
+ com/gemstone/gemfire/cache/query/CqExistsException,true,-4805225282677926623
+ com/gemstone/gemfire/cache/query/FunctionDomainException,true,1198115662851760423
+ com/gemstone/gemfire/cache/query/IndexCreationException,true,-2218359458870240534
+ com/gemstone/gemfire/cache/query/IndexExistsException,true,-168312863985932144
+ com/gemstone/gemfire/cache/query/IndexInvalidException,true,3285601274732772770
+ com/gemstone/gemfire/cache/query/IndexMaintenanceException,true,3326023943226474039
+ com/gemstone/gemfire/cache/query/IndexNameConflictException,true,7047969935188485334
+ com/gemstone/gemfire/cache/query/MultiIndexCreationException,true,6312081720315894780,exceptionsMap:java/util/Map
+ com/gemstone/gemfire/cache/query/NameNotFoundException,true,4827972941932684358
+ com/gemstone/gemfire/cache/query/NameResolutionException,true,-7409771357534316562
+ com/gemstone/gemfire/cache/query/ParameterCountInvalidException,true,-3249156440150789428
+ com/gemstone/gemfire/cache/query/QueryException,true,7100830250939955452
+ com/gemstone/gemfire/cache/query/QueryExecutionLowMemoryException,false
+ com/gemstone/gemfire/cache/query/QueryExecutionTimeoutException,false
+ com/gemstone/gemfire/cache/query/QueryInvalidException,true,2849255122285215114
+ com/gemstone/gemfire/cache/query/QueryInvocationTargetException,true,2978208305701582906
+ com/gemstone/gemfire/cache/query/RegionNotFoundException,true,592495934010222373
+ com/gemstone/gemfire/cache/query/TypeMismatchException,true,4205901708655503775
+ com/gemstone/gemfire/cache/query/internal/CompiledSelect$NullIteratorException,false
+ com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion$1,false,this$0:com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion
+ com/gemstone/gemfire/cache/query/internal/ObjectIntHashMap,true,7718697444988416372,hashingStrategy:com/gemstone/gemfire/cache/query/internal/HashingStrategy,loadFactor:float,threshold:int
+ com/gemstone/gemfire/cache/query/internal/ObjectIntHashMap$IntHashMapStrategy,false,this$0:com/gemstone/gemfire/cache/query/internal/ObjectIntHashMap
+ com/gemstone/gemfire/cache/query/internal/QueryExecutionCanceledException,false
+ com/gemstone/gemfire/cache/query/internal/StructBag$ObjectArrayHashingStrategy,false
+ com/gemstone/gemfire/cache/query/internal/index/IMQException,true,-5012914292321850775
+ com/gemstone/gemfire/cache/query/internal/index/IndexConcurrentHashSet,false
+ com/gemstone/gemfire/cache/query/internal/parse/ASTAggregateFunc,true,8713004765228379685,aggFunctionType:int,distinctOnly:boolean
+ com/gemstone/gemfire/cache/query/internal/parse/ASTAnd,true,7100190044926605881
+ com/gemstone/gemfire/cache/query/internal/parse/ASTCombination,true,-5390937242819850292
+ com/gemstone/gemfire/cache/query/internal/parse/ASTCompareOp,true,2764710765423856496
+ com/gemstone/gemfire/cache/query/internal/parse/ASTConstruction,true,6647545354866647845
+ com/gemstone/gemfire/cache/query/internal/parse/ASTConversionExpr,true,8713000632283704611
+ com/gemstone/gemfire/cache/query/internal/parse/ASTDummy,true,-5390937473819850292
+ com/gemstone/gemfire/cache/query/internal/parse/ASTGroupBy,true,2262777181888775078
+ com/gemstone/gemfire/cache/query/internal/parse/ASTHint,false
+ com/gemstone/gemfire/cache/query/internal/parse/ASTHintIdentifier,false
+ com/gemstone/gemfire/cache/query/internal/parse/ASTIdentifier,true,-7534067808767107958
+ com/gemstone/gemfire/cache/query/internal/parse/ASTImport,true,6002078657881181949
+ com/gemstone/gemfire/cache/query/internal/parse/ASTIn,true,-7688132343283983119
+ com/gemstone/gemfire/cache/query/internal/parse/ASTIteratorDef,true,-736956634497535951
+ com/gemstone/gemfire/cache/query/internal/parse/ASTLike,true,1171234838254852463
+ com/gemstone/gemfire/cache/query/internal/parse/ASTLimit,false
+ com/gemstone/gemfire/cache/query/internal/parse/ASTLiteral,true,8374021603235812835
+ com/gemstone/gemfire/cache/query/internal/parse/ASTMethodInvocation,true,-3158542132262327470,implicitReceiver:boolean
+ com/gemstone/gemfire/cache/query/internal/parse/ASTOr,true,5770135811089855867
+ com/gemstone/gemfire/cache/query/internal/parse/ASTOrderBy,true,2262777181888775078
+ com/gemstone/gemfire/cache/query/internal/parse/ASTParameter,true,2964948528198383319
+ com/gemstone/gemfire/cache/query/internal/parse/ASTPostfix,true,1100525641797867500
+ com/gemstone/gemfire/cache/query/internal/parse/ASTProjection,true,-1464858491766486290
+ com/gemstone/gemfire/cache/query/internal/parse/ASTRegionPath,true,-4326820914154387472
+ com/gemstone/gemfire/cache/query/internal/parse/ASTSelect,true,1389351692304773456
+ com/gemstone/gemfire/cache/query/internal/parse/ASTSortCriterion,true,-3654854374157753771
+ com/gemstone/gemfire/cache/query/internal/parse/ASTTrace,false
+ com/gemstone/gemfire/cache/query/internal/parse/ASTType,true,6155481284905422722,javaType:com/gemstone/gemfire/cache/query/types/ObjectType,typeName:java/lang/String
+ com/gemstone/gemfire/cache/query/internal/parse/ASTTypeCast,true,-6368577668325776355
+ com/gemstone/gemfire/cache/query/internal/parse/ASTUnary,true,-3906821390970046083
+ com/gemstone/gemfire/cache/query/internal/parse/ASTUndefinedExpr,true,-4629351288894274041
+ com/gemstone/gemfire/cache/query/internal/parse/ASTUnsupported,true,-1192307218047393827
+ com/gemstone/gemfire/cache/query/internal/parse/GemFireAST,true,779964802274305208
+ com/gemstone/gemfire/cache/query/internal/utils/PDXUtils$1,false
+ com/gemstone/gemfire/cache/query/internal/utils/PDXUtils$2,false
+ com/gemstone/gemfire/cache/snapshot/SnapshotOptions$SnapshotFormat,false
+ com/gemstone/gemfire/cache/util/BoundedLinkedHashMap,true,-3419897166186852692,_maximumNumberOfEntries:int
+ com/gemstone/gemfire/cache/util/Gateway$OrderPolicy,false
+ com/gemstone/gemfire/cache/wan/GatewaySender$OrderPolicy,false
+ com/gemstone/gemfire/compression/CompressionException,true,4118639654597191235
+ com/gemstone/gemfire/compression/SnappyCompressor,true,496609875302446099
+ com/gemstone/gemfire/distributed/AbstractLauncher$Status,false,description:java/lang/String
+ com/gemstone/gemfire/distributed/DistributedSystemDisconnectedException,true,-2484849299224086250
+ com/gemstone/gemfire/distributed/FutureCancelledException,true,-4599338440381989844
+ com/gemstone/gemfire/distributed/GatewayCancelledException,true,-1444310105860938512
+ com/gemstone/gemfire/distributed/LeaseExpiredException,true,6216142987243536540
+ com/gemstone/gemfire/distributed/LockNotHeldException,true,3827860179805916215
+ com/gemstone/gemfire/distributed/LockServiceDestroyedException,true,7528711924957352636
+ com/gemstone/gemfire/distributed/OplogCancelledException,true,106566926222526806
+ com/gemstone/gemfire/distributed/PoolCancelledException,true,-4562742255812266767
+ com/gemstone/gemfire/distributed/TXManagerCancelledException,true,3902857360354568446
+ com/gemstone/gemfire/distributed/internal/AtomicLongWithTerminalState,true,-6130409343386576390
+ com/gemstone/gemfire/distributed/internal/DistributionConfigSnapshot,true,7445728132965092798,modifiable:java/util/HashSet
+ com/gemstone/gemfire/distributed/internal/DistributionException,true,9039055444056269504
+ com/gemstone/gemfire/distributed/internal/FlowControlParams,true,7322447678546893647,byteAllowance:int,rechargeBlockMs:int,rechargeThreshold:float
+ com/gemstone/gemfire/distributed/internal/HighPriorityAckedMessage$operationType,false
+ com/gemstone/gemfire/distributed/internal/OverflowQueueWithDMStats,true,-1846248853494394996,stats:com/gemstone/gemfire/distributed/internal/QueueStatHelper
+ com/gemstone/gemfire/distributed/internal/ReliableReplyException,true,472566058783450438
+ com/gemstone/gemfire/distributed/internal/ReplyException,true,-4410839793809166071
+ com/gemstone/gemfire/distributed/internal/ResourceEvent,false
+ com/gemstone/gemfire/distributed/internal/RuntimeDistributionConfigImpl,true,-805637520096606113
+ com/gemstone/gemfire/distributed/internal/ThrottlingMemLinkedQueueWithDMStats,true,5425180246954573433,maxMemSize:int,maxSize:int,memSize:int,startThrottleMemSize:int,startThrottleSize:int
+ com/gemstone/gemfire/distributed/internal/deadlock/DLockDependencyMonitor$LockId,false,serviceName:java/lang/String,tokenName:java/io/Serializable
+ com/gemstone/gemfire/distributed/internal/deadlock/Dependency,true,1,depender:java/lang/Object,dependsOn:java/lang/Object
+ com/gemstone/gemfire/distributed/internal/deadlock/DependencyGraph,true,-6794339771271587648,edges:java/util/Set,vertices:java/util/Map
+ com/gemstone/gemfire/distributed/internal/deadlock/GemFireDeadlockDetector$CollectDependencyFunction,true,6204378622627095817
+ com/gemstone/gemfire/distributed/internal/deadlock/LocalLockInfo,true,1,info:com/gemstone/gemfire/internal/concurrent/LI,locatility:java/io/Serializable
+ com/gemstone/gemfire/distributed/internal/deadlock/LocalThread,true,1,locality:java/io/Serializable,threadId:long,threadName:java/lang/String,threadStack:java/lang/String
+ com/gemstone/gemfire/distributed/internal/deadlock/MessageDependencyMonitor$MessageKey,true,414781046295505260,myId:com/gemstone/gemfire/distributed/internal/membership/InternalDistributedMember,processorId:int
+ com/gemstone/gemfire/distributed/internal/direct/ShunnedMemberException,true,-6455664684151074915
+ com/gemstone/gemfire/distributed/internal/locks/DistributedMemberLock$LockReentryPolicy,false
+ com/gemstone/gemfire/distributed/internal/locks/LockGrantorDestroyedException,true,-3540124531032570817
+ com/gemstone/gemfire/distributed/internal/membership/gms/messages/InstallViewMessage$messageType,false
+ com/gemstone/gemfire/distributed/internal/membership/gms/messenger/JGAddress,true,-1818672332115113291,ip_addr:java/net/InetAddress,port:int,vmViewId:int
+ com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager$BoundedLinkedHashMap,true,-3419897166186852692,_maximumNumberOfEntries:int
+ com/gemstone/gemfire/internal/AbstractConfig$SortedProperties,true,7156507110684631135
+ com/gemstone/gemfire/internal/ConfigSource,true,-4097017272431018553,description:java/lang/String,type:com/gemstone/gemfire/internal/ConfigSource$Type
+ com/gemstone/gemfire/internal/ConfigSource$Type,false
+ com/gemstone/gemfire/internal/CopyOnWriteHashSet,true,8591978652141659932
+ com/gemstone/gemfire/internal/DSFIDFactory$SqlfSerializationException,true,5076687296705595933
+ com/gemstone/gemfire/internal/DSFIDNotFoundException,true,130596009484324655,dsfid:int,versionOrdinal:short
+ com/gemstone/gemfire/internal/InsufficientDiskSpaceException,true,-6167707908956900841
+ com/gemstone/gemfire/internal/InternalDataSerializer$SERIALIZATION_VERSION,false
+ com/gemstone/gemfire/internal/InternalStatisticsDisabledException,true,4146181546364258311
+ com/gemstone/gemfire/internal/LinuxProcFsStatistics$CPU,false
+ com/gemstone/gemfire/internal/ObjIdConcurrentMap,true,7249069246763182397,segmentMask:int,segmentShift:int,segments:com/gemstone/gemfire/internal/ObjIdConcurrentMap$Segment[]
+ com/gemstone/gemfire/internal/ObjIdConcurrentMap$Segment,true,2249069246763182397,loadFactor:float
+ com/gemstone/gemfire/internal/SystemAdmin$CombinedResources,false
+ com/gemstone/gemfire/internal/admin/CompoundEntrySnapshot,true,5776382582897895718,allUserAttributes:java/util/Set,allValues:java/util/Set,hitRatio:float,hitRatioSum:double,hitResponders:long,lastAccessTime:long,lastModifiedTime:long,name:java/lang/Object,numHits:long,numMisses:long
+ com/gemstone/gemfire/internal/admin/CompoundRegionSnapshot,true,6295026394298398004,allCacheLoaders:java/util/Set,allCacheWriters:java/util/Set,allCapControllers:java/util/Set,allConcLevels:java/util/Set,allCustomIdle:java/util/HashSet,allCustomTtl:java/util/HashSet,allDataPolicies:java/util/Set,allEntryIdleTimeout:java/util/Set,allEntryTtl:java/util/Set,allInitialCaps:java/util/Set,allKeyConstraints:java/util/Set,allListeners:java/util/Set,allLoadFactors:java/util/Set,allRegionIdleTimeout:java/util/Set,allRegionTtl:java/util/Set,allScopes:java/util/Set,allStatsEnabled:java/util/Set,allUserAttributes:java/util/Set,allValueConstraints:java/util/Set,hitRatio:float,hitRatioSum:double,hitResponders:long,lastAccessTime:long,lastModifiedTime:long,name:java/lang/String,numHits:long,numMisses:long
+ com/gemstone/gemfire/internal/admin/StatAlert,true,5725457607122449170,definitionId:int,time:java/util/Date,values:java/lang/Number[]
+ com/gemstone/gemfire/internal/admin/remote/DistributionLocatorId,true,6587390186971937865,bindAddress:java/lang/String,host:java/net/InetAddress,hostnameForClients:java/lang/String,peerLocator:boolean,port:int,serverLocator:boolean
+ com/gemstone/gemfire/internal/admin/remote/EntryValueNodeImpl,false,fields:com/gemstone/gemfire/internal/admin/remote/EntryValueNodeImpl[],name:java/lang/String,primitive:boolean,primitiveVal:java/lang/Object,type:java/lang/String
+ com/gemstone/gemfire/internal/cache/AbstractRegionMap$1,false,this$0:com/gemstone/gemfire/internal/cache/AbstractRegionMap
+ com/gemstone/gemfire/internal/cache/BackupLock,false,backupDone:java/util/concurrent/locks/Condition,backupThread:java/lang/Thread,isBackingUp:boolean
+ com/gemstone/gemfire/internal/cache/BucketAdvisor$SetFromMap,true,2454657854757543876,m:java/util/Map
+ com/gemstone/gemfire/internal/cache/BucketNotFoundException,false
+ com/gemstone/gemfire/internal/cache/BucketRegion$SizeOp,false
+ com/gemstone/gemfire/internal/cache/CacheClientStatus,true,-56148046466517217,_id:com/gemstone/gemfire/internal/cache/tier/sockets/ClientProxyMembershipID,_memberId:java/lang/String,_numberOfConnections:int,_socketAddresses:java/util/List,_socketPorts:java/util/List
+ com/gemstone/gemfire/internal/cache/CacheServerLauncher$Status,true,190943081363646485,baseName:java/lang/String,dsMsg:java/lang/String,exception:java/lang/Throwable,msg:java/lang/String,pid:int,state:int
+ com/gemstone/gemfire/internal/cache/CommitReplyException,true,-7711083075296622596,exceptions:java/util/Set
+ com/gemstone/gemfire/internal/cache/DataLocationException,false
+ com/gemstone/gemfire/internal/cache/DiskInitFile$DiskRegionFlag,false
+ com/gemstone/gemfire/internal/cache/DiskStoreAttributes,true,1,allowForceCompaction:boolean,autoCompact:boolean,compactionThreshold:int,diskDirSizes:int[],diskDirs:java/io/File[],diskUsageCriticalPct:float,diskUsageWarningPct:float,maxOplogSizeInBytes:long,name:java/lang/String,queueSize:int,timeInterval:long,writeBufferSize:int
+ com/gemstone/gemfire/internal/cache/DiskStoreImpl$KillCompactorException,false
+ com/gemstone/gemfire/internal/cache/DiskWriteAttributesImpl,true,-4269181954992768424,bytesThreshold:long,compactOplogs:boolean,isSynchronous:boolean,maxOplogSize:long,timeInterval:long
+ com/gemstone/gemfire/internal/cache/DistTXCommitMessage$DistTxCommitExceptionCollectingException,true,-2681117727592137893,cacheExceptions:java/util/Set,fatalExceptions:java/util/Map,id:com/gemstone/gemfire/internal/cache/TXId,regionExceptions:java/util/Map
+ com/gemstone/gemfire/internal/cache/DistTXPrecommitMessage$DistTxPrecommitExceptionCollectingException,true,-2681117727592137893,cacheExceptions:java/util/Set,fatalExceptions:java/util/Map,id:com/gemstone/gemfire/internal/cache/TXId,regionExceptions:java/util/Map
+ com/gemstone/gemfire/internal/cache/DistTXRollbackMessage$DistTxRollbackExceptionCollectingException,true,-2681117727592137893,cacheExceptions:java/util/Set,fatalExceptions:java/util/Map,id:com/gemstone/gemfire/internal/cache/TXId,regionExceptions:java/util/Map
+ com/gemstone/gemfire/internal/cache/DistributedClearOperation$OperationType,false
+ com/gemstone/gemfire/internal/cache/DistributedTombstoneOperation$TOperation,false
+ com/gemstone/gemfire/internal/cache/FilterProfile$interestType,false
+ com/gemstone/gemfire/internal/cache/FilterProfile$operationType,false
+ com/gemstone/gemfire/internal/cache/ForceReattemptException,true,-595988965679204903,hasHash:boolean,keyHash:int
+ com/gemstone/gemfire/internal/cache/ForceableLinkedBlockingQueue,true,-6903933977591709194,capacity:int,count:java/util/concurrent/atomic/AtomicInteger,notEmpty:java/util/concurrent/locks/Condition,notFull:java/util/concurrent/locks/Condition,putLock:java/util/concurrent/locks/ReentrantLock,takeLock:java/util/concurrent/locks/ReentrantLock
+ com/gemstone/gemfire/internal/cache/GemFireCacheImpl$3,true,-6456778743822843838,this$0:com/gemstone/gemfire/internal/cache/GemFireCacheImpl
+ com/gemstone/gemfire/internal/cache/GemFireCacheImpl$4,true,1,this$0:com/gemstone/gemfire/internal/cache/GemFireCacheImpl
+ com/gemstone/gemfire/internal/cache/GemFireCacheImpl$5,true,1,this$0:com/gemstone/gemfire/internal/cache/GemFireCacheImpl
+ com/gemstone/gemfire/internal/cache/GemFireCacheImpl$6,true,1,this$0:com/gemstone/gemfire/internal/cache/GemFireCacheImpl
+ com/gemstone/gemfire/internal/cache/IdentityArrayList,true,449125332499184497,size:int,wrapped:boolean
+ com/gemstone/gemfire/internal/cache/IncomingGatewayStatus,true,-4579815367602658353,_memberId:java/lang/String,_socketAddress:java/net/InetAddress,_socketPort:int
+ com/gemstone/gemfire/internal/cache/InitialImageOperation$GIIStatus,false
+ com/gemstone/gemfire/internal/cache/InitialImageOperation$GIITestHookType,false
+ com/gemstone/gemfire/internal/cache/LocalRegion$1,true,0,this$0:com/gemstone/gemfire/internal/cache/LocalRegion
+ com/gemstone/gemfire/internal/cache/LocalRegion$IteratorType,false
+ com/gemstone/gemfire/internal/cache/Oplog$OkToSkipResult,false
+ com/gemstone/gemfire/internal/cache/Oplog$OplogFileType,false
+ com/gemstone/gemfire/internal/cache/PRContainsValueFunction,false
+ com/gemstone/gemfire/internal/cache/PRHARedundancyProvider$ArrayListWithClearState,true,1,wasCleared:boolean
+ com/gemstone/gemfire/internal/cache/PartitionedRegion$8,true,0,this$0:com/gemstone/gemfire/internal/cache/PartitionedRegion,val$bucketId:int
+ com/gemstone/gemfire/internal/cache/PartitionedRegion$PRIdMap,true,3667357372967498179,cleared:boolean
+ com/gemstone/gemfire/internal/cache/PartitionedRegion$SizeEntry,false,isPrimary:boolean,size:int
+ com/gemstone/gemfire/internal/cache/PartitionedRegionDataStore$CreateBucketResult,false,nowExists:boolean
+ com/gemstone/gemfire/internal/cache/PartitionedRegionException,true,5113786059279106007
+ com/gemstone/gemfire/internal/cache/PartitionedRegionQueryEvaluator$MemberResultsList,false,isLastChunkReceived:boolean
+ com/gemstone/gemfire/internal/cache/PartitionedRegionQueryEvaluator$TaintableArrayList,false,isPoison:boolean
+ com/gemstone/gemfire/internal/cache/PartitionedRegionStatus,true,-6755318987122602065,numberOfLocalEntries:int
+ com/gemstone/gemfire/internal/cache/PrimaryBucketException,true,1
+ com/gemstone/gemfire/internal/cache/PutAllPartialResultException,false,result:com/gemstone/gemfire/internal/cache/PutAllPartialResultException$PutAllPartialResult
+ com/gemstone/gemfire/internal/cache/PutAllPartialResultException$PutAllPartialResult,false,firstCauseOfFailure:java/lang/Exception,firstFailedKey:java/lang/Object,succeededKeys:com/gemstone/gemfire/internal/cache/tier/sockets/VersionedObjectList,totalMapSize:int
+ com/gemstone/gemfire/internal/cache/RegionClearedException,true,1266503771775907997
+ com/gemstone/gemfire/internal/cache/RegionQueueException,true,4159307586325821105
+ com/gemstone/gemfire/internal/cache/RegionStatus,true,3442040750396350302,heapSize:long,numberOfEntries:int
+ com/gemstone/gemfire/internal/cache/RemoteOperationException,true,-595988965679204903,hasHash:boolean,keyHash:int
+ com/gemstone/gemfire/internal/cache/RemoteRegionOperation$Operation,false
+ com/gemstone/gemfire/internal/cache/SearchLoadAndWriteProcessor$TryAgainException,false
+ com/gemstone/gemfire/internal/cache/TXCommitMessage$CommitExceptionCollectingException,true,589384721273797822,cacheExceptions:java/util/Set,fatalExceptions:java/util/Map,id:com/gemstone/gemfire/internal/cache/TXId,regionExceptions:java/util/Map
+ com/gemstone/gemfire/internal/cache/TXCommitMessage$RegionCommitList,true,-8910813949027683641
+ com/gemstone/gemfire/internal/cache/TXFarSideCMTracker$2,false,this$0:com/gemstone/gemfire/internal/cache/TXFarSideCMTracker
+ com/gemstone/gemfire/internal/cache/TXManagerImpl$1,true,-4156018226167594134,this$0:com/gemstone/gemfire/internal/cache/TXManagerImpl
+ com/gemstone/gemfire/internal/cache/control/InternalResourceManager$ResourceType,false,id:int
+ com/gemstone/gemfire/internal/cache/control/MemoryThresholds$MemoryState,false
+ com/gemstone/gemfire/internal/cache/control/PartitionRebalanceDetailsImpl,true,5880667005758250156,bucketCreateBytes:long,bucketCreateTime:long,bucketCreatesCompleted:int,bucketRemoveBytes:long,bucketRemoveTime:long,bucketRemovesCompleted:int,bucketTransferBytes:long,bucketTransferTime:long,bucketTransfersCompleted:int,partitionMemberDetailsAfter:java/util/Set,partitionMemberDetailsBefore:java/util/Set,primaryTransferTime:long,primaryTransfersCompleted:int,time:long
+ com/gemstone/gemfire/internal/cache/control/RebalanceResultsImpl,false,detailSet:java/util/Set,totalBucketCreateBytes:long,totalBucketCreateTime:long,totalBucketCreatesCompleted:int,totalBucketTransferBytes:long,totalBucketTransferTime:long,totalBucketTransfersCompleted:int,totalPrimaryTransferTime:long,totalPrimaryTransfersCompleted:int,totalTime:long
+ com/gemstone/gemfire/internal/cache/execute/BucketMovedException,true,4893171227542647452
+ com/gemstone/gemfire/internal/cache/execute/InternalFunctionException,false
+ com/gemstone/gemfire/internal/cache/execute/InternalFunctionInvocationTargetException,false,failedIds:java/util/Set
+ com/gemstone/gemfire/internal/cache/execute/MemberMappedArgument,true,-6465867775653599576,defaultArgument:java/lang/Object,memberToArgMap:java/util/Map
+ com/gemstone/gemfire/internal/cache/execute/NoResult,true,-4901369422864228848
+ com/gemstone/gemfire/internal/cache/execute/util/CommitFunction,true,7851518767859544501
+ com/gemstone/gemfire/internal/cache/execute/util/FindRestEnabledServersFunction,true,7851518767859544678
+ com/gemstone/gemfire/internal/cache/execute/util/NestedTransactionFunction,true,1400965724856341543
+ com/gemstone/gemfire/internal/cache/execute/util/RollbackFunction,true,1377183180063184795
+ com/gemstone/gemfire/internal/cache/ha/ThreadIdentifier$Bits,false,position:int,width:int
+ com/gemstone/gemfire/internal/cache/ha/ThreadIdentifier$WanType,false
+ com/gemstone/gemfire/internal/cache/locks/GFEAbstractQueuedSynchronizer,true,7373984972572414691,state:int
+ com/gemstone/gemfire/internal/cache/locks/ReentrantReadWriteWriteShareLock$CASSync,false,allowUpgradeOfWriteShare:boolean,ownerId:java/lang/Object
+ com/gemstone/gemfire/internal/cache/lru/HeapLRUCapacityController,true,4970685814429530675,perEntryOverhead:int,sizer:com/gemstone/gemfire/cache/util/ObjectSizer
+ com/gemstone/gemfire/internal/cache/lru/LRUAlgorithm,false,bucketRegion:com/gemstone/gemfire/internal/cache/BucketRegion,evictionAction:com/gemstone/gemfire/cache/EvictionAction
+ com/gemstone/gemfire/internal/cache/lru/LRUCapacityController,true,-4383074909189355938,maximumEntries:int
+ com/gemstone/gemfire/internal/cache/lru/MemLRUCapacityController,true,6364183985590572514,isOffHeap:boolean,limit:long,perEntryOverHead:int,sizer:com/gemstone/gemfire/cache/util/ObjectSizer
+ com/gemstone/gemfire/internal/cache/partitioned/DumpB2NRegion$PrimaryInfo,true,6334695270795306178,hostToken:java/lang/String,isHosting:boolean,isPrimary:boolean
+ com/gemstone/gemfire/internal/cache/partitioned/FetchEntriesMessage$FetchEntriesResponse$1,true,0,this$0:com/gemstone/gemfire/internal/cache/partitioned/FetchEntriesMessage$FetchEntriesResponse,val$bucketId:int,val$recipient:com/gemstone/gemfire/distributed/internal/membership/InternalDistributedMember
+ com/gemstone/gemfire/internal/cache/partitioned/PRLocallyDestroyedException,true,-1291911181409686840
+ com/gemstone/gemfire/internal/cache/partitioned/PartitionMemberInfoImpl,true,8245020687604034289,bucketCount:int,configuredMaxMemory:long,distributedMember:com/gemstone/gemfire/distributed/DistributedMember,primaryCount:int,size:long
+ com/gemstone/gemfire/internal/cache/partitioned/PartitionRegionInfoImpl,true,6462414089469761476,actualRedundantCopies:int,colocatedWith:java/lang/String,configuredBucketCount:int,configuredRedundantCopies:int,createdBucketCount:int,lowRedundancyBucketCount:int,memberDetails:java/util/Set,offlineMembers:com/gemstone/gemfire/internal/cache/partitioned/OfflineMemberDetails,regionPath:java/lang/String
+ com/gemstone/gemfire/internal/cache/partitioned/RedundancyAlreadyMetException,false
+ com/gemstone/gemfire/internal/cache/partitioned/rebalance/PartitionedRegionLoadModel$RefusalReason,false
+ com/gemstone/gemfire/internal/cache/persistence/OplogType,false,prefix:java/lang/String
+ com/gemstone/gemfire/internal/cache/persistence/PersistentMemberState,false
+ com/gemstone/gemfire/internal/cache/persistence/soplog/SoplogToken,false,val:byte
+ com/gemstone/gemfire/internal/cache/persistence/soplog/SortedOplogFactory$SortedOplogConfiguration$Checksum,false
+ com/gemstone/gemfire/internal/cache/persistence/soplog/SortedOplogFactory$SortedOplogConfiguration$Compression,false
+ com/gemstone/gemfire/internal/cache/persistence/soplog/SortedOplogFactory$SortedOplogConfiguration$KeyEncoding,false
+ com/gemstone/gemfire/internal/cache/persistence/soplog/SortedReader$Metadata,false
+ com/gemstone/gemfire/internal/cache/persistence/soplog/hfile/HFileSortedOplog$InternalMetadata,false
+ com/gemstone/gemfire/internal/cache/snapshot/ClientExporter$ClientArgs,true,1,options:com/gemstone/gemfire/cache/snapshot/SnapshotOptions,prSingleHop:boolean,region:java/lang/String
+ com/gemstone/gemfire/internal/cache/snapshot/ClientExporter$ProxyExportFunction,true,1
+ com/gemstone/gemfire/internal/cache/snapshot/RegionSnapshotServiceImpl$1,true,1
+ com/gemstone/gemfire/internal/cache/snapshot/RegionSnapshotServiceImpl$ParallelArgs,true,1,file:java/io/File,format:com/gemstone/gemfire/cache/snapshot/SnapshotOptions$SnapshotFormat,options:com/gemstone/gemfire/internal/cache/snapshot/SnapshotOptionsImpl
+ com/gemstone/gemfire/internal/cache/snapshot/RegionSnapshotServiceImpl$ParallelExportFunction,false
+ com/gemstone/gemfire/internal/cache/snapshot/RegionSnapshotServiceImpl$ParallelImportFunction,false
+ com/gemstone/gemfire/internal/cache/snapshot/SnapshotOptionsImpl,true,1,filter:com/gemstone/gemfire/cache/snapshot/SnapshotFilter,mapper:com/gemstone/gemfire/internal/cache/snapshot/SnapshotFileMapper,parallel:boolean
+ com/gemstone/gemfire/internal/cache/snapshot/WindowedExporter$WindowedArgs,true,1,exporter:com/gemstone/gemfire/distributed/DistributedMember,options:com/gemstone/gemfire/cache/snapshot/SnapshotOptions
+ com/gemstone/gemfire/internal/cache/snapshot/WindowedExporter$WindowedExportFunction,true,1
+ com/gemstone/gemfire/internal/cache/tier/BatchException,true,-6707074107791305564,_index:int
+ com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientNotifier$2,false,this$0:com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientNotifier
+ com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy$MessageDispatcher$1,true,0,this$0:com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy$MessageDispatcher
+ com/gemstone/gemfire/internal/cache/tier/sockets/ClientTombstoneMessage$TOperation,false
++com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException,true,-8970585803331525833
+ com/gemstone/gemfire/internal/cache/tier/sockets/UnregisterAllInterest,true,5026160621257178459
+ com/gemstone/gemfire/internal/cache/tx/TransactionalOperation$ServerRegionOperation,false
+ com/gemstone/gemfire/internal/cache/versions/ConcurrentCacheModificationException,false
+ com/gemstone/gemfire/internal/cache/wan/AsyncEventQueueConfigurationException,true,1
+ com/gemstone/gemfire/internal/cache/wan/BatchException70,true,-6707074107791305564,batchId:int,exceptions:java/util/List,index:int
+ com/gemstone/gemfire/internal/cache/wan/GatewayReceiverException,true,7079321411869820364
+ com/gemstone/gemfire/internal/cache/wan/GatewaySenderConfigurationException,true,1
+ com/gemstone/gemfire/internal/cache/wan/GatewaySenderException,true,8090143153569084886
+ com/gemstone/gemfire/internal/cache/wan/parallel/BucketRegionQueueUnavailableException,false
+ com/gemstone/gemfire/internal/cache/xmlcache/CacheXmlVersion,false,publicId:java/lang/String,schemaLocation:java/lang/String,systemId:java/lang/String,version:java/lang/String
+ com/gemstone/gemfire/internal/cache/xmlcache/DiskStoreAttributesCreation,false
+ com/gemstone/gemfire/internal/cache/xmlcache/RegionAttributesCreation,true,2241078661206355376,asyncEventQueueIds:java/util/Set,cacheListeners:java/util/ArrayList,cacheLoader:com/gemstone/gemfire/cache/CacheLoader,cacheWriter:com/gemstone/gemfire/cache/CacheWriter,cloningEnabled:boolean,compressor:com/gemstone/gemfire/compression/Compressor,concurrencyChecksEnabled:boolean,concurrencyLevel:int,customEntryIdleTimeout:com/gemstone/gemfire/cache/CustomExpiry,customEntryTimeToLive:com/gemstone/gemfire/cache/CustomExpiry,dataPolicy:com/gemstone/gemfire/cache/DataPolicy,diskDirs:java/io/File[],diskSizes:int[],diskStoreName:java/lang/String,diskWriteAttributes:com/gemstone/gemfire/cache/DiskWriteAttributes,earlyAck:boolean,enableAsyncConflation:boolean,enableSubscriptionConflation:boolean,entryIdleTimeout:com/gemstone/gemfire/cache/ExpirationAttributes,entryTimeToLive:com/gemstone/gemfire/cache/ExpirationAttributes,evictionAttributes:com/gemstone/gemfire/internal/cache/EvictionAttributesI
 mpl,gatewaySenderIds:java/util/Set,hdfsStoreName:java/lang/String,hdfsWriteOnly:boolean,id:java/lang/String,ignoreJTA:boolean,indexMaintenanceSynchronous:boolean,initialCapacity:int,isDiskSynchronous:boolean,isLockGrantor:boolean,keyConstraint:java/lang/Class,loadFactor:float,membershipAttributes:com/gemstone/gemfire/cache/MembershipAttributes,multicastEnabled:boolean,offHeap:boolean,partitionAttributes:com/gemstone/gemfire/cache/PartitionAttributes,poolName:java/lang/String,publisher:boolean,refid:java/lang/String,regionIdleTimeout:com/gemstone/gemfire/cache/ExpirationAttributes,regionTimeToLive:com/gemstone/gemfire/cache/ExpirationAttributes,scope:com/gemstone/gemfire/cache/Scope,statisticsEnabled:boolean,subscriptionAttributes:com/gemstone/gemfire/cache/SubscriptionAttributes,valueConstraint:java/lang/Class
+ com/gemstone/gemfire/internal/concurrent/AtomicLong5,true,-1915700199064062938
+ com/gemstone/gemfire/internal/concurrent/CompactConcurrentHashSet2,true,7249069246763182397
+ com/gemstone/gemfire/internal/concurrent/CompactConcurrentHashSet2$Segment,true,2249069246763182397,loadFactor:float
+ com/gemstone/gemfire/internal/concurrent/ConcurrentHashSet,true,-3338819662572203596,map:java/util/concurrent/ConcurrentHashMap
+ com/gemstone/gemfire/internal/concurrent/LI,true,-6014738350371493969,className:java/lang/String,identityHashCode:int,lockedStackFrame:java/lang/StackTraceElement
+ com/gemstone/gemfire/internal/datasource/AbstractDataSource,false,configProps:com/gemstone/gemfire/internal/datasource/ConfiguredDataSourceProperties,isActive:boolean,jdbcDriver:java/lang/String,loginTimeOut:int,password:java/lang/String,serverName:java/lang/String,url:java/lang/String,user:java/lang/String
+ com/gemstone/gemfire/internal/datasource/AbstractPoolCache,false,INIT_LIMIT:int,MAX_LIMIT:int,activeConnections:int,configProps:com/gemstone/gemfire/internal/datasource/ConfiguredDataSourceProperties,connEventListner:java/util/EventListener,expirationTime:int,expiredConns:java/util/List,loginTimeOut:int,sleepTime:long,th:java/lang/Thread,timeOut:int,totalConnections:int
+ com/gemstone/gemfire/internal/datasource/ConfiguredDataSourceProperties,true,1241739895646314739,connPoolDSClass:java/lang/String,expirationTime:int,initialPoolSize:int,jdbcDriver:java/lang/String,loginTimeOut:int,maxPoolSize:int,mcfClass:java/lang/String,password:java/lang/String,timeOut:int,txnType:java/lang/String,url:java/lang/String,user:java/lang/String,xadsClass:java/lang/String
+ com/gemstone/gemfire/internal/datasource/ConnectionPoolCacheImpl,true,-3096029291871746431,m_cpds:javax/sql/ConnectionPoolDataSource
+ com/gemstone/gemfire/internal/datasource/ConnectionProviderException,true,-7406652144153958227,excep:java/lang/Exception
+ com/gemstone/gemfire/internal/datasource/DataSourceCreateException,true,8759147832954825309,excep:java/lang/Exception
+ com/gemstone/gemfire/internal/datasource/GemFireBasicDataSource,true,-4010116024816908360
+ com/gemstone/gemfire/internal/datasource/GemFireConnPooledDataSource,true,1177231744410855158,provider:com/gemstone/gemfire/internal/datasource/ConnectionProvider
+ com/gemstone/gemfire/internal/datasource/GemFireConnectionPoolManager,true,23723212980453813,connPoolCache:com/gemstone/gemfire/internal/datasource/ConnectionPoolCache
+ com/gemstone/gemfire/internal/datasource/GemFireTransactionDataSource,true,-3095123666092414103,provider:com/gemstone/gemfire/internal/datasource/ConnectionProvider,xaResourcesMap:java/util/Map
+ com/gemstone/gemfire/internal/datasource/JCAConnectionManagerImpl,true,5281512854051120661,conReqInfo:javax/resource/spi/ConnectionRequestInfo,isActive:boolean,mannPoolCache:com/gemstone/gemfire/internal/datasource/ConnectionPoolCache,subject:javax/security/auth/Subject,xaResourcesMap:java/util/Map
+ com/gemstone/gemfire/internal/datasource/ManagedPoolCacheImpl,true,1064642271736399718,connFactory:javax/resource/spi/ManagedConnectionFactory,connReqInfo:javax/resource/spi/ConnectionRequestInfo,sub:javax/security/auth/Subject
+ com/gemstone/gemfire/internal/datasource/PoolException,true,-6178632158204356727
+ com/gemstone/gemfire/internal/datasource/TranxPoolCacheImpl,true,3295652525163658888,m_xads:javax/sql/XADataSource
+ com/gemstone/gemfire/internal/hll/CardinalityMergeException,false
+ com/gemstone/gemfire/internal/hll/HyperLogLog,true,-4661220245111112301,alphaMM:double,log2m:int,registerSet:com/gemstone/gemfire/internal/hll/RegisterSet
+ com/gemstone/gemfire/internal/hll/HyperLogLog$Builder,true,-979314356097156719,rsd:double
+ com/gemstone/gemfire/internal/hll/HyperLogLog$HyperLogLogMergeException,false
+ com/gemstone/gemfire/internal/hll/HyperLogLog$SerializationHolder,false,hyperLogLogHolder:com/gemstone/gemfire/internal/hll/HyperLogLog
+ com/gemstone/gemfire/internal/hll/HyperLogLogPlus,true,7504952025744337762,alphaMM:double,format:com/gemstone/gemfire/internal/hll/HyperLogLogPlus$Format,m:int,p:int,registerSet:com/gemstone/gemfire/internal/hll/RegisterSet,sm:int,sortThreshold:int,sp:int,sparseSet:int[],sparseSetThreshold:int,tmpIndex:int,tmpSet:int[]
+ com/gemstone/gemfire/internal/hll/HyperLogLogPlus$Builder,true,-1608419770500158843,p:int,sp:int
+ com/gemstone/gemfire/internal/hll/HyperLogLogPlus$Format,false
+ com/gemstone/gemfire/internal/hll/HyperLogLogPlus$HyperLogLogPlusMergeException,false
+ com/gemstone/gemfire/internal/hll/HyperLogLogPlus$SerializationHolder,false,hyperLogLogHolder:com/gemstone/gemfire/internal/hll/HyperLogLogPlus
+ com/gemstone/gemfire/internal/jta/TransactionManagerImpl,true,5033392316185449821,globalTransactionMap:java/util/Map,gtxSet:java/util/SortedSet,isActive:boolean,transactionMap:java/util/Map
+ com/gemstone/gemfire/internal/jta/UserTransactionImpl,true,2994652455204901910,storedTimeOut:int,tm:javax/transaction/TransactionManager
+ com/gemstone/gemfire/internal/logging/log4j/AlertAppender,false,alertingDisabled:boolean,appenderContext:com/gemstone/gemfire/internal/logging/log4j/AppenderContext,listeners:java/util/concurrent/CopyOnWriteArrayList
+ com/gemstone/gemfire/internal/logging/log4j/LogWriterAppender,false,appenderContexts:com/gemstone/gemfire/internal/logging/log4j/AppenderContext[],appenderName:java/lang/String,fos:java/io/FileOutputStream,logWriter:com/gemstone/gemfire/internal/logging/PureLogWriter,logWriterLoggerName:java/lang/String
+ com/gemstone/gemfire/internal/memcached/Command,false
+ com/gemstone/gemfire/internal/memcached/Command$1,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$10,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$11,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$12,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$13,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$14,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$15,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$16,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$17,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$18,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$19,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$2,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$20,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$21,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$22,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$23,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$24,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$25,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$26,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$27,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$28,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$29,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$3,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$30,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$31,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$32,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$33,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$34,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$4,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$5,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$6,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$7,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$8,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Command$9,false,processor:com/gemstone/gemfire/internal/memcached/CommandProcessor
+ com/gemstone/gemfire/internal/memcached/Reply,false
+ com/gemstone/gemfire/internal/memcached/Reply$1,false
+ com/gemstone/gemfire/internal/memcached/Reply$2,false
+ com/gemstone/gemfire/internal/memcached/Reply$3,false
+ com/gemstone/gemfire/internal/memcached/Reply$4,false
+ com/gemstone/gemfire/internal/memcached/Reply$5,false
+ com/gemstone/gemfire/internal/memcached/Reply$6,false
+ com/gemstone/gemfire/internal/memcached/Reply$7,false
+ com/gemstone/gemfire/internal/memcached/Reply$8,false
+ com/gemstone/gemfire/internal/memcached/Reply$9,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus$1,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus$2,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus$3,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus$4,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus$5,false
+ com/gemstone/gemfire/internal/memcached/ResponseStatus$6,false
+ com/gemstone/gemfire/internal/memcached/commands/ClientError,true,-2426928000696680541
+ com/gemstone/gemfire/internal/offheap/MemoryBlock$State,false
+ com/gemstone/gemfire/internal/offheap/OffHeapStorage$1,false
+ com/gemstone/gemfire/internal/offheap/OffHeapStorage$2,false
+ com/gemstone/gemfire/internal/offheap/annotations/OffHeapIdentifier,false,id:java/lang/String
+ com/gemstone/gemfire/internal/process/ConnectionFailedException,true,5622636452836752700
+ com/gemstone/gemfire/internal/process/FileAlreadyExistsException,true,5471082555536094256
+ com/gemstone/gemfire/internal/process/MBeanInvocationFailedException,true,7991096466859690801
+ com/gemstone/gemfire/internal/process/PidUnavailableException,true,-1660269538268828059
+ com/gemstone/gemfire/internal/process/signal/Signal,false,description:java/lang/String,name:java/lang/String,number:int,type:com/gemstone/gemfire/internal/process/signal/SignalType
+ com/gemstone/gemfire/internal/process/signal/SignalEvent,false,signal:com/gemstone/gemfire/internal/process/signal/Signal
+ com/gemstone/gemfire/internal/process/signal/SignalType,false,description:java/lang/String
+ com/gemstone/gemfire/internal/redis/RedisCommandParserException,true,4707944288714910949
+ com/gemstone/gemfire/internal/redis/RedisCommandType,false
+ com/gemstone/gemfire/internal/redis/RedisCommandType$1,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$10,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$100,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$101,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$102,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$103,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$104,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$105,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$106,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$107,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$108,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$109,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$11,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$110,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$111,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$112,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$113,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$12,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$13,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$14,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$15,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$16,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$17,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$18,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$19,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$2,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$20,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$21,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$22,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$23,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$24,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$25,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$26,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$27,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$28,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$29,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$3,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$30,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$31,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$32,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$33,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$34,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$35,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$36,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$37,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$38,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$39,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$4,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$40,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$41,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$42,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$43,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$44,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$45,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$46,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$47,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$48,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$49,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$5,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$50,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$51,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$52,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$53,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$54,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$55,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$56,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$57,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$58,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$59,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$6,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$60,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$61,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$62,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$63,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$64,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$65,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$66,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$67,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$68,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$69,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$7,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$70,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$71,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$72,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$73,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$74,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$75,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$76,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$77,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$78,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$79,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$8,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$80,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$81,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$82,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$83,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$84,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$85,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$86,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$87,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$88,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$89,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$9,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$90,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$91,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$92,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$93,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$94,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$95,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$96,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$97,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$98,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisCommandType$99,false,dataType:com/gemstone/gemfire/internal/redis/RedisDataType,executor:com/gemstone/gemfire/internal/redis/Executor
+ com/gemstone/gemfire/internal/redis/RedisDataType,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$1,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$2,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$3,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$4,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$5,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$6,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$7,false
+ com/gemstone/gemfire/internal/redis/RedisDataType$8,false
+ com/gemstone/gemfire/internal/redis/RedisDataTypeMismatchException,true,-2451663685348513870
+ com/gemstone/gemfire/internal/redis/executor/list/ListExecutor$ListDirection,false
+ com/gemstone/gemfire/internal/sequencelog/GraphType,false
+ com/gemstone/gemfire/internal/sequencelog/model/GraphID,false,graphName:java/lang/String,type:com/gemstone/gemfire/internal/sequencelog/GraphType
+ com/gemstone/gemfire/internal/size/ReflectionObjectSizer,false
+ com/gemstone/gemfire/internal/size/SizeClassOnceObjectSizer,false
+ com/gemstone/gemfire/internal/statistics/CounterMonitor$Type,false
+ com/gemstone/gemfire/internal/statistics/IgnoreResourceException,true,3371071862581873081
+ com/gemstone/gemfire/internal/statistics/StatisticNotFoundException,true,-6232790142851058203
+ com/gemstone/gemfire/internal/statistics/StatisticsNotification$Type,false
+ com/gemstone/gemfire/internal/statistics/ValueMonitor$Type,false
+ com/gemstone/gemfire/internal/tcp/ByteBufferInputStream,false,buffer:com/gemstone/gemfire/internal/tcp/ByteBufferInputStream$ByteSource
+ com/gemstone/gemfire/internal/tcp/ConnectExceptions,true,-4173688946448867706,causes:java/util/List,members:java/util/List
+ com/gemstone/gemfire/internal/tcp/ConnectionException,true,-1977443644277412122
+ com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream,false
+ com/gemstone/gemfire/internal/tcp/MemberShunnedException,true,-8453126202477831557,member:com/gemstone/gemfire/distributed/DistributedMember
+ com/gemstone/gemfire/internal/tcp/ReenteredConnectException,false
+ com/gemstone/gemfire/internal/tcp/VersionedByteBufferInputStream,false,version:com/gemstone/gemfire/internal/Version
+ com/gemstone/gemfire/internal/util/Breadcrumbs$CrumbType,false
+ com/gemstone/gemfire/internal/util/SingletonValue$ValueState,false
+ com/gemstone/gemfire/internal/util/SunAPINotFoundException,false
+ com/gemstone/gemfire/internal/util/concurrent/CopyOnWriteHashMap,false,map:java/util/Map
+ com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap,true,-7056732555635108300,compareValues:boolean,entryCreator:com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$HashEntryCreator,segmentMask:int,segmentShift:int,segments:com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$Segment[]
+ com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$DefaultHashEntryCreator,true,3765680607280951726
+ com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$IdentitySegment,true,3086228147110819882
+ com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$Segment,true,-6972364566212065192,entryCreator:com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$HashEntryCreator,listUpdateLock:java/util/concurrent/locks/ReentrantReadWriteLock,loadFactor:float
+ com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$SimpleReusableEntry,true,1591026397367910439,key:java/lang/Object,this$0:com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap,value:java/lang/Object
+ com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap$WriteThroughEntry,true,-6364816773849437756,this$0:com/gemstone/gemfire/internal/util/concurrent/CustomEntryConcurrentHashMap
+ com/gemstone/gemfire/internal/util/concurrent/ReentrantSemaphore,false,holdCount:java/lang/ThreadLocal
+ com/gemstone/gemfire/internal/util/concurrent/StoppableCondition,true,-7091681525970431937,condition:java/util/concurrent/locks/Condition,stopper:com/gemstone/gemfire/CancelCriterion
+ com/gemstone/gemfire/internal/util/concurrent/StoppableReentrantReadWriteLock,true,-1185707921434766946
+ com/gemstone/gemfire/lang/AttachAPINotFoundException,false
+ com/gemstone/gemfire/management/AlreadyRunningException,true,8947734854770335071
+ com/gemstone/gemfire/management/DependenciesNotFoundException,true,9082304929238159814
+ com/gemstone/gemfire/management/ManagementException,true,879398950879472121
+ com/gemstone/gemfire/management/cli/CommandProcessingException,true,-1398779521639575884,errorData:java/lang/Object,errorType:int
+ com/gemstone/gemfire/management/cli/CommandServiceException,true,7316102209844678329
+ com/gemstone/gemfire/management/cli/Result$Status,false,code:int
+ com/gemstone/gemfire/management/internal/JmxManagerLocator$StartJmxManagerFunction,true,-2860286061903069789
+ com/gemstone/gemfire/management/internal/ManagementAgent$GemFireRMIClientSocketFactory,true,-7604285019188827617
+ com/gemstone/gemfire/management/internal/ManagementAgent$GemFireRMIServerSocketFactory,true,-811909050641332716,bindAddr:java/net/InetAddress
+ com/gemstone/gemfire/management/internal/ManagementFunction,true,1,mbeanServer:javax/management/MBeanServer,notificationHub:com/gemstone/gemfire/management/internal/NotificationHub
+ com/gemstone/gemfire/management/internal/NotificationKey,false,currentTime:long,objectName:javax/management/ObjectName
+ com/gemstone/gemfire/management/internal/beans/QueryDataFunction,true,1
+ com/gemstone/gemfire/management/internal/beans/QueryDataFunction$LocalQueryFunction,true,1,id:java/lang/String,optimizeForWrite:boolean,regionName:java/lang/String,showMembers:boolean,this$0:com/gemstone/gemfire/management/internal/beans/QueryDataFunction
+ com/gemstone/gemfire/management/internal/beans/QueryDataFunction$QueryDataFunctionResult,true,1,compressedBytes:byte[],message:java/lang/String
+ com/gemstone/gemfire/management/internal/beans/stats/StatType,false
+ com/gemstone/gemfire/management/internal/cli/AbstractCliAroundInterceptor$Response,false,text:java/lang/String
+ com/gemstone/gemfire/management/internal/cli/CliUtil$DeflaterInflaterData,true,1104813333595216795,data:byte[],dataLength:int
+ com/gemstone/gemfire/management/internal/cli/domain/AsyncEventQueueDetails,true,1,batchSize:int,diskStoreName:java/lang/String,id:java/lang/String,listener:java/lang/String,listenerProperties:java/util/Properties,maxQueueMemory:int,persistent:boolean
+ com/gemstone/gemfire/management/internal/cli/domain/CacheServerInfo,true,1,bindAddress:java/lang/String,isRunning:boolean,port:int
+ com/gemstone/gemfire/management/internal/cli/domain/DataCommandResult,true,1,command:java/lang/String,error:java/lang/Throwable,errorString:java/lang/String,getResult:java/lang/Object,hasResultForAggregation:boolean,infoString:java/lang/String,inputKey:java/lang/Object,inputQuery:java/lang/Object,inputValue:java/lang/Object,keyClass:java/lang/String,limit:int,locateEntryLocations:java/util/List,locateEntryResult:com/gemstone/gemfire/management/internal/cli/domain/DataCommandResult$KeyInfo,operationCompletedSuccessfully:boolean,putResult:java/lang/Object,queryTraceString:java/lang/String,removeResult:java/lang/Object,selectResult:java/util/List,valueClass:java/lang/String
+ com/gemstone/gemfire/management/internal/cli/domain/DataCommandResult$KeyInfo,false,host:java/lang/String,locations:java/util/ArrayList,memberId:java/lang/String,memberName:java/lang/String,pid:int
+ com/gemstone/gemfire/management/internal/cli/domain/DataCommandResult$SelectResultRow,true,1,type:int,value:java/lang/Object
+ com/gemstone/gemfire/management/internal/cli/domain/DiskStoreDetails,false,allowForceCompaction:java/lang/Boolean,asyncEventQueueDetailsSet:java/util/Set,autoCompact:java/lang/Boolean,cacheServerDetailsSet:java/util/Set,compactionThreshold:java/lang/Integer,diskDirDetailsSet:java/util/Set,diskUsageCriticalPercentage:java/lang/Float,diskUsageWarningPercentage:java/lang/Float,gatewayDetailsSet:java/util/Set,id:java/util/UUID,maxOplogSize:java/lang/Long,memberId:java/lang/String,memberName:java/lang/String,name:java/lang/String,offline:java/lang/Boolean,pdxSerializationMetaDataStored:java/lang/Boolean,queueSize:java/lang/Integer,regionDetailsSet:java/util/Set,timeInterval:java/lang/Long,writeBufferSize:java/lang/Integer
+ com/gemstone/gemfire/management/internal/cli/domain/DiskStoreDetails$AsyncEventQueueDetails,false,id:java/lang/String
+ com/gemstone/gemfire/management/internal/cli/domain/DiskStoreDetails$CacheServerDetails,false,bindAddress:java/lang/String,hostName:java/lang/String,port:int
+ com/gemstone/gemfire/management/internal/cli/domain/DiskStoreDetails$DiskDirDetails,false,absolutePath:java/lang/String,size:int
+ com/gemstone/gemfire/management/internal/cli/domain/DiskStoreDetails$GatewayDetails,false,id:java/lang/String,persistent:boolean
+ com/gemstone/gemfire/management/internal/cli/domain/DiskStoreDetails$RegionDetails,false,fullPath:java/lang/String,name:java/lang/String,overflowToDisk:boolean,persistent:boolean
+ com/gemstone/gemfire/management/internal/cli/domain/DurableCqNamesResult,true,1,cqNames:java/util/List
+ com/gemstone/gemfire/management/internal/cli/domain/EvictionAttributesInfo,true,1,evictionAction:java/lang/String,evictionAlgorithm:java/lang/String,evictionMaxValue:int,nonDefaultAttributes:java/util/Map
+ com/gemstone/gemfire/management/internal/cli/domain/FixedPartitionAttributesInfo,true,1,isPrimary:boolean,numBucke

<TRUNCATED>


[079/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
index 0000000,69ae6d8..f650fee
mode 000000,100755..100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
@@@ -1,0 -1,3112 +1,3116 @@@
+ /*
+  * 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 com.gemstone.gemfire.internal.cache.tier.sockets;
+ 
+ import java.io.ByteArrayInputStream;
+ import java.io.DataInputStream;
+ import java.io.IOException;
+ import java.net.Socket;
+ import java.net.SocketException;
+ import java.nio.ByteBuffer;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.Date;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.ConcurrentLinkedQueue;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.concurrent.atomic.AtomicReference;
+ import java.util.concurrent.locks.Lock;
+ import java.util.concurrent.locks.ReadWriteLock;
+ import java.util.concurrent.locks.ReentrantReadWriteLock;
+ import java.util.regex.Pattern;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.DataSerializer;
+ import com.gemstone.gemfire.StatisticsFactory;
+ import com.gemstone.gemfire.cache.Cache;
+ import com.gemstone.gemfire.cache.CacheClosedException;
+ import com.gemstone.gemfire.cache.CacheException;
+ import com.gemstone.gemfire.cache.ClientSession;
+ import com.gemstone.gemfire.cache.DynamicRegionFactory;
+ import com.gemstone.gemfire.cache.InterestRegistrationEvent;
+ import com.gemstone.gemfire.cache.InterestResultPolicy;
+ import com.gemstone.gemfire.cache.Region;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.RegionExistsException;
+ import com.gemstone.gemfire.cache.client.internal.RegisterInterestTracker;
+ import com.gemstone.gemfire.cache.operations.DestroyOperationContext;
+ import com.gemstone.gemfire.cache.operations.InvalidateOperationContext;
+ import com.gemstone.gemfire.cache.operations.OperationContext;
+ import com.gemstone.gemfire.cache.operations.PutOperationContext;
+ import com.gemstone.gemfire.cache.operations.RegionClearOperationContext;
+ import com.gemstone.gemfire.cache.operations.RegionCreateOperationContext;
+ import com.gemstone.gemfire.cache.operations.RegionDestroyOperationContext;
+ import com.gemstone.gemfire.cache.query.CqException;
+ import com.gemstone.gemfire.cache.query.CqQuery;
+ import com.gemstone.gemfire.cache.query.internal.cq.CqService;
+ import com.gemstone.gemfire.cache.query.internal.cq.InternalCqQuery;
+ import com.gemstone.gemfire.distributed.DistributedMember;
+ import com.gemstone.gemfire.distributed.internal.DistributionManager;
+ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+ import com.gemstone.gemfire.internal.SystemTimer;
+ import com.gemstone.gemfire.internal.SystemTimer.SystemTimerTask;
+ import com.gemstone.gemfire.internal.Version;
+ import com.gemstone.gemfire.internal.cache.ClientServerObserver;
+ import com.gemstone.gemfire.internal.cache.ClientServerObserverHolder;
+ import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisee;
+ import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.InitialImageAdvice;
+ import com.gemstone.gemfire.internal.cache.Conflatable;
+ import com.gemstone.gemfire.internal.cache.DistributedRegion;
+ import com.gemstone.gemfire.internal.cache.EnumListenerEvent;
+ import com.gemstone.gemfire.internal.cache.EventID;
+ import com.gemstone.gemfire.internal.cache.FilterProfile;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.internal.cache.InterestRegistrationEventImpl;
+ import com.gemstone.gemfire.internal.cache.LocalRegion;
+ import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+ import com.gemstone.gemfire.internal.cache.StateFlushOperation;
+ import com.gemstone.gemfire.internal.cache.ha.HAContainerWrapper;
+ import com.gemstone.gemfire.internal.cache.ha.HARegionQueue;
+ import com.gemstone.gemfire.internal.cache.ha.HARegionQueueAttributes;
+ import com.gemstone.gemfire.internal.cache.ha.HARegionQueueStats;
+ import com.gemstone.gemfire.internal.cache.tier.InterestType;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.ClientUpdateMessageImpl.CqNameToOp;
+ import com.gemstone.gemfire.internal.cache.tier.sockets.command.Get70;
+ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+ import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.LoggingThreadGroup;
+ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+ import com.gemstone.gemfire.internal.security.AuthorizeRequestPP;
+ import com.gemstone.gemfire.security.AccessControl;
+ import com.gemstone.gemfire.i18n.StringId;
+ 
+ /**
+  * Class <code>CacheClientProxy</code> represents the server side of the
+  * {@link CacheClientUpdater}. It queues messages to be sent from the server to
+  * the client. It then reads those messages from the queue and sends them to the
+  * client.
+  *
+  * @author Barry Oglesby
+  *
+  * @since 4.2
+  */
+ @SuppressWarnings("synthetic-access")
+ public class CacheClientProxy implements ClientSession {
+   private static final Logger logger = LogService.getLogger();
+   
+   /**
+    * The socket between the server and the client
+    */
+   protected Socket _socket;
+   
+   private final AtomicBoolean _socketClosed = new AtomicBoolean();
+ 
+   /**
+    * A communication buffer used by each message we send to the client
+    */
+   protected ByteBuffer _commBuffer;
+ 
+   /**
+    * The remote host's IP address string (cached for convenience)
+    */
+   protected String _remoteHostAddress;
+ 
+   /**
+    * Concurrency: protected by synchronization of {@link #isMarkedForRemovalLock}
+    */
+   protected boolean isMarkedForRemoval = false;
+   
+   /**
+    * @see #isMarkedForRemoval
+    */
+   protected final Object isMarkedForRemovalLock = new Object();
+   
+   /**
+    * The proxy id of the client represented by this proxy
+    */
+   protected ClientProxyMembershipID proxyID;
+ 
+   /**
+    * The GemFire cache
+    */
+   protected final GemFireCacheImpl _cache;
+ 
+   /**
+    * The list of keys that the client represented by this proxy is interested in
+    * (stored by region)
+    */
+   protected final ClientInterestList[] cils = new ClientInterestList[2];
+   
+   /**
+    * A thread that dispatches messages to the client
+    */
+   protected volatile MessageDispatcher _messageDispatcher;
+ 
+   /**
+    * The statistics for this proxy
+    */
+   protected final CacheClientProxyStats _statistics;
+ 
+   protected final AtomicReference _durableExpirationTask = new AtomicReference();
+ 
+   protected SystemTimer durableTimer;
+ 
+   /**
+    * Whether this dispatcher is paused
+    */
+   protected volatile boolean _isPaused = true;
+ 
+   /**
+    * True if we are connected to a client.
+    */
+   private volatile boolean connected = false;
+ //  /**
+ //   * A string representing interest in all keys
+ //   */
+ //  protected static final String ALL_KEYS = "ALL_KEYS";
+ //
+   /**
+    * True if a marker message is still in the ha queue.
+    */
+   private boolean markerEnqueued = false;
+ 
+   /**
+    * The number of times to peek on shutdown before giving up and shutting down
+    */
+   protected static final int MAXIMUM_SHUTDOWN_PEEKS = Integer.getInteger("gemfire.MAXIMUM_SHUTDOWN_PEEKS",50).intValue();
+ 
+   /**
+    * The number of milliseconds to wait for an offering to the message queue
+    */
+   protected static final int MESSAGE_OFFER_TIME = 0;
+ 
+   /**
+    * The default maximum message queue size
+    */
+ //   protected static final int MESSAGE_QUEUE_SIZE_DEFAULT = 230000;
+ 
+   /** The message queue size */
+   protected final int _maximumMessageCount;
+ 
+   /**
+    * The time (in seconds ) after which a message in the client queue will
+    * expire.
+    */
+   protected final int _messageTimeToLive;
+ 
+   /**
+    * The <code>CacheClientNotifier</code> registering this proxy.
+    */
+   protected final CacheClientNotifier _cacheClientNotifier;
+ 
+   /**
+    * Defaults to true; meaning do some logging of dropped client notification
+    * messages. Set the system property to true to cause dropped messages to NOT
+    * be logged.
+    */
+   protected static final boolean LOG_DROPPED_MSGS = !Boolean
+       .getBoolean("gemfire.disableNotificationWarnings");
+ 
+   /**
+    * for testing purposes, delays the start of the dispatcher thread
+    */
+   public static boolean isSlowStartForTesting = false;
+ 
+   /**
+    * Default value for slow starting time of dispatcher
+    */
+   private static final long DEFAULT_SLOW_STARTING_TIME = 5000;
+ 
+   /**
+    * Key in the system property from which the slow starting time value will be
+    * retrieved
+    */
+   private static final String KEY_SLOW_START_TIME_FOR_TESTING = "slowStartTimeForTesting";
+ 
+   private boolean isPrimary;
+   
+   /** @since 5.7 */
+   protected byte clientConflation = HandShake.CONFLATION_DEFAULT;
+   
+   /**
+    * Flag to indicate whether to keep a durable client's queue alive
+    */
+   boolean keepalive = false;
+ 
+   private AccessControl postAuthzCallback;
+ 
+   /**
+    * For multiuser environment..
+    */
+   private ClientUserAuths clientUserAuths;
+   
+   private final Object clientUserAuthsLock = new Object();
+   
+   /**
+    * The version of the client
+    */
+   private Version clientVersion;  
+ 
+   /**
+    * A map of region name as key and integer as its value. Basically, it stores
+    * the names of the regions with <code>DataPolicy</code> as EMPTY. If an 
+    * event's region name is present in this map, it's full value (and not 
+    * delta) is sent to the client represented by this proxy.
+    *
+    * @since 6.1
+    */
+   private volatile Map regionsWithEmptyDataPolicy = new HashMap();
+ 
+   /**
+    * A debug flag used for testing Backward compatibility
+    */
+   public static boolean AFTER_MESSAGE_CREATION_FLAG = false;
+   
+   /**
+    * Notify the region when a client interest registration occurs. This tells
+    * the region to update access time when an update is to be pushed to a
+    * client. It is enabled only for <code>PartitionedRegion</code>s
+    * currently.
+    */
+   protected static final boolean NOTIFY_REGION_ON_INTEREST = Boolean
+       .getBoolean("gemfire.updateAccessTimeOnClientInterest");   
+   
+   /**
+    * The AcceptorImpl identifier to which the proxy is connected.
+    */
+   private final long _acceptorId;
+   
+   /** acceptor's setting for notifyBySubscription */
+   private final boolean notifyBySubscription;
+   
+   /** To queue the events arriving during message dispatcher initialization */ 
+   private volatile ConcurrentLinkedQueue<Conflatable> queuedEvents = new ConcurrentLinkedQueue<Conflatable>();
+   
+   private final Object queuedEventsSync = new Object();
+   
+   private volatile boolean messageDispatcherInit = false;
+ 
+   /**
+    * A counter that keeps track of how many task iterations that have occurred
+    * since the last ping or message. The
+    * {@linkplain CacheClientNotifier#scheduleClientPingTask ping task}
+    * increments it. Normal messages sent to the client reset it. If the counter
+    * reaches 3, a ping is sent.
+    */
+   private final AtomicInteger pingCounter = new AtomicInteger();
+   
+   
+   /** Date on which this instances was created */
+   private Date creationDate;
+ 
+   /** true when the durable client associated with this proxy is being 
+    * restarted and prevents cqs from being closed and drained**/
+   private boolean drainLocked = false;
+   private final Object drainLock = new Object();
+ 
+   /** number of cq drains that are currently in progress **/
+   private int numDrainsInProgress = 0;
+   private final Object drainsInProgressLock = new Object();
+   
+   /**
+    * Constructor.
+    *
+    * @param ccn
+    *          The <code>CacheClientNotifier</code> registering this proxy
+    * @param socket
+    *          The socket between the server and the client
+    * @param proxyID
+    *          representing the Connection Proxy of the clien
+    * @param isPrimary
+    *          The boolean stating whether this prozxy is primary
+    * @throws CacheException {
+    */
+   protected CacheClientProxy(CacheClientNotifier ccn, Socket socket,
+       ClientProxyMembershipID proxyID, boolean isPrimary, byte clientConflation, 
+       Version clientVersion, long acceptorId, boolean notifyBySubscription)
+       throws CacheException {
+     initializeTransientFields(socket, proxyID, isPrimary, clientConflation, clientVersion);
+     this._cacheClientNotifier = ccn;
+     this._cache = (GemFireCacheImpl)ccn.getCache();
+     this._maximumMessageCount = ccn.getMaximumMessageCount();    
+     this._messageTimeToLive = ccn.getMessageTimeToLive();
+     this._acceptorId = acceptorId;
+     this.notifyBySubscription = notifyBySubscription;
+     StatisticsFactory factory = this._cache.getDistributedSystem();
+     this._statistics = new CacheClientProxyStats(factory, 
+         "id_"+this.proxyID.getDistributedMember().getId()+ "_at_"+ this._remoteHostAddress + ":" + this._socket.getPort());
+ 
+     // Create the interest list
+     this.cils[RegisterInterestTracker.interestListIndex] =
+       new ClientInterestList(this, this.proxyID);
+     // Create the durable interest list
+     this.cils[RegisterInterestTracker.durableInterestListIndex] =
+       new ClientInterestList(this, this.getDurableId());
+     this.postAuthzCallback = null;
+     this._cacheClientNotifier.getAcceptorStats().incCurrentQueueConnections();
+     this.creationDate = new Date();
+     initializeClientAuths();
+   }
+   
+   private void initializeClientAuths()
+   {
+     if(AcceptorImpl.isPostAuthzCallbackPresent())
+       this.clientUserAuths = ServerConnection.getClientUserAuths(this.proxyID);
+   }
+ 
+   private void reinitializeClientAuths()
+   {
+     if (this.clientUserAuths != null && AcceptorImpl.isPostAuthzCallbackPresent()) {
+       synchronized (this.clientUserAuthsLock) {
+         ClientUserAuths newClientAuth = ServerConnection.getClientUserAuths(this.proxyID);
+         newClientAuth.fillPreviousCQAuth(this.clientUserAuths);
+         this.clientUserAuths = newClientAuth;
+       }        
+     }
+   }
+   
+   public void setPostAuthzCallback(AccessControl authzCallback) {
+     //TODO:hitesh synchronization
+     synchronized (this.clientUserAuthsLock) {
+       if (this.postAuthzCallback != null)
+         this.postAuthzCallback.close();
+       this.postAuthzCallback = authzCallback;
+     }
+   }
+   
+   public void setCQVsUserAuth(String cqName, long uniqueId, boolean isDurable)
+   {
+     if(postAuthzCallback == null) //only for multiuser
+     {
+       if(this.clientUserAuths != null)
+         this.clientUserAuths.setUserAuthAttributesForCq(cqName, uniqueId, isDurable);
+     }
+   }
+ 
+   private void initializeTransientFields(Socket socket,
+       ClientProxyMembershipID pid, boolean ip,  byte cc, Version vers) {
+     this._socket = socket;
+     this.proxyID = pid;
+     this.connected = true;
+     {
+       int bufSize = 1024;
+       try {
+         bufSize = _socket.getSendBufferSize();
+         if (bufSize < 1024) {
+           bufSize = 1024;
+         }
+       } catch (SocketException ignore) {
+       }
+       this._commBuffer = ServerConnection.allocateCommBuffer(bufSize, socket);
+     }
+     this._remoteHostAddress = socket.getInetAddress().getHostAddress();
+     this.isPrimary = ip;
+     this.clientConflation = cc;
+     this.clientVersion = vers;
+   }
+ 
+   public boolean isMarkerEnqueued() {
+     return markerEnqueued;
+   }
+ 
+   public void setMarkerEnqueued(boolean bool) {
+     markerEnqueued = bool;
+   }
+ 
+   public long getAcceptorId(){
+     return this._acceptorId;
+   }
+ 
+   /**
+    * @return the notifyBySubscription
+    */
+   public boolean isNotifyBySubscription() {
+     return this.notifyBySubscription;
+   }
+ 
+   
+   /**
+    * Returns the DistributedMember represented by this proxy
+    */
+   public ClientProxyMembershipID getProxyID()
+   {
+     return this.proxyID;
+   }
+   
+   // the following code was commented out simply because it was not used
+ //   /**
+ //    * Determines if the proxy represents the client host (and only the host, not
+ //    * necessarily the exact VM running on the host)
+ //    *
+ //    * @return Whether the proxy represents the client host
+ //    */
+ //   protected boolean representsClientHost(String clientHost)
+ //   {
+ //     // [bruce] TODO BUGBUGBUG: this should compare InetAddresses, not Strings
+ //     return this._remoteHostAddress.equals(clientHost);
+ //   }
+ 
+ //   protected boolean representsClientVM(DistributedMember remoteMember)
+ //   {
+ //     // logger.warn("Is input port " + clientPort + " contained in " +
+ //     // logger.warn("Does input host " + clientHost + " equal " +
+ //     // this._remoteHostAddress+ ": " + representsClientHost(clientHost));
+ //     // logger.warn("representsClientVM: " +
+ //     // (representsClientHost(clientHost) && containsPort(clientPort)));
+ //     return (proxyID.getDistributedMember().equals(remoteMember));
+ //   }
+ 
+ //   /**
+ //    * Determines if the CacheClientUpdater proxied by this instance is listening
+ //    * on the input clientHost and clientPort
+ //    *
+ //    * @param clientHost
+ //    *          The host name of the client to compare
+ //    * @param clientPort
+ //    *          The port number of the client to compare
+ //    *
+ //    * @return Whether the CacheClientUpdater proxied by this instance is
+ //    *         listening on the input clientHost and clientPort
+ //    */
+ //   protected boolean representsCacheClientUpdater(String clientHost,
+ //       int clientPort)
+ //   {
+ //     return (clientPort == this._socket.getPort() && representsClientHost(clientHost));
+ //   }
+ 
+   protected boolean isMember(ClientProxyMembershipID memberId)
+   {
+     return this.proxyID.equals(memberId);
+   }
+ 
+   protected boolean isSameDSMember(ClientProxyMembershipID memberId)
+   {
+     return this.proxyID.isSameDSMember(memberId);
+   }
+ 
+   /**
+    * Set the queue keepalive option
+    *
+    * @param option whether to keep the durable client's queue alive
+    */
+   protected void setKeepAlive(boolean option) {
+     this.keepalive = option;
+   }
+ 
+   /**
+    * Returns the socket between the server and the client
+    *
+    * @return the socket between the server and the client
+    */
+   protected Socket getSocket()
+   {
+     return this._socket;
+   }
+   
+   public String getSocketHost()
+   {
+     return this._socket.getInetAddress().getHostAddress();
+   }
+   
+   protected ByteBuffer getCommBuffer() {
+     return this._commBuffer;
+   }
+ 
+   /**
+    * Returns the remote host's IP address string
+    *
+    * @return the remote host's IP address string
+    */
+   protected String getRemoteHostAddress()
+   {
+     return this._remoteHostAddress;
+   }
+ 
+   /**
+    * Returns the remote host's port
+    *
+    * @return the remote host's port
+    */
+   public int getRemotePort()
+   {
+     return this._socket.getPort();
+   }
+ 
+   /**
+    * Returns whether the proxy is connected to a remote client
+    *
+    * @return whether the proxy is connected to a remote client
+    */
+   public boolean isConnected() {
+     return this.connected;
+   }
+ 
+   /**
+    * Mark the receiver as needing removal
+    * @return true if it was already marked for removal
+    */
+   protected boolean startRemoval() {
+     boolean result;
+     synchronized (this.isMarkedForRemovalLock) {
+       result = this.isMarkedForRemoval;
+       this.isMarkedForRemoval = true;
+     }
+     return result;
+   }
+   
+   /**
+    * Wait until the receiver's removal has completed before
+    * returning.
+    * @return true if the proxy was initially marked for removal
+    */
+   protected boolean waitRemoval() {
+     boolean result;
+     synchronized (this.isMarkedForRemovalLock) {
+       result = this.isMarkedForRemoval;
+       boolean interrupted = false;
+       try {
+         while (this.isMarkedForRemoval) {
+           if (logger.isDebugEnabled()) {
+             logger.debug("Waiting for CacheClientProxy removal: {}", this);
+           }
+           try {
+             this.isMarkedForRemovalLock.wait();
+           }
+           catch (InterruptedException e) {
+             interrupted = true;
+             this._cache.getCancelCriterion().checkCancelInProgress(e);
+           }
+         } // while
+       }
+       finally {
+         if (interrupted) {
+           Thread.currentThread().interrupt();
+         }
+       }
+     } // synchronized
+     return result;
+   }
+   
+   /**
+    * Indicate that removal has completed on this instance
+    */
+   protected void notifyRemoval() {
+     synchronized (this.isMarkedForRemovalLock) {
+       this.isMarkedForRemoval = false;
+       this.isMarkedForRemovalLock.notifyAll();
+     }
+   }
+   
+   /**
+    * Returns the GemFire cache
+    *
+    * @return the GemFire cache
+    */
+   public GemFireCacheImpl getCache()
+   {
+     return this._cache;
+   }
+ 
+   public Set<String> getInterestRegisteredRegions() {
+     HashSet<String> regions = new HashSet<String>();
+     for(int i=0; i < this.cils.length; i++){
+       if (!this.cils[i].regions.isEmpty()) {
+         regions.addAll(this.cils[i].regions);
+       }
+     }
+     return regions;
+   }
+   
+   /**
+    * Returns the proxy's statistics
+    *
+    * @return the proxy's statistics
+    */
+   public CacheClientProxyStats getStatistics()
+   {
+     return this._statistics;
+   }
+ 
+   /**
+    * Returns this proxy's <code>CacheClientNotifier</code>.
+    * @return this proxy's <code>CacheClientNotifier</code>
+    */
+   protected CacheClientNotifier getCacheClientNotifier() {
+     return this._cacheClientNotifier;
+   }
+ 
+   /**
+    * Returns the size of the queue for heuristic purposes.  This
+    * size may be changing concurrently if puts/gets are occurring
+    * at the same time.
+    */
+   public int getQueueSize() {
+     return this._messageDispatcher == null ? 0
+         : this._messageDispatcher.getQueueSize();
+   }
+   
+   /** 
+    * returns the queue size calculated through stats
+    */
+   public int getQueueSizeStat() {
+     return this._messageDispatcher == null ? 0
+         : this._messageDispatcher.getQueueSizeStat();  
+   }
+   
+       
+   public boolean drainInProgress() {
+     synchronized(drainsInProgressLock) {
+       return numDrainsInProgress > 0;
+     }
+   }
+   
+   //Called from CacheClientNotifier when attempting to restart paused proxy
+   //locking the drain lock requires that no drains are in progress 
+   //when the lock was acquired.
+   public boolean lockDrain() {
+     synchronized(drainsInProgressLock) {
+       if (!drainInProgress()) {
+         synchronized(drainLock) {
+           if (testHook != null) {
+             testHook.doTestHook("PRE_ACQUIRE_DRAIN_LOCK_UNDER_SYNC");
+           }
+           //prevent multiple lockings of drain lock
+           if (!drainLocked) {
+             drainLocked = true;
+             return true;
+           }
+         }
+       }
+     }
+     return false;
+   }
+   
+   //Called from CacheClientNotifier when completed restart of proxy
+   public void unlockDrain() {
+     if (testHook != null) {
+       testHook.doTestHook("PRE_RELEASE_DRAIN_LOCK");
+     }
+     synchronized(drainLock) {
+       drainLocked = false;
+     }
+   }
+   
+   //Only close the client cq if it is paused and no one is attempting to restart the proxy
+   public boolean closeClientCq(String clientCQName) throws CqException {
+     if (testHook != null) {
+       testHook.doTestHook("PRE_DRAIN_IN_PROGRESS");
+     }
+     synchronized(drainsInProgressLock) {
+       numDrainsInProgress ++;
+     }
+     if (testHook != null) {
+       testHook.doTestHook("DRAIN_IN_PROGRESS_BEFORE_DRAIN_LOCK_CHECK");
+     }
+     try {
+       //If the drain lock was acquired, the other thread did so before we could bump up
+       //the numDrainsInProgress.  That means we need to stop.
+       if (drainLocked) {
+         // someone is trying to restart a paused proxy
+         String msg = LocalizedStrings.CacheClientProxy_COULD_NOT_DRAIN_CQ_DUE_TO_RESTARTING_DURABLE_CLIENT.toLocalizedString(clientCQName, proxyID.getDurableId());
+         logger.info(msg);
+         throw new CqException(msg);
+       }
+       //isConnected is to protect against the case where a durable client has reconnected
+       //but has not yet sent a ready for events message
+       //we can probably remove the isPaused check
+       if (isPaused() && !isConnected()) {
+         CqService cqService = getCache().getCqService();
+         if (cqService != null) {
+           InternalCqQuery  cqToClose = cqService.getCq(cqService.constructServerCqName(
+               clientCQName, this.proxyID));
+           // close and drain
+           if (cqToClose != null) {
+             cqService.closeCq(clientCQName, this.proxyID);
+             this._messageDispatcher.drainClientCqEvents(this.proxyID, cqToClose);
+           }
+           else {
+             String msg = LocalizedStrings.CqService_CQ_NOT_FOUND_FAILED_TO_CLOSE_THE_SPECIFIED_CQ_0.toLocalizedString(clientCQName);
+             logger.info(msg);
+             throw new CqException(msg);
+           }
+         }
+       } else {
+         String msg = LocalizedStrings.CacheClientProxy_COULD_NOT_DRAIN_CQ_DUE_TO_ACTIVE_DURABLE_CLIENT.toLocalizedString(clientCQName, proxyID.getDurableId());
+         logger.info(msg);
+         throw new CqException(msg);
+       }
+     } finally {
+       synchronized (drainsInProgressLock) {
+         numDrainsInProgress--;
+       }
+       if (testHook != null) {
+         testHook.doTestHook("DRAIN_COMPLETE");
+       }
+ 
+     }
+     return true;
+   }
+   
+   
+   /**
+    * Returns whether the proxy is alive. It is alive if its message dispatcher
+    * is processing messages.
+    *
+    * @return whether the proxy is alive
+    */
+   protected boolean isAlive()
+   {
+     if (this._messageDispatcher == null) {
+       return false;
+     }
+     return !this._messageDispatcher.isStopped();
+   }
+ 
+   /**
+    * Returns whether the proxy is paused. It is paused if its message dispatcher
+    * is paused. This only applies to durable clients.
+    *
+    * @return whether the proxy is paused
+    *
+    * @since 5.5
+    */
+   protected boolean isPaused() {
+     return this._isPaused;
+   }
+ 
+   protected void setPaused(boolean isPaused) {
+     this._isPaused = isPaused;
+   }
+ 
+   /**
+    * Closes the proxy. This method checks the message queue for any unprocessed
+    * messages and processes them for MAXIMUM_SHUTDOWN_PEEKS.
+    *
+    * @see CacheClientProxy#MAXIMUM_SHUTDOWN_PEEKS
+    */
+   protected void close()
+   {
+     close(true, false);
+   }
+ 
+   /**
+    * Set to true once this proxy starts being closed.
+    * Remains true for the rest of its existence.
+    */
+   private final AtomicBoolean closing = new AtomicBoolean(false);
+ 
+   /**
+    * Close the <code>CacheClientProxy</code>.
+    *
+    * @param checkQueue
+    *          Whether to message check the queue and process any contained
+    *          messages (up to MAXIMUM_SHUTDOWN_PEEKS).
+    * @param stoppedNormally
+    *          Whether client stopped normally
+    *
+    * @return whether to keep this <code>CacheClientProxy</code>
+    * @see CacheClientProxy#MAXIMUM_SHUTDOWN_PEEKS
+    */
+   protected boolean close(boolean checkQueue, boolean stoppedNormally) {
+     boolean pauseDurable = false;
+     // If the client is durable and either (a) it hasn't stopped normally or (b) it
+     // has stopped normally but it is configured to be kept alive, set pauseDurable
+     // to true
+     if (isDurable()
+         && (!stoppedNormally || (getDurableKeepAlive() && stoppedNormally))) {
+       pauseDurable = true;
+     }
+ 
+     boolean keepProxy = false;
+     if (pauseDurable) {
+       pauseDispatching();
+       keepProxy = true;
+     } else {
+       terminateDispatching(checkQueue);
+       closeTransientFields();
+     }
+ 
+     this.connected = false;
+ 
+     // Close the Authorization callback (if any)
+     try {
+       if (!pauseDurable) {
+         if (this.postAuthzCallback != null) {//for single user
+           this.postAuthzCallback.close();
+           this.postAuthzCallback = null;
+         }else if(this.clientUserAuths != null) {//for multiple users
+           this.clientUserAuths.cleanup(true);
+           this.clientUserAuths = null;
+         }
+       }
+     }
+     catch (Exception ex) {
+       if (this._cache.getSecurityLoggerI18n().warningEnabled()) {
+         this._cache.getSecurityLoggerI18n().warning(LocalizedStrings.TWO_ARG_COLON, new Object[] {this, ex});
+       }
+     }
+     // Notify the caller whether to keep this proxy. If the proxy is durable
+     // and should be paused, then return true; otherwise return false.
+     return keepProxy;
+   }
+ 
+   protected void pauseDispatching() {
+     if (this._messageDispatcher == null){
+       return;
+     }
+ 
+     // If this is the primary, pause the dispatcher (which closes its transient
+     // fields. Otherwise, just close the transient fields.
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Pausing processing", this);
+     }
+     //BUGFIX for BUG#38234
+     if(!testAndSetPaused(true) && this.isPrimary) {
+       if (this._messageDispatcher != Thread.currentThread()) {
+         // don't interrupt ourself to fix bug 40611
+         this._messageDispatcher.interrupt();
+       }
+     }
+ 
+     try {
+       // Close transient fields
+       closeTransientFields();
+     } finally {
+       // make sure this gets called if closeTransientFields throws; see bug 40611
+       // Start timer
+       scheduleDurableExpirationTask();
+     }
+   }
+ 
+   private boolean testAndSetPaused(boolean newValue) {
+     
+     synchronized(this._messageDispatcher._pausedLock) {
+       if (this._isPaused != newValue) {
+         this._isPaused = newValue;
+         this._messageDispatcher._pausedLock.notifyAll();
+         return !this._isPaused;
+       }
+       else {
+         this._messageDispatcher._pausedLock.notifyAll();
+         return this._isPaused;
+       }
+     }
+   }
+   protected void terminateDispatching(boolean checkQueue) {
+     if (this._messageDispatcher == null){
+       return;
+     }
+     
+     try {
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Terminating processing", this);
+     }
+     if (this._messageDispatcher == Thread.currentThread()) {
+       // I'm not even sure this is possible but if the dispatcher
+       // calls us then at least call stopDispatching
+       // the old code did this (I'm not even sure it is safe to do).
+       // This needs to be done without testing OR setting "closing".
+       this._messageDispatcher.stopDispatching(checkQueue);
+       this.cils[RegisterInterestTracker.interestListIndex].clearClientInterestList();
+       this.cils[RegisterInterestTracker.durableInterestListIndex].clearClientInterestList();
+       // VJR: bug 37487 fix
+       destroyRQ();
+       return;
+     }
+ 
+     if (!this.closing.compareAndSet(false, true)) {
+       // must already be closing so just return
+       // this is part of the fix for 37684
+       return;
+     }
+     // Unregister interest in all interests (if necessary) 
+     this.cils[RegisterInterestTracker.interestListIndex].clearClientInterestList();
+     this.cils[RegisterInterestTracker.durableInterestListIndex].clearClientInterestList();
+ 
+     // If the message dispatcher is paused, unpause it. The next bit of
+     // code will interrupt the waiter.
+     if (this.testAndSetPaused(false)) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Paused but terminating processing", this);
+       }
+       // Cancel the expiration task
+       cancelDurableExpirationTask(false);
+     }
+ 
+     boolean alreadyDestroyed = false;
+     boolean gotInterrupt = Thread.interrupted(); // clears the flag
+     try {
+       // Stop the message dispatcher
+       this._messageDispatcher.stopDispatching(checkQueue);
+ 
+       gotInterrupt |= Thread.interrupted(); // clears the flag
+ 
+       // to fix bug 37684
+       // 1. check to see if dispatcher is still alive
+       if (this._messageDispatcher.isAlive()) {
+         closeSocket();
+         destroyRQ();
+         alreadyDestroyed = true;
+         this._messageDispatcher.interrupt();
+         if (this._messageDispatcher.isAlive()) {
+           try {
+             this._messageDispatcher.join(1000);
+           } catch (InterruptedException ex) {
+             gotInterrupt = true;
+           }
+           // if it is still alive then warn and move on
+           if (this._messageDispatcher.isAlive()) {
+             //com.gemstone.gemfire.internal.OSProcess.printStacks(com.gemstone.gemfire.internal.OSProcess.getId());
+             logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0_COULD_NOT_STOP_MESSAGE_DISPATCHER_THREAD, this));
+           }
+         }
+       }
+     }
+     finally {
+       if (gotInterrupt) {
+         Thread.currentThread().interrupt();
+       }
+       if (!alreadyDestroyed) {
+         destroyRQ();
+       }
+     }
+     } finally {
+       //  Close the statistics
+       this._statistics.close(); // fix for bug 40105
+       closeTransientFields(); // make sure this happens
+     }
+   }
+ 
+   private void closeSocket() {
+     if (this._socketClosed.compareAndSet(false, true)) {
+       // Close the socket
+       this._cacheClientNotifier.getSocketCloser().asyncClose(this._socket, this._remoteHostAddress, null);
+       getCacheClientNotifier().getAcceptorStats().decCurrentQueueConnections();
+     }
+   }
+   
+   private void closeTransientFields() {
+     closeSocket();
+ 
+     // Null out comm buffer, host address, ports and proxy id. All will be
+     // replaced when the client reconnects.
+     releaseCommBuffer();
+     {
+       String remoteHostAddress = this._remoteHostAddress;
+       if (remoteHostAddress != null) {
+         this._cacheClientNotifier.getSocketCloser().releaseResourcesForAddress(remoteHostAddress);
+         this._remoteHostAddress = null;
+       }
+     }
+     try {
+       this.cils[RegisterInterestTracker.interestListIndex].clearClientInterestList();
+     } catch (CacheClosedException e) {
+       // ignore if cache is shutting down
+     }
+     // Commented to fix bug 40259
+     //this.clientVersion = null;
+     closeNonDurableCqs();    
+   }
+   
+   private void releaseCommBuffer() {
+     ByteBuffer bb = this._commBuffer;
+     if (bb != null) {
+       this._commBuffer = null;
+       ServerConnection.releaseCommBuffer(bb);
+     }
+   }
+ 
+   private void closeNonDurableCqs(){
+     CqService cqService = getCache().getCqService();
+     if (cqService != null) {
+       try {
+         cqService.closeNonDurableClientCqs(getProxyID());
+       }
+       catch (CqException ex) {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_CQEXCEPTION_WHILE_CLOSING_NON_DURABLE_CQS_0, ex.getLocalizedMessage()));
+       }
+     }
+   }
+   
+   private void destroyRQ() {
+     if (this._messageDispatcher == null) {
+       return;
+     }
+     try {
+       // Using Destroy Region bcoz this method is modified in HARegion so as
+       // not to distribute.
+       // For normal Regions , even the localDestroyRegion actually propagates
+       HARegionQueue rq = this._messageDispatcher._messageQueue;
+       rq.destroy();
+ 
+       // if (!rq.getRegion().isDestroyed()) {
+       // rq.getRegion().destroyRegion();
+       // }
+     }
+     catch (RegionDestroyedException rde) {
+ //      throw rde;
+     }
+     catch (CancelException e) {
+ //      throw e;
+     }
+     catch (Exception warning) {
+       logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0_EXCEPTION_IN_CLOSING_THE_UNDERLYING_HAREGION_OF_THE_HAREGIONQUEUE, this), warning);
+     }
+   }
+ 
+   public void registerInterestRegex(String regionName, String regex,
+       boolean isDurable) {
+     registerInterestRegex(regionName, regex, isDurable, true);
+   }
+   
+   public void registerInterestRegex(String regionName, String regex,
+       boolean isDurable, boolean receiveValues) {
+     if (this.isPrimary) {
+       // Notify all secondaries and client of change in interest
+       notifySecondariesAndClient(regionName, regex, InterestResultPolicy.NONE,
+           isDurable, receiveValues, InterestType.REGULAR_EXPRESSION);
+     } else {
+       throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
+     }
+   }
+ 
+   public void registerInterest(String regionName, Object keyOfInterest,
+       InterestResultPolicy policy, boolean isDurable) {
+     registerInterest(regionName, keyOfInterest, policy, isDurable, true);
+   }
+   
+   public void registerInterest(String regionName, Object keyOfInterest,
+       InterestResultPolicy policy, boolean isDurable,
+       boolean receiveValues) {
+     if (keyOfInterest instanceof String && keyOfInterest.equals("ALL_KEYS")) {
+       registerInterestRegex(regionName, ".*", isDurable, receiveValues);
+     } else if (keyOfInterest instanceof List) {
+       if (this.isPrimary) {
+         notifySecondariesAndClient(regionName, keyOfInterest, policy,
+             isDurable, receiveValues, InterestType.KEY);
+       } else {
+         throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
+       }
+     } else {
+       if (this.isPrimary) {
+         // Notify all secondaries and client of change in interest
+         notifySecondariesAndClient(regionName, keyOfInterest, policy,
+             isDurable, receiveValues, InterestType.KEY);
+         
+         // Enqueue the initial value message for the client if necessary
+         if (policy == InterestResultPolicy.KEYS_VALUES) {
+           Get70 request = (Get70)Get70.getCommand();
+           LocalRegion lr = (LocalRegion) this._cache.getRegion(regionName);
+           Get70.Entry entry = request.getValueAndIsObject(lr, keyOfInterest, null,
+               null);
+           boolean isObject = entry.isObject;
+           byte[] value = null;
+           if (entry.value instanceof byte[]) {
+             value = (byte[])entry.value;
+           } else {
+             try {
+               value = CacheServerHelper.serialize(entry.value);
+             } catch (IOException e) {
+               logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_THE_FOLLOWING_EXCEPTION_OCCURRED_0, entry.value), e);
+             }
+           }
+           VersionTag tag = entry.versionTag;
+           ClientUpdateMessage updateMessage = new ClientUpdateMessageImpl(
+               EnumListenerEvent.AFTER_CREATE, lr, keyOfInterest, value, null,
+               (isObject ? (byte) 0x01 : (byte) 0x00), null, this.proxyID,
+               new EventID(this._cache.getDistributedSystem()), tag);
+           CacheClientNotifier.routeSingleClientMessage(updateMessage, this.proxyID);
+         }
+         // Add the client to the region's filters
+         //addFilterRegisteredClients(regionName, keyOfInterest);
+       } else {
+         throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
+       }
+     }
+   }
+ 
+   private void notifySecondariesAndClient(String regionName,
+       Object keyOfInterest, InterestResultPolicy policy, boolean isDurable,
+       boolean receiveValues, int interestType) {
+     // Create a client interest message for the keyOfInterest
+     ClientInterestMessageImpl message = new ClientInterestMessageImpl(
+         new EventID(this._cache.getDistributedSystem()), regionName,
+         keyOfInterest, interestType, policy.getOrdinal(), isDurable,
+         !receiveValues, ClientInterestMessageImpl.REGISTER);
+ 
+     // Notify all secondary proxies of a change in interest
+     notifySecondariesOfInterestChange(message);
+ 
+     // Modify interest registration
+     if (keyOfInterest instanceof List) {
+       registerClientInterestList(regionName, (List) keyOfInterest, isDurable,
+           !receiveValues, true);
+     } else {
+       registerClientInterest(regionName, keyOfInterest, interestType,
+           isDurable, !receiveValues, true);
+     }
+ 
+     // Enqueue the interest registration message for the client.
+     // If the client is not 7.0.1 or greater and the key of interest is a list,
+     // then create an individual message for each entry in the list since the
+     // client doesn't support a ClientInterestMessageImpl containing a list.
+     if (Version.GFE_701.compareTo(this.clientVersion) > 0
+         && keyOfInterest instanceof List) {
+       for (Iterator i = ((List) keyOfInterest).iterator(); i.hasNext();) {
+         this._messageDispatcher.enqueueMessage(new ClientInterestMessageImpl(
+             new EventID(this._cache.getDistributedSystem()), regionName,
+             i.next(), interestType, policy.getOrdinal(), isDurable, !receiveValues,
+             ClientInterestMessageImpl.REGISTER));
+      }
+     } else {
+       this._messageDispatcher.enqueueMessage(message);
+     }
+   }
+ 
+   public void unregisterInterestRegex(String regionName, String regex,
+       boolean isDurable) {
+     unregisterInterestRegex(regionName, regex, isDurable, true);
+   }
+   
+   public void unregisterInterestRegex(String regionName, String regex,
+       boolean isDurable, boolean receiveValues) {
+     if (this.isPrimary) {
+       notifySecondariesAndClient(regionName, regex, isDurable, receiveValues,
+           InterestType.REGULAR_EXPRESSION);
+     } else {
+       throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
+     }
+   }
+   
+   public void unregisterInterest(String regionName, Object keyOfInterest,
+       boolean isDurable) {
+     unregisterInterest(regionName, keyOfInterest, isDurable, true);
+   }
+   
+   public void unregisterInterest(String regionName, Object keyOfInterest,
+       boolean isDurable, boolean receiveValues) {
+     if (keyOfInterest instanceof String && keyOfInterest.equals("ALL_KEYS")) {
+       unregisterInterestRegex(regionName, ".*", isDurable, receiveValues);
+     } else {
+       if (this.isPrimary) {
+         notifySecondariesAndClient(regionName, keyOfInterest, isDurable,
+             receiveValues, InterestType.KEY);
+       } else {
+         throw new IllegalStateException(LocalizedStrings.CacheClientProxy_NOT_PRIMARY.toLocalizedString());
+       }
+     }
+   }
+ 
+   private void notifySecondariesAndClient(String regionName,
+       Object keyOfInterest, boolean isDurable, boolean receiveValues,
+       int interestType) {
+     // Notify all secondary proxies of a change in interest
+     ClientInterestMessageImpl message = new ClientInterestMessageImpl(
+         new EventID(this._cache.getDistributedSystem()), regionName,
+         keyOfInterest, interestType, (byte) 0, isDurable, !receiveValues,
+         ClientInterestMessageImpl.UNREGISTER);
+     notifySecondariesOfInterestChange(message);
+  
+     // Modify interest registration
+     if (keyOfInterest instanceof List) {
+       unregisterClientInterest(regionName, (List) keyOfInterest, false);
+     } else {
+       unregisterClientInterest(regionName, keyOfInterest, interestType,
+           false);
+     }
+  
+     // Enqueue the interest unregistration message for the client.
+     // If the client is not 7.0.1 or greater and the key of interest is a list,
+     // then create an individual message for each entry in the list since the
+     // client doesn't support a ClientInterestMessageImpl containing a list.
+     if (Version.GFE_701.compareTo(this.clientVersion) > 0
+         && keyOfInterest instanceof List) {
+       for (Iterator i = ((List) keyOfInterest).iterator(); i.hasNext();) {
+         this._messageDispatcher.enqueueMessage(new ClientInterestMessageImpl(
+             new EventID(this._cache.getDistributedSystem()), regionName,
+             i.next(), interestType, (byte) 0, isDurable, !receiveValues,
+             ClientInterestMessageImpl.UNREGISTER));
+       }
+     } else {
+       this._messageDispatcher.enqueueMessage(message);
+     }
+   }
+   
+   protected void notifySecondariesOfInterestChange(ClientInterestMessageImpl message) {
+     if (logger.isDebugEnabled()) {
+       StringBuffer subBuffer = new StringBuffer();
+       if (message.isRegister()) {
+         subBuffer
+           .append("register ")
+           .append(message.getIsDurable() ? "" : "non-")
+           .append("durable interest in ");
+       } else {
+         subBuffer.append("unregister interest in ");
+       }
+       StringBuffer buffer = new StringBuffer();
+       buffer
+         .append(this)
+         .append(": Notifying secondary proxies to ")
+         .append(subBuffer.toString())
+         .append(message.getRegionName())
+         .append("->")
+         .append(message.getKeyOfInterest())
+         .append("->")
+         .append(InterestType.getString(message.getInterestType()));
+       logger.debug(buffer.toString());
+     }
+     this._cacheClientNotifier.deliverInterestChange(this.proxyID, message);
+   }
+ 
+   /*
+   protected void addFilterRegisteredClients(String regionName,
+       Object keyOfInterest) {
+     try {
+       this._cacheClientNotifier.addFilterRegisteredClients(regionName,
+           this.proxyID);
+     } catch (RegionDestroyedException e) {
+       logger.warn(LocalizedStrings.CacheClientProxy_0_INTEREST_REG_FOR_0_FAILED, regionName + "->" + keyOfInterest, e);
+     }
+   }
+   */
+   
+   /**
+    * Registers interest in the input region name and key
+    *
+    * @param regionName
+    *          The fully-qualified name of the region in which to register
+    *          interest
+    * @param keyOfInterest
+    *          The key in which to register interest
+    */
+   protected void registerClientInterest(String regionName,
+       Object keyOfInterest, int interestType, boolean isDurable,
+       boolean sendUpdatesAsInvalidates, boolean flushState)
+   {
+     ClientInterestList cil =
+       this.cils[RegisterInterestTracker.getInterestLookupIndex(
+           isDurable, false)];
+     cil.registerClientInterest(regionName, keyOfInterest, interestType, sendUpdatesAsInvalidates);
+     if (flushState) {
+       flushForInterestRegistration(regionName, this._cache.getDistributedSystem().getDistributedMember());
+     }
+     HARegionQueue queue = getHARegionQueue();
+     if (queue != null) { // queue is null during initialization
+       queue.setHasRegisteredInterest(true);
+     }
+   }
+   
+   /**
+    * flush other regions to the given target.  This is usually the member
+    * that is registering the interest.  During queue creation it is the
+    * queue's image provider.
+    */
+   public void flushForInterestRegistration(String regionName, DistributedMember target) {
+     Region r = this._cache.getRegion(regionName);
+     if (r == null) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("Unable to find region '{}' to flush for interest registration", regionName);
+       }
+     } else if (r.getAttributes().getScope().isDistributed()) {
+       if (logger.isDebugEnabled()){
+         logger.debug("Flushing region '{}' for interest registration", regionName);
+       }
+       CacheDistributionAdvisee cd = (CacheDistributionAdvisee)r;
+       final StateFlushOperation sfo;
+       if (r instanceof PartitionedRegion) {
+         // need to flush all buckets.  SFO should be changed to target buckets
+         // belonging to a particular PR, but it doesn't have that option right now
+         sfo = new StateFlushOperation(
+             this._cache.getDistributedSystem().getDistributionManager());
+       } else {
+         sfo = new StateFlushOperation((DistributedRegion)r);
+       }
+       try {
+         // bug 41681 - we need to flush any member that may have a cache operation
+         // in progress so that the changes are received there before returning
+         // from this method
+         InitialImageAdvice advice = cd.getCacheDistributionAdvisor().adviseInitialImage(null);
+         HashSet recips = new HashSet(advice.getReplicates());
+         recips.addAll(advice.getUninitialized());
+         recips.addAll(advice.getEmpties());
+         recips.addAll(advice.getPreloaded());
+         recips.addAll(advice.getOthers());
+         sfo.flush(recips,
+             target,
+             DistributionManager.HIGH_PRIORITY_EXECUTOR, true);
+       } catch (InterruptedException ie) {
+         Thread.currentThread().interrupt();
+         return;
+       }
+     }
+   }
+ 
+   /**
+    * Unregisters interest in the input region name and key
+    *
+    * @param regionName
+    *          The fully-qualified name of the region in which to unregister
+    *          interest
+    * @param keyOfInterest
+    *          The key in which to unregister interest
+    * @param isClosing
+    *          Whether the caller is closing
+    */
+   protected void unregisterClientInterest(String regionName,
+       Object keyOfInterest, int interestType, boolean isClosing)
+   {
+     // only unregister durable interest if isClosing and !keepalive
+     if (!isClosing /* explicit unregister */
+         || !getDurableKeepAlive() /* close and no keepAlive*/) {
+       this.cils[RegisterInterestTracker.durableInterestListIndex].
+         unregisterClientInterest(regionName, keyOfInterest, interestType);
+     }
+     // always unregister non durable interest
+     this.cils[RegisterInterestTracker.interestListIndex].
+       unregisterClientInterest(regionName, keyOfInterest, interestType);
+   }
+ 
+   /**
+    * Registers interest in the input region name and list of keys
+    *
+    * @param regionName
+    *          The fully-qualified name of the region in which to register
+    *          interest
+    * @param keysOfInterest
+    *          The list of keys in which to register interest
+    */
+   protected void registerClientInterestList(String regionName,
+       List keysOfInterest, boolean isDurable, boolean sendUpdatesAsInvalidates,
+       boolean flushState)
+   {
+     // we only use two interest lists to map the non-durable and durable
+     // identifiers to their interest settings
+     ClientInterestList cil =
+       this.cils[RegisterInterestTracker.getInterestLookupIndex(
+           isDurable, false/*sendUpdatesAsInvalidates*/)];
+     cil.registerClientInterestList(regionName, keysOfInterest, sendUpdatesAsInvalidates);
+     if (getHARegionQueue() != null) {
+       if (flushState) {
+         flushForInterestRegistration(regionName, this._cache.getDistributedSystem().getDistributedMember());
+       }
+       getHARegionQueue().setHasRegisteredInterest(true);
+     }
+   }
+ 
+   /**
+    * Unregisters interest in the input region name and list of keys
+    *
+    * @param regionName
+    *          The fully-qualified name of the region in which to unregister
+    *          interest
+    * @param keysOfInterest
+    *          The list of keys in which to unregister interest
+    * @param isClosing
+    *          Whether the caller is closing
+    */
+   protected void unregisterClientInterest(String regionName,
+       List keysOfInterest, boolean isClosing)
+   {
+     // only unregister durable interest if isClosing and !keepalive
+     if (!isClosing /* explicit unregister */
+         || !getDurableKeepAlive() /* close and no keepAlive*/) {
+       this.cils[RegisterInterestTracker.durableInterestListIndex].
+         unregisterClientInterestList(regionName, keysOfInterest);
+     }
+     // always unregister non durable interest
+     this.cils[RegisterInterestTracker.interestListIndex].
+       unregisterClientInterestList(regionName, keysOfInterest);
+   }
+ 
+ 
+   /** sent by the cache client notifier when there is an interest registration change */
+   protected void processInterestMessage(ClientInterestMessageImpl message) { 
+     int interestType = message.getInterestType(); 
+     String regionName = message.getRegionName(); 
+     Object key = message.getKeyOfInterest(); 
+     if (message.isRegister()) {
+       // Register interest in this region->key
+       if (key instanceof List) {
+         registerClientInterestList(regionName, (List) key,
+             message.getIsDurable(), message.getForUpdatesAsInvalidates(), true);
+       } else {
+         registerClientInterest(regionName, key, interestType,
+             message.getIsDurable(), message.getForUpdatesAsInvalidates(), true);
+       }
+        
+       // Add the client to the region's filters 
+       //addFilterRegisteredClients(regionName, key); 
+  
+       if (logger.isDebugEnabled()) { 
+         StringBuffer buffer = new StringBuffer();
+         buffer 
+           .append(this) 
+           .append(": Interest listener registered ") 
+           .append(message.getIsDurable() ? "" : "non-") 
+           .append("durable interest in ") 
+           .append(message.getRegionName()) 
+           .append("->") 
+           .append(message.getKeyOfInterest())
+           .append("->")
+           .append(InterestType.getString(message.getInterestType()));
+         logger.debug(buffer.toString()); 
+       } 
+     } else { 
+       // Unregister interest in this region->key 
+       if (key instanceof List) {
+         unregisterClientInterest(regionName, (List) key, false);
+       } else {
+         unregisterClientInterest(regionName, key, interestType, false);
+       }
+        
+       if (logger.isDebugEnabled()) { 
+         StringBuffer buffer = new StringBuffer(); 
+         buffer 
+           .append(this) 
+           .append(": Interest listener unregistered interest in ") 
+           .append(message.getRegionName()) 
+           .append("->") 
+           .append(message.getKeyOfInterest())
+           .append("->")
+           .append(InterestType.getString(message.getInterestType()));
+         logger.debug(buffer.toString()); 
+       } 
+     } 
+   } 
+ 
+   private boolean postDeliverAuthCheckPassed(ClientUpdateMessage clientMessage) {
+     // Before adding it in the queue for dispatching, check for post
+     // process authorization
+     if (AcceptorImpl.isAuthenticationRequired()
+         && this.postAuthzCallback == null
+         && AcceptorImpl.isPostAuthzCallbackPresent()) {
+       // security is on and callback is null: it means multiuser mode.
+       ClientUpdateMessageImpl cumi = (ClientUpdateMessageImpl)clientMessage;
+ 
+       CqNameToOp clientCq = cumi.getClientCq(this.proxyID);
+ 
+       if (clientCq != null && !clientCq.isEmpty()) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("CCP clientCq size before processing auth {}", clientCq.size());
+         }
+         String[] regionNameHolder = new String[1];
+         OperationContext opctxt = getOperationContext(clientMessage,
+             regionNameHolder);
+         if (opctxt == null) {
+           logger.warn(LocalizedMessage.create(
+               LocalizedStrings.CacheClientProxy__0_NOT_ADDING_MESSAGE_TO_QUEUE_1_BECAUSE_THE_OPERATION_CONTEXT_OBJECT_COULD_NOT_BE_OBTAINED_FOR_THIS_CLIENT_MESSAGE,
+               new Object[] {this, clientMessage}));
+           return false;
+         }
+ 
+         String[] cqNames = clientCq.getNames();
+         if (logger.isDebugEnabled()) {
+           logger.debug("CCP clientCq names array size {}", cqNames.length);
+         }
+         for (int i = 0; i < cqNames.length; i++) {
+           try {
+             if (logger.isDebugEnabled()) {
+               logger.debug("CCP clientCq name {}", cqNames[i]);
+             }
+             boolean isAuthorized = false;
+ 
+             if (this.proxyID.isDurable() && this.getDurableKeepAlive()
+                 && this._isPaused) {
+               // need to take lock as we may be reinitializing proxy cache
+               synchronized (this.clientUserAuthsLock) {
+                 AuthorizeRequestPP postAuthCallback = this.clientUserAuths
+                     .getUserAuthAttributes(cqNames[i]).getPostAuthzRequest();
+                 if (logger.isDebugEnabled() && postAuthCallback == null) {
+                   logger.debug("CCP clientCq post callback is null");
+                 }
+                 if (postAuthCallback != null && postAuthCallback
+                     .getPostAuthzCallback().authorizeOperation(
+                         regionNameHolder[0], opctxt)) {
+                   isAuthorized = true;
+                 }
+               }
+             } else {
+               UserAuthAttributes userAuthAttributes = this.clientUserAuths
+                   .getUserAuthAttributes(cqNames[i]);
+ 
+               AuthorizeRequestPP postAuthCallback = userAuthAttributes
+                   .getPostAuthzRequest();
+               if (postAuthCallback == null && logger.isDebugEnabled()) {
+                 logger.debug("CCP clientCq post callback is null");
+               }
+               if (postAuthCallback != null && postAuthCallback
+                   .getPostAuthzCallback().authorizeOperation(
+                       regionNameHolder[0], opctxt)) {
+                 isAuthorized = true;
+               }
+             }
+ 
+             if (!isAuthorized) {
+               logger.warn(LocalizedMessage.create(
+                   LocalizedStrings.CacheClientProxy__0_NOT_ADDING_CQ_MESSAGE_TO_QUEUE_1_BECAUSE_AUTHORIZATION_FAILED,
+                   new Object[] {this, clientMessage}));
+               clientCq.delete(cqNames[i]);
+             }
+           } catch (Exception ex) {
+             // ignore...
+           }
+           if (logger.isDebugEnabled()) {
+             logger.debug("CCP clientCq size after processing auth {}", clientCq.size());
+           }
+         }
+         // again need to check as there may be no CQ available
+         if (!clientMessage.hasCqs(this.proxyID)) {
+           this._statistics.incMessagesNotQueuedNotInterested();
+           if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
+             logger.debug("{}: Not adding message to queue. It is not interested in this region and key: {}", clientMessage);
+           }
+           return false;
+         }
+       }
+     }
+     else if (this.postAuthzCallback != null) {
+       String[] regionNameHolder = new String[1];
+       boolean isAuthorize = false;
+       OperationContext opctxt = getOperationContext(clientMessage,
+           regionNameHolder);
+       if (opctxt == null) {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy__0_NOT_ADDING_MESSAGE_TO_QUEUE_1_BECAUSE_THE_OPERATION_CONTEXT_OBJECT_COULD_NOT_BE_OBTAINED_FOR_THIS_CLIENT_MESSAGE, new Object[] {this, clientMessage}));
+         return false;
+       }
+       if (logger.isTraceEnabled()){
+         logger.trace("{}: Invoking authorizeOperation for message: {}", this, clientMessage);
+       }
+ 
+       if (this.proxyID.isDurable() && this.getDurableKeepAlive()
+           && this._isPaused) {
+         synchronized (this.clientUserAuthsLock) {
+           isAuthorize = this.postAuthzCallback.authorizeOperation(
+               regionNameHolder[0], opctxt);
+         }
+       } else {
+         isAuthorize = this.postAuthzCallback.authorizeOperation(
+             regionNameHolder[0], opctxt);
+       }
+       if (!isAuthorize) {
+         logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy__0_NOT_ADDING_MESSAGE_TO_QUEUE_1_BECAUSE_AUTHORIZATION_FAILED, new Object[] {this, clientMessage}));
+         return false;
+       }
+     }
+ 
+     return true;
+   }
+ 
+   /**
+    * Delivers the message to the client representing this client proxy.
+    * @param conflatable 
+    */
+   protected void deliverMessage(Conflatable conflatable)
+   {
+     ClientUpdateMessage clientMessage = null;
+     if(conflatable instanceof HAEventWrapper) {
+       clientMessage = ((HAEventWrapper)conflatable).getClientUpdateMessage();
+     } else {
+       clientMessage = (ClientUpdateMessage)conflatable;
+     } 
+ 
+     this._statistics.incMessagesReceived();
+ 
+     if (clientMessage.needsNoAuthorizationCheck() || postDeliverAuthCheckPassed(clientMessage)) {
+       // If dispatcher is getting initialized, add the event to temporary queue.
+       if (this.messageDispatcherInit) {
+         synchronized (this.queuedEventsSync) {
+           if (this.messageDispatcherInit) {  // Check to see value did not changed while getting the synchronize lock.
+             if (logger.isDebugEnabled()) {
+               logger.debug("Message dispatcher for proxy {} is getting initialized. Adding message to the queuedEvents.", this);
+             }
+             this.queuedEvents.add(conflatable);
+             return;
+           }
+         }
+       }
+       
+       if (this._messageDispatcher != null) {
+         this._messageDispatcher.enqueueMessage(conflatable);
+       } else {
+         this._statistics.incMessagesFailedQueued();
+         if (logger.isDebugEnabled()) {
+           logger.debug("Message is not added to the queue. Message dispatcher for proxy: {} doesn't exist.", this);
+         }
+       }
+     } else {
+       this._statistics.incMessagesFailedQueued();
+     }
+   }
+ 
+   protected void sendMessageDirectly(ClientMessage message) {
+     // Send the message directly if the connection exists
+     // (do not go through the queue).
+     if (logger.isDebugEnabled()){
+       logger.debug("About to send message directly to {}", this);
+     }
+     if (this._messageDispatcher != null && this._socket != null && !this._socket.isClosed()) {
+       // If the socket is open, send the message to it
+       this._messageDispatcher.sendMessageDirectly(message);
+       if (logger.isDebugEnabled()){
+         logger.debug("Sent message directly to {}", this);
+       }
+     } else {
+       // Otherwise just reset the ping counter
+       resetPingCounter();
+       if (logger.isDebugEnabled()){
+         logger.debug("Skipped sending message directly to {}", this);
+       }
+     }
+   }
+   
+   private OperationContext getOperationContext(ClientMessage cmsg,
+       String[] regionNameHolder) {
+     ClientUpdateMessageImpl cmsgimpl = (ClientUpdateMessageImpl)cmsg;
+     OperationContext opctxt = null;
+     // TODO SW: Special handling for DynamicRegions; this should be reworked
+     // when DynamicRegion API is deprecated
+     String regionName = cmsgimpl.getRegionName();
+     regionNameHolder[0] = regionName;
+     if (cmsgimpl.isCreate()) {
+       if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
+         regionNameHolder[0] = (String)cmsgimpl.getKeyOfInterest();
+         opctxt = new RegionCreateOperationContext(true);
+       }
+       else {
+         PutOperationContext tmp = new PutOperationContext(cmsgimpl.getKeyOfInterest(), cmsgimpl
+             .getValue(), cmsgimpl.valueIsObject(), PutOperationContext.CREATE,
+             true);
+         tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
+         opctxt = tmp;
+       }
+     }
+     else if (cmsgimpl.isUpdate()) {
+       if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
+         regionNameHolder[0] = (String)cmsgimpl.getKeyOfInterest();
+         opctxt = new RegionCreateOperationContext(true);
+       }
+       else {
+         PutOperationContext tmp = new PutOperationContext(cmsgimpl.getKeyOfInterest(), cmsgimpl
+             .getValue(), cmsgimpl.valueIsObject(), PutOperationContext.UPDATE,
+             true);
+         tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
+         opctxt = tmp;
+       }
+     }
+     else if (cmsgimpl.isDestroy()) {
+       if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
+         regionNameHolder[0] = (String)cmsgimpl.getKeyOfInterest();
+         opctxt = new RegionDestroyOperationContext(true);
+       }
+       else {
+         DestroyOperationContext tmp = new DestroyOperationContext(cmsgimpl.getKeyOfInterest(), true);
+         tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
+         opctxt = tmp;
+       }
+     }
+     else if (cmsgimpl.isDestroyRegion()) {
+       opctxt = new RegionDestroyOperationContext(true);
+     }
+     else if (cmsgimpl.isInvalidate()) {
+       InvalidateOperationContext tmp = new InvalidateOperationContext(cmsgimpl.getKeyOfInterest(), true);
+       tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
+       opctxt = tmp;
+     }
+     else if (cmsgimpl.isClearRegion()) {
+       RegionClearOperationContext tmp = new RegionClearOperationContext(true);
+       tmp.setCallbackArg(cmsgimpl.getCallbackArgument());
+       opctxt = tmp;
+     }
+     return opctxt;
+   }
+ 
+   /**
+    * Initializes the message dispatcher thread. The
+    * <code>MessageDispatcher</code> processes the message queue.
+    *
+    * @throws CacheException
+    */
+   public void initializeMessageDispatcher() throws CacheException
+   {
+     this.messageDispatcherInit = true; // Initialization process.
+     try {
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: Initializing message dispatcher with capacity of {} entries", this, _maximumMessageCount);
+       }
+       String name = "Client Message Dispatcher for "
+         + getProxyID().getDistributedMember() + (isDurable()? " (" + getDurableId()+")" : "");
+       this._messageDispatcher = new MessageDispatcher(this, name);
+       
+       //Fix for 41375 - drain as many of the queued events
+       //as we can without synchronization.
+       if (logger.isDebugEnabled()) {
+         logger.debug("{} draining {} events from init queue into intialized queue", this, this.queuedEvents.size());
+       }
+       Conflatable nextEvent;
+       while((nextEvent = queuedEvents.poll()) != null) {
+         this._messageDispatcher.enqueueMessage(nextEvent);
+       }
+       
+       //Now finish emptying the queue with synchronization to make
+       //sure we don't miss any events.
+       synchronized (this.queuedEventsSync){
+           while((nextEvent = queuedEvents.poll()) != null) {
+             this._messageDispatcher.enqueueMessage(nextEvent);
+           }
+           
+           this.messageDispatcherInit = false; // Done initialization.
+       }
+     } finally {
+       if (this.messageDispatcherInit) { // If its not successfully completed.
+         this._statistics.close();
+       }
+     }
+   }
+ 
+   protected void startOrResumeMessageDispatcher(boolean processedMarker) {
+     // Only start or resume the dispatcher if it is Primary
+     if (this.isPrimary) {
+       // Add the marker to the queue
+       if (!processedMarker) {
+         EventID eventId = new EventID(this._cache.getDistributedSystem());
+         this._messageDispatcher.enqueueMarker(new ClientMarkerMessageImpl(eventId));
+       }
+ 
+       // Set the message queue to primary.
+       this._messageDispatcher._messageQueue.setPrimary(true);
+ 
+       // Start or resume the dispatcher
+       synchronized (this._messageDispatcher._pausedLock) {
+         if (this.isPaused()) {
+           // It is paused, resume it
+           this.setPaused(false);
+           if (this._messageDispatcher.isStopped()) {
+             if (logger.isDebugEnabled()) {
+               logger.debug("{}: Starting dispatcher", this);
+             }
+             this._messageDispatcher.start();
+           }
+           else {
+             // ARB: Initialize transient fields.
+             this._messageDispatcher.initializeTransients();
+             if (logger.isDebugEnabled()) {
+               logger.debug("{}: Resuming dispatcher", this);
+             }
+             this._messageDispatcher.resumeDispatching();
+           }
+         } else if (!this._messageDispatcher.isAlive()) {
+           if (logger.isDebugEnabled()) {
+             logger.debug("{}: Starting dispatcher", this);
+           }
+           this._messageDispatcher.start();
+         }
+       }
+     }
+   }
+ 
+   /*
+    * Returns whether the client represented by this <code> CacheClientProxy
+    * </code> has registered interest in anything. @return whether the client
+    * represented by this <code> CacheClientProxy </code> has registered interest
+    * in anything
+    */
+   protected boolean hasRegisteredInterested()
+   {
+     return
+     this.cils[RegisterInterestTracker.interestListIndex].hasInterest() ||
+     this.cils[RegisterInterestTracker.durableInterestListIndex].hasInterest();
+   }
+ 
+   /**
+    * Returns a string representation of the proxy
+    */
+   @Override
+   public String toString()
+   {
+     StringBuffer buffer = new StringBuffer();
+     buffer.append("CacheClientProxy[")
+       // .append("client proxy id=")
+       .append(this.proxyID)
+       // .append("; client host name=")
+       // .append(this._socket.getInetAddress().getCanonicalHostName())
+       // .append("; client host address=")
+       // .append(this._remoteHostAddress)
+       .append("; port=").append(this._socket.getPort())
+       .append("; primary=").append(isPrimary)
+       .append("; version=").append(clientVersion)
+       .append("]");
+     return buffer.toString();
+   }
+   
+   public String getState(){
+     StringBuffer buffer = new StringBuffer();
+     buffer.append("CacheClientProxy[")
+       // .append("client proxy id=")
+       .append(this.proxyID)
+       // .append("; client host name=")
+       // .append(this._socket.getInetAddress().getCanonicalHostName())
+       // .append("; client host address=")
+       // .append(this._remoteHostAddress)
+       .append("; port=").append(this._socket.getPort())
+       .append("; primary=").append(isPrimary)
+       .append("; version=").append(clientVersion)
+       .append("; paused=").append(isPaused())
+       .append("; alive=").append(isAlive())
+       .append("; connected=").append(isConnected())
+       .append("; isMarkedForRemoval=").append(isMarkedForRemoval)
+       .append("]");
+     return buffer.toString();
+   }
+ 
+   public boolean isPrimary()
+   {
+     //boolean primary = this._messageDispatcher.isAlive()
+     //    || this._messageDispatcher._messageQueue.isPrimary();
+     boolean primary = this.isPrimary;
+     //System.out.println(this + ": DISPATCHER IS ALIVE: " + this._messageDispatcher.isAlive());
+     //System.out.println(this + ": DISPATCHER QUEUE IS PRIMARY: " + this._messageDispatcher._messageQueue.isPrimary());
+     //System.out.println(this + ": IS PRIMARY: " + primary);
+     return primary;
+     // return this.isPrimary ;
+   }
+ 
+   protected boolean basicIsPrimary() {
+     return this.isPrimary;
+   }
+ 
+   protected void setPrimary(boolean isPrimary) {
+     this.isPrimary = isPrimary;
+   }
+ 
+   // private static int nextId = 0;
+   // static protected int getNextId() {
+   // synchronized (CacheClientProxy.class) {
+   // return ++nextId;
+   // }
+   // }
+   /*
+    * Return this client's HA region queue
+    * @returns - HARegionQueue of the client
+    */
+    public HARegionQueue getHARegionQueue() {
+      if (this._messageDispatcher != null){
+        return _messageDispatcher._messageQueue;
+      }
+      return null;
+    }
+ 
+ 
+   /**
+    * Reinitialize a durable <code>CacheClientProxy</code> with a new client.
+    * @param socket
+    *          The socket between the server and the client
+    * @param ip
+    *          whether this proxy represents the primary
+    */
+   protected void reinitialize(Socket socket, ClientProxyMembershipID proxyId,
+       Cache cache, boolean ip, byte cc, Version ver) {
+     // Re-initialize transient fields
+     initializeTransientFields(socket, proxyId, ip, cc, ver);
+     getCacheClientNotifier().getAcceptorStats().incCurrentQueueConnections();
+ 
+ 
+     // Cancel expiration task
+     cancelDurableExpirationTask(true);
+ 
+     // Set the message dispatcher's primary flag. This could go from primary
+     // to secondary
+     this._messageDispatcher._messageQueue.setPrimary(ip);
+     this._messageDispatcher._messageQueue.setClientConflation(cc);
+ 
+     reinitializeClientAuths();
+     this.creationDate = new Date();
+     if (logger.isDebugEnabled()) {
+       logger.debug("{}: Has been reinitialized", this);
+     }
+   }
+ 
+   protected boolean isDurable() {
+     return getProxyID().isDurable();
+   }
+ 
+   protected String getDurableId() {
+     return getProxyID().getDurableId();
+   }
+ 
+   protected int getDurableTimeout() {
+     return getProxyID().getDurableTimeout();
+   }
+ 
+   private boolean getDurableKeepAlive() {
+     return this.keepalive;
+   }
+ 
+   protected String getHARegionName() {
+     return getProxyID().getHARegionName();
+   }
+ 
+   public Region getHARegion() {
+     return this._messageDispatcher._messageQueue.getRegion();
+   }
+   
+   public Version getVersion() {
+     return this.clientVersion;
+   }
+   
+   protected void scheduleDurableExpirationTask() {
+     SystemTimer.SystemTimerTask task = new SystemTimer.SystemTimerTask() {
+       @Override
+       public void run2() {
+         _durableExpirationTask.compareAndSet(this, null);
+         logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0__THE_EXPIRATION_TASK_HAS_FIRED_SO_THIS_PROXY_IS_BEING_TERMINATED, CacheClientProxy.this));
+         // Remove the proxy from the CacheClientNofier's registry
+         getCacheClientNotifier().removeClientProxy(CacheClientProxy.this);
+         getCacheClientNotifier().durableClientTimedOut(CacheClientProxy.this.proxyID);
+ 
+         // Close the proxy
+         terminateDispatching(false);
+         _cacheClientNotifier._statistics.incQueueDroppedCount();
+ 
+         /**
+          * Setting the expiration task to null again and cancelling existing
+          * one, if any. See #50894.
+          * <p/>
+          * The message dispatcher may again set the expiry task in below path:
+          * <code>
+          *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.scheduleDurableExpirationTask(CacheClientProxy.java:2020)
+          *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.pauseDispatching(CacheClientProxy.java:924)
+          *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy$MessageDispatcher.pauseOrUnregisterProxy(CacheClientProxy.java:2813)
+          *  com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy$MessageDispatcher.run(CacheClientProxy.java:2692)
+          * </code>
+          * <p/>
+          * This is because message dispatcher may get an IOException with
+          * "Proxy closing due to socket being closed locally" during/after
+          * terminateDispatching(false) above.
+          */
+         Object task = _durableExpirationTask.getAndSet(null);
+         if (task != null) {
+           ((SystemTimerTask)task).cancel();
+         }
+       }
+ 
+     };
+     if(this._durableExpirationTask.compareAndSet(null, task)) {
+       _cache.getCCPTimer().schedule(task,
+           getDurableTimeout()*1000L);
+     }
+   }
+ 
+   protected void cancelDurableExpirationTask(boolean logMessage) {
+     SystemTimer.SystemTimerTask task = (SystemTimerTask) _durableExpirationTask.getAndSet(null);
+     if (task != null) {
+       if (logMessage) {
+         logger.info(LocalizedMessage.create(LocalizedStrings.CacheClientProxy_0_CANCELLING_EXPIRATION_TASK_SINCE_THE_CLIENT_HAS_RECONNECTED, this));
+       }
+       task.cancel();
+     }
+   }
+ 
+   /**
+    * Class <code>ClientInterestList</code> provides a convenient interface
+    * for manipulating client interest information.
+    */
+   static protected class ClientInterestList
+    {
+     
+     final CacheClientProxy ccp;
+     
+     final Object id;
+ 
+      /**
+      * An object used for synchronizing the interest lists
+      */
+     final private Object interestListLock = new Object();
+     
+     /**
+      * Regions that this client is interested in
+      */
+     final protected Set<String> regions = new HashSet<String>();
+ 
+     /**
+      * Constructor.
+      */
+     protected ClientInterestList(CacheClientProxy ccp, Object interestID) {
+       this.ccp = ccp;
+       this.id = interestID;
+       // this.id = getNextId();
+     }
+ 
+     /**
+      * Registers interest in the input region name and key
+      */
+     protected void registerClientInterest(String regionName,
+         Object keyOfInterest, int interestType, boolean sendUpdatesAsInvalidates)
+     {
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: registerClientInterest region={} key={}", ccp, regionName, keyOfInterest);
+       }
+       Set keysRegistered = null;
+       synchronized(this.interestListLock) {
+         LocalRegion r = (LocalRegion)this.ccp._cache.getRegion(regionName, true);
+         if (r == null) {
+           throw new RegionDestroyedException("Region could not be found for interest registration", regionName);
+         }
+         if ( ! (r instanceof CacheDistributionAdvisee) ) {
+           throw new IllegalArgumentException("region " + regionName + " is not distributed and does not support interest registration");
+         }
+         FilterProfile p = r.getFilterProfile();
+         keysRegistered = p.registerClientInterest(id, keyOfInterest, interestType, sendUpdatesAsInvalidates);
+         regions.add(regionName);
+       }
+       // Perform actions if any keys were registered  
+       if ((keysRegistered != null) && containsInterestRegistrationListeners()
+           && !keysRegistered.isEmpty()) {
+         handleInterestEvent(regionName, keysRegistered, interestType, true);
+       } 
+     }
+     
+     
+     protected FilterProfile getProfile(String regionName) {
+       try {
+         return this.ccp._cache.getFilterProfile(regionName);
+       } catch (CacheClosedException e) {
+         return null;
+       }
+     }
+ 
+     /**
+      * Unregisters interest in the input region name and key
+      *
+      * @param regionName
+      *          The fully-qualified name of the region in which to unregister
+      *          interest
+      * @param keyOfInterest
+      *          The key in which to unregister interest
+      */
+     protected void unregisterClientInterest(String regionName,
+         Object keyOfInterest, int interestType)
+     {
+       if (logger.isDebugEnabled()) {
+         logger.debug("{}: unregisterClientInterest region={} key={}", ccp, regionName, keyOfInterest);
+       }
+       FilterProfile p = getProfile(regionName);
+       Set keysUnregistered = null;
+       synchronized(this.interestListLock) {
+         if (p != null) {
+           keysUnregistered = p.unregisterClientInterest(
+             id, keyOfInterest, interestType);
+           if (!p.hasInterestFor(id)) {
+             this.regions.remove(regionName);
+           }
+         } else {
+           this.regions.remove(regionName);
+         }
+       }
+       if (keysUnregistered != null && !keysUnregistered.isEmpty()) { 
+         handleInterestEvent(regionName, keysUnregistered, interestType, false); 
+       } 
+     }
+ 
+     /**
+      * Registers interest in the input region name and list of keys
+      *
+      * @param regionName
+      *          The fully-qualified name of the region in which to register
+      *          interest
+      * @param keysOfInterest
+      *          The list of keys in which to register interest
+      */
+     protected void registerClientInterestList(String regionName,
+         List keysOfInterest, boolean sendUpdatesAsInvalidates) {
+       FilterProfile p = getProfile(regionName);
+       if (p == null) {
+         throw new RegionDestroyedException("Region not found during client interest registration", regionName);
+       }
+       Set keysRegistered = null;
+       synchronized(this.interestListLock) {
+         keysRegistered = p.registerClientInterestList(id, keysOfInterest, sendUpdatesAsInvalidates);
+         regions.add(regionName);
+       }
+       // Perform actions if any keys were registered 
+       if (containsInterestRegistrationListeners() && !keysRegistered.isEmpty()) {
+         handleInterestEvent(regionName, keysRegistered, InterestType.KEY, true);
+       } 
+     }
+ 
+     /**
+      * Unregisters interest in the input region name and list of keys
+      *
+      * @param regionName
+      *          The fully-qualified name of the region in which to unregister
+      *          interest
+      * @param keysOfInterest
+      *          The list of keys in which to unregister interest
+      */
+     protected void unregisterClientInterestList(String regionName,
+         List keysOfInterest)
+     {
+       FilterProfile p = getProfile(regionName);
+       Set keysUnregistered = null;
+       synchronized(this.interestListLock) {
+         if (p != null) {
+           keysUnregistered = p.unregisterClientInterestList(
+               id, keysOfInterest);
+           if (!p.hasInterestFor(id)) {
+             regions.remove(regionName);
+           }
+         } else {
+           regions.remove(regionName);
+         }
+       }
+      // Perform actions if any keys were unregistered
+       if (!keysUnregistered.isEmpty()) { 
+         handleInterestEvent(regionName, keysUnregistered, InterestType.KEY,false); 
+       } 
+     }
+ 
+     /*
+      * Returns whether this interest list has any keys, patterns or filters of
+      * interest. It answers the question: Are any clients being notified because
+      * of this interest list? @return whether this interest list has any keys,
+      * patterns or filters of interest
+      */
+     protected boolean hasInterest() {
+       return regions.size() > 0;
+     }
+ 
+     protected void clearClientInterestList() {
+       boolean isClosed = ccp.getCache().isClosed();
+       
+       synchronized(this.interestListLock) {
+         for (String regionName: regions) {
+           FilterProfile p = getProfile(regionName);
+           if (p == null) {
+             continue;
+           }
+           if (!isClosed) {
+             if (p.hasAllKeysInterestFor(id)) {
+               Set allKeys = new HashSet();
+               allKeys.add(".*");
+               allKeys = Collections.unmodifiableSet(allKeys);
+               handleInterestEvent(regionName, allKeys,
+                   InterestType.REGULAR_EXPRESSION, false);
+             }
+             Set keysOfInterest = p.getKeysOfInterestFor(id);
+             if (keysOfInterest != null && keysOfInterest.size() > 0) {
+               handleInterestEvent(regionName, keysOfInterest,
+                   InterestType.KEY, false);
+             }
+             Map<String,Pattern> patternsOfInterest =
+               p.getPatternsOfInterestFor(id);
+             if (patternsOfInterest != null && patternsOfInterest.size() > 0) {
+               handleInterestEvent(regionName, patternsOfInterest.keySet(),
+                   InterestType.REGULAR_EXPRESSION, false);
+             }
+           }
+           p.clearInterestFor(id);
+         }
+         regions.clear();
+       }
+     }
+ 
+ 
+     private void handleInterestEvent(String regionName, Set keysOfInterest,
+         int interestType, boolean isRegister) {
+       // Notify the region about this register interest event if:
+       // - the application has requested it
+       // - this is a primary CacheClientProxy (otherwise multiple notifications
+       // may occur)
+       // - it is a key interest type (regex is currently not supported)
+       InterestRegistrationEvent event = null;
+       if (NOTIFY_REGION_ON_INTEREST && this.ccp.isPrimary()
+           && interestType == InterestType.KEY) {
+         event = new InterestRegistrationEventImpl(this.ccp, regionName,
+             keysOfInterest, interestType, isRegister);
+         try {
+           notifyRegionOfInterest(event);
+         }
+         catch (Exception e) {
+           logger.warn(LocalizedStrings.CacheClientProxy_REGION_NOTIFICATION_OF_INTEREST_FAILED, e);
+         }
+       }
+       // Invoke interest registration listeners
+       if (containsInterestRegistrationListeners()) {
+         if (event == null) {
+           event = new InterestRegistrationEventImpl(this.ccp, regionName,
+               keysOfInterest, interestType, isRegister);
+         }
+         notifyInterestRegistrationListeners(event);
+       }      
+     }
+ 
+     private void notifyRegionOfInterest(InterestRegistrationEvent event) {
+       this.ccp.getCacheClientNotifier().handleInterestEvent(event);
+     }
+ 
+     private void notifyInterestRegistrationListeners(
+         InterestRegistrationEvent event) {
+       this.ccp.getCacheClientNotifier().notifyInterestRegistrationListeners(
+           event);
+     }
+ 
+     private boolean containsInterestRegistrationListeners() {
+       return this.ccp.getCacheClientNotifier()
+           .containsInterestRegistrationListeners();
+     }
+   }
+ 
+ 
+   /**
+    * Class <code>MessageDispatcher</code> is a <code>Thread</code> that
+    * processes messages bound for the client by taking messsages from the
+    * message queue and sending them to the client over the socket.
+    */
+   static class MessageDispatcher extends Thread
+    {
+ 
+     /**
+      * The queue of messages to be sent to the client
+      */
+     protected final HARegionQueue _messageQueue;
+ 
+ //    /**
+ //     * An int used to keep track of the number of messages dropped for logging
+ //     * purposes. If greater than zero then a warning has been logged about
+ //     * messages being dropped.
+ //     */
+ //    private int _numberOfMessagesDropped = 0;
+ 
+     /**
+      * The proxy for which this dispatcher is processing messages
+      */
+     private final CacheClientProxy _proxy;
+ 
+ //    /**
+ //     * The conflator faciliates message conflation
+ //     */
+ //     protected BridgeEventConflator _eventConflator;
+ 
+     /**
+      * Whether the dispatcher is stopped
+      */
+     private volatile boolean _isStopped = true;
+ 
+     /**
+      * @guarded.By _pausedLock
+      */
+     //boolean _isPausedDispatcher = false;
+     
+     /**
+      * A lock object used to control pausing this dispatcher
+      */
+     protected final Object _pausedLock = new Object();
+ 
+     /**
+      * An object used to protect when dispatching is being stopped.
+      */
+     private final Object _stopDispatchingLock = new Object();
+ 
+     private final ReadWriteLock socketLock = new ReentrantReadWriteLock();
+ 
+     private final Lock socketWriteLock = socketLock.writeLock();
+ //    /**
+ //     * A boolean verifying whether a warning has already been issued if the
+ //     * message queue has reached its capacity.
+ //     */
+ //    private boolean _messageQueueCapacityReachedWarning = false;
+ 
+     /**
+      * Constructor.
+      *
+      * @param proxy
+      *          The <code>CacheClientProxy</code> for which this dispatcher is
+      *          processing messages
+      * @param name thread name for this dispatcher
+      

<TRUNCATED>


[092/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
index 0000000,ca14b76..5d05fe5
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
@@@ -1,0 -1,973 +1,985 @@@
+ /*
+  * 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 com.gemstone.gemfire.cache.client.internal;
+ 
+ import java.io.EOFException;
+ import java.io.IOException;
+ import java.io.NotSerializableException;
+ import java.net.ConnectException;
+ import java.net.SocketException;
+ import java.net.SocketTimeoutException;
+ import java.nio.BufferUnderflowException;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ 
+ import org.apache.logging.log4j.Logger;
+ 
+ import com.gemstone.gemfire.CancelCriterion;
+ import com.gemstone.gemfire.CancelException;
+ import com.gemstone.gemfire.CopyException;
+ import com.gemstone.gemfire.GemFireException;
++import com.gemstone.gemfire.GemFireIOException;
+ import com.gemstone.gemfire.SerializationException;
+ import com.gemstone.gemfire.cache.CacheRuntimeException;
+ import com.gemstone.gemfire.cache.RegionDestroyedException;
+ import com.gemstone.gemfire.cache.SynchronizationCommitConflictException;
+ import com.gemstone.gemfire.cache.TransactionException;
+ import com.gemstone.gemfire.cache.client.NoAvailableServersException;
+ import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+ import com.gemstone.gemfire.cache.client.ServerOperationException;
+ import com.gemstone.gemfire.cache.client.ServerRefusedConnectionException;
+ import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
+ import com.gemstone.gemfire.cache.client.internal.ExecuteFunctionOp.ExecuteFunctionOpImpl;
+ import com.gemstone.gemfire.cache.client.internal.ExecuteRegionFunctionOp.ExecuteRegionFunctionOpImpl;
+ import com.gemstone.gemfire.cache.client.internal.QueueManager.QueueConnections;
+ import com.gemstone.gemfire.cache.client.internal.pooling.ConnectionDestroyedException;
+ import com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManager;
+ import com.gemstone.gemfire.cache.execute.FunctionException;
+ import com.gemstone.gemfire.cache.execute.FunctionInvocationTargetException;
+ import com.gemstone.gemfire.distributed.internal.ServerLocation;
+ import com.gemstone.gemfire.internal.cache.PoolManagerImpl;
+ import com.gemstone.gemfire.internal.cache.PutAllPartialResultException;
+ import com.gemstone.gemfire.internal.cache.TXManagerImpl;
+ import com.gemstone.gemfire.internal.cache.TXStateProxy;
+ import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
+ import com.gemstone.gemfire.internal.cache.tier.BatchException;
++import com.gemstone.gemfire.internal.cache.tier.sockets.MessageTooLargeException;
+ import com.gemstone.gemfire.internal.cache.wan.BatchException70;
+ import com.gemstone.gemfire.internal.logging.LogService;
+ import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+ import com.gemstone.gemfire.security.AuthenticationRequiredException;
+ import com.gemstone.gemfire.security.GemFireSecurityException;
+ 
+ /**
+  * Called from the client and execute client to server
+  * requests against servers. Handles retrying to different servers,
+  * and marking servers dead if we get exception from them.
+  * @author dsmith
+  * @since 5.7
+  */
+ public class OpExecutorImpl implements ExecutablePool {
+   private static final Logger logger = LogService.getLogger();
+   
+   private static final boolean TRY_SERVERS_ONCE = Boolean.getBoolean("gemfire.PoolImpl.TRY_SERVERS_ONCE");
+   private static final int TX_RETRY_ATTEMPT = Integer.getInteger("gemfire.txRetryAttempt", 500);
+   
+   private final ConnectionManager connectionManager;
+   private final int retryAttempts;
+   private final long serverTimeout;
+   private final boolean threadLocalConnections;
+   private final ThreadLocal<Connection> localConnection = new ThreadLocal<Connection>();
+   /**
+    * maps serverLocations to Connections when threadLocalConnections is enabled with single-hop.
+    */
+   private final ThreadLocal<Map<ServerLocation, Connection>> localConnectionMap = new ThreadLocal<Map<ServerLocation,Connection>>();
+   private final EndpointManager endpointManager;
+   private final RegisterInterestTracker riTracker;
+   private final QueueManager queueManager;
+   private final CancelCriterion cancelCriterion;
+   private /*final*/ PoolImpl pool;
+   private final ThreadLocal<Boolean> serverAffinity = new ThreadLocal<Boolean>() {
+     @Override
+     protected Boolean initialValue() {
+       return Boolean.FALSE;};
+   };
+   private boolean serverAffinityFailover = false;
+   private final ThreadLocal<ServerLocation> affinityServerLocation = new ThreadLocal<ServerLocation>();
+   private final ThreadLocal<Integer> affinityRetryCount = new ThreadLocal<Integer>() {
+     protected Integer initialValue() {
+       return 0;
+     };
+   };
+   
+   public OpExecutorImpl(ConnectionManager manager, QueueManager queueManager, EndpointManager endpointManager, RegisterInterestTracker riTracker, int retryAttempts,
+       long serverTimeout, boolean threadLocalConnections, CancelCriterion cancelCriterion, PoolImpl pool)  {
+     this.connectionManager = manager;
+     this.queueManager = queueManager;
+     this.endpointManager = endpointManager;
+     this.riTracker = riTracker;
+     this.retryAttempts = retryAttempts;
+     this.serverTimeout = serverTimeout;
+     this.threadLocalConnections = threadLocalConnections;
+     this.cancelCriterion = cancelCriterion;
+     this.pool = pool;
+   }  
+   
+   public Object execute(Op op) {
+     return execute(op, retryAttempts);
+   }
+   
+   public Object execute(Op op, int retries) {
+     if (this.serverAffinity.get()) {
+       ServerLocation loc = this.affinityServerLocation.get();
+       if (loc == null) {
+         loc = getNextOpServerLocation();
+         this.affinityServerLocation.set(loc);
+         if (logger.isDebugEnabled()) {
+           logger.debug("setting server affinity to {}", this.affinityServerLocation.get());
+         }
+       }
+       return executeWithServerAffinity(loc, op);
+     }
+     boolean success = false;
+     
+     Set attemptedServers = new HashSet();
+     
+     Connection conn = (Connection) (threadLocalConnections ? localConnection.get() : null);
+     if (conn == null || conn.isDestroyed()) {
+       conn = connectionManager.borrowConnection(serverTimeout);
+     }
+     else if (threadLocalConnections) {
+       //Fix for 43718. Clear the thread local connection
+       //while we're performing the op. It will be reset
+       //if the op succeeds.
+       localConnection.set(null);
+       try {
+         this.connectionManager.activate(conn);
+       }
+       catch (ConnectionDestroyedException ex) {
+         conn = connectionManager.borrowConnection(serverTimeout);
+       }
+     }
+     try {
+       for(int attempt = 0; true; attempt++) {
+         // when an op is retried we may need to try to recover the previous
+         // attempt's version stamp
+         if (attempt == 1 && (op instanceof AbstractOp)) {
+           AbstractOp absOp = (AbstractOp)op;
+           absOp.getMessage().setIsRetry();
+         }
+         try {
+           authenticateIfRequired(conn, op);
+           Object result = executeWithPossibleReAuthentication(conn, op);
+           success = true;
+           return result;
++        } catch (MessageTooLargeException e) {
++          throw new GemFireIOException("unable to transmit message to server", e);
+         }
+         catch (Exception e) {
+           //This method will throw an exception if we need to stop
+           //It also unsets the threadlocal connection and notifies
+           //the connection manager if there are failures.
+           handleException(e, conn, attempt, attempt >= retries && retries != -1);
+           attemptedServers.add(conn.getServer());
+           try {
+             conn = connectionManager.exchangeConnection(conn, attemptedServers, serverTimeout);
+           }
+           catch(NoAvailableServersException nse) {
+             //if retries is -1, don't try again after the last server has failed
+             if(retries == -1 || TRY_SERVERS_ONCE) {
+               handleException(e, conn, attempt, true);
+             }
+             else {
+               //try one of the failed servers again, until we exceed the retry attempts.
+               attemptedServers.clear();
+               try {
+                 conn = connectionManager.exchangeConnection(conn, attemptedServers, serverTimeout);
+               }
+               catch(NoAvailableServersException nse2) {
+                 handleException(e, conn, attempt, true);
+               }
+             }
+           }
+         }
+       }
+     } finally {
+       if(threadLocalConnections) {
+         this.connectionManager.passivate(conn, success);
+         //Fix for 43718. If the thread local was set to a different
+         //connection deeper in the call stack, return that connection
+         //and set our connection on the thread local.
+         Connection existingConnection = localConnection.get();
+         if(existingConnection != null && existingConnection != conn) {
+           connectionManager.returnConnection(existingConnection);
+         }
+         
+         if(!conn.isDestroyed()) {
+           localConnection.set(conn);
+         } else {
+           localConnection.set(null);
+         }
+       } else {
+         connectionManager.returnConnection(conn);
+       }
+     }
+   }
+ 
+   /**
+    * execute the given op on the given server. If the server cannot
+    * be reached, sends a TXFailoverOp, then retries the given op
+    * @param loc the server to execute the op on
+    * @param op the op to execute
+    * @return the result of execution
+    */
+   private Object executeWithServerAffinity(ServerLocation loc, Op op) {
+     try {
+       Object retVal = executeOnServer(loc, op, true, false);
+       affinityRetryCount.set(0);
+       return retVal;
+     } catch (ServerConnectivityException e) {
+       if (logger.isDebugEnabled()) {
+         logger.debug("caught exception while executing with affinity:{}", e.getMessage(), e);
+       }
+       if (!this.serverAffinityFailover || e instanceof ServerOperationException) {
+         affinityRetryCount.set(0);
+         throw e;
+       }
+       int retryCount = affinityRetryCount.get();
+       if ((retryAttempts != -1 && retryCount >= retryAttempts) ||
+           retryCount > TX_RETRY_ATTEMPT) { // prevent stack overflow fixes bug 46535
+         affinityRetryCount.set(0);
+         throw e;
+       }
+       affinityRetryCount.set(retryCount + 1);
+     }
+     this.affinityServerLocation.set(null);
+     if (logger.isDebugEnabled()) {
+       logger.debug("reset server affinity: attempting txFailover");
+     }
+     // send TXFailoverOp, so that new server can
+     // do bootstrapping, then re-execute original op
+     AbstractOp absOp = (AbstractOp) op;
+     absOp.getMessage().setIsRetry();
+     int transactionId = absOp.getMessage().getTransactionId();
+     // for CommitOp we do not have transactionId in AbstractOp
+     // so set it explicitly for TXFailoverOp
+     try {
+       TXFailoverOp.execute(this.pool, transactionId);
+     } catch (TransactionException e) {
+       // If this is the first operation in the transaction then
+       // do not throw TransactionDataNodeHasDeparted back to the
+       // user, re-try the op instead. fixes bug 44375. NOTE: TXFailoverOp
+       // is sent even after first op, as it is not known if the first
+       // operation has established a TXState already
+       TXStateProxy txState = TXManagerImpl.getCurrentTXState();
+       if (txState == null) {
+         throw e;
+       } else if (txState.operationCount() > 1) {
+         throw e;
+       }
+     }
+     if(op instanceof ExecuteRegionFunctionOpImpl){
+       op = new ExecuteRegionFunctionOpImpl(
+           (ExecuteRegionFunctionOpImpl)op, (byte)1/*isReExecute*/, new HashSet<String>());
+       ((ExecuteRegionFunctionOpImpl)op).getMessage().setTransactionId(transactionId);
+     }else if (op instanceof ExecuteFunctionOpImpl){
+       op = new ExecuteFunctionOpImpl(
+           (ExecuteFunctionOpImpl)op, (byte)1/*isReExecute*/);
+       ((ExecuteFunctionOpImpl)op).getMessage().setTransactionId(transactionId);
+     }
+     return this.pool.execute(op);
+   }
+ 
+   public void setupServerAffinity(boolean allowFailover) {
+     if (logger.isDebugEnabled()) {
+       logger.debug("setting up server affinity");
+     }
+     this.serverAffinityFailover = allowFailover;
+     this.serverAffinity.set(Boolean.TRUE);
+   }
+   
+   public void releaseServerAffinity() {
+     if (logger.isDebugEnabled()) {
+       logger.debug("reset server affinity");
+     }
+     this.serverAffinity.set(Boolean.FALSE);
+     this.affinityServerLocation.set(null);
+   }
+   
+   public ServerLocation getServerAffinityLocation() {
+     return this.affinityServerLocation.get();
+   }
+   
+   public void setServerAffinityLocation(ServerLocation serverLocation) {
+     assert this.affinityServerLocation.get() == null;
+     this.affinityServerLocation.set(serverLocation);
+   }
+   
+   public ServerLocation getNextOpServerLocation() {
+     ServerLocation retVal = null;
+     Connection conn = (Connection) (threadLocalConnections ? localConnection.get() : null);
+     if (conn == null || conn.isDestroyed()) {
+       conn = connectionManager.borrowConnection(serverTimeout);
+       retVal = conn.getServer();
+     this.connectionManager.returnConnection(conn);
+     } else {
+       retVal = conn.getServer();
+     }
+     return retVal;
+   }
+   
+   /* (non-Javadoc)
+    * @see com.gemstone.gemfire.cache.client.internal.OpExecutor#executeOn(com.gemstone.gemfire.distributed.internal.ServerLocation, com.gemstone.gemfire.cache.client.internal.Op)
+    */
+   public Object executeOn(ServerLocation server, Op op) {
+     return executeOn(server, op, true,false);
+   }
+   public Object executeOn(ServerLocation p_server, Op op, boolean accessed,boolean onlyUseExistingCnx) {
+     ServerLocation server = p_server;
+     if (this.serverAffinity.get()) {
+       ServerLocation affinityserver = this.affinityServerLocation.get();
+       if (affinityserver != null) {
+         server = affinityserver;
+       } else {
+         this.affinityServerLocation.set(server);
+       }
+       // redirect to executeWithServerAffinity so that we
+       // can send a TXFailoverOp.
+       return executeWithServerAffinity(server, op);
+     }
+     return executeOnServer(server, op, accessed, onlyUseExistingCnx);
+   }
+   private Object executeOnServer(ServerLocation p_server, Op op, boolean accessed,boolean onlyUseExistingCnx) {
+     ServerLocation server = p_server;
+     boolean returnCnx = true;
+     boolean pingOp = (op instanceof PingOp.PingOpImpl);
+     Connection conn = null;
+     if (pingOp) {
+       // currently for pings we prefer to queue clientToServer cnx so that we will
+       // not create a pooled cnx when all we have is queue cnxs.
+       if (this.queueManager != null) {
+         // see if our QueueManager has a connection to this guy that we can send
+         // the ping on.
+         Endpoint ep = (Endpoint)this.endpointManager.getEndpointMap().get(server);
+         if (ep != null) {
+           QueueConnections qcs = this.queueManager.getAllConnectionsNoWait();
+           conn = qcs.getConnection(ep);
+           if (conn != null) {
+             // we found one to do the ping on
+             returnCnx = false;
+           }
+         }
+       }
+     }
+     if (conn == null) {
+       if (useThreadLocalConnection(op, pingOp)) {
+         // no need to set threadLocal to null while the op is in progress since
+         // 43718 does not impact single-hop
+         conn = getActivatedThreadLocalConnectionForSingleHop(server, onlyUseExistingCnx);
+         returnCnx = false;
+       } else {
+         conn = connectionManager.borrowConnection(server, serverTimeout,onlyUseExistingCnx);
+       }
+     }
+     boolean success = true;
+     try {
+       return executeWithPossibleReAuthentication(conn, op);
+     } catch (Exception e) {
+       success = false;
+       //This method will throw an exception if we need to stop
+       //It also unsets the threadlocal connection and notifies
+       //the connection manager if there are failures.
+       handleException(e, conn, 0, true);
+       //this shouldn't actually be reached, handle exception will throw something
+       throw new ServerConnectivityException("Received error connecting to server", e);
+     } finally {
+       if (this.serverAffinity.get() && this.affinityServerLocation.get() == null) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("setting server affinity to {} server:{}", conn.getEndpoint().getMemberId(), conn.getServer());
+         }
+         this.affinityServerLocation.set(conn.getServer());
+       }
+       if (useThreadLocalConnection(op, pingOp)) {
+         this.connectionManager.passivate(conn, success);
+         setThreadLocalConnectionForSingleHop(server, conn);
+       }
+       if (returnCnx) {
+         connectionManager.returnConnection(conn, accessed);
+       }
+     }
+   }
+ 
+   private boolean useThreadLocalConnection(Op op, boolean pingOp) {
+     return threadLocalConnections && !pingOp && op.useThreadLocalConnection();
+   }
+ 
+   /**
+    * gets a connection to the given serverLocation either by looking up the threadLocal {@link #localConnectionMap}.
+    * If a connection does not exist (or has been destroyed) we borrow one from connectionManager.
+    * @return the activated connection
+    */
+   private Connection getActivatedThreadLocalConnectionForSingleHop(ServerLocation server, boolean onlyUseExistingCnx) {
+     assert threadLocalConnections;
+     Connection conn = null;
+     Map<ServerLocation, Connection> connMap = this.localConnectionMap.get();
+     if (connMap != null && !connMap.isEmpty()) {
+       conn = connMap.get(server);
+     }
+     boolean borrow = true;
+     if (conn != null) {
+       try {
+         this.connectionManager.activate(conn);
+         borrow = false;
+         if (!conn.getServer().equals(server)) {
+           // poolLoadConditioningMonitor can replace the connection's
+           // endpoint from underneath us. fixes bug 45151
+           borrow = true;
+         }
+       } catch (ConnectionDestroyedException e) {
+       }
+     }
+     if (conn == null || borrow) {
+       conn = connectionManager.borrowConnection(server, serverTimeout, onlyUseExistingCnx);
+     }
+     if (borrow && connMap != null) {
+       connMap.remove(server);
+     }
+     return conn;
+   }
+   
+   /**
+    * initializes the threadLocal {@link #localConnectionMap} and adds mapping
+    * of serverLocation to Connection.
+    */
+   private void setThreadLocalConnectionForSingleHop(ServerLocation server,
+       Connection conn) {
+     assert threadLocalConnections;
+     Map<ServerLocation, Connection> connMap = this.localConnectionMap.get();
+     if (connMap == null) {
+       connMap = new HashMap<ServerLocation, Connection>();
+       this.localConnectionMap.set(connMap);
+     }
+     connMap.put(server, conn);
+   }
+ 
+   /*
+    * (non-Javadoc)
+    * @see com.gemstone.gemfire.cache.client.internal.ExecutablePool#executeOnPrimary(com.gemstone.gemfire.cache.client.internal.Op)
+    */
+   public Object executeOnPrimary(Op op) {
+     if(queueManager == null) {
+       throw new SubscriptionNotEnabledException();
+     }
+     
+     HashSet attemptedPrimaries = new HashSet();
+     while(true) {
+       Connection primary = queueManager.getAllConnections().getPrimary();
+       try {
+         return executeWithPossibleReAuthentication(primary, op);
+       } catch (Exception e) {
+         boolean finalAttempt = ! attemptedPrimaries.add(primary.getServer());
+         handleException(e, primary, 0, finalAttempt);
+         //we shouldn't reach this code, but just in case
+         if(finalAttempt) {
+           throw new ServerConnectivityException("Tried the same primary server twice.", e);
+         }
+       }
+     }
+   }
+   
+   public void executeOnAllQueueServers(Op op) {
+     if(queueManager == null) {
+       throw new SubscriptionNotEnabledException();
+     }
+     
+     RuntimeException lastException = null;
+     
+     QueueConnections connections = queueManager.getAllConnectionsNoWait();
+     Connection primary = connections.getPrimary();
+     if(primary != null) {
+       try {
+         executeWithPossibleReAuthentication(primary, op);
+       } catch (Exception e) {
+         try {
+           handleException(e, primary, 0, false);
+         } catch(RuntimeException e2) {
+           lastException = e2;
+         }
+       }
+     }
+ 
+     List backups = connections.getBackups();
+     for(int i = 0; i < backups.size(); i++) {
+       Connection conn = (Connection) backups.get(i);
+       try {
+         executeWithPossibleReAuthentication(conn, op);
+       } catch (Exception e) {
+         try {
+           handleException(e, conn, 0, false);
+         } catch(RuntimeException e2) {
+           lastException = e2;
+         }
+       }
+     }
+     
+     if (lastException != null) {
+       throw lastException;
+     }
+   }
+ 
+   /*
+    * (non-Javadoc)
+    * @see com.gemstone.gemfire.cache.client.internal.ExecutablePool#executeOnAllQueueServers(com.gemstone.gemfire.cache.client.internal.Op)
+    */
+   public Object executeOnQueuesAndReturnPrimaryResult(Op op) {
+     if(queueManager == null) {
+       throw new SubscriptionNotEnabledException();
+     }
+     QueueConnections connections = queueManager.getAllConnections();
+     
+     List backups = connections.getBackups();
+     if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
+       logger.trace(LogMarker.BRIDGE_SERVER, "sending {} to backups: {}", op, backups);
+     }
+     for(int i = backups.size() - 1; i >= 0; i--) {
+       Connection conn = (Connection) backups.get(i);
+       try {
+         executeWithPossibleReAuthentication(conn, op);
+       } catch (Exception e)  {
+         handleException(e, conn, 0, false);
+       }
+     }
+ 
+     Connection primary = connections.getPrimary();
+     HashSet attemptedPrimaries = new HashSet();
+     while(true) {
+       try {
+         if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
+           logger.trace(LogMarker.BRIDGE_SERVER, "sending {} to primary: {}", op, primary);
+         }
+         return executeWithPossibleReAuthentication(primary, op);
+       } catch (Exception e) {
+         if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
+           logger.trace(LogMarker.BRIDGE_SERVER, "caught exception sending to primary {}", e.getMessage(), e);
+         }
+         boolean finalAttempt = !attemptedPrimaries.add(primary.getServer());
+         handleException(e, primary, 0, finalAttempt);
+         primary = queueManager.getAllConnections().getPrimary();
+         //we shouldn't reach this code, but just in case
+         if(finalAttempt) {
+           throw new ServerConnectivityException("Tried the same primary server twice.", e);
+         }
+       }
+     }
+   }
+ 
+   public void releaseThreadLocalConnection() {
+     Connection conn = localConnection.get();
+     localConnection.set(null);
+     if(conn != null) {
+       connectionManager.returnConnection(conn);
+     }
+     Map<ServerLocation, Connection> connMap = localConnectionMap.get();
+     localConnectionMap.set(null);
+     if (connMap != null) {
+       for (Connection c : connMap.values()) {
+         connectionManager.returnConnection(c);
+       }
+     }
+   }
+ 
+   /**
+    * Used by GatewayBatchOp
+    */
+   public Object executeOn(Connection conn, Op op, boolean timeoutFatal) {
+     try {
+       return executeWithPossibleReAuthentication(conn, op);
+     } catch (Exception e) {
+       //This method will throw an exception if we need to stop
+       //It also unsets the threadlocal connection and notifies
+       //the connection manager if there are failures.
+       handleException(op, e, conn, 0,  true, timeoutFatal);
+       //this shouldn't actually be reached, handle exception will throw something
+       throw new ServerConnectivityException("Received error connecting to server", e);
+     } 
+   }
+   /**
+    * This is used by unit tests
+    */
+   public Object executeOn(Connection conn, Op op) {
+     return executeOn(conn, op, false);
+   }
+ 
+   public RegisterInterestTracker getRITracker() {
+     return riTracker;
+   }
+   
+   protected void handleException(Throwable e, 
+                                  Connection conn,
+                                  int retryCount, boolean finalAttempt) {
+     handleException(e, conn, retryCount, finalAttempt, false/*timeoutFatal*/);
+   }
+ 
+   protected void handleException(Op op, 
+                                  Throwable e,
+                                  Connection conn,
+                                  int retryCount,
+                                  boolean finalAttempt,
+                                  boolean timeoutFatal)
+   throws CacheRuntimeException {
+     if (op instanceof AuthenticateUserOp.AuthenticateUserOpImpl) {
+       if (e instanceof GemFireSecurityException) {
+         throw (GemFireSecurityException)e;
+       } else if (e instanceof ServerRefusedConnectionException) {
+         throw (ServerRefusedConnectionException)e;
+       }
+     }
+     handleException(e, conn, retryCount, finalAttempt, timeoutFatal);
+   }
+ 
+   protected void handleException(Throwable e, 
+                                  Connection conn,
+                                  int retryCount,
+                                  boolean finalAttempt,
+                                  boolean timeoutFatal)
+   throws CacheRuntimeException 
+   {
+     GemFireException exToThrow = null;
+     String title;
+     boolean invalidateServer = true;
+     boolean warn = true;
+     boolean forceThrow = false;
+     Throwable cause = e;
+     
+     cancelCriterion.checkCancelInProgress(e);
+ 
+     if(logger.isDebugEnabled() && !(e instanceof java.io.EOFException)) {
+       if (e instanceof java.io.EOFException){
+         logger.debug("OpExecutor.handleException on Connection to {} found EOF", conn.getServer());
+       } else if (e instanceof java.net.SocketTimeoutException) {
+         logger.debug("OpExecutor.handleException on Connection to {} read timed out", conn.getServer());
+       } else {
+         logger.debug("OpExecutor.handleException on Connection to {}", conn.getServer(),e);
+       }
+     }
 -    if (e instanceof NotSerializableException) {
++    
++    // first take care of all exceptions that should not invalidate the
++    // connection and do not need to be logged
++    
++    if (e instanceof MessageTooLargeException) {
++      title = null;
++      exToThrow = new GemFireIOException("message is too large to transmit", e);
++    }
++    else if (e instanceof NotSerializableException) {
+       title = null; //no message
+       exToThrow = new SerializationException("Pool message failure", e);
+     }
+     else if (e instanceof BatchException || e instanceof BatchException70) {
+       title = null; //no message
+       exToThrow = new ServerOperationException(e);
+     }
+     else if (e instanceof RegionDestroyedException) {
+       invalidateServer = false;
+       title = null;
+       exToThrow =(RegionDestroyedException) e;
+     }
+     else if (e instanceof GemFireSecurityException) {
+       title = null;
+       exToThrow = new ServerOperationException(e);
+     }
+     else if (e instanceof SerializationException) {
+       title = null; // no message
+       exToThrow = new ServerOperationException(e);
+     }
+     else if (e instanceof CopyException) {
+       title = null; // no message
+       exToThrow = new ServerOperationException(e);
+     }
+     else if (e instanceof ClassNotFoundException) {
+       title = null; // no message
+       exToThrow = new ServerOperationException(e);
+     }
+     else if (e instanceof TransactionException) {
+       title = null; // no message
+       exToThrow = (TransactionException)e;
+       invalidateServer = false;
+     }
+     else if (e instanceof SynchronizationCommitConflictException) {
+       title = null;
+       exToThrow = (SynchronizationCommitConflictException)e;
+       invalidateServer = false;
+     }
+     else if (e instanceof SocketException) {
+       if ("Socket closed".equals(e.getMessage())
+           || "Connection reset".equals(e.getMessage())
+           || "Connection refused: connect".equals(e.getMessage())
+           || "Connection refused".equals(e.getMessage())) {
+         title = e.getMessage();
+       } else {
+         title = "SocketException";
+       }
+     }
+     else if (e instanceof SocketTimeoutException) {
+       invalidateServer = timeoutFatal;
+       title = "socket timed out on client";
+       cause = null;
+     }
+     else if (e instanceof ConnectionDestroyedException) {
+       invalidateServer = false;
+       title = "connection was asynchronously destroyed";
+       cause = null;
+     }
+     else if (e instanceof java.io.EOFException) {
+       /*
+ //      it is still listening so make this into a timeout exception
+         invalidateServer = false;
+         title = "socket closed on server";
+         SocketTimeoutException ste = new SocketTimeoutException(title);
+         ste.setStackTrace(e.getStackTrace());
+         e = ste;
+         cause = null;
+         */ 
+       
+       /*
+        * note: the old code in ConnectionProxyImpl used to create a new socket here to the server to determine if it really crashed.
+        * We may have to add this back in for some reason, but hopefully not.
+        * 
+        * note 05/21/08: an attempt to address this was made by increasing the time waited on server before closing timeoutd clients
+        * see ServerConnection.hasBeenTimedOutOnClient
+        */
+       title = "closed socket on server";
+     }
+     else if (e instanceof IOException) {
+       title = "IOException";
+     }
+     else if (e instanceof BufferUnderflowException) {
+       title = "buffer underflow reading from server";
+     }
+     else if (e instanceof CancelException) {
+       title = "Cancelled";
+       warn = false;
+     }
+     else if (e instanceof InternalFunctionInvocationTargetException) {  
+       //In this case, function will be re executed
+       title = null;
+       exToThrow = (InternalFunctionInvocationTargetException)e;
+     }
+     else if (e instanceof FunctionInvocationTargetException) {  
+       //in this case function will not be re executed
+       title = null; 
+       exToThrow = (GemFireException)e;
+     }
+     else if (e instanceof PutAllPartialResultException) {
+       title = null;
+       exToThrow =(PutAllPartialResultException) e;
+       invalidateServer = false;
+     }
+     else {
+       Throwable t = e.getCause();
+       if ((t instanceof ConnectException)
+           || (t instanceof SocketException)
+           || (t instanceof SocketTimeoutException)
+           || (t instanceof IOException)
+           || (t instanceof SerializationException)
+           || (t instanceof CopyException)
+           || (t instanceof GemFireSecurityException)
+           || (t instanceof ServerOperationException)
+           || (t instanceof TransactionException)
+           || (t instanceof CancelException)) {
+         handleException(t,  conn, retryCount, finalAttempt, timeoutFatal);
+         return;
+       } else if (e instanceof ServerOperationException) {
+           title = null; // no message
+           exToThrow = (ServerOperationException)e;
+           invalidateServer = false; // fix for bug #42225
+       }
+       else if (e instanceof FunctionException) {
+         if (t instanceof InternalFunctionInvocationTargetException) {
+           // Client server to re-execute for node failure
+           handleException(t, conn, retryCount, finalAttempt, timeoutFatal);
+           return;
+         }
+         else {
+           title = null; // no message
+           exToThrow = (FunctionException)e;
+         }
+       } else if (e instanceof ServerConnectivityException
+           && e.getMessage()
+               .equals("Connection error while authenticating user")) {
+         title = null;
+         if (logger.isDebugEnabled()) {
+           logger.debug(e.getMessage(), e);
+         }
+       } else {
+         title = e.toString();
+         forceThrow = true;
+       }
+     }
+     if (title != null) {
+       conn.destroy();
+       if(invalidateServer) {
+         endpointManager.serverCrashed(conn.getEndpoint());
+       }
+       boolean logEnabled = warn ? logger.isWarnEnabled() : logger.isDebugEnabled();
+       boolean msgNeeded = logEnabled || finalAttempt;
+       if (msgNeeded) {
+         final StringBuffer sb = getExceptionMessage(title, retryCount, finalAttempt, conn, e);
+         final String msg = sb.toString();
+         if (logEnabled) {
+           if (warn) {
+             logger.warn(msg /*, e*/);
+           } else {
+             logger.debug(msg /*, e*/);
+           }
+         }
+         if (forceThrow || finalAttempt) {
+           exToThrow = new ServerConnectivityException(msg, cause);
+         }
+       }
+     }
+     if (exToThrow != null) {
+       throw exToThrow;
+     }
+   }
+   
+   private StringBuffer getExceptionMessage(String exceptionName, 
+       int retryCount,
+       boolean finalAttempt,
+       Connection connection,
+       Throwable ex) {
+     StringBuffer message = new StringBuffer(200);
+     message
+     .append("Pool unexpected ")
+     .append(exceptionName);
+     if (connection != null) {
+       message
+       .append(" connection=")
+       .append(connection);
+     }
+     if (retryCount > 0) {
+       message
+       .append(" attempt=")
+       .append(retryCount+1);
+     }
+     message.append(')');
+     if (finalAttempt) {
+       message
+       .append(". Server unreachable: could not connect after ")
+       .append(retryCount+1)
+       .append(" attempts");
+     }
+     return message;
+   }
+ 
+   public Connection getThreadLocalConnection() {
+     return localConnection.get();
+   }
+ 
+   public void setThreadLocalConnection(Connection conn) {
+     localConnection.set(conn);
+   }
+ 
+   private void authenticateIfRequired(Connection conn, Op op) {
+     if (!conn.getServer().getRequiresCredentials()) {
+       return;
+     }
+     
+     if (this.pool == null) {
+       PoolImpl poolImpl = (PoolImpl)PoolManagerImpl.getPMI().find(
+           this.endpointManager.getPoolName());
+       if (poolImpl == null) {
+         return;
+       }
+       this.pool = poolImpl;
+     }
+     if (this.pool.getMultiuserAuthentication()) {
+       if (((AbstractOp)op).needsUserId()) {
+         UserAttributes ua = UserAttributes.userAttributes.get();
+         if (ua != null) {
+           if (!ua.getServerToId().containsKey(conn.getServer())) {
+             authenticateMultiuser(this.pool, conn, ua);
+           }
+         } else {
+           // This should never be reached.
+         }
+       }
+     } else if (((AbstractOp)op).needsUserId()) {
+       // This should not be reached, but keeping this code here in case it is
+       // reached.
+       if (conn.getServer().getUserId() == -1) {
+         Connection connImpl = this.connectionManager.getConnection(conn);
+         conn.getServer().setUserId(
+             (Long)AuthenticateUserOp.executeOn(connImpl, this.pool));
+         if (logger.isDebugEnabled()) {
+           logger.debug("OpExecutorImpl.execute() - single user mode - authenticated this user on {}", conn);
+         }
+       }
+     }
+   }
+ 
+   private void authenticateMultiuser(PoolImpl pool, Connection conn,
+       UserAttributes ua) {
+     try {
+       Long userId = (Long)AuthenticateUserOp.executeOn(conn.getServer(),
+           pool, ua.getCredentials());
+       if (userId != null) {
+         ua.setServerToId(conn.getServer(), userId);
+         if (logger.isDebugEnabled()) {
+           logger.debug("OpExecutorImpl.execute() - multiuser mode - authenticated this user on {}", conn);
+         }
+       }
+     } catch (ServerConnectivityException sce) {
+       Throwable cause = sce.getCause();
+       if (cause instanceof SocketException
+           || cause instanceof EOFException
+           || cause instanceof IOException
+           || cause instanceof BufferUnderflowException
+           || cause instanceof CancelException
+           || (sce.getMessage() != null && (sce.getMessage().indexOf(
+               "Could not create a new connection to server") != -1
+               || sce.getMessage().indexOf("socket timed out on client") != -1 || sce
+               .getMessage().indexOf(
+                   "connection was asynchronously destroyed") != -1))) {
+         throw new ServerConnectivityException(
+             "Connection error while authenticating user");
+       } else {
+         throw sce;
+       }
+     }
+   }
+ 
+   private Object executeWithPossibleReAuthentication(Connection conn, Op op)
+       throws Exception {
+     try {
+       return conn.execute(op);
+ 
+     } catch (ServerConnectivityException sce) {
+       Throwable cause = sce.getCause();
+       if ((cause instanceof AuthenticationRequiredException
+           && "User authorization attributes not found.".equals(cause
+               .getMessage())) 
+           || sce.getMessage().contains(
+               "Connection error while authenticating user")) {
+         // (ashetkar) Need a cleaner way of doing above check.
+         // 2nd exception-message above is from AbstractOp.sendMessage()
+ 
+         PoolImpl pool = (PoolImpl)PoolManagerImpl.getPMI().find(
+             this.endpointManager.getPoolName());
+         if (!pool.getMultiuserAuthentication()) {
+           Connection connImpl = this.connectionManager.getConnection(conn);
+           conn.getServer().setUserId(
+               (Long)AuthenticateUserOp.executeOn(connImpl, this));
+           return conn.execute(op);
+         } else {
+           UserAttributes ua = UserAttributes.userAttributes.get();
+           if (ua != null) {
+             authenticateMultiuser(pool, conn, ua);
+           }
+           return conn.execute(op);
+         }
+ 
+       } else {
+         throw sce;
+       }
+     }
+   }
+ 
+ }
+ 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
index 0000000,d973cd7..11d9248
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
@@@ -1,0 -1,124 +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 com.gemstone.gemfire.cache.operations.internal;
+ 
+ import com.gemstone.gemfire.SerializationException;
+ import com.gemstone.gemfire.cache.operations.GetOperationContext;
 -import com.gemstone.gemfire.internal.offheap.Chunk;
++import com.gemstone.gemfire.internal.offheap.ObjectChunk;
+ import com.gemstone.gemfire.internal.offheap.Releasable;
+ import com.gemstone.gemfire.internal.offheap.StoredObject;
+ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
+ 
+ /**
+  * This subclass's job is to keep customers from getting a reference to a value
+  * that is off-heap. Any access to an off-heap value should appear to the customer
+  * as a serialized value.
+  * 
+  * @author dschneider
+  *
+  */
+ public class GetOperationContextImpl extends GetOperationContext implements Releasable {
+ 
+   private boolean released;
+   
+   public GetOperationContextImpl(Object key, boolean postOperation) {
+     super(key, postOperation);
+   }
+ 
+   /**
+    * This method is for internal use and should not be on the public apis.
+    */
+   public @Unretained Object getRawValue() {
+     return super.getValue();
+   }
+   
+   @Override
+   public Object getObject() {
+     Object result = super.getObject();
+     if (result instanceof StoredObject) {
+       // For off-heap object act as if they are serialized forcing them to call getSerializedValue or getValue
+       result = null;
+     }
+     return result;
+   }
+ 
+   @Override
+   public void setObject(Object value, boolean isObject) {
+     this.released = false;
+     super.setObject(value, isObject);
+   }
+ 
+   @Override
+   public void setValue(Object value, boolean isObject) {
+     this.released = false;
+     super.setValue(value, isObject);
+   }
+ 
+   private void checkForReleasedOffHeapValue(Object v) {
+     // Note that we only care about Chunk (instead of all StoredObject) because it is the only one using a refcount
 -    if (this.released && v instanceof Chunk) {
++    if (this.released && v instanceof ObjectChunk) {
+       throw new IllegalStateException("Attempt to access off-heap value after the OperationContext callback returned.");
+     }
+   }
+   
+   @Override
+   public byte[] getSerializedValue() {
+     byte[] result = super.getSerializedValue();
+     if (result == null) {
+       Object v = super.getValue();
+       if (v instanceof StoredObject) {
+         checkForReleasedOffHeapValue(v);
+         result = ((StoredObject) v).getValueAsHeapByteArray();
+       }
+     }
+     return result;
+   }
+ 
+   @Override
+   public Object getDeserializedValue() throws SerializationException {
+     Object result = super.getDeserializedValue();
+     if (result instanceof StoredObject) {
+       checkForReleasedOffHeapValue(result);
+       result = ((StoredObject) result).getValueAsDeserializedHeapObject();
+     }
+     return result;
+   }
+ 
+   @Override
+   public Object getValue() {
+     Object result = super.getValue();
+     if (result instanceof StoredObject) {
+       checkForReleasedOffHeapValue(result);
+       // since they called getValue they don't care if it is serialized or deserialized so return it as serialized
+       result = ((StoredObject) result).getValueAsHeapByteArray();
+     }
+     return result;
+   }
+ 
+   @Override
+   public void release() {
+     // Note that if the context's value is stored off-heap
+     // and release has been called then we do not release
+     // our value (since this context did not retain it)
+     // but we do make sure that any future attempt to access
+     // the off-heap value fails.
 -    if (super.getValue() instanceof Chunk) {
++    if (super.getValue() instanceof ObjectChunk) {
+       this.released = true;
+     }
+   }
+ 
+ }



[073/100] [abbrv] incubator-geode git commit: GEODE-917: Merge branch 'feature/GEODE-917' into develop

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c741a68f/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
----------------------------------------------------------------------
diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
index 0000000,3133aa0..9bb573b
mode 000000,100644..100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
@@@ -1,0 -1,2231 +1,2231 @@@
+ /*
+  * 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 com.gemstone.gemfire.management.internal.cli.i18n;
+ 
+ import java.text.MessageFormat;
+ 
+ import com.gemstone.gemfire.cache.PartitionAttributesFactory;
+ import com.gemstone.gemfire.cache.server.CacheServer;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.distributed.internal.SharedConfiguration;
+ import com.gemstone.gemfire.internal.cache.xmlcache.CacheXml;
+ import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
+ 
+ /**-*
+  * Contains 'String' constants used as key to the Localized strings to be used
+  * in classes under <code>com.gemstone.gemfire.management.internal.cli</code>
+  * for Command Line Interface (CLI).
+  *
+  * @since 7.0
+  */
+ /*-
+  * NOTES:
+  * 1. CONVENTIONS: Defining constants for Command Name, option, argument, help:
+  * 1.1 Command Name:
+  *     Command name in BOLD. Multiple words separated by single underscore ('_')
+  *     E.g. COMPACT_DISK_STORE
+  * 1.2 Command Help Text:
+  *     Command name in BOLD followed by double underscore ('__') followed by HELP
+  *     in BOLD.
+  *     E.g.COMPACT_DISK_STORE__HELP
+  * 1.3 Command Option:
+  *     Command name in BOLD followed by double underscore ('__') followed by option
+  *     name in BOLD - multiple words concatenated by removing space.
+  *     E.g. for option "--disk-dirs" - COMPACT_DISK_STORE__DISKDIRS
+  * 1.4 Command Option Help:
+  *     As mentioned in 1.3, followed by double underscore ('__') followed by HELP
+  *     in BOLD.
+  *     E.g. COMPACT_DISK_STORE__DISKDIRS__HELP
+  * 1.5 Info/Error Message used in a command:
+  *     Command name in BOLD followed by double underscore ('__') followed by MSG
+  *     in BOLD followed by brief name for the message (Similar to used in LocalizedStrings).
+  *     E.g. COMPACT_DISK_STORE__MSG__ERROR_WHILE_COMPACTING = "Error occurred while compacting disk store."
+  * 1.6 Parameterized messages are supposed to be handled by users. It's
+  *     recommended to use the same conventions as used in LocalizedStrings.
+  *     E.g. COMPACT_DISK_STORE__MSG__ERROR_WHILE_COMPACTING__0 = "Error occurred while compacting disk store {0}."
+  *
+  * 2. Defining Topic constants:
+  * 2.1 The constants' names should begin with "TOPIC_"
+  *     E.g. TOPIC_GEMFIRE_REGION
+  * 2.2 Topic brief description should be defined with suffix "__DESC".
+  *     E.g. TOPIC_GEMFIRE_REGION__DESC
+  *
+  * 3. Order for adding constants: It should be alphabetically sorted at least
+  *    on the first name within the current group
+  */
+ public class CliStrings {
+ 
+   /*-*************************************************************************
+    *************                  T O P I C S                  ***************
+    ***************************************************************************/
+   public static final String DEFAULT_TOPIC_GEMFIRE = "GemFire";
+   public static final String DEFAULT_TOPIC_GEMFIRE__DESC = "vFabric GemFire is a distributed data management platform providing dynamic scalability, high performance and database-like persistence.";
+   public static final String TOPIC_GEMFIRE_REGION = "Region";
+   public static final String TOPIC_GEMFIRE_REGION__DESC = "A region is the core building block of the vFabric GemFire distributed system. Cached data is organized into regions and all data puts, gets, and querying activities are done against them.";
+   public static final String TOPIC_GEMFIRE_WAN = "WAN";
+   public static final String TOPIC_GEMFIRE_WAN__DESC = "For multiple data centers in remote locations, GemFire provides a WAN gateway to facilitate data sharing. The WAN gateway connects two or more remote sites and then sends asynchronous, batched updates as data is changed.";
+   public static final String TOPIC_GEMFIRE_JMX = "JMX";
+   public static final String TOPIC_GEMFIRE_JMX__DESC = "JMX technology provides the tools for building distributed, Web-based, modular and dynamic solutions for managing and monitoring devices, applications, and service-driven networks.";
+   public static final String TOPIC_GEMFIRE_DISKSTORE = "Disk Store";
+   public static final String TOPIC_GEMFIRE_DISKSTORE__DESC = "Disk stores are used to persist data to disk as a backup to your in-memory copy or as overflow storage when memory use is too high.";
+   public static final String TOPIC_GEMFIRE_LOCATOR = "Locator";
+   public static final String TOPIC_GEMFIRE_LOCATOR__DESC = "JVMs running GemFire discover each other through a TCP service named the locator.";
+   public static final String TOPIC_GEMFIRE_SERVER = "Server";
+   public static final String TOPIC_GEMFIRE_SERVER__DESC = "A server is GemFire cluster member which holds a GemFire cache. Depending on the topology used it can refer to either a system that responds to client requests or a system that is only a peer to other members.";
+   public static final String TOPIC_GEMFIRE_MANAGER = "Manager";
+   public static final String TOPIC_GEMFIRE_MANAGER__DESC = "The Manager is a member which has the additional role of a managing & monitoring the GemFire distributed system.";
+   public static final String TOPIC_GEMFIRE_STATISTICS = "Statistics";
+   public static final String TOPIC_GEMFIRE_STATISTICS__DESC = "Every application and server in a vFabric GemFire distributed system can be configured to perform statistical data collection for analysis.";
+   public static final String TOPIC_GEMFIRE_LIFECYCLE = "Lifecycle";
+   public static final String TOPIC_GEMFIRE_LIFECYCLE__DESC = "Launching, execution and termination of GemFire cluster members such as servers and locators.";
+   public static final String TOPIC_GEMFIRE_M_AND_M = "Management-Monitoring";
+   public static final String TOPIC_GEMFIRE_M_AND_M__DESC = "The management of and monitoring of GemFire systems using GemFire tools, such as vFabric GemFire Pulse or VSD or Data Browser, and JConsole, which is provided with the JDK(TM)";
+   public static final String TOPIC_GEMFIRE_DATA = "Data";
+   public static final String TOPIC_GEMFIRE_DATA__DESC = "User data as stored in regions of the GemFire distributed system.";
+   public static final String TOPIC_GEMFIRE_CONFIG = "Configuration";
+   public static final String TOPIC_GEMFIRE_CONFIG__DESC = "Configuration of vFabric GemFire Cache & Servers/Locators hosting the Cache.";
+   public static final String TOPIC_GEMFIRE_FUNCTION = "Function Execution";
+   public static final String TOPIC_GEMFIRE_FUNCTION__DESC = "The function execution service provides solutions for these application use cases: \n\tAn application that executes a server-side transaction or carries out data updates using the GemFire distributed locking service. \n\tAn application that needs to initialize some of its components once on each server, which might be used later by executed functions. Initialization and startup of a third-party service, such as a messaging service. \n\tAny arbitrary aggregation operation that requires iteration over local data sets that can be done more efficiently through a single call to the cache server. \n\tAny kind of external resource provisioning that can be done by executing a function on a server.";
+   public static final String TOPIC_GEMFIRE_HELP = "Help";
+   public static final String TOPIC_GEMFIRE_HELP__DESC = "Provides usage information for gfsh & its commands.";
+   public static final String TOPIC_GEMFIRE_DEBUG_UTIL = "Debug-Utility";
+   public static final String TOPIC_GEMFIRE_DEBUG_UTIL__DESC = "Debugging aids & utilities to use with vFabric GemFire.";
+   public static final String TOPIC_GFSH = "GFSH";
+   public static final String TOPIC_GFSH__DESC = "The GemFire SHell";
+   public static final String TOPIC_SHARED_CONFIGURATION = "Cluster Configuration";
+   public static final String TOPIC_SHARED_CONFIGURATION_HELP = "Configuration for cluster and various groups. It consists of cache.xml, gemfire properties and deployed jars.\nChanges due to gfshs command are persisted to the locator hosting the cluster configuration service.";
 -  public static final String TOPIC_CHANGELOGLEVEL = "User can change the log-level for a  memeber run time and generate log contents as per the need";
++  public static final String TOPIC_CHANGELOGLEVEL = "User can change the log-level for a  member run time and generate log contents as per the need";
+ 
+   /*-*************************************************************************
+    * ********* String Constants other than command name, options & help ******
+    * *************************************************************************/
+ 
+   public static final String DESKSTOP_APP_RUN_ERROR_MESSAGE = "Running desktop applications is not supported on %1$s.";
+   public static final String GEMFIRE_HOME_NOT_FOUND_ERROR_MESSAGE = "The GEMFIRE environment variable was not defined.  Please set the GEMFIRE environment variable to the directory where GemFire is installed.";
+   public static final String JAVA_HOME_NOT_FOUND_ERROR_MESSAGE = "Unable to locate the Java executables and dependencies.  Please set the JAVA_HOME environment variable.";
+   public static final String CACHE_XML_NOT_FOUND_MESSAGE = "Warning: The GemFire cache XML file {0} could not be found.";
+   public static final String GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE = "Warning: The GemFire {0}properties file {1} could not be found.";
+   public static final String MEMBER_NOT_FOUND_ERROR_MESSAGE = "Member {0} could not be found.  Please verify the member name or ID and try again.";
+   public static final String NO_MEMBERS_IN_GROUP_ERROR_MESSAGE = "No caching members for group {0} could be found.  Please verify the group and try again.";
+   public static final String NO_MEMBERS_FOUND_MESSAGE = "No Members Found";
+   public static final String NO_CACHING_MEMBERS_FOUND_MESSAGE = "No caching members found.";
+   public static final String COMMAND_FAILURE_MESSAGE = "Error occured while executing : {0}";
+   public static final String EXCEPTION_CLASS_AND_MESSAGE = "Exception : {0} , Message : {1}";
+   public static final String GROUP_EMPTY_ERROR_MESSAGE = "No members found in group : {0}";
+   public static final String REGION_NOT_FOUND = "Region : {0} not found";
+   public static final String INVALID_REGION_NAME = "Invalid region name";
+   public static final String INVALID_FILE_EXTENTION = "Invalid file type, the file extension must be \"{0}\"";
+   public static final String GEMFIRE_DATA_FILE_EXTENSION = ".gfd";
+   public static final String LOCATOR_HEADER = "Locator";
+   public static final String ERROR__MSG__HEADER = "Error";
+   public static final String ZIP_FILE_EXTENSION=".zip";
+   // This should be thrown for FunctionInvocationTargetException
+   public static final String COULD_NOT_EXECUTE_COMMAND_TRY_AGAIN = "Could not execute \" {0} \", please try again ";
+   public static final String UNEXPECTED_RETURN_TYPE_EXECUTING_COMMAND_ERROR_MESSAGE = "Received an unexpected return type ({0}) while executing command {1}.";
+   public static final String PROVIDE_ATLEAST_ONE_OPTION = "\"{0}\" requires that one or more parameters be provided.";
+   public static final String STATUS_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE = "Gfsh must be connected in order to get the status of a {0} by member name or ID.";
+   public static final String STOP_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE = "Gfsh must be connected in order to stop a {0} by member name or ID.";
+   public static final String PROVIDE_EITHER_MEMBER_OR_GROUP_MESSAGE = "Please provide either \"member\" or \"group\" option.";
+   public static final String GFSH_MUST_BE_CONNECTED_FOR_LAUNCHING_0 = "Gfsh must be connected for launching {0}";
+   public static final String GFSH_MUST_BE_CONNECTED_VIA_JMX_FOR_LAUNCHING_0 = "Gfsh must be connected via JMX for launching {0}";
+   public static final String ATTACH_API_IN_0_NOT_FOUND_ERROR_MESSAGE = "The JDK {0} is required by 'start', 'status' and 'stop' commands for Locators and Servers. Please set JAVA_HOME to the JDK Directory or add the JDK {0} to the classpath, restart Gfsh and try again.";
+   public static final String ASYNC_PROCESS_LAUNCH_MESSAGE = "Broken out of wait... the %1$s process will continue to startup in the background.%n";
+   public static final String NO_NON_LOCATOR_MEMBERS_FOUND = "No non-locator members found.";
+   public static final String NO_CLIENT_FOUND = "No client found on this server";
+   public static final String NO_CLIENT_FOUND_WITH_CLIENT_ID = "No client found with client-id : {0}";
+   public static final String ACTION_SUCCCEEDED_ON_MEMBER = "{0} on following members.";
+   public static final String OCCURRED_ON_MEMBERS = "Occurred on members";
+   public static final String SHARED_CONFIGURATION_NOT_STARTED = "Cluster configuration service is enabled but has not started yet.";
+   public static final String SHARED_CONFIGURATION_NO_LOCATORS_WITH_SHARED_CONFIGURATION = "No locators with cluster configuration enabled.";
+   public static final String SHARED_CONFIGURATION_FAILED_TO_PERSIST_COMMAND_CHANGES = "Failed to persist the configuration changes due to this command, Revert the command to maintain consistency.\nPlease use \"status cluster-config-service\" to determine whether Cluster configuration service is RUNNING.";
+   /* Other Constants */
+   public static final String GFSH__MSG__NO_LONGER_CONNECTED_TO_0 = "No longer connected to {0}.";
+   public static final String GFSHPARSER__MSG__REQUIRED_ARGUMENT_0 = "Required Argument: \"{0}\"";
+   public static final String GFSHPARSER__MSG__VALUE_REQUIRED_FOR_OPTION_0 = "Value is required for parameter \"{0}\"";
+   public static final String GFSHPARSER__MSG__AMBIGIOUS_COMMAND_0_FOR_ASSISTANCE_USE_1_OR_HINT_HELP = "Ambigious command \"{0}\" (for assistance press \"{1}\" or type \"hint\" or \"help <command name>\" & then hit ENTER)";
+   public static final String GFSHPARSER__MSG__COMMAND_ARGUMENT_0_IS_REQUIRED_USE_HELP = "Command parameter \"{0}\" is required. Use \"help <command name>\" for assistance.";
+   public static final String GFSHPARSER__MSG__COMMAND_OPTION_0_IS_REQUIRED_USE_HELP = "Parameter \"{0}\" is required. Use \"help <command name>\" for assistance.";
+   public static final String GFSHPARSER__MSG__VALUE_0_IS_NOT_APPLICABLE_FOR_1 = "Value \"{0}\" is not applicable for \"{1}\".";
+   public static final String GFSHPARSER__MSG__INVALID_COMMAND_STRING_0 = "Invalid command String: {0}";
+   public static final String GFSHPARSER__MSG__COMMAND_0_IS_NOT_VALID = "Command \"{0}\" is not valid.";
+   public static final String GFSHPARSER__MSG__NO_MATCHING_COMMAND = "No matching command";
+   public static final String GFSHPARSER__MSG__USE_0_HELP_COMMAND_TODISPLAY_DETAILS = "Use {0}help <command name> to display detailed usage information for a specific command.";
+   public static final String GFSHPARSER__MSG__HELP_CAN_ALSO_BE_OBTAINED_BY_0_KEY = "Help with command and parameter completion can also be obtained by entering all or a portion of either followed by the \"{0}\" key.";
+   public static final String GFSHPARSER__MSG__0_IS_NOT_AVAILABLE_REASON_1 = "\"{0}\" is not available. Reason: {1}";
+   public static final String GFSHPARSER__MSG__OTHER_COMMANDS_STARTING_WITH_0_ARE = "Other commands starting with \"{0}\" are: ";
+ 
+   public static final String ABSTRACTRESULTDATA__MSG__FILE_WITH_NAME_0_EXISTS_IN_1 = "File with name \"{0}\" already exists in \"{1}\".";
+   public static final String ABSTRACTRESULTDATA__MSG__PARENT_DIRECTORY_OF_0_DOES_NOT_EXIST = "Parent directory of \"{0}\" does not exist.";
+   public static final String ABSTRACTRESULTDATA__MSG__PARENT_DIRECTORY_OF_0_IS_NOT_WRITABLE = "Parent directory of \"{0}\" is not writable.";
+   public static final String ABSTRACTRESULTDATA__MSG__PARENT_OF_0_IS_NOT_DIRECTORY = "Parent of \"{0}\" is not a directory.";
+ 
+   public static final String AVAILABILITYTARGET_MSG_DEFAULT_UNAVAILABILITY_DESCRIPTION = "Requires connection.";
+ 
+   public static final String LAUNCHERLIFECYCLECOMMANDS__MSG__FAILED_TO_START_0_REASON_1 = "Failed to start {0}. Reason: {1}";
+ 
+   public static final String GFSH__PLEASE_CHECK_LOGS_AT_0 = "Please check logs {0}";
+ 
+   /*-**************************************************************************
+    * *********** COMMAND NAME, OPTION, ARGUMENT, HELP, MESSAGES ****************
+    * **************************************************************************/
+   /* 'alter disk-store' command */
+   public static final String ALTER_DISK_STORE = "alter disk-store";
+   public static final String ALTER_DISK_STORE__HELP = "Alter some options for a region or remove a region in an offline disk store.";
+   public static final String ALTER_DISK_STORE__DISKSTORENAME = "name";
+   public static final String ALTER_DISK_STORE__DISKSTORENAME__HELP = "Name of the disk store whose contents will be altered.";
+   public static final String ALTER_DISK_STORE__REGIONNAME = "region";
+   public static final String ALTER_DISK_STORE__REGIONNAME__HELP = "Name/Path of the region in the disk store to alter.";
+   public static final String ALTER_DISK_STORE__DISKDIRS = "disk-dirs";
+   public static final String ALTER_DISK_STORE__DISKDIRS__HELP = "Directories where data for the disk store was previously written.";
+   public static final String ALTER_DISK_STORE__LRU__EVICTION__ALGORITHM = "lru-algorthm";
+   public static final String ALTER_DISK_STORE__LRU__EVICTION__ALGORITHM__HELP = "Least recently used eviction algorithm.  Valid values are: none, lru-entry-count, lru-heap-percentage and lru-memory-size.";
+   public static final String ALTER_DISK_STORE__LRU__EVICTION__ACTION = "lru-action";
+   public static final String ALTER_DISK_STORE__LRU__EVICTION__ACTION__HELP = "Action to take when evicting entries from the region. Valid values are: none, overflow-to-disk and local-destroy.";
+   public static final String ALTER_DISK_STORE__LRU__EVICTION__LIMIT = "lru-limit";
+   public static final String ALTER_DISK_STORE__LRU__EVICTION__LIMIT__HELP = "Number of entries allowed in the region before eviction will occur.";
+   public static final String ALTER_DISK_STORE__CONCURRENCY__LEVEL = "concurrency-level";
+   public static final String ALTER_DISK_STORE__CONCURRENCY__LEVEL__HELP = "An estimate of the maximum number of application threads that will concurrently modify a region at one time. This attribute does not apply to partitioned regions.";
+   public static final String ALTER_DISK_STORE__INITIAL__CAPACITY = "initial-capacity";
+   public static final String ALTER_DISK_STORE__INITIAL__CAPACITY__HELP = "Together with --load-factor, sets the parameters on the underlying java.util.ConcurrentHashMap used for storing region entries.";
+   public static final String ALTER_DISK_STORE__LOAD__FACTOR = "load-factor";
+   public static final String ALTER_DISK_STORE__LOAD__FACTOR__HELP = "Together with --initial-capacity, sets the parameters on the underlying java.util.ConcurrentHashMap used for storing region entries. This must be a floating point number between 0 and 1, inclusive.";
+   public static final String ALTER_DISK_STORE__COMPRESSOR = "compressor";
+   public static final String ALTER_DISK_STORE__COMPRESSOR__HELP = "The fully-qualifed class name of the Compressor to use when compressing region entry values. A value of 'none' will remove the Compressor.";
+   public static final String ALTER_DISK_STORE__STATISTICS__ENABLED = "enable-statistics";
+   public static final String ALTER_DISK_STORE__STATISTICS__ENABLED__HELP = "Whether to enable statistics. Valid values are: true and false.";
+   public static final String ALTER_DISK_STORE__OFF_HEAP = "off-heap";
+   public static final String ALTER_DISK_STORE__OFF_HEAP__HELP = "Whether to use off-heap memory for the region. Valid values are: true and false.";
+   public static final String ALTER_DISK_STORE__REMOVE = "remove";
+   public static final String ALTER_DISK_STORE__REMOVE__HELP = "Whether to remove the region from the disk store.";
+ 
+   /* 'alter region' command */
+   public static final String ALTER_REGION = "alter region";
+   public static final String ALTER_REGION__HELP = "Alter a region with the given path and configuration.";
+   public static final String ALTER_REGION__REGION = "name";
+   public static final String ALTER_REGION__REGION__HELP = "Name/Path of the region to be altered.";
+   public static final String ALTER_REGION__GROUP = "group";
+   public static final String ALTER_REGION__GROUP__HELP = "Group(s) of members on which the region will be altered.";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONIDLETIME = "entry-idle-time-expiration";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONIDLETIME__HELP = "How long the region's entries can remain in the cache without being accessed. The default is no expiration of this type.";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONIDLETIMEACTION = "entry-idle-time-expiration-action";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONIDLETIMEACTION__HELP = "Action to be taken on an entry that has exceeded the idle expiration.";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONTIMETOLIVE = "entry-time-to-live-expiration";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONTIMETOLIVE__HELP = "How long the region's entries can remain in the cache without being accessed or updated. The default is no expiration of this type.";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONTTLACTION = "entry-time-to-live-expiration-action";
+   public static final String ALTER_REGION__ENTRYEXPIRATIONTTLACTION__HELP = "Action to be taken on an entry that has exceeded the TTL expiration.";
+   public static final String ALTER_REGION__REGIONEXPIRATIONIDLETIME = "region-idle-time-expiration";
+   public static final String ALTER_REGION__REGIONEXPIRATIONIDLETIME__HELP = "How long the region can remain in the cache without being accessed. The default is no expiration of this type.";
+   public static final String ALTER_REGION__REGIONEXPIRATIONIDLETIMEACTION = "region-idle-time-expiration-action";
+   public static final String ALTER_REGION__REGIONEXPIRATIONIDLETIMEACTION__HELP = "Action to be taken on a region that has exceeded the idle expiration.";
+   public static final String ALTER_REGION__REGIONEXPIRATIONTTL = "region-time-to-live-expiration";
+   public static final String ALTER_REGION__REGIONEXPIRATIONTTL__HELP = "How long the region can remain in the cache without being accessed or updated. The default is no expiration of this type.";
+   public static final String ALTER_REGION__REGIONEXPIRATIONTTLACTION = "region-time-to-live-expiration-action";
+   public static final String ALTER_REGION__REGIONEXPIRATIONTTLACTION__HELP = "Action to be taken on a region that has exceeded the TTL expiration.";
+   public static final String ALTER_REGION__CACHELISTENER = "cache-listener";
+   public static final String ALTER_REGION__CACHELISTENER__HELP = "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.";
+   public static final String ALTER_REGION__CACHELOADER = "cache-loader";
+   public static final String ALTER_REGION__CACHELOADER__HELP = "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.";
+   public static final String ALTER_REGION__CACHEWRITER = "cache-writer";
+   public static final String ALTER_REGION__CACHEWRITER__HELP = "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.";
+   public static final String ALTER_REGION__ASYNCEVENTQUEUEID = "async-event-queue-id";
+   public static final String ALTER_REGION__ASYNCEVENTQUEUEID__HELP = "IDs of the Async Event Queues that will be used for write-behind operations."; // TODO - Abhishek Is this correct?
+   public static final String ALTER_REGION__GATEWAYSENDERID = "gateway-sender-id";
+   public static final String ALTER_REGION__GATEWAYSENDERID__HELP = "IDs of the Gateway Senders to which data will be routed.";
+   public static final String ALTER_REGION__CLONINGENABLED = "enable-cloning";
+   public static final String ALTER_REGION__CLONINGENABLED__HELP = "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.";
+   public static final String ALTER_REGION__EVICTIONMAX = "eviction-max";
+   public static final String ALTER_REGION__EVICTIONMAX__HELP = "Maximum value for the Eviction Attributes which the Eviction Algorithm uses to determine when to perform its Eviction Action. The unit of the maximum value is determined by the Eviction Algorithm.";
+   public static final String ALTER_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_CACHELISTENER_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__CACHELISTENER + ". \"{0}\" is not valid.";
+   public static final String ALTER_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_CACHEWRITER_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__CACHEWRITER + ". \"{0}\" is not valid.";
+   public static final String ALTER_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_CACHELOADER_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__CACHELOADER + ". \"{0}\" is not valid.";
+   public static final String ALTER_REGION__MSG__REGION_0_ALTERED_ON_1 = "Region \"{0}\" altered on \"{1}\"";
+   public static final String ALTER_REGION__MSG__COULDNOT_FIND_CLASS_0_SPECIFIED_FOR_1 = "Could not find class \"{0}\" specified for \"{1}\".";
+   public static final String ALTER_REGION__MSG__COULDNOT_INSTANTIATE_CLASS_0_SPECIFIED_FOR_1 = "Could not instantiate class \"{0}\" specified for \"{1}\".";
+   public static final String ALTER_REGION__MSG__CLASS_SPECIFIED_FOR_0_SPECIFIED_FOR_1_IS_NOT_OF_EXPECTED_TYPE = "Class \"{0}\" specified for \"{1}\" is not of an expected type.";
+   public static final String ALTER_REGION__MSG__COULDNOT_ACCESS_CLASS_0_SPECIFIED_FOR_1 = "Could not access class \"{0}\" specified for \"{1}\".";
+   public static final String ALTER_REGION__MSG__SPECIFY_POSITIVE_INT_FOR_EVICTIONMAX_0_IS_NOT_VALID = "Specify 0 or a positive integer value for "
+       + CliStrings.ALTER_REGION__EVICTIONMAX + ".  \"{0}\" is not valid.";
+   public static final String ALTER_REGION__MSG__REGION_DOESNT_EXIST_0 = "Region doesn't exist: {0}";
+ 
+   public static final String ALTER_RUNTIME_CONFIG = "alter runtime";
+   public static final String ALTER_RUNTIME_CONFIG__HELP = "Alter a subset of member or members configuration properties while running.";
+   public static final String ALTER_RUNTIME_CONFIG__MEMBER = "member";
+   public static final String ALTER_RUNTIME_CONFIG__MEMBER__HELP = "Name/Id of the member in whose configuration will be altered.";
+   public static final String ALTER_RUNTIME_CONFIG__GROUP = "group";
+   public static final String ALTER_RUNTIME_CONFIG__GROUP__HELP = "Group of members whose configuration will be altered.";
+   public static final String ALTER_RUNTIME_CONFIG__ARCHIVE__FILE__SIZE__LIMIT = DistributionConfig.ARCHIVE_FILE_SIZE_LIMIT_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__ARCHIVE__FILE__SIZE__LIMIT__HELP = "Archive file size limit. Valid values are (in megabytes): "
+       + DistributionConfig.MIN_ARCHIVE_FILE_SIZE_LIMIT + " - " + DistributionConfig.MAX_ARCHIVE_FILE_SIZE_LIMIT + ".";
+   public static final String ALTER_RUNTIME_CONFIG__ARCHIVE__DISK__SPACE__LIMIT = DistributionConfig.ARCHIVE_DISK_SPACE_LIMIT_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__ARCHIVE__DISK__SPACE__LIMIT__HELP = "Archive disk space limit. Valid values are (in megabytes): "
+       + DistributionConfig.MIN_ARCHIVE_DISK_SPACE_LIMIT + " - " + DistributionConfig.MAX_ARCHIVE_DISK_SPACE_LIMIT + ".";
+   public static final String ALTER_RUNTIME_CONFIG__LOG__FILE__SIZE__LIMIT = DistributionConfig.LOG_FILE_SIZE_LIMIT_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__LOG__FILE__SIZE__LIMIT__HELP = "Log file size limit. Valid values are (in megabytes): "
+       + DistributionConfig.MIN_LOG_FILE_SIZE_LIMIT + " - " + DistributionConfig.MAX_LOG_FILE_SIZE_LIMIT + ".";
+   public static final String ALTER_RUNTIME_CONFIG__LOG__DISK__SPACE__LIMIT = DistributionConfig.LOG_DISK_SPACE_LIMIT_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__LOG__DISK__SPACE__LIMIT__HELP = "Log disk space limit. Valid values are (in megabytes): "
+       + DistributionConfig.MIN_LOG_DISK_SPACE_LIMIT + " - " + DistributionConfig.MAX_LOG_DISK_SPACE_LIMIT + ".";
+   public static final String ALTER_RUNTIME_CONFIG__LOG__LEVEL = DistributionConfig.LOG_LEVEL_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__LOG__LEVEL__HELP = "Log level. Valid values are: none, error, info, config , warning, severe, fine, finer and finest.";
+   public static final String ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLING__ENABLED = "enable-statistics";
+   public static final String ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLING__ENABLED__HELP = "Whether statistic sampling should be enabled. Valid values are: true and false.";
+   public static final String ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLE__RATE = DistributionConfig.STATISTIC_SAMPLE_RATE_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__STATISTIC__SAMPLE__RATE__HELP = "Statistic sampling rate. Valid values are (in milliseconds): "
+       + DistributionConfig.MIN_STATISTIC_SAMPLE_RATE + " - " + DistributionConfig.MAX_STATISTIC_SAMPLE_RATE + ".";
+   public static final String ALTER_RUNTIME_CONFIG__STATISTIC__ARCHIVE__FILE = DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME;
+   public static final String ALTER_RUNTIME_CONFIG__STATISTIC__ARCHIVE__FILE__HELP = "File to which the statistics will be written.";
+   
+   public static final String ALTER_RUNTIME_CONFIG__COPY__ON__READ = CacheXml.COPY_ON_READ;
+   public static final String ALTER_RUNTIME_CONFIG__COPY__ON__READ__HELP = "Sets the \"copy on read\" feature for cache read operations";
+   public static final String ALTER_RUNTIME_CONFIG__LOCK__LEASE = CacheXml.LOCK_LEASE;
+   public static final String ALTER_RUNTIME_CONFIG__LOCK__LEASE__HELP = "Sets the length, in seconds, of distributed lock leases obtained by this cache.";
+   public static final String ALTER_RUNTIME_CONFIG__LOCK__TIMEOUT = CacheXml.LOCK_TIMEOUT;
+   public static final String ALTER_RUNTIME_CONFIG__LOCK__TIMEOUT__HELP  = "Sets the number of seconds a cache operation may wait to obtain a distributed lock lease before timing out.";  
+   public static final String ALTER_RUNTIME_CONFIG__MESSAGE__SYNC__INTERVAL = CacheXml.MESSAGE_SYNC_INTERVAL;
+   public static final String ALTER_RUNTIME_CONFIG__MESSAGE__SYNC__INTERVAL__HELP = "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";
+   public static final String ALTER_RUNTIME_CONFIG__SEARCH__TIMEOUT = CacheXml.SEARCH_TIMEOUT;
+   public static final String ALTER_RUNTIME_CONFIG__SEARCH__TIMEOUT__HELP = "Sets the number of seconds a cache get operation can spend searching for a value.";
+   
+   
+   public static final String ALTER_RUNTIME_CONFIG__SUCCESS__MESSAGE = "Runtime configuration altered successfully for the following member(s)";
+   public static final String ALTER_RUNTIME_CONFIG__MEMBER__NOT__FOUND = "Member : {0} not found";
+   public static final String ALTER_RUNTIME_CONFIG__RELEVANT__OPTION__MESSAGE = "Please provide a relevant parameter(s)";
+ 
+   /* 'backup disk-store' command */
+   public static final String BACKUP_DISK_STORE = "backup disk-store";
+   public static final String BACKUP_DISK_STORE__HELP = "Perform a backup on all members with persistent data. The target directory must exist on all members, but can be either local or shared. This command can safely be executed on active members and is strongly recommended over copying files via operating system commands.";
+   public static final String BACKUP_DISK_STORE__DISKDIRS = "dir";
+   public static final String BACKUP_DISK_STORE__BASELINEDIR = "baseline-dir";
+   public static final String BACKUP_DISK_STORE__BASELINEDIR__HELP = "Directory which contains the baseline backup used for comparison during an incremental backup.";
+   public static final String BACKUP_DISK_STORE__DISKDIRS__HELP = "Directory to which backup files will be written.";
+   public static final String BACKUP_DISK_STORE_MSG_BACKED_UP_DISK_STORES = "The following disk stores were backed up successfully";
+   public static final String BACKUP_DISK_STORE_MSG_OFFLINE_DISK_STORES = "The backup may be incomplete. The following disk stores are not online";
+   public static final String BACKUP_DISK_STORE_MSG_HOST = "Host";
+   public static final String BACKUP_DISK_STORE_MSG_DIRECTORY = "Directory";
+   public static final String BACKUP_DISK_STORE_MSG_UUID = "UUID";
+   public static final String BACKUP_DISK_STORE_MSG_MEMBER = "Member";
+   public static final String BACKUP_DISK_STORE_MSG_NO_DISKSTORES_BACKED_UP = "No disk store(s) were backed up.";
+ 
+   /* 'compact disk-store' command */
+   public static final String COMPACT_DISK_STORE = "compact disk-store";
+   public static final String COMPACT_DISK_STORE__HELP = "Compact a disk store on all members with that disk store. This command uses the compaction threshold that each member has configured for its disk stores. The disk store must have \"allow-force-compaction\" set to true.";
+   public static final String COMPACT_DISK_STORE__NAME = "name";
+   public static final String COMPACT_DISK_STORE__NAME__HELP = "Name of the disk store to be compacted.";
+   public static final String COMPACT_DISK_STORE__GROUP = "group";
+   public static final String COMPACT_DISK_STORE__GROUP__HELP = "Group(s) of members that will perform disk compaction. If no group is specified the disk store will be compacted by all members.";
+   public static final String COMPACT_DISK_STORE__DISKSTORE_0_DOESNOT_EXIST = "Disk store \"{0}\" does not exist.";
+   public static final String COMPACT_DISK_STORE__MSG__FOR_GROUP = " for group(s) \"{0}\"";
+   public static final String COMPACT_DISK_STORE__NO_MEMBERS_FOUND_IN_SPECIFED_GROUP = "No members found in the specified group(s) \"{0}\".";
+   public static final String COMPACT_DISK_STORE__COMPACTION_ATTEMPTED_BUT_NOTHING_TO_COMPACT = "Attempted to compact disk store, but there was nothing to do.";
+   public static final String COMPACT_DISK_STORE__ERROR_WHILE_COMPACTING_REASON_0 = "An error occurred while doing compaction: \"{0}\"";
+ 
+   /* 'compact offline-disk-store' command */
+   public static final String COMPACT_OFFLINE_DISK_STORE = "compact offline-disk-store";
+   public static final String COMPACT_OFFLINE_DISK_STORE__HELP = "Compact an offline disk store. If the disk store is large, additional memory may need to be allocated to the process using the --J=-Xmx??? parameter.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__NAME = "name";
+   public static final String COMPACT_OFFLINE_DISK_STORE__NAME__HELP = "Name of the offline disk store to be compacted.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__DISKDIRS = "disk-dirs";
+   public static final String COMPACT_OFFLINE_DISK_STORE__DISKDIRS__HELP = "Directories where data for the disk store was previously written.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MAXOPLOGSIZE = "max-oplog-size";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MAXOPLOGSIZE__HELP = "Maximum size (in megabytes) of the oplogs created by compaction.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__J = "J";
+   public static final String COMPACT_OFFLINE_DISK_STORE__J__HELP = "Arguments passed to the Java Virtual Machine performing the compact operation on the disk store.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__DISKSTORE_0_DOESNOT_EXIST = "Disk store \"{0}\" does not exist.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__COMPACTION_ATTEMPTED_BUT_NOTHING_TO_COMPACT = "Attempted to compact disk store, but there was nothing to do.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__ERROR_WHILE_COMPACTING_REASON_0 = "An error occurred while doing compaction: \"{0}\"";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__VERIFY_WHETHER_DISKSTORE_EXISTS_IN_0 = "Verify whether the disk store exists in \"{0}\".";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__DISKSTORE_IN_USE_COMPACT_DISKSTORE_CAN_BE_USED = "This disk store is in use by other process. \""
+       + CliStrings.COMPACT_DISK_STORE + "\" can be used to compact disk store that is current in use.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__CANNOT_ACCESS_DISKSTORE_0_FROM_1_CHECK_GFSH_LOGS = "Can not access disk store \"{0}\" from  \"{1}\". Check "
+       + com.gemstone.gemfire.management.internal.cli.shell.Gfsh.GFSH_APP_NAME + " logs for error.";
+   public static final String COMPACT_OFFLINE_DISK_STORE__MSG__ERROR_WHILE_COMPACTING_DISKSTORE_0_WITH_1_REASON_2 = "While compacting disk store={0} {1}. Reason: {2}";
+ 
+   /* connect command */
+   public static final String CONNECT = "connect";
+   public static final String CONNECT__HELP = "Connect to a jmx-manager either directly or via a Locator. If connecting via a Locator, and a jmx-manager doesn't already exist, the Locator will start one.";
+   public static final String CONNECT__JMX_MANAGER = "jmx-manager";
+   public static final String CONNECT__JMX_MANAGER__HELP = "Network address of the jmx-manager in the form: host[port].";
+   public static final String CONNECT__LOCATOR = "locator";
+   public static final String CONNECT__LOCATOR__HELP = "Network address of the Locator in the form: host[port].";
+   public static final String CONNECT__URL = "url";
+   public static final String CONNECT__DEFAULT_BASE_URL = "http://localhost:" + DistributionConfig.DEFAULT_HTTP_SERVICE_PORT + "/gemfire/v1";
+   public static final String CONNECT__DEFAULT_SSL_BASE_URL = "https://localhost:" + DistributionConfig.DEFAULT_HTTP_SERVICE_PORT + "/gemfire/v1";
+   public static final String CONNECT__URL__HELP = "Indicates the base URL to the Manager's HTTP service.  For example: 'http://<host>:<port>/gemfire/v1' Default is '" + CONNECT__DEFAULT_BASE_URL + "'";
+   public static final String CONNECT__USE_HTTP = "use-http";
+   public static final String CONNECT__USE_HTTP__HELP = "Connects to Manager by sending HTTP requests to HTTP service hostint the Management REST API.  You must first 'disconnect' in order to reconnect to the Manager via locator or jmx-manager using JMX.";
+   public static final String CONNECT__USERNAME = "user";
+   public static final String CONNECT__USERNAME__HELP = "User name to securely connect to the jmx-manager. If the --password parameter is not specified then it will be prompted for.";
+   public static final String CONNECT__PASSWORD = "password";
+   public static final String CONNECT__PASSWORD__HELP = "Password to securely connect to the jmx-manager.";
+   public static final String CONNECT__KEY_STORE = "key-store";
+   public static final String CONNECT__KEY_STORE__HELP = "Java keystore file containing this application's certificate and private key. If the --key-store-password parameter is not specified then it will be prompted for.";
+   public static final String CONNECT__KEY_STORE_PASSWORD = "key-store-password";
+   public static final String CONNECT__KEY_STORE_PASSWORD__HELP = "Password to access the private key from the keystore file specified by --key-store.";
+   public static final String CONNECT__TRUST_STORE = "trust-store";
+   public static final String CONNECT__TRUST_STORE__HELP = "Java keystore file containing the collection of CA certificates trusted by this application. If the --trust-store-password parameter is not specified then it will be prompted for.";
+   public static final String CONNECT__TRUST_STORE_PASSWORD = "trust-store-password";
+   public static final String CONNECT__TRUST_STORE_PASSWORD__HELP = "Password to unlock the keystore file specified by --trust-store";
+   public static final String CONNECT__SSL_CIPHERS = "ciphers";
+   public static final String CONNECT__SSL_CIPHERS__HELP = "SSL/TLS ciphers used when encrypting the connection. The default is \"any\".";
+   public static final String CONNECT__SSL_PROTOCOLS = "protocols";
+   public static final String CONNECT__SSL_PROTOCOLS__HELP = "SSL/TLS protocol versions to enable when encrypting the connection. The default is \"any\".";
+   public static final String CONNECT__MSG__CONNECTING_TO_LOCATOR_AT_0 = "Connecting to Locator at {0} ..";
+   public static final String CONNECT__SECURITY_PROPERTIES = "security-properties-file";
+   public static final String CONNECT__SECURITY_PROPERTIES__HELP = "The gfsecurity.properties file for configuring gfsh to connect to the Locator/Manager. The file's path can be absolute or relative to gfsh directory.";
+   public static final String CONNECT__USE_SSL = "use-ssl";
+   public static final String CONNECT__USE_SSL__HELP = "Whether to use SSL for communication with Locator and/or JMX Manager. If set to \"true\", will also read \"gfsecurity.properties\". SSL Options take precedence over proeprties file. If none are specified, defaults will be used. The default value for this options is \"false\".";
+   public static final String CONNECT__MSG__CONNECTING_TO_MANAGER_AT_0 = "Connecting to Manager at {0} ..";
+   public static final String CONNECT__MSG__CONNECTING_TO_MANAGER_HTTP_SERVICE_AT_0 = "Connecting to Manager's HTTP service at {0} ..";
+   public static final String CONNECT__MSG__LOCATOR_COULD_NOT_FIND_MANAGER = "Locator could not find a JMX Manager";
+   public static final String CONNECT__MSG__JMX_PASSWORD_MUST_BE_SPECIFIED = "jmx password must be specified.";
+   public static final String CONNECT__MSG__ALREADY_CONNECTED = "Already connected to: {0}";
+   public static final String CONNECT__MSG__SUCCESS = "Successfully connected to: {0}";
+   public static final String CONNECT__MSG__ERROR = "Could not connect to : {0}. {1}";
+   public static final String CONNECT__MSG__SERVICE_UNAVAILABLE_ERROR = "Could not find a GemFire jmx-manager service at {0}.";
+   public static final String CONNECT__MSG__COULD_NOT_CONNECT_TO_LOCATOR_0 = "Could not connect to GemFire Locator service at {0}.";
+   public static final String CONNECT__MSG__COULD_NOT_READ_CONFIG_FROM_0 = "Could not read config from {0}.";
+   public static final String CONNECT__MSG__COULD_NOT_CONNECT_TO_LOCATOR_0_POSSIBLY_SSL_CONFIG_ERROR = "Could not connect to Locator at {0}."+Gfsh.LINE_SEPARATOR+"Possible reason: Wrong or no SSL configuration provided.";
+   public static final String CONNECT__MSG__COULD_NOT_CONNECT_TO_MANAGER_0_POSSIBLY_SSL_CONFIG_ERROR = "Could not connect to Manager at {0}."+Gfsh.LINE_SEPARATOR+"Possible reason: Wrong or no SSL configuration provided.";
+ 
+   /* 'create async-event-queue' command */
+   public static final String CREATE_ASYNC_EVENT_QUEUE = "create async-event-queue";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__HELP = "Create Async Event Queue.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ID = "id";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ID__HELP = "ID of the queue to be created.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__PARALLEL = "parallel";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__PARALLEL__HELP = "Whether this queue is parallel.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__BATCH_SIZE = "batch-size";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__BATCH_SIZE__HELP = "Maximum number of events that a batch can contain.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__BATCHTIMEINTERVAL = "batch-time-interval";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__BATCHTIMEINTERVAL__HELP = "Maximum amount of time, in ms, that can elapse before a batch is delivered.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ENABLEBATCHCONFLATION = "enable-batch-conflation";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ENABLEBATCHCONFLATION__HELP = "Whether to enable batch conflation.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__PERSISTENT = "persistent";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__PERSISTENT__HELP = "Whether events should be persisted to a disk store.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__DISK_STORE = "disk-store";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__DISK_STORE__HELP = "Disk store to be used by this queue.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__DISKSYNCHRONOUS = "disk-synchronous";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__DISKSYNCHRONOUS__HELP = "Whether disk writes are synchronous.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__MAXIMUM_QUEUE_MEMORY = "max-queue-memory";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__MAXIMUM_QUEUE_MEMORY__HELP = "Maximum amount of memory, in megabytes, that the queue can consume before overflowing to disk.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__GATEWAYEVENTFILTER = "gateway-event-filter";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__GATEWAYEVENTFILTER__HELP = "List of fully qualified class names of GatewayEventFilters for this queue.  These classes filter events before dispatching to remote servers.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ORDERPOLICY = "order-policy";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ORDERPOLICY__HELP = "Policy for dispatching events when --dispatcher-threads is > 1. Possible values are 'THREAD', 'KEY', 'PARTITION'.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__DISPATCHERTHREADS = "dispatcher-threads";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__DISPATCHERTHREADS__HELP = "Number of threads to use for sending events.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__SUBSTITUTION_FILTER = "gateway-event-substitution-filter";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__SUBSTITUTION_FILTER__HELP = "Fully qualified class name of the GatewayEventSubstitutionFilter for this queue.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__LISTENER = "listener";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__LISTENER__HELP = "Fully qualified class name of the AsyncEventListener for this queue.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__LISTENER_PARAM_AND_VALUE = "listener-param";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__LISTENER_PARAM_AND_VALUE__HELP = "Parameter name for the AsyncEventListener.  Optionally, parameter names may be followed by # and a value for the parameter.  Example: --listener-param=loadAll --listener-param=maxRead#1024";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__GROUP = "group";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__GROUP__HELP = "Group(s) of members on which queue will be created. If no group is specified the queue will be created on all members.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__ERROR_WHILE_CREATING_REASON_0 = "An error occurred while creating the queue: {0}";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__MSG__COULDNOT_ACCESS_CLASS_0_SPECIFIED_FOR_1 = "Could not access class \"{0}\" specified for \"{1}\".";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__MSG__COULDNOT_INSTANTIATE_CLASS_0_SPECIFIED_FOR_1 = "Could not instantiate class \"{0}\" specified for \"{1}\".";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__MSG__CLASS_0_SPECIFIED_FOR_1_IS_NOT_OF_EXPECTED_TYPE = "Class \"{0}\" specified for \"{1}\" is not of an expected type.";
+   public static final String CREATE_ASYNC_EVENT_QUEUE__MSG__COULDNOT_FIND_CLASS_0_SPECIFIED_FOR_1 = "Could not find class \"{0}\" specified for \"{1}\".";
+ 
+   /* 'create disk-store' command */
+   public static final String CREATE_DISK_STORE = "create disk-store";
+   public static final String CREATE_DISK_STORE__HELP = "Create a disk store.";
+   public static final String CREATE_DISK_STORE__NAME = "name";
+   public static final String CREATE_DISK_STORE__NAME__HELP = "Name of the disk store to be created.";
+   public static final String CREATE_DISK_STORE__ALLOW_FORCE_COMPACTION = "allow-force-compaction";
+   public static final String CREATE_DISK_STORE__ALLOW_FORCE_COMPACTION__HELP = "Whether to allow manual compaction through the API or command-line tools.";
+   public static final String CREATE_DISK_STORE__AUTO_COMPACT = "auto-compact";
+   public static final String CREATE_DISK_STORE__AUTO_COMPACT__HELP = "Whether to automatically compact a file when it reaches the compaction-threshold.";
+   public static final String CREATE_DISK_STORE__COMPACTION_THRESHOLD = "compaction-threshold";
+   public static final String CREATE_DISK_STORE__COMPACTION_THRESHOLD__HELP = "Percentage of garbage allowed in the file before it is eligible for compaction.";
+   public static final String CREATE_DISK_STORE__MAX_OPLOG_SIZE = "max-oplog-size";
+   public static final String CREATE_DISK_STORE__MAX_OPLOG_SIZE__HELP = "The largest size, in megabytes, to allow an operation log to become before automatically rolling to a new file.";
+   public static final String CREATE_DISK_STORE__QUEUE_SIZE = "queue-size";
+   public static final String CREATE_DISK_STORE__QUEUE_SIZE__HELP = "For asynchronous queueing. The maximum number of operations to allow into the write queue before automatically flushing the queue. The default of 0 indicates no limit.";
+   public static final String CREATE_DISK_STORE__TIME_INTERVAL = "time-interval";
+   public static final String CREATE_DISK_STORE__TIME_INTERVAL__HELP = "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.";
+   public static final String CREATE_DISK_STORE__WRITE_BUFFER_SIZE = "write-buffer-size";
+   public static final String CREATE_DISK_STORE__WRITE_BUFFER_SIZE__HELP = "Size of the buffer used to write to disk.";
+   public static final String CREATE_DISK_STORE__DIRECTORY_AND_SIZE = "dir";
+   public static final String CREATE_DISK_STORE__DIRECTORY_AND_SIZE__HELP = "Directories where the disk store files will be written, the directories will be created if they don't exist.  Optionally, directory names may be followed by # and the maximum number of megabytes that the disk store can use in the directory.  Example: --dir=/data/ds1 --dir=/data/ds2#5000";
+   public static final String CREATE_DISK_STORE__GROUP = "group";
+   public static final String CREATE_DISK_STORE__GROUP__HELP = "Group(s) of members on which the disk store will be created. If no group is specified the disk store will be created on all members.";
+   public static final String CREATE_DISK_STORE__DISK_USAGE_WARNING_PCT = "disk-usage-warning-percentage";
+   public static final String CREATE_DISK_STORE__DISK_USAGE_WARNING_PCT__HELP = "Warning percentage for disk volume usage.";
+   public static final String CREATE_DISK_STORE__DISK_USAGE_CRITICAL_PCT = "disk-usage-critical-percentage";
+   public static final String CREATE_DISK_STORE__DISK_USAGE_CRITICAL_PCT__HELP = "Critical percentage for disk volume usage.";
+   public static final String CREATE_DISK_STORE__ERROR_WHILE_CREATING_REASON_0 = "An error occurred while creating the disk store: \"{0}\"";
+ 
+   /* create index */
+   public static final String CREATE_INDEX = "create index";
+   public static final String CREATE_INDEX__HELP = "Create an index that can be used when executing queries.";
+   public static final String CREATE_INDEX__NAME = "name";
+   public static final String CREATE_INDEX__NAME__HELP = "Name of the index to create.";
+   public static final String CREATE_INDEX__EXPRESSION = "expression";
+   public static final String CREATE_INDEX__EXPRESSION__HELP = "Field of the region values that are referenced by the index.";
+   public static final String CREATE_INDEX__REGION = "region";
+   public static final String CREATE_INDEX__REGION__HELP = "Name/Path of the region which corresponds to the \"from\" clause in a query.";
+   public static final String CREATE_INDEX__MEMBER = "member";
+   public static final String CREATE_INDEX__MEMBER__HELP = "Name/Id of the member in which the index will be created.";
+   public static final String CREATE_INDEX__TYPE = "type";
+   public static final String CREATE_INDEX__TYPE__HELP = "Type of the index. Valid values are: range, key and hash.";
+   public static final String CREATE_INDEX__GROUP = "group";
+   public static final String CREATE_INDEX__GROUP__HELP = "Group of members in which the index will be created.";
+   public static final String CREATE_INDEX__INVALID__INDEX__TYPE__MESSAGE = "Invalid index type,value must be one of the following: range, key or hash.";
+   public static final String CREATE_INDEX__SUCCESS__MSG = "Index successfully created with following details";
+   public static final String CREATE_INDEX__FAILURE__MSG = "Failed to create index \"{0}\" due to following reasons";
+   public static final String CREATE_INDEX__ERROR__MSG = "Exception \"{0}\" occured on following members";
+   public static final String CREATE_INDEX__NAME__CONFLICT = "Index \"{0}\" already exists.  "
+       + "Create failed due to duplicate name.";
+   public static final String CREATE_INDEX__INDEX__EXISTS = "Index \"{0}\" already exists.  "
+       + "Create failed due to duplicate definition.";
+   public static final String CREATE_INDEX__INVALID__EXPRESSION = "Invalid indexed expression : \"{0}\"";
+   public static final String CREATE_INDEX__INVALID__REGIONPATH = "Region not found : \"{0}\"";
+   public static final String CREATE_INDEX__NAME__MSG = "Name       : {0}";
+   public static final String CREATE_INDEX__EXPRESSION__MSG = "Expression : {0}";
+   public static final String CREATE_INDEX__REGIONPATH__MSG = "RegionPath : {0}";
+   public static final String CREATE_INDEX__TYPE__MSG = "Type       : {0}";
+   public static final String CREATE_INDEX__MEMBER__MSG = "Members which contain the index";
+   public static final String CREATE_INDEX__NUMBER__AND__MEMBER = "{0}. {1}";
+   public static final String CREATE_INDEX__EXCEPTION__OCCURRED__ON = "Occurred on following members";
+   public static final String CREATE_INDEX__INVALID__INDEX__NAME = "Invalid index name";
+ 
+   public static final String DEFINE_INDEX = "define index";
+   public static final String DEFINE_INDEX__HELP = "Define an index that can be used when executing queries.";
+   public static final String DEFINE_INDEX__SUCCESS__MSG = "Index successfully defined with following details";
+   public static final String DEFINE_INDEX__FAILURE__MSG = "No indexes defined";
+   public static final String DEFINE_INDEX_NAME = CREATE_INDEX__NAME;
+   public static final String DEFINE_INDEX__EXPRESSION = CREATE_INDEX__EXPRESSION;
+   public static final String DEFINE_INDEX__EXPRESSION__HELP = CREATE_INDEX__EXPRESSION__HELP;
+   public static final String DEFINE_INDEX__REGION = CREATE_INDEX__REGION;
+   public static final String DEFINE_INDEX__REGION__HELP = CREATE_INDEX__REGION__HELP;
+   public static final String DEFINE_INDEX__TYPE = CREATE_INDEX__TYPE;
+   public static final String DEFINE_INDEX__TYPE__HELP = CREATE_INDEX__TYPE__HELP;
+   public static final String DEFINE_INDEX__INVALID__INDEX__TYPE__MESSAGE = CREATE_INDEX__INVALID__INDEX__TYPE__MESSAGE;
+   public static final String DEFINE_INDEX__INVALID__INDEX__NAME = CREATE_INDEX__INVALID__INDEX__NAME;
+   public static final String DEFINE_INDEX__INVALID__EXPRESSION = CREATE_INDEX__INVALID__EXPRESSION;
+   public static final String DEFINE_INDEX__INVALID__REGIONPATH = CREATE_INDEX__INVALID__REGIONPATH;
+   public static final String DEFINE_INDEX__NAME__MSG = CREATE_INDEX__NAME__MSG;
+   public static final String DEFINE_INDEX__EXPRESSION__MSG = CREATE_INDEX__EXPRESSION__MSG;
+   public static final String DEFINE_INDEX__REGIONPATH__MSG = CREATE_INDEX__REGIONPATH__MSG;
+   
+   public static final String CREATE_DEFINED_INDEXES = "create defined indexes";
+   public static final String CREATE_DEFINED__HELP = "Creates all the defined indexes.";
+   public static final String CREATE_DEFINED_INDEXES__SUCCESS__MSG = "Indexes successfully created. Use list indexes to get details.";
+   public static final String CREATE_DEFINED_INDEXES__FAILURE__MSG = "Failed to create some or all indexes \"{0}\" due to following reasons";
+   public static final String CREATE_DEFINED_INDEXES__MEMBER = CREATE_INDEX__MEMBER;
+   public static final String CREATE_DEFINED_INDEXES__MEMBER__HELP = CREATE_INDEX__MEMBER__HELP;
+   public static final String CREATE_DEFINED_INDEXES__GROUP = CREATE_INDEX__GROUP;
+   public static final String CREATE_DEFINED_INDEXES__GROUP__HELP = CREATE_INDEX__GROUP__HELP;
+   public static final String CREATE_DEFINED_INDEXES__MEMBER__MSG = CREATE_INDEX__MEMBER__MSG;
+   public static final String CREATE_DEFINED_INDEXES__NUMBER__AND__MEMBER = CREATE_INDEX__NUMBER__AND__MEMBER;
+   public static final String CREATE_DEFINED_INDEXES__EXCEPTION__OCCURRED__ON = CREATE_INDEX__EXCEPTION__OCCURRED__ON;
+ 
+   
+   public static final String CLEAR_DEFINED_INDEXES = "clear defined indexes";
+   public static final String CLEAR_DEFINED__HELP = "Clears all the defined indexes.";
+   public static final String CLEAR_DEFINED_INDEX__SUCCESS__MSG = "Index definitions successfully cleared";
+   
+   /* create region */
+   public static final String CREATE_REGION = "create region";
+   public static final String CREATE_REGION__HELP = "Create a region with the given path and configuration. Specifying a --key-constraint and --value-constraint makes object type information available during querying and indexing.";
+   public static final String CREATE_REGION__REGION = "name";
+   public static final String CREATE_REGION__REGION__HELP = "Name/Path of the region to be created.";
+   public static final String CREATE_REGION__REGIONSHORTCUT = "type";
+   public static final String CREATE_REGION__REGIONSHORTCUT__HELP = "Type of region to create. The following types are pre-defined by the product (see RegionShortcut javadocs for more information): PARTITION, PARTITION_REDUNDANT, PARTITION_PERSISTENT, PARTITION_REDUNDANT_PERSISTENT, PARTITION_OVERFLOW, PARTITION_REDUNDANT_OVERFLOW, PARTITION_PERSISTENT_OVERFLOW, PARTITION_REDUNDANT_PERSISTENT_OVERFLOW, PARTITION_HEAP_LRU, PARTITION_REDUNDANT_HEAP_LRU, REPLICATE, REPLICATE_PERSISTENT, REPLICATE_OVERFLOW, REPLICATE_PERSISTENT_OVERFLOW, REPLICATE_HEAP_LRU, LOCAL, LOCAL_PERSISTENT, LOCAL_HEAP_LRU, LOCAL_OVERFLOW, LOCAL_PERSISTENT_OVERFLOW, PARTITION_PROXY, PARTITION_PROXY_REDUNDANT, and REPLICATE_PROXY.";
+   public static final String CREATE_REGION__GROUP = "group";
+   public static final String CREATE_REGION__GROUP__HELP = "Group(s) of members on which the region will be created.";
+   public static final String CREATE_REGION__USEATTRIBUTESFROM = "template-region";
+   public static final String CREATE_REGION__USEATTRIBUTESFROM__HELP = "Name/Path of the region whose attributes should be duplicated when creating this region.";
+   public static final String CREATE_REGION__SKIPIFEXISTS = "skip-if-exists";
+   public static final String CREATE_REGION__SKIPIFEXISTS__HELP = "Skip region ceation if the region already exists.";
+   public static final String CREATE_REGION__KEYCONSTRAINT = "key-constraint";
+   public static final String CREATE_REGION__KEYCONSTRAINT__HELP = "Fully qualified class name of the objects allowed as region keys. Ensures that keys for region entries are all of the same class.";
+   public static final String CREATE_REGION__VALUECONSTRAINT = "value-constraint";
+   public static final String CREATE_REGION__VALUECONSTRAINT__HELP = "Fully qualified class name of the objects allowed as region values. If not specified then region values can be of any class.";
+   public static final String CREATE_REGION__STATISTICSENABLED = "enable-statistics";
+   public static final String CREATE_REGION__STATISTICSENABLED__HELP = "Whether to gather statistics for the region. Must be true to use expiration on the region.";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONIDLETIME = "entry-idle-time-expiration";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONIDLETIME__HELP = "How long the region's entries can remain in the cache without being accessed. The default is no expiration of this type.";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONIDLETIMEACTION = "entry-idle-time-expiration-action";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONIDLETIMEACTION__HELP = "Action to be taken on an entry that has exceeded the idle expiration.";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONTIMETOLIVE = "entry-time-to-live-expiration";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONTIMETOLIVE__HELP = "How long the region's entries can remain in the cache without being accessed or updated. The default is no expiration of this type.";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONTTLACTION = "entry-time-to-live-expiration-action";
+   public static final String CREATE_REGION__ENTRYEXPIRATIONTTLACTION__HELP = "Action to be taken on an entry that has exceeded the TTL expiration.";
+   public static final String CREATE_REGION__REGIONEXPIRATIONIDLETIME = "region-idle-time-expiration";
+   public static final String CREATE_REGION__REGIONEXPIRATIONIDLETIME__HELP = "How long the region can remain in the cache without being accessed. The default is no expiration of this type.";
+   public static final String CREATE_REGION__REGIONEXPIRATIONIDLETIMEACTION = "region-idle-time-expiration-action";
+   public static final String CREATE_REGION__REGIONEXPIRATIONIDLETIMEACTION__HELP = "Action to be taken on a region that has exceeded the idle expiration.";
+   public static final String CREATE_REGION__REGIONEXPIRATIONTTL = "region-time-to-live-expiration";
+   public static final String CREATE_REGION__REGIONEXPIRATIONTTL__HELP = "How long the region can remain in the cache without being accessed or updated. The default is no expiration of this type.";
+   public static final String CREATE_REGION__REGIONEXPIRATIONTTLACTION = "region-time-to-live-expiration-action";
+   public static final String CREATE_REGION__REGIONEXPIRATIONTTLACTION__HELP = "Action to be taken on a region that has exceeded the TTL expiration.";
+   public static final String CREATE_REGION__DISKSTORE = "disk-store";
+   public static final String CREATE_REGION__DISKSTORE__HELP = "Disk Store to be used by this region. \"list disk-store\" can be used to display existing disk stores.";
+   public static final String CREATE_REGION__DISKSYNCHRONOUS = "enable-synchronous-disk";
+   public static final String CREATE_REGION__DISKSYNCHRONOUS__HELP = "Whether writes are done synchronously for regions that persist data to disk.";
+   public static final String CREATE_REGION__ENABLEASYNCCONFLATION = "enable-async-conflation";
+   public static final String CREATE_REGION__ENABLEASYNCCONFLATION__HELP = "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.";
+   public static final String CREATE_REGION__ENABLESUBSCRIPTIONCONFLATION = "enable-subscription-conflation";
+   public static final String CREATE_REGION__ENABLESUBSCRIPTIONCONFLATION__HELP = "Whether the server should conflate its messages to the client. A false value causes all server-client messages to be sent individually.";
+   public static final String CREATE_REGION__CACHELISTENER = "cache-listener";
+   public static final String CREATE_REGION__CACHELISTENER__HELP = "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.";
+   public static final String CREATE_REGION__CACHELOADER = "cache-loader";
+   public static final String CREATE_REGION__CACHELOADER__HELP = "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.";
+   public static final String CREATE_REGION__CACHEWRITER = "cache-writer";
+   public static final String CREATE_REGION__CACHEWRITER__HELP = "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.";
+   public static final String CREATE_REGION__ASYNCEVENTQUEUEID = "async-event-queue-id";
+   public static final String CREATE_REGION__ASYNCEVENTQUEUEID__HELP = "IDs of the Async Event Queues that will be used for write-behind operations."; // TODO - Abhishek Is this correct?
+   public static final String CREATE_REGION__GATEWAYSENDERID = "gateway-sender-id";
+   public static final String CREATE_REGION__GATEWAYSENDERID__HELP = "IDs of the Gateway Senders to which data will be routed.";
+   public static final String CREATE_REGION__CONCURRENCYCHECKSENABLED = "enable-concurrency-checks";
+   public static final String CREATE_REGION__CONCURRENCYCHECKSENABLED__HELP = "Enables a versioning system that detects concurrent modifications and ensures that region contents are consistent across the distributed system.";
+   public static final String CREATE_REGION__CLONINGENABLED = "enable-cloning";
+   public static final String CREATE_REGION__CLONINGENABLED__HELP = "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.";
+   public static final String CREATE_REGION__CONCURRENCYLEVEL = "concurrency-level";
+   public static final String CREATE_REGION__CONCURRENCYLEVEL__HELP = "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.";
+   public static final String CREATE_REGION__COLOCATEDWITH = "colocated-with";
+   public static final String CREATE_REGION__COLOCATEDWITH__HELP = "Central Region with which this region should be colocated.";
+   public static final String CREATE_REGION__LOCALMAXMEMORY = "local-max-memory";
+   public static final String CREATE_REGION__LOCALMAXMEMORY__HELP = "Sets the maximum amount of memory, in megabytes, to be used by the region in this process. (Default: 90% of available heap)";
+   public static final String CREATE_REGION__MULTICASTENABLED = "enable-multicast";
+   public static final String CREATE_REGION__MULTICASTENABLED__HELP = "Enables multicast messaging on the region.  Multicast must also be enabled in the cache distributed system properties.  This is primarily useful for replicated regions that are in all servers.";
+   public static final String CREATE_REGION__RECOVERYDELAY = "recovery-delay";
+   public static final String CREATE_REGION__RECOVERYDELAY__HELP = "Sets the delay in milliseconds that existing members will wait before satisfying redundancy after another member crashes. -1 (the default) indicates that redundancy will not be recovered after a failure.";
+   public static final String CREATE_REGION__REDUNDANTCOPIES = "redundant-copies";
+   public static final String CREATE_REGION__REDUNDANTCOPIES__HELP = "Sets the number of extra copies of buckets desired. Extra copies allow for both high availability in the face of VM departure (intended or unintended) and and load balancing read operations. (Allowed values: 0, 1, 2 and 3)";
+   public static final String CREATE_REGION__STARTUPRECOVERYDDELAY = "startup-recovery-delay";
+   public static final String CREATE_REGION__STARTUPRECOVERYDDELAY__HELP = "Sets the delay in milliseconds that new members will wait before satisfying redundancy. -1 indicates that adding new members will not trigger redundancy recovery. The default is to recover redundancy immediately when a new member is added.";
+   public static final String CREATE_REGION__TOTALMAXMEMORY = "total-max-memory";
+   public static final String CREATE_REGION__TOTALMAXMEMORY__HELP = "Sets the maximum amount of memory, in megabytes, to be used by the region in all processes.";
+   public static final String CREATE_REGION__TOTALNUMBUCKETS = "total-num-buckets";
+   public static final String CREATE_REGION__TOTALNUMBUCKETS__HELP = "Sets the total number of hash buckets to be used by the region in all processes. (Default: "		  
+       + PartitionAttributesFactory.GLOBAL_MAX_BUCKETS_DEFAULT + ").";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH = "Specify a valid " + CliStrings.CREATE_REGION__REGION;
+   public static final String CREATE_REGION__MSG__PARENT_REGION_FOR_0_DOESNOT_EXIST = "Parent region for \"{0}\" doesn't exist. ";
+   public static final String CREATE_REGION__MSG__GROUPS_0_ARE_INVALID = "Group(s) \"{0}\" are invalid.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_USE_ATTR_FROM = "Specify a valid region path for "
+       + CliStrings.CREATE_REGION__USEATTRIBUTESFROM;
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_KEYCONSTRAINT_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__KEYCONSTRAINT + ". \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_VALUECONSTRAINT_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__VALUECONSTRAINT + ". \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_CACHELISTENER_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__CACHELISTENER + ". \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_CACHEWRITER_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__CACHEWRITER + ". \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_CLASSNAME_FOR_CACHELOADER_0_IS_INVALID = "Specify a valid class name for "
+       + CliStrings.CREATE_REGION__CACHELOADER + ". \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__NO_GATEWAYSENDERS_IN_THE_SYSTEM = "There are no GatewaySenders defined currently in the system.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_GATEWAYSENDER_ID_UNKNOWN_0 = "Specify valid "
+       + CliStrings.CREATE_REGION__GATEWAYSENDERID + ". Unknown Gateway Sender(s): \"{0}\".";
+   public static final String CREATE_REGION__MSG__SPECIFY_POSITIVE_INT_FOR_CONCURRENCYLEVEL_0_IS_NOT_VALID = "Specify positive integer value for "
+       + CliStrings.CREATE_REGION__CONCURRENCYLEVEL + ".  \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_DISKSTORE_UNKNOWN_DISKSTORE_0 = "Specify valid "
+       + CliStrings.CREATE_REGION__DISKSTORE + ". Unknown Disk Store : \"{0}\".";
+   public static final String CREATE_REGION__MSG__USE_ONE_OF_THESE_SHORTCUTS_0 = "Use one of these shortcuts: {0}";
+   public static final String CREATE_REGION__MSG__SKIPPING_0_REGION_PATH_1_ALREADY_EXISTS = "Skipping \"{0}\". Region \"{1}\" already exists.";
+   public static final String CREATE_REGION__MSG__REGION_PATH_0_ALREADY_EXISTS_ON_1 = "Region with path \"{0}\" already exists on \"{1}\"";
+   public static final String CREATE_REGION__MSG__REGION_0_CREATED_ON_1 = "Region \"{0}\" created on \"{1}\"";
+   public static final String CREATE_REGION__MSG__ONLY_ONE_OF_REGIONSHORTCUT_AND_USEATTRIBUESFROM_CAN_BE_SPECIFIED = "Only one of "
+       + CREATE_REGION__REGIONSHORTCUT + " & " + CREATE_REGION__USEATTRIBUTESFROM + " can be specified.";
+   public static final String CREATE_REGION__MSG__ONE_OF_REGIONSHORTCUT_AND_USEATTRIBUESFROM_IS_REQUIRED = "One of \""
+       + CREATE_REGION__REGIONSHORTCUT + "\" or \"" + CREATE_REGION__USEATTRIBUTESFROM + "\" is required.";
+   public static final String CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND = "Specify a valid region path for {0}. Region {1} not found.";
+   public static final String CREATE_REGION__MSG__COULDNOT_FIND_CLASS_0_SPECIFIED_FOR_1 = "Could not find class \"{0}\" specified for \"{1}\".";
+   public static final String CREATE_REGION__MSG__CLASS_SPECIFIED_FOR_0_SPECIFIED_FOR_1_IS_NOT_OF_EXPECTED_TYPE = "Class \"{0}\" specified for \"{1}\" is not of an expected type.";
+   public static final String CREATE_REGION__MSG__COULDNOT_INSTANTIATE_CLASS_0_SPECIFIED_FOR_1 = "Could not instantiate class \"{0}\" specified for \"{1}\".";
+   public static final String CREATE_REGION__MSG__COULDNOT_ACCESS_CLASS_0_SPECIFIED_FOR_1 = "Could not access class \"{0}\" specified for \"{1}\".";
+   public static final String CREATE_REGION__MSG__EXPIRATION_ACTION_0_IS_NOT_VALID = "Expiration action \"{0}\" is not valid.";
+   public static final String CREATE_REGION__MSG__ERROR_ON_MEMBER_0 = "Error on member: {0}. "; // leave space in the end
+                                                                                                // for further message
+   public static final String CREATE_REGION__MSG__COULD_NOT_RETRIEVE_REGION_ATTRS_FOR_PATH_0_REASON_1 = "Could not retrieve region attributes for given path \"{0}\". Reason: {1}";
+   public static final String CREATE_REGION__MSG__COULD_NOT_RETRIEVE_REGION_ATTRS_FOR_PATH_0_VERIFY_REGION_EXISTS = "Could not retrieve region attributes for given path \"{0}\". Use \""
+       + CliStrings.LIST_REGION + "\" to verify region exists.";
+   public static final String CREATE_REGION__MSG__USE_ATTRIBUTES_FORM_REGIONS_EXISTS_BUT_DIFFERENT_SCOPE_OR_DATAPOLICY_USE_DESCRIBE_REGION_FOR_0 = "The region mentioned for \""
+       + CliStrings.CREATE_REGION__USEATTRIBUTESFROM
+       + "\" exists in this GemFire Cluster but with different Scopes or Data Policies on different members. For details, use command \""
+       + CliStrings.DESCRIBE_REGION + "\" for \"{0}\".";
+   public static final String CREATE_REGION__MSG__USE_ATTRIBUTES_FROM_REGION_0_IS_NOT_WITH_PERSISTENCE = CREATE_REGION__USEATTRIBUTESFROM
+       + " region \"{0}\" is not persistent.";
+   public static final String CREATE_REGION__MSG__OPTION_0_CAN_BE_USED_ONLY_FOR_PARTITIONEDREGION = "Parameter(s) \"{0}\" can be used only for creating a Partitioned Region.";
+   public static final String CREATE_REGION__MSG__0_IS_NOT_A_PARITIONEDREGION = "\"{0}\" is not a Partitioned Region.";
+   public static final String CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_IS_NOT_PARTITIONEDREGION = CREATE_REGION__COLOCATEDWITH
+       + " \"{0}\" is not a Partitioned Region.";
+   public static final String CREATE_REGION__MSG__COLOCATEDWITH_REGION_0_DOESNOT_EXIST = CREATE_REGION__COLOCATEDWITH
+       + " \"{0}\" does not exists.";
+   public static final String CREATE_REGION__MSG__REDUNDANT_COPIES_SHOULD_BE_ONE_OF_0123 = CREATE_REGION__REDUNDANTCOPIES
+       + " \"{0}\" is not valid. It should be one of 0, 1, 2, 3.";
+   public static final String CREATE_REGION__MSG__COULDNOT_LOAD_REGION_ATTRIBUTES_FOR_SHORTCUT_0 = "Could not load Region Attributes for a valid "
+       + CREATE_REGION__REGIONSHORTCUT + "={0}. Please check logs for any errors.";
+   public static final String CREATE_REGION__MSG__0_IS_A_PR_CANNOT_HAVE_SUBREGIONS = "\"{0}\" is a Partitioned Region and cannot have Subregions.";
+ 
+   public static final String CREATE_REGION__COMPRESSOR = "compressor";
+   public static final String CREATE_REGION__COMPRESSOR__HELP = "The fully-qualifed class name of the Compressor to use when compressing region entry values.  The default is no compression.";
+   public static final String CREATE_REGION__MSG__INVALID_COMPRESSOR = "{0} is an invalid Compressor."; // leave space in the end
+ 
+   public static final String CREATE_REGION__OFF_HEAP = "off-heap";
+   public static final String CREATE_REGION__OFF_HEAP__HELP = "Causes the values of the region to be stored in off-heap memory. The default is on heap.";
+ 
+   /* debug command */
+   public static final String DEBUG = "debug";
+   public static final String DEBUG__HELP = "Enable/Disable debugging output in GFSH.";
+   public static final String DEBUG__STATE = "state";
+   public static final String DEBUG__STATE__HELP = "ON or OFF to enable or disable debugging output.";
+   public static final String DEBUG__MSG_DEBUG_STATE_IS = "Debug is ";
+   public static final String DEBUG__MSG_0_INVALID_STATE_VALUE = "Invalid state value : {0}. It should be \"ON\" or \"OFF\" ";
+ 
+   /* deploy command */
+   public static final String DEPLOY = "deploy";
+   public static final String DEPLOY__HELP = "Deploy JARs to a member or members.  Only one of either --jar or --dir may be specified.";
+   public static final String DEPLOY__DIR = "dir";
+   public static final String DEPLOY__DIR__HELP = "Directory from which to deploy the JARs.";
+   public static final String DEPLOY__GROUP = "group";
+   public static final String DEPLOY__GROUP__HELP = "Group(s) to which the specified JARs will be deployed. If not specified, deploy will occur on all members.";
+   public static final String DEPLOY__JAR = "jar";
+   public static final String DEPLOY__JAR__HELP = "Path of the JAR to deploy.";
+ 
+   /* describe config command */
+   public static final String DESCRIBE_CONFIG = "describe config";
+   public static final String DESCRIBE_CONFIG__HELP = "Display configuration details of a member or members.";
+   public static final String DESCRIBE_CONFIG__MEMBER = "member";
+   public static final String DESCRIBE_CONFIG__MEMBER__HELP = "Name/Id of the member whose configuration will be described.";
+   public static final String DESCRIBE_CONFIG__HIDE__DEFAULTS = "hide-defaults";
+   public static final String DESCRIBE_CONFIG__HIDE__DEFAULTS__HELP = "Whether to hide configuration information for properties with the default value.";
+   public static final String DESCRIBE_CONFIG__MEMBER__NOT__FOUND = "Member \"{0}\" not found";
+   public static final String DESCRIBE_CONFIG__HEADER__TEXT = "Configuration of member : \"{0}\"";
+ 
+   /* 'describe connection' command */
+   public static final String DESCRIBE_CONNECTION = "describe connection";
+   public static final String DESCRIBE_CONNECTION__HELP = "Display information about the current connection.";
+ 
+   /* 'describe disk-store' command */
+   public static final String DESCRIBE_DISK_STORE = "describe disk-store";
+   public static final String DESCRIBE_DISK_STORE__HELP = "Display information about a member's disk store.";
+   public static final String DESCRIBE_DISK_STORE__MEMBER = "member";
+   public static final String DESCRIBE_DISK_STORE__MEMBER__HELP = "Name/Id of the member with the disk store to be described.";
+   public static final String DESCRIBE_DISK_STORE__NAME = "name";
+   public static final String DESCRIBE_DISK_STORE__NAME__HELP = "Name of the disk store to be described.";
+   public static final String DESCRIBE_DISK_STORE__ERROR_MESSAGE = "An error occurred while collecting Disk Store information for member (%1$s) with disk store (%2$s) in the GemFire cluster: %3$s";
+ 
+   /* 'describe member' command */
+   public static final String DESCRIBE_MEMBER = "describe member";
+   public static final String DESCRIBE_MEMBER__HELP = "Display information about a member, including name, id, groups, regions, etc.";
+   public static final String DESCRIBE_MEMBER__IDENTIFIER = "name";
+   public static final String DESCRIBE_MEMBER__IDENTIFIER__HELP = "Name/Id of the member to be described.";
+   public static final String DESCRIBE_MEMBER__MSG__NOT_FOUND = "Member \"{0}\" not found";
+   public static final String DESCRIBE_MEMBER__MSG__INFO_FOR__0__COULD_NOT_BE_RETRIEVED = "Information for the member \"{0}\" could not be retrieved.";
+ 
+   /* 'describe offline-disk-store' command */
+   public static final String DESCRIBE_OFFLINE_DISK_STORE = "describe offline-disk-store";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__HELP = "Display information about an offline disk store.";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__DISKSTORENAME = "name";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__DISKSTORENAME__HELP = "Name of the disk store to be described.";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__REGIONNAME = "region";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__REGIONNAME__HELP = "Name/Path of the region in the disk store to be described.";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__DISKDIRS = "disk-dirs";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__DISKDIRS__HELP = "Directories which contain the disk store files.";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__PDX_TYPES = "pdx";
+   public static final String DESCRIBE_OFFLINE_DISK_STORE__PDX_TYPES__HELP = "Display all the pdx types stored in the disk store";
+   
+   /* 'export offline-disk-store' command */
+   public static final String EXPORT_OFFLINE_DISK_STORE = "export offline-disk-store";
+   public static final String EXPORT_OFFLINE_DISK_STORE__HELP = "Export region data from an offline disk store into gemfire snapshot files.";
+   public static final String EXPORT_OFFLINE_DISK_STORE__DISKSTORENAME = "name";
+   public static final String EXPORT_OFFLINE_DISK_STORE__DISKSTORENAME__HELP = "Name of the disk store to be exported.";
+   public static final String EXPORT_OFFLINE_DISK_STORE__DIR = "dir";
+   public static final String EXPORT_OFFLINE_DISK_STORE__DIR__HELP = "Directory to export snapshot files to.";
+   public static final String EXPORT_OFFLINE_DISK_STORE__DISKDIRS = "disk-dirs";
+   public static final String EXPORT_OFFLINE_DISK_STORE__DISKDIRS__HELP = "Directories which contain the disk store files.";
+   public static final String EXPORT_OFFLINE_DISK_STORE__ERROR = "Error exporting disk store {0} is : {1}";
+   public static final String EXPORT_OFFLINE_DISK_STORE__SUCCESS = "Exported all regions from disk store {0} to the directory {1}";
+ 
+   /* 'describe region' command */
+   public static final String DESCRIBE_REGION = "describe region";
+   public static final String DESCRIBE_REGION__HELP = "Display the attributes and key information of a region.";
+   public static final String DESCRIBE_REGION__NAME = "name";
+   public static final String DESCRIBE_REGION__NAME__HELP = "Name/Path of the region to be described.";
+   public static final String DESCRIBE_REGION__MSG__NOT_FOUND = "Region not found";
+   public static final String DESCRIBE_REGION__MSG__ERROR = "Error";
+   public static final String DESCRIBE_REGION__ATTRIBUTE__TYPE = "Type";
+   public static final String DESCRIBE_REGION__MEMBER = "Member";
+   public static final String DESCRIBE_REGION__ATTRIBUTE__NAME = "Name";
+   public static final String DESCRIBE_REGION__ATTRIBUTE__VALUE = "Value";
+   public static final String DESCRIBE_REGION__NONDEFAULT__COMMONATTRIBUTES__HEADER = "Non-Default Attributes Shared By {0}  ";
+   public static final String DESCRIBE_REGION__NONDEFAULT__PERMEMBERATTRIBUTES__HEADER = "Non-Default Attributes Specific To The {0} ";
+   public static final String DESCRIBE_REGION__HOSTING__MEMBER = "Hosting Members";
+   public static final String DESCRIBE_REGION__ACCESSOR__MEMBER = "Accessor Members";
+   public static final String DESCRIBE_REGION__ATTRIBUTE__TYPE__REGION = "Region";
+   public static final String DESCRIBE_REGION__ATTRIBUTE__TYPE__PARTITION = "Partition";
+   public static final String DESCRIBE_REGION__ATTRIBUTE__TYPE__EVICTION = "Eviction";
+ 
+   /* 'destroy disk-store' command */
+   public static final String DESTROY_DISK_STORE = "destroy disk-store";
+   public static final String DESTROY_DISK_STORE__HELP = "Destroy a disk store, including deleting all files on disk used by the disk store. Data for closed regions previously using the disk store will be lost.";
+   public static final String DESTROY_DISK_STORE__NAME = "name";
+   public static final String DESTROY_DISK_STORE__NAME__HELP = "Name of the disk store that will be destroyed.";
+   public static final String DESTROY_DISK_STORE__GROUP = "group";
+   public static final String DESTROY_DISK_STORE__GROUP__HELP = "Group(s) of members on which the disk store will be destroyed. If no group is specified the disk store will be destroyed on all members.";
+   public static final String DESTROY_DISK_STORE__ERROR_WHILE_DESTROYING_REASON_0 = "An error occurred while destroying the disk store: \"{0}\"";
+ 
+   /* 'destroy function' command */
+   public static final String DESTROY_FUNCTION = "destroy function";
+   public static final String DESTROY_FUNCTION__HELP = "Destroy/Unregister a function. The default is for the function to be unregistered from all members.";
+   public static final String DESTROY_FUNCTION__ID = "id";
+   public static final String DESTROY_FUNCTION__ID__HELP = "ID of the function.";
+   public static final String DESTROY_FUNCTION__ONGROUPS = "groups";
+   public static final String DESTROY_FUNCTION__ONGROUPS__HELP = "Groups of members from which this function will be unregistered.";
+   public static final String DESTROY_FUNCTION__ONMEMBER = "member";
+   public static final String DESTROY_FUNCTION__ONMEMBER__HELP = "Name/Id of the member from which this function will be unregistered.";
+   public static final String DESTROY_FUNCTION__MSG__CANNOT_EXECUTE = "Cannot execute";
+   public static final String DESTROY_FUNCTION__MSG__PROVIDE_OPTION = "Provide either --groups or --member";
+ 
+   /* 'destroy index' command */
+   public static final String DESTROY_INDEX = "destroy index";
+   public static final String DESTROY_INDEX__HELP = "Destroy/Remove the specified index.";
+   public static final String DESTROY_INDEX__NAME = "name";
+   public static final String DESTROY_INDEX__NAME__HELP = "Name of the index to remove.";
+   public static final String DESTROY_INDEX__MEMBER = "member";
+   public static final String DESTROY_INDEX__MEMBER__HELP = "Name/Id of the member from which the index will be removed.";
+   public static final String DESTROY_INDEX__REGION = "region";
+   public static final String DESTROY_INDEX__REGION__HELP = "Name/Path of the region from which the index will be removed.";
+   public static final String DESTROY_INDEX__GROUP = "group";
+   public static final String DESTROY_INDEX__GROUP__HELP = "Group of members from which the index will be removed.";
+   public static final String DESTROY_INDEX__SUCCESS__MSG = "Index \"{0}\" successfully destroyed on the following members";
+   public static final String DESTROY_INDEX__ON__REGION__SUCCESS__MSG = "Index \"{0}\" on region : \"{1}\" successfully destroyed on the following members";
+   public static final String DESTROY_INDEX__ON__REGION__ONLY__SUCCESS__MSG = "Indexes on region : {0} successfully

<TRUNCATED>


[010/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/PutAllWithIndexPerfDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/PutAllWithIndexPerfDUnitTest.java
index fd50e63,0000000..960bd4e
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/PutAllWithIndexPerfDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/PutAllWithIndexPerfDUnitTest.java
@@@ -1,216 -1,0 +1,216 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache.query.internal.index;
 +
 +import java.io.IOException;
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.Properties;
 +
 +import org.junit.Ignore;
 +import org.junit.experimental.categories.Category;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.client.ClientCache;
 +import com.gemstone.gemfire.cache.client.ClientCacheFactory;
 +import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
 +import com.gemstone.gemfire.cache.query.data.PortfolioPdx;
 +import com.gemstone.gemfire.cache.query.dunit.RemoteQueryDUnitTest;
 +import com.gemstone.gemfire.cache.server.CacheServer;
 +import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
 +import com.gemstone.gemfire.cache30.CacheTestCase;
 +import com.gemstone.gemfire.internal.AvailablePort;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.NetworkUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.junit.categories.DistributedTest;
 +
 +/**
 + * @author shobhit
 + *
 + */
 +@Category(DistributedTest.class)
 +@Ignore("Test was disabled by renaming to DisabledTest")
 +public class PutAllWithIndexPerfDUnitTest extends CacheTestCase {
 +
 +  /** The port on which the bridge server was started in this VM */
 +  private static int bridgeServerPort;
 +  static long timeWithoutStructTypeIndex = 0;
 +  static long timeWithStructTypeIndex = 0;
 +  
 +  public PutAllWithIndexPerfDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  public void setUp() throws Exception {
 +    super.setUp();
 +    disconnectAllFromDS();
 +  }
 +
 +  @Override
 +  protected final void postTearDownCacheTestCase() throws Exception {
 +    disconnectAllFromDS();
 +  }
 +
 +  public void testPutAllWithIndexes() {
 +    final String name = "testRegion";
 +    final Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    final int numberOfEntries = 10000;
 +
 +    // Start server
 +    vm0.invoke(new CacheSerializableRunnable("Create Bridge Server") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.put("locators", "localhost["+DistributedTestUtils.getDUnitLocatorPort()+"]");
 +          Cache cache = new CacheFactory(config).create();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          cache.createRegionFactory(factory.create()).create(name);
 +          try {
 +            startBridgeServer(0, false);
 +          } catch (Exception ex) {
 +            Assert.fail("While starting CacheServer", ex);
 +          }
 +          //Create Index on empty region
 +          try {
 +            cache.getQueryService().createIndex("idIndex", "ID", "/"+name);
 +          } catch (Exception e) {
 +            Assert.fail("index creation failed", e);
 +          }
 +        }
 +      });
 +
 +    // Create client region
-     final int port = vm0.invokeInt(PutAllWithIndexPerfDUnitTest.class, "getCacheServerPort");
++    final int port = vm0.invoke(() -> PutAllWithIndexPerfDUnitTest.getCacheServerPort());
 +    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
 +    vm1.invoke(new CacheSerializableRunnable("Create region") {
 +        public void run2() throws CacheException {
 +          Properties config = new Properties();
 +          config.setProperty("mcast-port", "0");
 +          ClientCache cache = new ClientCacheFactory().addPoolServer(host0, port).create();
 +          AttributesFactory factory = new AttributesFactory();
 +          factory.setScope(Scope.LOCAL);
 +          cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(name);
 +        }
 +      });
 +
 +    vm1.invoke(new CacheSerializableRunnable("putAll() test") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region exampleRegion = ClientCacheFactory.getAnyInstance().getRegion(name);
 +
 +        Map warmupMap = new HashMap();
 +        Map data =  new HashMap();
 +        for(int i=0; i<10000; i++){
 +          Object p = new PortfolioPdx(i);
 +          if (i < 1000) warmupMap.put(i, p);
 +          data.put(i, p);
 +        }
 +        
 +        for (int i=0; i<10; i++) {
 +          exampleRegion.putAll(warmupMap);
 +        }
 +        
 +        long start = System.currentTimeMillis();
 +        for (int i=0; i<10; i++) {
 +          exampleRegion.putAll(data);
 +        }
 +        long end = System.currentTimeMillis();
 +        timeWithoutStructTypeIndex = ((end-start)/10);
 +        System.out.println("Total putall time for 10000 objects is: "+ ((end-start)/10) + "ms");
 + 
 +      }
 +    });
 +    
 +    vm0.invoke(new CacheSerializableRunnable("Remove Index and create new one") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        try {
 +          Cache cache = CacheFactory.getAnyInstance();
 +          cache.getQueryService().removeIndexes();
 +          cache.getRegion(name).clear();
 +          cache.getQueryService().createIndex("idIndex", "p.ID", "/"+name+" p");
 +        } catch (Exception e) {
 +          Assert.fail("index creation failed", e);
 +        }
 +      }
 +    });
 +
 +    vm1.invoke(new CacheSerializableRunnable("putAll() test") {
 +      
 +      @Override
 +      public void run2() throws CacheException {
 +        Region exampleRegion = ClientCacheFactory.getAnyInstance().getRegion(name);
 +        exampleRegion.clear();
 +        Map warmupMap = new HashMap();
 +        Map data =  new HashMap();
 +        for(int i=0; i<10000; i++){
 +          Object p = new PortfolioPdx(i);
 +          if (i < 1000) warmupMap.put(i, p);
 +          data.put(i, p);
 +        }
 +        
 +        for (int i=0; i<10; i++) {
 +          exampleRegion.putAll(warmupMap);
 +        }
 +        
 +        long start = System.currentTimeMillis();
 +        for (int i=0; i<10; i++) {
 +          exampleRegion.putAll(data);
 +        }
 +        long end = System.currentTimeMillis();
 +        timeWithStructTypeIndex  = ((end-start)/10);
 +        System.out.println("Total putall time for 10000 objects is: "+ ((end-start)/10) + "ms");
 + 
 +      }
 +    });
 +    
 +    if (timeWithoutStructTypeIndex > timeWithStructTypeIndex) {
 +      fail("putAll took more time without struct type index than simple index");
 +    }
 +  }
 +
 +  /**
 +   * Starts a bridge server on the given port, using the given
 +   * deserializeValues and notifyBySubscription to serve up the
 +   * given region.
 +   */
 +  protected void startBridgeServer(int port, boolean notifyBySubscription)
 +    throws IOException {
 +
 +    Cache cache = CacheFactory.getAnyInstance();
 +    CacheServer bridge = cache.addCacheServer();
 +    bridge.setPort(port);
 +    bridge.start();
 +    bridgeServerPort = bridge.getPort();
 +  }
 +
 +  private static int getCacheServerPort() {
 +    return bridgeServerPort;
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/Bug34387DUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/Bug34387DUnitTest.java
index 9c35b1b,0000000..879600d
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/Bug34387DUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/Bug34387DUnitTest.java
@@@ -1,174 -1,0 +1,174 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.UnsupportedOperationInTransactionException;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * Test create + localDestroy for bug 34387
 + *
 + * @author darrel
 + * @since 5.0
 + */
 +public class Bug34387DUnitTest extends CacheTestCase {
 +
 +//  private transient Region r;
 +//  private transient DistributedMember otherId;
 +  protected transient int invokeCount;
 +  
 +  static volatile boolean callbackFailure;
 +  
 +  public Bug34387DUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  protected static void callbackAssertEquals(String message, Object expected, 
 +      Object actual) {
 +    if (expected == null && actual == null)
 +      return;
 +    if (expected != null && expected.equals(actual))
 +      return;
 +    callbackFailure = true;
 +    // Throws an error that is ignored, but...
 +    assertEquals(message, expected, actual);
 +  }
 +  
 +
 +  private VM getOtherVm() {
 +    Host host = Host.getHost(0);
 +    return host.getVM(0);
 +  }
 +    
 +  private void initOtherId() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("Connect") {
 +        public void run2() throws CacheException {
 +          getCache();
 +        }
 +      });
-     vm.invoke(Bug34387DUnitTest.class, "getVMDistributedMember");
++    vm.invoke(() -> Bug34387DUnitTest.getVMDistributedMember());
 +  }
 +  private void doCommitOtherVm(final boolean doDestroy) {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("create root") {
 +        public void run2() throws CacheException {
 +          AttributesFactory af = new AttributesFactory();
 +          af.setScope(Scope.DISTRIBUTED_ACK);
 +          af.setConcurrencyChecksEnabled(true);
 +          Region r1 = createRootRegion("r1", af.create());
 +          CacheTransactionManager ctm =  getCache().getCacheTransactionManager();
 +          ctm.begin();
 +          r1.create("createKey", "createValue");
 +          if (doDestroy) {
 +            try {
 +              r1.localDestroy("createKey");
 +              fail("expected exception not thrown");
 +            } catch (UnsupportedOperationInTransactionException e) {
 +              assertEquals(e.getMessage(), LocalizedStrings.TXStateStub_LOCAL_DESTROY_NOT_ALLOWED_IN_TRANSACTION.toLocalizedString());
 +            }
 +          } else {
 +            try {
 +              r1.localInvalidate("createKey");
 +              fail("expected exception not thrown");
 +            } catch (UnsupportedOperationInTransactionException e) {
 +              assertEquals(e.getMessage(), LocalizedStrings.TXStateStub_LOCAL_INVALIDATE_NOT_ALLOWED_IN_TRANSACTION.toLocalizedString());
 +            }
 +          }
 +          ctm.commit();
 +        }
 +      });
 +  }
 +
 +  public static DistributedMember getVMDistributedMember() {
 +    return InternalDistributedSystem.getAnyInstance().getDistributedMember();
 +  }
 +  
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  /**
 +   * test create followed by localDestroy
 +   */
 +  public void testCreateAndLD() throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(DataPolicy.REPLICATE);
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    af.setConcurrencyChecksEnabled(true);
 +    callbackFailure = false;
 +    
 +    CacheListener cl1 = new CacheListenerAdapter() {
 +        public void afterCreate(EntryEvent e) {
 +          callbackAssertEquals("Keys not equal", "createKey", e.getKey());
 +          callbackAssertEquals("Values not equal", "createValue", e.getNewValue());
 +          Bug34387DUnitTest.this.invokeCount++;
 +        }
 +      };
 +    af.addCacheListener(cl1);
 +    Region r1 = createRootRegion("r1", af.create());
 +
 +    this.invokeCount = 0;
 +    assertNull(r1.getEntry("createKey"));
 +    doCommitOtherVm(true);
 +    assertNotNull(r1.getEntry("createKey"));
 +    assertEquals("createValue", r1.getEntry("createKey").getValue());
 +    assertEquals(1, this.invokeCount);
 +    assertFalse("Errors in callbacks; check logs for details", callbackFailure);
 +  }
 +  /**
 +   * test create followed by localInvalidate
 +   */
 +  public void testCreateAndLI() throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(DataPolicy.REPLICATE);
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    af.setConcurrencyChecksEnabled(true);
 +    callbackFailure = false;
 +    
 +    CacheListener cl1 = new CacheListenerAdapter() {
 +        public void afterCreate(EntryEvent e) {
 +          callbackAssertEquals("key not equal", "createKey", e.getKey());
 +          callbackAssertEquals("value not equal", "createValue", e.getNewValue());
 +          Bug34387DUnitTest.this.invokeCount++;
 +        }
 +      };
 +    af.addCacheListener(cl1);
 +    Region r1 = createRootRegion("r1", af.create());
 +
 +    this.invokeCount = 0;
 +    assertNull(r1.getEntry("createKey"));
 +    doCommitOtherVm(false);
 +    assertNotNull(r1.getEntry("createKey"));
 +    assertEquals("createValue", r1.getEntry("createKey").getValue());
 +    assertEquals(1, this.invokeCount);
 +    assertFalse("Errors in callbacks; check logs for details", callbackFailure);
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheMapTxnDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheMapTxnDUnitTest.java
index b889bc7,0000000..f7e1739
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheMapTxnDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/CacheMapTxnDUnitTest.java
@@@ -1,534 -1,0 +1,534 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * CacheMapTxnDUnitTest.java
 + *
 + * Created on August 9, 2005, 11:18 AM
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.UnsupportedOperationInTransactionException;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +public class CacheMapTxnDUnitTest extends DistributedTestCase{
 +    
 +    protected static Cache cache;
 +    protected static Properties props = new Properties();
 +    static DistributedSystem ds = null;
 +    static Region region;
 +    static Region mirroredRegion;
 +    protected static CacheTransactionManager cacheTxnMgr;
 +    
 +    /** Creates a new instance of CacheMapTxnDUnitTest */
 +    public CacheMapTxnDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(CacheMapTxnDUnitTest.class, "createCache");
-       vm1.invoke(CacheMapTxnDUnitTest.class, "createCache");
++      vm0.invoke(() -> CacheMapTxnDUnitTest.createCache());
++      vm1.invoke(() -> CacheMapTxnDUnitTest.createCache());
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(CacheMapTxnDUnitTest.class, "closeCache");
-       vm1.invoke(CacheMapTxnDUnitTest.class, "closeCache");
++      vm0.invoke(() -> CacheMapTxnDUnitTest.closeCache());
++      vm1.invoke(() -> CacheMapTxnDUnitTest.closeCache());
 +    }
 +    
 +    public static void createCache(){
 +        try{
 +            //            props.setProperty("mcast-port", "1234");
 +            //            ds = DistributedSystem.connect(props);
 +            ds = (new CacheMapTxnDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setDataPolicy(DataPolicy.REPLICATE);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static void closeCache(){
 +        try{            
 +            cache.close();
 +            ds.disconnect();            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public void testCommitTxn() {
 +        //this is to test single VM region transactions
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
-         vm0.invoke(CacheMapTxnDUnitTest.class, "commitTxn");
++        vm0.invoke(() -> CacheMapTxnDUnitTest.commitTxn());
 +    }//end of testCommitTxn
 +    
 +    public void testRollbackTxn() {
 +        //this is to test single VM region transactions
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
-         vm0.invoke(CacheMapTxnDUnitTest.class, "rollbackTxn");
++        vm0.invoke(() -> CacheMapTxnDUnitTest.rollbackTxn());
 +    }//end of testRollbackTxn
 +    
 +    public void testRollbackTxnClear() {
 +        //this is to test single VM region transactions
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        int i=0;
 +        Object ob2;
 +        Object [] objArr = new Object[1];
 +        
 +        for (i=0;i<5; i++){
 +            objArr [0] = ""+i;
 +            vm1.invoke(CacheMapTxnDUnitTest.class, "putMethod", objArr);
 +        }
 +        
-         vm0.invoke(CacheMapTxnDUnitTest.class, "rollbackTxnClear");
++        vm0.invoke(() -> CacheMapTxnDUnitTest.rollbackTxnClear());
 +        
 +        i=3;
 +        objArr [0] = ""+i;
 +        ob2 = vm1.invoke(CacheMapTxnDUnitTest.class, "getMethod", objArr);
 +        
 +        if(ob2 != null){
 +            fail("failed in testRollbackTxnClear");
 +        }
 +    }//end of testRollbackTxnClear
 +    
 +    public void testMiscMethods() throws Throwable{
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
-         vm0.invoke(CacheMapTxnDUnitTest.class, "miscMethodsOwner");
-         AsyncInvocation o2 = vm0.invokeAsync(CacheMapTxnDUnitTest.class, "miscMethodsNotOwner");//invoke in same vm but in seperate thread
-         AsyncInvocation o3 = vm1.invokeAsync(CacheMapTxnDUnitTest.class, "miscMethodsNotOwner");//invoke in another vm
++        vm0.invoke(() -> CacheMapTxnDUnitTest.miscMethodsOwner());
++        AsyncInvocation o2 = vm0.invokeAsync(() -> CacheMapTxnDUnitTest.miscMethodsNotOwner());//invoke in same vm but in seperate thread
++        AsyncInvocation o3 = vm1.invokeAsync(() -> CacheMapTxnDUnitTest.miscMethodsNotOwner());//invoke in another vm
 +        ThreadUtils.join(o2, 30 * 1000);
 +        ThreadUtils.join(o3, 30 * 1000);
 +        
 +        if(o2.exceptionOccurred()){
 +          Assert.fail("o2 failed", o2.getException());
 +        }
 +        
 +        if(o3.exceptionOccurred()){
 +          Assert.fail("o3 failed", o3.getException());
 +        }
 +        
 +    }//end of testMiscMethods
 +    
 +    
 +    //methods to be executed in remote vms...and called through vm.invoke
 +    
 +    public static void commitTxn(){
 +        try{
 +            cacheTxnMgr = cache.getCacheTransactionManager();
 +            int [] i = {0,1,2,3,4,5,6,7,8,9};
 +            Object o3;
 +            o3="init";
 +            region.put(""+i[0], "zero");
 +            region.create(""+i[5], "fifth");
 +            //begin transaction
 +            cacheTxnMgr.begin();
 +            region.put(""+i[1], "first");
 +            //test get
 +            o3 = region.get(""+i[1]);
 +            if( !(o3.toString().equals("first"))){
 +                fail("get inside transaction returns incorrect object");
 +            }
 +            
 +            //test remove
 +            region.put(""+i[2], "second");
 +            o3 = region.remove(""+i[2]);
 +            if( !(o3.toString().equals("second"))){
 +                fail("remove inside transaction returns incorrect object");
 +            }
 +            
 +            boolean flag = region.containsKey(""+i[2]);
 +            if (flag){
 +                fail("region.containsKey after region.remove inside txn returns incorrect value");
 +            }
 +            
 +            region.put(""+i[3], "third");
 +            region.put(""+i[0], "updatedZero");
 +
 +            // test putIfAbsent
 +            region.putIfAbsent(""+i[4], "fourth");
 +            if (!region.get(""+i[4]).toString().equals("fourth")) {
 +              fail("putIfAbsent inside transaction returns incorrect object");
 +            }
 +            
 +            // test replace
 +            region.replace(""+i[4], "fourth2");
 +            if (!region.get(""+i[4]).toString().equals("fourth2")) {
 +              fail("replace inside transaction returns incorrect object)");
 +            }
 +
 +            // test replace
 +            region.replace(""+i[4], "fourth2", "fourth3");
 +            if (!region.get(""+i[4]).toString().equals("fourth3")) {
 +              fail("replace inside transaction returns incorrect object)");
 +            }
 +            
 +            // test a failed removal
 +            boolean succeeded = region.remove(""+i[5], new Object());
 +            assertTrue(!succeeded);
 +            assertTrue(region.get(""+i[5]).equals("fifth"));
 +            
 +            // test remove
 +            region.remove(""+i[5]);
 +            
 +            //commit the transaction
 +            cacheTxnMgr.commit();
 +            
 +            //verify for persistent data now
 +            o3 = region.get(""+i[1]);
 +            if( !(o3.toString().equals("first"))){
 +                fail("get after committed transaction returns incorrect object");
 +            }
 +            
 +            o3 = region.get(""+i[2]);
 +            if(o3 != null){
 +                fail("get after committed transaction returns incorrect object");
 +            }
 +            
 +            o3 = region.get(""+i[3]);
 +            if( !(o3.toString().equals("third"))){
 +                fail("get after committed transaction returns incorrect object");
 +            }
 +            
 +            if (!region.get(""+i[4]).toString().equals("fourth3")) {
 +              fail("get after committed transaction returns incorrect object");
 +            }
 +            
 +            if (region.containsKey(""+i[5])) {
 +              fail("containsKey after committed transaction was true");
 +            }
 +            
 +            boolean val = region.containsValue("updatedZero");
 +            if(! val){
 +                fail("containsValue after committed transaction returns incorrect result");
 +            }
 +            
 +        }
 +        catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("failed in commitTxn");
 +        }
 +        finally{
 +            if(cacheTxnMgr.exists()){
 +                try {cacheTxnMgr.commit();} catch (Exception cce){cce.printStackTrace();}
 +            }
 +        }
 +        
 +    }//end of commitTxn
 +    
 +    
 +    public static void rollbackTxn(){
 +        try{
 +            cacheTxnMgr = cache.getCacheTransactionManager();
 +            int [] i = {0,1,2,3,4,5,6,7,8,9};
 +            Object o3;
 +            o3="init";
 +            region.put(""+i[0], "zero");
 +            region.put(""+i[5], "fifth");
 +            cacheTxnMgr.begin();
 +            region.put(""+i[1], "first");
 +            //test get
 +            o3 = region.get(""+i[1]);
 +            if( !(o3.toString().equals("first"))){
 +                fail("get inside transaction returns incorrect object");
 +            }
 +            
 +            //test containsValue
 +            boolean flag = region.containsValue(new String("first"));
 +            //assertEquals(true, flag);
 +            
 +            //test remove
 +            region.put(""+i[2], "second");
 +            o3 = region.remove(""+i[2]);
 +            if( !(o3.toString().equals("second"))){
 +                fail("remove inside transaction returns incorrect object");
 +            }
 +            
 +            region.put(""+i[3], "third");
 +            region.put(""+i[0], "updatedZero");
 +
 +            
 +            // test putIfAbsent
 +            region.putIfAbsent(""+i[4], "fourth");
 +            if (!region.get(""+i[4]).toString().equals("fourth")) {
 +              fail("putIfAbsent inside transaction returns incorrect object");
 +            }
 +            
 +            // test replace
 +            region.replace(""+i[4], "fourth2");
 +            if (!region.get(""+i[4]).toString().equals("fourth2")) {
 +              fail("replace inside transaction returns incorrect object)");
 +            }
 +
 +            // test replace
 +            region.replace(""+i[4], "fourth2", "fourth3");
 +            if (!region.get(""+i[4]).toString().equals("fourth3")) {
 +              fail("replace inside transaction returns incorrect object)");
 +            }
 +            
 +            // test a failed removal
 +            boolean succeeded = region.remove(""+i[5], new Object());
 +            assertTrue(!succeeded);
 +            assertTrue(region.get(""+i[5]).equals("fifth"));
 +
 +            // test remove
 +            region.remove(""+i[5]);
 +            
 +            //rollback the transaction
 +            cacheTxnMgr.rollback();
 +            
 +            //verify for persistent data now
 +            o3 = region.get(""+i[1]);
 +            if( o3 != null){ //null?
 +                fail("get after rolled back transaction returns incorrect object");
 +            }
 +            
 +            o3 = region.get(""+i[2]);
 +            if( o3 != null){ //null?
 +                fail("get after rolled back transaction returns incorrect object");
 +            }
 +            
 +            o3 = region.get(""+i[3]);
 +            if( o3 != null){ //null?
 +                fail("get after rolled back transaction returns incorrect object");
 +            }
 +            
 +            o3 = region.get(""+i[4]);
 +            if( o3 != null){ //null?
 +                fail("get after rolled back transaction returns incorrect object");
 +            }
 +            
 +            o3 = region.get(""+i[5]);
 +            if (o3 == null) {
 +              fail("get after rolled back transaction returns incorrect object");
 +            }
 +            
 +            //            boolean val = region.containsValue("zero");
 +            //            if( !val){
 +            //                fail("containsValue after rolled back transaction returns incorrect result");
 +            //            }
 +            
 +        }
 +        catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("failed in rollbackTxn");
 +        }
 +        finally{
 +            if(cacheTxnMgr.exists()){
 +                try {cacheTxnMgr.commit();} catch (Exception cce){cce.printStackTrace();}
 +            }
 +        }
 +        
 +    }//end of rollbackTxn
 +    
 +    public static void rollbackTxnClear(){
 +        try{
 +            cacheTxnMgr = cache.getCacheTransactionManager();
 +            int [] i = {0,1,2,3,4,5,6,7,8,9};
 +            region.put(""+i[0], "zero");
 +            //begin transaction
 +            cacheTxnMgr.begin();
 +            region.put(""+i[1], "first");
 +            region.put(""+i[0], "updatedZero");
 +            
 +            try {
 +              region.clear(); //clear is not transactional operation
 +              fail("excpected exception not thrown");
 +            } catch (UnsupportedOperationInTransactionException e) {
 +            }
 +            
 +            //rollback the transaction
 +            cacheTxnMgr.rollback();
 +            
 +            //verify for persistent data now
 +            
 +            boolean val = region.containsValue("updatedZero");
 +            if(val){
 +                fail("containsValue after region.clear & rolled back transaction returns incorrect result");
 +            }
 +            region.clear();
 +            val = region.containsValue("first");
 +            if(val){
 +                fail("containsValue after region.clear & rolled back transaction returns incorrect result");
 +            }
 +            
 +        }
 +        catch(Exception ex){
 +            cacheTxnMgr = null;
 +            ex.printStackTrace();
 +            fail("failed in rollbackTxnClear");
 +        }
 +        
 +    }//end of rollbackTxnClear
 +    
 +    public static void miscMethodsOwner(){
 +        try{
 +            cacheTxnMgr = cache.getCacheTransactionManager();
 +            int [] i = {0,1,2,3,4,5,6,7,8,9};
 +            region.clear();
 +            region.put(""+i[0], "zero");
 +            region.put(""+i[1], "first");
 +            region.put(""+i[2], "second");
 +            region.put(""+i[3], "third");
 +            
 +            cacheTxnMgr.begin();
 +            region.put(""+i[4], "forth");
 +            region.put(""+i[5], "fifth");
 +            
 +            //test size method
 +            int j = region.size();
 +            if(j != 6){
 +                fail("region.size inside transaction returns incorrect results");
 +            }
 +            
 +            //test entrySet method
 +            Set set = region.entrySet();
 +            int k = set.size();
 +            if(j != 6){
 +                fail("region.entrySet inside transaction returns incorrect results");
 +            }
 +            
 +            //test keySet method
 +            set = region.keySet();
 +            k = set.size();
 +            if(j != 6){
 +                fail("region.keySet inside transaction returns incorrect results");
 +            }
 +            
 +            boolean val = region.containsValue("forth");
 +            if( !val){
 +                fail("containsValue inside transaction returns incorrect result");
 +            }
 +            
 +            //commit the transaction
 +            cacheTxnMgr.rollback();
 +            
 +            //verify for persistent data now
 +            
 +        }
 +        catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("failed in miscMethodsOwner");
 +        }
 +        finally{
 +            if(cacheTxnMgr.exists()){
 +                try {cacheTxnMgr.commit();} catch (Exception cce){cce.printStackTrace();}
 +            }
 +        }
 +        
 +    }//end of miscMethodsOwner
 +    
 +    public static void miscMethodsNotOwner(){
 +        try{
 +//            int [] i = {0,1,2,3,4,5,6,7,8,9};
 +            //it is assumed that there are already four committed entried inside region
 +            //test size method
 +            int j = region.size();
 +            if(j != 4){
 +                fail("region.size for not owner of transaction returns incorrect results, size is "+j+ " but expected 4");
 +            }
 +            
 +            //test entrySet method
 +            Set set = region.entrySet();
 +            int k = set.size();
 +            if(j != 4){
 +                fail("region.entrySet for not owner of transaction returns incorrect results");
 +            }
 +            
 +            //test keySet method
 +            set = region.keySet();
 +            k = set.size();
 +            if(j != 4){
 +                fail("region.keySet for not owner of transaction returns incorrect results");
 +            }
 +            boolean val = region.containsKey("forth");
 +            if(val){
 +                fail("containsValue for not owner of transaction returns incorrect result");
 +            }
 +            
 +        }
 +        catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("failed in miscMethodsNotOwner");
 +        }
 +    }//end of miscMethodsNotOwner
 +    
 +    
 +    
 +    //helper methods
 +    public static Object putMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            if(ob != null){
 +                String str = "first";
 +                obj = region.put(ob, str);
 +            }
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.put");
 +        }
 +        return obj;
 +    }
 +    
 +    public static Object getMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.get(ob);
 +        } catch(Exception ex){
 +            fail("Failed while region.get");
 +        }
 +        return obj;
 +    }
 +    
 +    
 +}//end of test class

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/CachedAllEventsDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/CachedAllEventsDUnitTest.java
index c0a1fc4,0000000..c3f97f7
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/CachedAllEventsDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/CachedAllEventsDUnitTest.java
@@@ -1,111 -1,0 +1,111 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.InterestPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.SubscriptionAttributes;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * Make sure that create are distributed and done in
 + * remote regions that are CACHED_ALL_EVENTS*.
 + *
 + * @author darrel
 + * @since 5.0
 + */
 +public class CachedAllEventsDUnitTest extends CacheTestCase {
 +
 +//  private transient Region r;
 +//  private transient DistributedMember otherId;
 +//  private transient int invokeCount;
 +  
 +  public CachedAllEventsDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  private VM getOtherVm() {
 +    Host host = Host.getHost(0);
 +    return host.getVM(0);
 +  }
 +    
 +  private void initOtherId() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("Connect") {
 +        public void run2() throws CacheException {
 +          getCache();
 +        }
 +      });
-     vm.invoke(CachedAllEventsDUnitTest.class, "getVMDistributedMember");
++    vm.invoke(() -> CachedAllEventsDUnitTest.getVMDistributedMember());
 +  }
 +  private void doCreateOtherVm() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("create root") {
 +        public void run2() throws CacheException {
 +          AttributesFactory af = new AttributesFactory();
 +          af.setScope(Scope.DISTRIBUTED_ACK);
 +          Region r1 = createRootRegion("r1", af.create());
 +          r1.create("key", "value");
 +        }
 +      });
 +  }
 +
 +  public static DistributedMember getVMDistributedMember() {
 +    return InternalDistributedSystem.getAnyInstance().getDistributedMember();
 +  }
 +  
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  /**
 +   * make sure a remote create will be done in a NORMAL+ALL region
 +   * @param rmtCreate is true if create should happen in remote region
 +   */
 +  private void remoteCreate(DataPolicy dp, InterestPolicy ip, boolean rmtCreate) throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(dp);
 +    af.setSubscriptionAttributes(new SubscriptionAttributes(ip));
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    Region r1 = createRootRegion("r1", af.create());
 +
 +    assertEquals(false, r1.containsKey("key"));
 +    doCreateOtherVm();
 +    if (rmtCreate) {
 +      assertEquals(true, r1.containsKey("key"));
 +      assertEquals("value", r1.getEntry("key").getValue());
 +    } else {
 +      assertEquals(false, r1.containsKey("key"));
 +    }
 +  }
 +  // TODO these are never used
 +  public void testRemoteCreate_CAE() throws CacheException {
 +    remoteCreate(DataPolicy.NORMAL, InterestPolicy.ALL, true);
 +  }
 +  public void testRemoteCreate_CAER() throws CacheException {
 +    remoteCreate(DataPolicy.REPLICATE, InterestPolicy.CACHE_CONTENT, true);
 +  }
 +  public void testRemoteCreate_C() throws CacheException {
 +    remoteCreate(DataPolicy.NORMAL, InterestPolicy.CACHE_CONTENT, false);
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/CallbackArgDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/CallbackArgDUnitTest.java
index 49e38c0,0000000..f0bae93
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/CallbackArgDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/CallbackArgDUnitTest.java
@@@ -1,185 -1,0 +1,185 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.TransactionEvent;
 +import com.gemstone.gemfire.cache.TransactionListener;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.cache.util.TransactionListenerAdapter;
 +import com.gemstone.gemfire.distributed.DistributedMember;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.SerializableCallable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + * Test the getCallbackArgument in light of bug 34075.
 + *
 + * @author darrel
 + * @since 5.0
 + */
 +public class CallbackArgDUnitTest extends CacheTestCase {
 +
 +//  private transient Region r;
 +//  private transient DistributedMember otherId;
 +  protected transient int invokeCount;
 +  protected static String callbackArg;
 +  
 +  public CallbackArgDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  private VM getOtherVm() {
 +    Host host = Host.getHost(0);
 +    return host.getVM(0);
 +  }
 +    
 +  private void initOtherId() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("Connect") {
 +        public void run2() throws CacheException {
 +          getCache();
 +        }
 +      });
-     vm.invoke(CallbackArgDUnitTest.class, "getVMDistributedMember");
++    vm.invoke(() -> CallbackArgDUnitTest.getVMDistributedMember());
 +  }
 +  private void doCommitOtherVm() {
 +    VM vm = getOtherVm();
 +    vm.invoke(new CacheSerializableRunnable("create root") {
 +        public void run2() throws CacheException {
 +          AttributesFactory af = new AttributesFactory();
 +          CacheListener cl1 = new CacheListenerAdapter() {
 +              public void afterCreate(EntryEvent e) {
 +                assertEquals(callbackArg, e.getCallbackArgument());
 +              }
 +            };
 +          af.addCacheListener(cl1);
 +          af.setScope(Scope.DISTRIBUTED_ACK);
 +          Region r1 = createRootRegion("r1", af.create());
 +          Region r2 = r1.createSubregion("r2", af.create());
 +          Region r3 = r2.createSubregion("r3", af.create());
 +          CacheTransactionManager ctm =  getCache().getCacheTransactionManager();
 +          TransactionListener tl1 = new TransactionListenerAdapter() {
 +              public void afterCommit(TransactionEvent e) {
 +                assertEquals(6, e.getEvents().size());
 +                Iterator it = e.getEvents().iterator();
 +                while (it.hasNext()) {
 +                  EntryEvent ee = (EntryEvent)it.next();
 +                  assertEquals(callbackArg, ee.getCallbackArgument());
 +                  assertEquals(true, ee.isCallbackArgumentAvailable());
 +                }
 +              }
 +            };
 +          ctm.addListener(tl1);
 +          ctm.begin();
 +          r2.put("b", "value1", callbackArg);
 +          r3.put("c", "value2", callbackArg);
 +          r1.put("a", "value3", callbackArg);
 +          r1.put("a2", "value4", callbackArg);
 +          r3.put("c2", "value5", callbackArg);
 +          r2.put("b2", "value6", callbackArg);
 +          ctm.commit();
 +        }
 +      });
 +  }
 +
 +  public static DistributedMember getVMDistributedMember() {
 +    return InternalDistributedSystem.getAnyInstance().getDistributedMember();
 +  }
 +  
 +  //////////////////////  Test Methods  //////////////////////
 +
 +  List expectedKeys;
 +  int clCount = 0;
 +
 +  Object getCurrentExpectedKey() {
 +    Object result = this.expectedKeys.get(this.clCount);
 +    this.clCount += 1;
 +    return result;
 +  }
 +  /**
 +   * make sure callback arg is NOT_AVAILABLE in all the places it should be
 +   */
 +  public void testForNA_CA() throws CacheException {
 +    doTest();
 +  }
 +  public void testForCA() throws Exception {
 +    callbackArg = "cbArg";
 +    getOtherVm().invoke(new SerializableCallable() {
 +      public Object call() throws Exception {
 +        callbackArg = "cbArg";
 +        return null;
 +      }
 +    });
 +    doTest();
 +  }
 +  private void doTest() throws CacheException {
 +    initOtherId();
 +    AttributesFactory af = new AttributesFactory();
 +    af.setDataPolicy(DataPolicy.REPLICATE);
 +    af.setScope(Scope.DISTRIBUTED_ACK);
 +    CacheListener cl1 = new CacheListenerAdapter() {
 +        public void afterCreate(EntryEvent e) {
 +          assertEquals(getCurrentExpectedKey(), e.getKey());
 +          assertEquals(callbackArg, e.getCallbackArgument());
 +          assertEquals(true, e.isCallbackArgumentAvailable());
 +        }
 +      };
 +    af.addCacheListener(cl1);
 +    Region r1 = createRootRegion("r1", af.create());
 +    Region r2 = r1.createSubregion("r2", af.create());
 +    r2.createSubregion("r3", af.create());
 +
 +    TransactionListener tl1 = new TransactionListenerAdapter() {
 +        public void afterCommit(TransactionEvent e) {
 +          assertEquals(6, e.getEvents().size());
 +          ArrayList keys = new ArrayList();
 +          Iterator it = e.getEvents().iterator();
 +          while (it.hasNext()) {
 +            EntryEvent ee = (EntryEvent)it.next();
 +            keys.add(ee.getKey());
 +            assertEquals(callbackArg, ee.getCallbackArgument());
 +            assertEquals(true, ee.isCallbackArgumentAvailable());
 +          }
 +          assertEquals(CallbackArgDUnitTest.this.expectedKeys, keys);
 +          CallbackArgDUnitTest.this.invokeCount = 1;
 +        }
 +      };
 +    CacheTransactionManager ctm =  getCache().getCacheTransactionManager();
 +    ctm.addListener(tl1);
 +
 +    this.invokeCount = 0;
 +    this.clCount = 0;
 +    this.expectedKeys = Arrays.asList(new String[]{"b", "c", "a", "a2", "c2", "b2"});
 +    doCommitOtherVm();
 +    assertEquals(1, this.invokeCount);
 +    assertEquals(6, this.clCount);
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmCallBkDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmCallBkDUnitTest.java
index 1d5b621,0000000..e748a42
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmCallBkDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmCallBkDUnitTest.java
@@@ -1,249 -1,0 +1,249 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * ClearMultiVmCallBkDUnitTest.java
 + *
 + * Created on August 11, 2005, 7:37 PM
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionEvent;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + *
 + * @author  prafulla/vjadhav
 + */
 +public class ClearMultiVmCallBkDUnitTest extends DistributedTestCase{
 +    
 +    /** Creates a new instance of ClearMultiVmCallBkDUnitTest */
 +    public ClearMultiVmCallBkDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    static Cache cache;
 +    static Properties props = new Properties();
 +    static Properties propsWork = new Properties();
 +    static DistributedSystem ds = null;
 +    static Region region;
 +    static Region paperWork;
 +    static CacheTransactionManager cacheTxnMgr;
 +    static boolean afterClear=false;
 +    
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(ClearMultiVmCallBkDUnitTest.class, "createCache");
-       vm1.invoke(ClearMultiVmCallBkDUnitTest.class, "createCache");
++      vm0.invoke(() -> ClearMultiVmCallBkDUnitTest.createCache());
++      vm1.invoke(() -> ClearMultiVmCallBkDUnitTest.createCache());
 +      LogWriterUtils.getLogWriter().fine("Cache created in successfully");
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(ClearMultiVmCallBkDUnitTest.class, "closeCache");
-       vm1.invoke(ClearMultiVmCallBkDUnitTest.class, "closeCache");
++      vm0.invoke(() -> ClearMultiVmCallBkDUnitTest.closeCache());
++      vm1.invoke(() -> ClearMultiVmCallBkDUnitTest.closeCache());
 +    }
 +    
 +    public static void createCache(){
 +        try{
 +            CacheListener aListener = new ListenerCallBk();
 +//            props.setProperty("mcast-port", "1234");
 +//            ds = DistributedSystem.connect(props);
 +            ds = (new ClearMultiVmCallBkDUnitTest("temp")).getSystem(props);            
 +            
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            
 +            // Set Cachelisterner : aListener
 +            
 +            factory.setCacheListener(aListener);
 +            RegionAttributes attr = factory.create();
 +            
 +            region = cache.createRegion("map", attr);
 +            
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static void closeCache(){
 +        try{
 +            
 +            cache.close();
 +            ds.disconnect();
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    //test methods
 +    
 +    public void testClearSingleVM(){
 +        
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        //VM vm1 = host.getVM(1);
 +        
 +//        Object obj0;
 +//        Object obj1;
 +        Object[] objArr = new Object[1];
 +        for (int i=1; i<4; i++){
 +            objArr[0] = ""+i;
 +            vm0.invoke(ClearMultiVmCallBkDUnitTest.class, "putMethod", objArr);
 +            
 +        }
 +        LogWriterUtils.getLogWriter().fine("Did all puts successfully");
 +        
-         vm0.invoke(ClearMultiVmCallBkDUnitTest.class,"clearMethod");
++        vm0.invoke(() -> ClearMultiVmCallBkDUnitTest.clearMethod());
 +        LogWriterUtils.getLogWriter().fine("Did clear successfully");
 +        
 +        while(afterClear){
 +        }       
 +        
-         int Regsize = vm0.invokeInt(ClearMultiVmCallBkDUnitTest.class, "sizeMethod");
++        int Regsize = vm0.invoke(() -> ClearMultiVmCallBkDUnitTest.sizeMethod());
 +        assertEquals(1, Regsize);
 +        
 +        
 +    }//end of test case1
 +    
 +     public void testClearMultiVM(){
 +        
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        Object[] objArr = new Object[1];
 +        for (int i=1; i<4; i++){
 +            objArr[0] = ""+i;
 +            vm0.invoke(ClearMultiVmCallBkDUnitTest.class, "putMethod", objArr);
 +            vm1.invoke(ClearMultiVmCallBkDUnitTest.class, "getMethod", objArr);
 +        }
 +        LogWriterUtils.getLogWriter().fine("Did all puts successfully");
-         //vm0.invoke(ClearMultiVmCallBkDUnitTest.class,"putMethod");
-         vm1.invoke(ClearMultiVmCallBkDUnitTest.class,"clearMethod");
++        //vm0.invoke(() -> ClearMultiVmCallBkDUnitTest.putMethod());
++        vm1.invoke(() -> ClearMultiVmCallBkDUnitTest.clearMethod());
 +        LogWriterUtils.getLogWriter().fine("Did clear successfully");
 +        
 +        while(afterClear){
 +        }       
 +        
-         int Regsize = vm0.invokeInt(ClearMultiVmCallBkDUnitTest.class, "sizeMethod");
++        int Regsize = vm0.invoke(() -> ClearMultiVmCallBkDUnitTest.sizeMethod());
 +        assertEquals(1, Regsize);
 +        
 +        
 +    }//end of test case2
 +    
 +    public static Object putMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            if(ob != null){
 +                String str = "first";
 +                obj = region.put(ob, str);
 +            }
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.put");
 +        }
 +        return obj;
 +    }
 +    
 +    public static Object getMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.get(ob);
 +        } catch(Exception ex){
 +            fail("Failed while region.get");
 +        }
 +        return obj;
 +    }
 +    
 +    public static boolean containsValueMethod(Object ob){
 +        boolean flag = false;
 +        try{
 +            flag = region.containsValue(ob);
 +        }catch(Exception ex){
 +            fail("Failed while region.containsValueMethod");
 +        }
 +        return flag;
 +    }
 +    
 +    public static int sizeMethod(){
 +        int i=0;
 +        try{
 +            i = region.size();
 +        }catch(Exception ex){
 +            fail("Failed while region.size");
 +        }
 +        return i;
 +    }
 +    
 +    public static void clearMethod(){
 +        try{
 +            region.clear();
 +        } catch(Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static boolean getBoolean(){
 +        return afterClear;
 +    }
 +    
 +    static class ListenerCallBk extends CacheListenerAdapter {
 +  
 +        public void afterRegionClear(RegionEvent event){
 +            LogWriterUtils.getLogWriter().fine("In afterClear:: CacheListener Callback");
 +            try {
 +                int i = 7;
 +                region.put(""+i, "inAfterClear");
 +                afterClear = true;
 +            }catch (Exception e){
 +                //
 +            }
 +            
 +        }
 +        
 +    }
 +    
 +    
 +    
 +}//end of class

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmDUnitTest.java
index 8553fe6,0000000..5f9450b
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/ClearMultiVmDUnitTest.java
@@@ -1,469 -1,0 +1,467 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * ClearMultiVmDUnitTest.java
 + *
 + * Created on August 11, 2005, 7:37 PM
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheTransactionManager;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.UnsupportedOperationInTransactionException;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.ThreadUtils;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + *
 + * @author  prafulla
 + */
 +public class ClearMultiVmDUnitTest extends DistributedTestCase{
 +    
 +    /** Creates a new instance of ClearMultiVmDUnitTest */
 +    public ClearMultiVmDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    static Cache cache;
 +    static Properties props = new Properties();
 +    static Properties propsWork = new Properties();
 +    static DistributedSystem ds = null;
 +    static Region region;
 +    static Region paperWork;
 +    static Region mirroredRegion;
 +    static CacheTransactionManager cacheTxnMgr;
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(ClearMultiVmDUnitTest.class, "createCache");
-       vm1.invoke(ClearMultiVmDUnitTest.class, "createCache");
++      vm0.invoke(() -> ClearMultiVmDUnitTest.createCache());
++      vm1.invoke(() -> ClearMultiVmDUnitTest.createCache());
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(ClearMultiVmDUnitTest.class, "closeCache");
-       vm1.invoke(ClearMultiVmDUnitTest.class, "closeCache");
++      vm0.invoke(() -> ClearMultiVmDUnitTest.closeCache());
++      vm1.invoke(() -> ClearMultiVmDUnitTest.closeCache());
 +      cache = null;
 +      Invoke.invokeInEveryVM(new SerializableRunnable() { public void run() { cache = null; } });
 +    }
 +    
 +    public static void createCache(){
 +        try{            
 +            ds = (new ClearMultiVmDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setConcurrencyChecksEnabled(true);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +            
 +            AttributesFactory factory1  = new AttributesFactory();
 +            factory1.setScope(Scope.DISTRIBUTED_ACK);
 +            factory.setConcurrencyChecksEnabled(true);
 +            factory1.setDataPolicy(DataPolicy.REPLICATE);
 +            paperWork = cache.createRegion("paperWork", factory1.create());
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static void closeCache(){
 +        try{
 +            cache.close();
 +            ds.disconnect();
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    //test methods
 +    
 +    public void testClearSimpleScenarios(){
 +        
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        //verifying Single VM clear functionalities
 +        vm0.invoke(new CacheSerializableRunnable("temp1"){
 +            public void run2()throws CacheException{
 +                region.put(new Integer(1), new String("first"));
 +                region.put(new Integer(2), new String("second"));
 +                region.put(new Integer(3), new String("third"));
 +                region.clear();
 +                assertEquals(0, region.size());
 +            }
 +        }
 +        );
 +        
 +        vm1.invoke(new CacheSerializableRunnable("temp1vm1"){
 +            public void run2()throws CacheException{
 +                assertEquals(0, region.size());
 +            }
 +        }
 +        );
 +        
 +        //verifying Single VM and single transaction clear functionalities
 +        vm1.invoke(new CacheSerializableRunnable("temp2"){
 +            public void run2() throws CacheException{
 +                try{
 +                    region.put(new Integer(1), new String("first"));
 +                    region.put(new Integer(2), new String("second"));
 +                    region.put(new Integer(3), new String("third"));
 +                    cacheTxnMgr = cache.getCacheTransactionManager();
 +                    cacheTxnMgr.begin();
 +                    region.put(new Integer(4), new String("forth"));
 +                    try {
 +                      region.clear();
 +                      fail("expected exception not thrown");
 +                    } catch (UnsupportedOperationInTransactionException e) {
 +                      // expected
 +                    }
 +                    region.put(new Integer(5), new String("fifth"));
 +                    cacheTxnMgr.commit();
 +                    assertEquals(5, region.size());
 +                    assertEquals("fifth", region.get(new Integer(5)).toString());
 +                }
 +                catch(CacheException ce){
 +                    ce.printStackTrace();
 +                }
 +                finally{
 +                    if(cacheTxnMgr.exists()){
 +                        try {cacheTxnMgr.commit();} catch (Exception cce){cce.printStackTrace();}
 +                    }
 +                }
 +                
 +            }
 +        }
 +        );
 +        
 +        //verifying that region.clear does not clear the entries from sub region
 +        vm0.invoke(new CacheSerializableRunnable("temp3"){
 +            public void run2()throws CacheException{
 +                region.put(new Integer(1), new String("first"));
 +                region.put(new Integer(2), new String("second"));
 +                AttributesFactory factory  = new AttributesFactory();
 +                factory.setScope(Scope.DISTRIBUTED_ACK);
 +                RegionAttributes attr = factory.create();
 +                Region subRegion = region.createSubregion("subr", attr);
 +                subRegion.put(new Integer(3), new String("third"));
 +                subRegion.put(new Integer(4), new String("forth"));
 +                region.clear();
 +                assertEquals(0, region.size());
 +                assertEquals(2, subRegion.size());
 +            }
 +        }
 +        );
 +        
 +    }//end of test case
 +    
 +    public void testClearMultiVM() throws Throwable{
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        //put 3 key/values in vm0 and get from vm1
 +        Object[] objArr = new Object[1];
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        for (int i=1; i<4; i++){
 +            objArr[0] = ""+i;
 +            vm0.invoke(ClearMultiVmDUnitTest.class, "putMethod", objArr);
 +            vm1.invoke(ClearMultiVmDUnitTest.class, "getMethod", objArr);
 +        }
 +        
-         AsyncInvocation as1 = vm0.invokeAsync(ClearMultiVmDUnitTest.class, "firstVM");
-         AsyncInvocation as2 = vm1.invokeAsync(ClearMultiVmDUnitTest.class, "secondVM");
++        AsyncInvocation as1 = vm0.invokeAsync(() -> ClearMultiVmDUnitTest.firstVM());
++        AsyncInvocation as2 = vm1.invokeAsync(() -> ClearMultiVmDUnitTest.secondVM());
 +        ThreadUtils.join(as1, 30 * 1000);
 +        ThreadUtils.join(as2, 30 * 1000);
 +        
 +        if(as1.exceptionOccurred()){
 +          Assert.fail("as1 failed", as1.getException());
 +        }
 +        
 +        if(as2.exceptionOccurred()){
 +          Assert.fail("as2 failed", as2.getException());
 +        }
 +        
-         int j = vm0.invokeInt(ClearMultiVmDUnitTest.class, "sizeMethod");
++        int j = vm0.invoke(() -> ClearMultiVmDUnitTest.sizeMethod());
 +        assertEquals(0, j);
 +        
-         j = vm1.invokeInt(ClearMultiVmDUnitTest.class, "sizeMethod");
++        j = vm1.invoke(() -> ClearMultiVmDUnitTest.sizeMethod());
 +        assertEquals(1, j);
 +        
 +        
 +        
 +        int i=6;
 +        objArr[0] = ""+i;
 +        vm1.invoke(ClearMultiVmDUnitTest.class, "getMethod", objArr);
 +        
-         Object ob[] = new Object[1];
-         ob[0] = "secondVM";
-         boolean val = vm1.invokeBoolean(ClearMultiVmDUnitTest.class, "containsValueMethod", ob);
++        boolean val = vm1.invoke(() -> containsValueMethod("secondVM"));
 +        assertEquals(true, val);
 +        
 +    }//end of testClearMultiVM
 +    
 +    public void testClearExceptions(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
-         vm1.invoke(ClearMultiVmDUnitTest.class, "localDestroyRegionMethod");
++        vm1.invoke(() -> ClearMultiVmDUnitTest.localDestroyRegionMethod());
 +        vm0.invoke(new CacheSerializableRunnable ("exception in vm0"){
 +            public void run2() throws CacheException {
 +               try{
 +                    region.clear();                    
 +                } catch(RegionDestroyedException rdex){
 +                    fail("Should NOT have thrown RegionDestroyedException");
 +                } 
 +            }
 +        }        
 +        );
 +        
 +        vm1.invoke(new CacheSerializableRunnable ("exception in vm1"){
 +            public void run2() throws CacheException {
 +               try{
 +                    region.clear();
 +                    fail("Should have thrown RegionDestroyedException");
 +                } catch(RegionDestroyedException rdex){
 +                    //pass
 +                } 
 +            }
 +        }        
 +        );
 +        
 +    }//end of testClearExceptions
 +
 +    public void testGiiandClear() throws Throwable{
 +      if (false) {
 +        getSystem().getLogWriter().severe("testGiiandClear skipped because of bug 34963");
 +      } else {
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        SerializableRunnable create = new
 +        CacheSerializableRunnable("create mirrored region") {
 +            public void run2() throws CacheException {
 +                AttributesFactory factory1  = new AttributesFactory();
 +                factory1.setScope(Scope.DISTRIBUTED_ACK);
 +                factory1.setDataPolicy(DataPolicy.REPLICATE);
 +                RegionAttributes attr1 = factory1.create();
 +                mirroredRegion = cache.createRegion("mirrored", attr1);
 +                // reset slow
 +                com.gemstone.gemfire.internal.cache.InitialImageOperation.slowImageProcessing = 0;
 +            }
 +        };
 +        
 +        
 +        vm0.invoke(create);
 +        
 +        vm0.invoke(new CacheSerializableRunnable("put initial data"){
 +            public void run2() throws CacheException {
 +                for(int i=0; i<1000; i++){
 +                    mirroredRegion.put(new Integer(i), (new Integer(i)).toString());
 +                }
 +            }
 +        }
 +        );
 +        
 +        // slow down image processing to make it more likely to get async updates
 +        vm1.invoke(new SerializableRunnable("set slow image processing") {
 +            public void run() {
 +                // if this is a no_ack test, then we need to slow down more because of the
 +                // pauses in the nonblocking operations
 +                int pause = 50;
 +                com.gemstone.gemfire.internal.cache.InitialImageOperation.slowImageProcessing = pause;
 +            }
 +        });
 +        
 +        // now do the get initial image in vm1
 +        AsyncInvocation async1 = vm1.invokeAsync(create);
 +
 +        // try to time a distributed clear to happen in the middle of gii
 +        vm0.invoke(new SerializableRunnable("call clear when gii") {
 +            public void run() {
 +                try{Thread.sleep(3*1000);}catch(InterruptedException ex){fail("interrupted");}
 +                mirroredRegion.clear();                
 +                assertEquals(0, mirroredRegion.size());
 +            }
 +        });
 +        
 +        ThreadUtils.join(async1, 30 * 1000);
 +        if(async1.exceptionOccurred()){
 +          Assert.fail("async1 failed", async1.getException());
 +        }
 +        
 +        SerializableRunnable validate = new
 +        CacheSerializableRunnable("validate for region size") {
 +            public void run2() throws CacheException {
 +                assertEquals(0, mirroredRegion.size());
 +            }
 +        };
 +        
 +        vm0.invoke(validate);
 +        vm1.invoke(validate);
 +      }
 +        
 +    }//end of testGiiandClear
 +    
 +    
 +    //remote vm methods
 +    
 +    public static void firstVM(){
 +          //put one entry
 +          int i=5;
 +          region.put(i, "firstVM");
 +            
 +          //test localClear
 +          region.localClear();
 +          assertFalse(region.containsKey(i));
 +          
 +          paperWork.put("localClear","true");
 +          
 +          // wait unit clear on 2nd VM
 +          boolean val=false;
 +          while (!val) {
 +            val = paperWork.containsKey("localClearVerified");
 +          }
 +          region.put("key10", "value");
 +          region.put("key11", "value");
 +          
 +          // test distributed clear
 +          region.clear();
 +          paperWork.put("clear", "value");
 +          
 +          val = false;
 +          while (!val) {
 +            val = paperWork.containsKey("clearVerified");
 +          }
 +          
 +    }//end of firstVM
 +    
 +    public static void secondVM(){
 +          // verify that localClear on the other VM does not affect size on this VM
 +          boolean val=false;
 +          while (!val) {
 +            val = paperWork.containsKey("localClear");
 +          }
 +          assertEquals(3, region.size());
 +          
 +          paperWork.put("localClearVerified", "value");
 +          
 +          // wait for clear
 +          val = false;
 +          while (!val) {
 +            val = paperWork.containsKey("clear");
 +          }
 +          assertEquals(0, region.size());
 +          
 +          paperWork.put("clearVerified", "value");
 +          region.put(""+6, "secondVM");
 +    }//end of secondVM
 +    
 +    //helper methods
 +    
 +    
 +    public static Object putMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            if(ob != null){
 +                String str = "first";
 +                obj = region.put(ob, str);
 +            }
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.put");
 +        }
 +        return obj;
 +    }
 +    
 +    public static Object getMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.get(ob);
 +        } catch(Exception ex){
 +            fail("Failed while region.get");
 +        }
 +        return obj;
 +    }
 +    
 +    public static boolean containsValueMethod(Object ob){
 +        boolean flag = false;
 +        try{
 +            flag = region.containsValue(ob);
 +        }catch(Exception ex){
 +            fail("Failed while region.containsValueMethod");
 +        }
 +        return flag;
 +    }
 +    
 +    public static int sizeMethod(){
 +        int i=0;
 +        try{
 +            i = region.size();
 +        }catch(Exception ex){
 +            fail("Failed while region.size");
 +        }
 +        return i;
 +    }
 +    
 +    public static void localDestroyRegionMethod(){
 +        try{
 +            region.localDestroyRegion();
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }//end of localDestroyRegionMethod
 +    
 +    public static void clearExceptions(){
 +        try{
 +            region.clear();
 +            //fail("Should have thrown RegionDestroyedException");
 +        } catch(RegionDestroyedException rdex){
 +            //pass
 +        }
 +    }//end of clearExceptions
 +    
 +}//end of class


[098/100] [abbrv] incubator-geode git commit: GEODE-870: Handling multiple concurrent locator restarts. Elder locator nomination

Posted by ud...@apache.org.
GEODE-870: Handling multiple concurrent locator restarts. Elder locator nomination


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/2d125ffa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/2d125ffa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/2d125ffa

Branch: refs/heads/feature/GEODE-870
Commit: 2d125ffa8ea89888ea31f1788cda8d569e8d4937
Parents: dad8cfd
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Wed Feb 10 12:29:02 2016 +1100
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Tue Feb 23 07:26:42 2016 +1100

----------------------------------------------------------------------
 .../membership/gms/membership/GMSJoinLeave.java   | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/2d125ffa/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index b246344..56b644c 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -195,24 +195,24 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
       }
 
       SearchState state = searchState;
-      
-      long locatorWaitTime = ((long)services.getConfig().getLocatorWaitTime()) * 1000L;
+
+      long locatorWaitTime = ((long) services.getConfig().getLocatorWaitTime()) * 1000L;
       long timeout = services.getConfig().getJoinTimeout();
       logger.debug("join timeout is set to {}", timeout);
-      long retrySleep =  JOIN_RETRY_SLEEP;
+      long retrySleep = JOIN_RETRY_SLEEP;
       long startTime = System.currentTimeMillis();
       long locatorGiveUpTime = startTime + locatorWaitTime;
       long giveupTime = startTime + timeout;
 
-      for (int tries=0; !this.isJoined && !this.isStopping; tries++) {
+      for (int tries = 0; !this.isJoined && !this.isStopping; tries++) {
         logger.debug("searching for the membership coordinator");
         boolean found = findCoordinator();
         if (found) {
           logger.debug("found possible coordinator {}", state.possibleCoordinator);
           if (localAddress.getNetMember().preferredForCoordinator()
               && state.possibleCoordinator.equals(this.localAddress)) {
-            if (tries > 2 || System.currentTimeMillis() < giveupTime ) {
-              synchronized(viewInstallationLock) {
+            if (tries > 2 || System.currentTimeMillis() < giveupTime) {
+              synchronized (viewInstallationLock) {
                 becomeCoordinator();
               }
               return true;
@@ -713,6 +713,8 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
     if (preparing) {
       this.preparedView = view;
     } else {
+      //Added a check in the view processor to turn off the ViewCreator
+      //if another server is the coordinator - GEODE-870
       if(!localAddress.equals(view.getCoordinator()) && getViewCreator() != null)
       {
         stopCoordinatorServices();
@@ -1075,12 +1077,16 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
 
   /**
    * for testing, do not use in any other case as it is not thread safe
+   *
+   * @param req
    */
   JoinResponseMessage[] getJoinResponseMessage() {
     return joinResponse;
   }
+
   /***
    * for testing purpose
+   *
    * @param jrm
    */
   void setJoinResponseMessage(JoinResponseMessage jrm) {


[008/100] [abbrv] [partial] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-917

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/DistAckMapMethodsDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/DistAckMapMethodsDUnitTest.java
index 44f7f06,0000000..cf6226d
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/DistAckMapMethodsDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/DistAckMapMethodsDUnitTest.java
@@@ -1,707 -1,0 +1,705 @@@
 +/*
 + * 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.
 + */
 +
 +/*
 + * DistAckMapMethodsDUnitTest.java
 + *
 + * Created on August 4, 2005, 12:36 PM
 + */
 +package com.gemstone.gemfire.cache30;
 +
 +import java.util.HashSet;
 +import java.util.Properties;
 +import java.util.Set;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.Cache;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheFactory;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.CacheWriter;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.Region;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionDestroyedException;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
 +import com.gemstone.gemfire.distributed.DistributedSystem;
 +import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.Invoke;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +
 +/**
 + *
 + * @author  prafulla
 + */
 +public class DistAckMapMethodsDUnitTest extends DistributedTestCase{
 +    static Cache cache;
 +    static Properties props = new Properties();
 +    static DistributedSystem ds = null;
 +    static Region region;
 +    static Region mirroredRegion;
 +    static Region remRegion;
 +    static boolean afterDestroy=false;
 +    
 +    
 +    //helper class referece objects
 +    static Object afterDestroyObj;
 +    
 +    /** Creates a new instance of DistAckMapMethodsDUnitTest */
 +    public DistAckMapMethodsDUnitTest(String name) {
 +        super(name);
 +    }
 +    
 +    @Override
 +    public void setUp() throws Exception {
 +      super.setUp();
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(DistAckMapMethodsDUnitTest.class, "createCache");
-       vm1.invoke(DistAckMapMethodsDUnitTest.class, "createCache");
++      vm0.invoke(() -> DistAckMapMethodsDUnitTest.createCache());
++      vm1.invoke(() -> DistAckMapMethodsDUnitTest.createCache());
 +    }
 +    
 +    @Override
 +    protected final void preTearDown() throws Exception {
 +      Host host = Host.getHost(0);
 +      VM vm0 = host.getVM(0);
 +      VM vm1 = host.getVM(1);
-       vm0.invoke(DistAckMapMethodsDUnitTest.class, "closeCache");
-       vm1.invoke(DistAckMapMethodsDUnitTest.class, "closeCache");
++      vm0.invoke(() -> DistAckMapMethodsDUnitTest.closeCache());
++      vm1.invoke(() -> DistAckMapMethodsDUnitTest.closeCache());
 +      cache = null;
 +      Invoke.invokeInEveryVM(new SerializableRunnable() { public void run() { cache = null; } });
 +    }
 +    
 +    public static void createCache(){
 +        try{
 +            //props.setProperty("mcast-port", "1234");
 +            //ds = DistributedSystem.connect(props);
 +            ds = (new DistAckMapMethodsDUnitTest("temp")).getSystem(props);
 +            cache = CacheFactory.create(ds);
 +            AttributesFactory factory  = new AttributesFactory();
 +            factory.setScope(Scope.DISTRIBUTED_ACK);
 +            RegionAttributes attr = factory.create();
 +            region = cache.createRegion("map", attr);
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static void closeCache(){
 +        try{
 +            cache.close();
 +            ds.disconnect();
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +        
 +    }
 +    
 +    public static void createMirroredRegion(){
 +        try{
 +            AttributesFactory factory1  = new AttributesFactory();
 +            factory1.setScope(Scope.DISTRIBUTED_ACK);
 +            factory1.setDataPolicy(DataPolicy.REPLICATE);
 +            RegionAttributes attr1 = factory1.create();
 +            mirroredRegion = cache.createRegion("mirrored", attr1);
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    public static void createRegionToTestRemove(){
 +        try{
 +            AttributesFactory factory2  = new AttributesFactory();
 +            factory2.setScope(Scope.DISTRIBUTED_ACK);
 +            CacheWriter cacheWriter = new RemoveCacheWriter();
 +            CacheListener cacheListener = new RemoveCacheListener();
 +            factory2.setCacheWriter(cacheWriter);
 +            factory2.setCacheListener(cacheListener);
 +            RegionAttributes attr2 = factory2.create();
 +            remRegion = cache.createRegion("remove", attr2);
 +            
 +        } catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +    }
 +    
 +    //testMethods
 +    
 +    public void testPutMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        Object obj1;
 +        //put from one and get from other
 +        int i=1;
 +        Object[] objArr = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
 +        obj1 = vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);
 +        if(obj1 == null ){
 +            fail("region.put(key, value) from one vm does not match with region.get(key) from other vm");
 +        }
 +        
 +        //put from both vms for same key
 +        i = 2;
 +        objArr[0] = ""+i;
 +        //in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
 +        obj1 = vm1.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
 +        if(obj1 != null){//here if some dummy object is returned on first time put then that should be checked
 +            fail("failed while region.put from both vms for same key");
 +        }
 +    }
 +    
 +    public void testRemoveMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        Object obj1, obj2;
 +        boolean ret;
 +        //put from one and get from other
 +        int i=1;
 +        Object objArr[] = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "removeMethod", objArr);
 +        //validate if vm0 has that key value entry
-         ret = vm0.invokeBoolean(DistAckMapMethodsDUnitTest.class, "containsKeyMethod", objArr);
++        ret = vm0.invoke(() -> containsKeyMethod("" + i));
 +        if( ret ){//if returned true means that the key is still there
 +            fail("region.remove failed with distributed ack scope");
 +        }
 +        
 +        //test if the correct value is returned
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
 +        obj1 = vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);//to make sure that vm1 region has the entry
 +        obj2 = vm1.invoke(DistAckMapMethodsDUnitTest.class, "removeMethod", objArr);
 +        LogWriterUtils.getLogWriter().fine("111111111"+obj1);
 +        LogWriterUtils.getLogWriter().fine("2222222222"+obj2);
 +        if (obj1 == null)
 +          fail("region1.getMethod returned null");
 +        if(!(obj1.equals(obj2))){
 +            fail("region.remove failed with distributed ack scope");
 +        }
 +    }
 +    
 +    public void testRemoveMethodDetails(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
-         vm0.invoke(DistAckMapMethodsDUnitTest.class, "createRegionToTestRemove");
-         vm1.invoke(DistAckMapMethodsDUnitTest.class, "createRegionToTestRemove");
++        vm0.invoke(() -> DistAckMapMethodsDUnitTest.createRegionToTestRemove());
++        vm1.invoke(() -> DistAckMapMethodsDUnitTest.createRegionToTestRemove());
 +        
-         vm0.invoke(DistAckMapMethodsDUnitTest.class, "removeMethodDetails");
++        vm0.invoke(() -> DistAckMapMethodsDUnitTest.removeMethodDetails());
 +        vm1.invoke(new CacheSerializableRunnable("testRemoveMethodDetails"){
 +            public void run2() throws CacheException {
 +                Object ob1 = remRegion.get(new Integer(1));
 +                assertEquals("beforeDestroy", ob1.toString());
 +                //wait till listeber switches afterDestroy to true
 +                //                    while(!afterDestroy){
 +                //                        //wait
 +                //                    }
 +                assertEquals("afterDestroy", remRegion.get(new Integer(3)).toString());
 +            }
 +        }
 +        );
 +    }//end of testRemoveMethodDetails
 +    
 +    public void testIsEmptyMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +//        boolean ret;
 +        //put from one and get from other
 +        int i=1;
 +        Object objArr[] = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
-         boolean val = vm1.invokeBoolean(DistAckMapMethodsDUnitTest.class, "isEmptyMethod");
++        boolean val = vm1.invoke(() -> DistAckMapMethodsDUnitTest.isEmptyMethod());
 +        if (!val){//val should be true
 +            fail("Failed in region.isEmpty");
 +        }
 +        
 +        vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);
-         boolean val1 = vm1.invokeBoolean(DistAckMapMethodsDUnitTest.class, "isEmptyMethod");
++        boolean val1 = vm1.invoke(() -> DistAckMapMethodsDUnitTest.isEmptyMethod());
 +        if (val1){
 +            fail("Failed in region.isEmpty");
 +        }
 +    }
 +    
 +    public void testContainsValueMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +//        boolean ret;
 +        //put from one and get from other
 +        int i=1;
 +        Object objArr[] = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
-         Object ob[] = new Object[1];
-         ob[0] = "first";
-         boolean val = vm1.invokeBoolean(DistAckMapMethodsDUnitTest.class, "containsValueMethod", ob);
++        boolean val = vm1.invoke(() -> containsValueMethod("first"));
 +        if (val){//val should be false.
 +            fail("Failed in region.ContainsValue");
 +        }
 +        
 +        vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);
-         boolean val1 = vm1.invokeBoolean(DistAckMapMethodsDUnitTest.class, "containsValueMethod", ob);
++        boolean val1 = vm1.invoke(() -> containsValueMethod("first"));
 +        if (!val1){//val1 should be true.
 +            fail("Failed in region.ContainsValue");
 +        }
 +    }
 +    
 +    public void testKeySetMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        int i=1;
 +        Object objArr[] = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
-         int temp = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "keySetMethod");
++        int temp = vm1.invoke(() -> DistAckMapMethodsDUnitTest.keySetMethod());
 +        if (temp != 0){
 +            fail("failed in keySetMethodtest method");
 +        }
 +        
 +        vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);//to make sure that vm1 region has the entry
-         temp = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "keySetMethod");
++        temp = vm1.invoke(() -> DistAckMapMethodsDUnitTest.keySetMethod());
 +        if (temp == 0){
 +            fail("failed in keySetMethodtest method");
 +        }
 +        //in the above scenarion we can test this for mirrorred region scenarion as well
 +        temp=0;
-         vm0.invoke(DistAckMapMethodsDUnitTest.class, "createMirroredRegion");
-         vm1.invoke(DistAckMapMethodsDUnitTest.class, "createMirroredRegion");
++        vm0.invoke(() -> DistAckMapMethodsDUnitTest.createMirroredRegion());
++        vm1.invoke(() -> DistAckMapMethodsDUnitTest.createMirroredRegion());
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
-         temp = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "keySetMethod");
++        temp = vm1.invoke(() -> DistAckMapMethodsDUnitTest.keySetMethod());
 +        if (temp == 0){
 +            fail("failed in keySetMethodtest method");
 +        }
 +    }
 +    
 +    
 +    public void testEntrySetMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        int i=1;
 +        Object objArr[] = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
-         int temp = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "entrySetMethod");
++        int temp = vm1.invoke(() -> DistAckMapMethodsDUnitTest.entrySetMethod());
 +        if (temp != 0){
 +            fail("failed in entrySetMethodtest method");
 +        }
 +        
 +        vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);//to make sure that vm1 region has the entry
-         temp = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "entrySetMethod");
++        temp = vm1.invoke(() -> DistAckMapMethodsDUnitTest.entrySetMethod());
 +        if (temp == 0){
 +            fail("failed in entrySetMethodtest method");
 +        }
 +        //in the above scenarion we can test this for mirrorred region scenarion as well
 +        temp=0;
-         vm0.invoke(DistAckMapMethodsDUnitTest.class, "createMirroredRegion");
-         vm1.invoke(DistAckMapMethodsDUnitTest.class, "createMirroredRegion");
++        vm0.invoke(() -> DistAckMapMethodsDUnitTest.createMirroredRegion());
++        vm1.invoke(() -> DistAckMapMethodsDUnitTest.createMirroredRegion());
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putOnMirroredRegion", objArr);
-         temp = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "entrySetMethod");
++        temp = vm1.invoke(() -> DistAckMapMethodsDUnitTest.entrySetMethod());
 +        if (temp == 0){
 +            fail("failed in entrySetMethodtest method");
 +        }
 +    }
 +    
 +    public void testSizeMethod(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
 +        VM vm1 = host.getVM(1);
 +        
 +        int i=1, j=0;
 +        Object objArr[] = new Object[1];
 +        objArr[0] = ""+i;
 +        //Integer in = new Integer(i);
 +        //objArr[0] = (Object) in;
 +        vm0.invoke(DistAckMapMethodsDUnitTest.class, "putMethod", objArr);
-         j = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "sizeMethod");
++        j = vm1.invoke(() -> DistAckMapMethodsDUnitTest.sizeMethod());
 +        if( j != 0){
 +            fail("failed in region.size method");
 +        }
 +        
 +        vm1.invoke(DistAckMapMethodsDUnitTest.class, "getMethod", objArr);//to make sure that vm1 region has the entry
-         j = vm1.invokeInt(DistAckMapMethodsDUnitTest.class, "sizeMethod");
++        j = vm1.invoke(() -> DistAckMapMethodsDUnitTest.sizeMethod());
 +        if( j == 0){
 +            fail("failed in region.size method");
 +        }
 +    }
 +    
 +    public void testallMethodsArgs(){
 +        Host host = Host.getHost(0);
 +        VM vm0 = host.getVM(0);
-         vm0.invoke(DistAckMapMethodsDUnitTest.class, "allMethodsArgs");
++        vm0.invoke(() -> DistAckMapMethodsDUnitTest.allMethodsArgs());
 +    }
 +    
 +    
 +    //following is the implementation of the methods of Map to use in dunit test cases.
 +    /*
 +     *
 +     *
 +     */
 +    
 +    public static Object putMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            if(ob != null){
 +                String str = "first";
 +                obj = region.put(ob, str);
 +            }
 +        }catch(Exception ex){
 +            fail("Failed while region.put");
 +        }
 +        return obj;
 +    }
 +    
 +    public static Object getMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.get(ob);
 +            
 +        } catch(Exception ex){
 +            fail("Failed while region.get");
 +        }
 +        return obj;
 +    }
 +    
 +    public static Object removeMethod(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = region.remove(ob);
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.remove");
 +        }
 +        return obj;
 +    }
 +    
 +    public static boolean containsKeyMethod(Object ob){
 +        boolean flag = false;
 +        try{
 +            flag = region.containsKey(ob);
 +        }catch(Exception ex){
 +            fail("Failed while region.containsKey");
 +        }
 +        return flag;
 +    }
 +    
 +    public static boolean isEmptyMethod(){
 +        boolean flag = false;
 +        try{
 +            flag = region.isEmpty();
 +        }catch(Exception ex){
 +            fail("Failed while region.isEmpty");
 +        }
 +        return flag;
 +    }
 +    
 +    public static boolean containsValueMethod(Object ob){
 +        boolean flag = false;
 +        try{
 +            flag = region.containsValue(ob);
 +        }catch(Exception ex){
 +            fail("Failed while region.containsValueMethod");
 +        }
 +        return flag;
 +    }
 +    
 +    public static int keySetMethod(){
 +        Set set = new HashSet();
 +        int i=0;
 +        try{
 +            set = region.keySet();
 +            i = set.size();
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.keySet");
 +        }
 +        return i;
 +    }
 +    
 +    public static int entrySetMethod(){
 +        Set set = new HashSet();
 +        int i=0;
 +        try{
 +            set = region.entrySet();
 +            i = set.size();
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while region.entrySet");
 +        }
 +        return i;
 +    }
 +    
 +    public static int sizeMethod(){
 +        int i=0;
 +        try{
 +            i = region.size();
 +        }catch(Exception ex){
 +            fail("Failed while region.size");
 +        }
 +        return i;
 +    }
 +    
 +    //following are methods for put on and get from mirrored regions
 +    
 +    public static Object putOnMirroredRegion(Object ob){
 +        Object obj=null;
 +        try{
 +            String str = "mirror";
 +            obj = mirroredRegion.put(ob, str);
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +            fail("Failed while mirroredRegion.put");
 +        }
 +        return obj;
 +    }
 +    
 +    public static Object getFromMirroredRegion(Object ob){
 +        Object obj=null;
 +        try{
 +            obj = mirroredRegion.get(ob);
 +            
 +        } catch(Exception ex){
 +            fail("Failed while mirroredRegion.get");
 +        }
 +        return obj;
 +    }
 +    
 +    public static void removeMethodDetails(){
 +        Object ob1;
 +//        Object ob2;
 +        Integer inOb1 = new Integer(1);
 +        try{
 +            region.put(inOb1, "first");
 +            ob1 = region.remove(inOb1);
 +            assertEquals("first", ob1.toString());
 +        }catch(Exception ex){
 +            ex.printStackTrace();
 +        }
 +        
 +        //to test EntryNotFoundException
 +        try{
 +            region.remove(new Integer(2));
 +            //fail("Should have thrown EntryNotFoundException");
 +        }//catch (EntryNotFoundException e){
 +        catch (Exception e){
 +            //pass
 +            //e.printStackTrace();
 +        }
 +        
 +        //to test NullPointerException
 +        try{
 +            Integer inOb2 = new Integer(2);
 +            region.put(inOb2, "second");
 +            inOb2 = null;
 +            region.remove(inOb2);
 +            fail("Should have thrown NullPointerException ");
 +        }catch (NullPointerException  e){
 +            //pass
 +        }
 +        
 +        //to test the cache writers and listeners
 +        try {
 +            //createRegionToTestRemove();
 +            Integer inOb2 = new Integer(2);
 +            remRegion.put(inOb2, "second");
 +            remRegion.remove(inOb2);
 +            
 +            //to test cacheWriter
 +            inOb2 = new Integer(1);
 +            assertEquals("beforeDestroy", remRegion.get(inOb2).toString());
 +            
 +            //wait till listeber switches afterDestroy to true
 +            while(!afterDestroy){
 +            }
 +            //to test cacheListener
 +            inOb2 = new Integer(3);
 +            assertEquals("afterDestroy", remRegion.get(inOb2).toString());
 +            
 +            //verify that entryEventvalue is correct for listener
 +            assertNotNull(afterDestroyObj);
 +            
 +        }catch (Exception ex){
 +            ex.printStackTrace();
 +        }
 +        
 +        
 +    }//end of removeMethodDetail
 +    
 +    public static void allMethodsArgs(){
 +        //testing args for put method
 +        try{
 +            region.put(new Integer(1), new String("first"));
 +            region.put(new Integer(2), new String("second"));
 +            region.put(new Integer(3), new String("third"));
 +            
 +            //test args for get method
 +            Object ob1 = region.get(new Integer(1));
 +            assertEquals("first", ob1.toString());
 +            
 +            //test args for containsKey method
 +            boolean val1 = region.containsKey(new Integer(2));
 +            assertEquals(true, val1);
 +            
 +            //test args for containsKey method
 +            boolean val2 = region.containsValue(new String("second"));
 +            //assertEquals(true, val2);
 +            
 +            //test args for remove method
 +            try{
 +                region.remove(new Integer(3));
 +            }//catch (EntryNotFoundException ex){
 +            catch (Exception ex){
 +                ex.printStackTrace();
 +                fail("failed while region.remove(new Object())");
 +            }
 +            
 +            //verifying the correct exceptions are thrown by the methods
 +            
 +            Object key=null, value=null;
 +            //testing put method
 +            try{
 +                region.put(key, value);
 +                fail("should have thrown NullPointerException");
 +            }catch(NullPointerException iex){
 +                //pass
 +            }
 +            
 +            //testing containsValue method
 +            try{
 +                region.containsValue(value);
 +                fail("should have thrown NullPointerException");
 +            }catch(NullPointerException iex){
 +                //pass
 +            }
 +            
 +            //RegionDestroyedException
 +            key = new Integer(5);
 +            value = new String("fifth");
 +            
 +            region.localDestroyRegion();
 +            //test put method
 +            try{
 +                region.put(key, value);
 +                fail("should have thrown RegionDestroyedException");
 +            }catch(RegionDestroyedException iex){
 +                //pass
 +            }
 +            
 +            //test remove method
 +            try{
 +                region.remove(key);
 +                fail("should have thrown RegionDestroyedException");
 +            }catch(RegionDestroyedException iex){
 +                //pass
 +            }
 +            
 +            //test containsValue method
 +            try{
 +                region.containsValue(value);
 +                fail("should have thrown RegionDestroyedException");
 +            }catch(RegionDestroyedException iex){
 +                //pass
 +            }
 +            
 +            //test size method
 +            try{
 +                region.size();
 +                fail("should have thrown RegionDestroyedException");
 +            }catch(RegionDestroyedException iex){
 +                //pass
 +            }
 +            
 +            //test keySet method
 +            try{
 +                region.keySet();
 +                fail("should have thrown RegionDestroyedException");
 +            }catch(RegionDestroyedException iex){
 +                //pass
 +            }
 +            
 +            //test entrySet method
 +            try{
 +                region.entrySet();
 +                fail("should have thrown RegionDestroyedException");
 +            }catch(RegionDestroyedException iex){
 +                //pass
 +            }
 +            
 +            
 +        } catch(Exception ex){
 +            ex.printStackTrace();
 +        }
 +        
 +    }//end of allMethodsArgs
 +    
 +    //helper classes
 +    
 +    static class RemoveCacheWriter extends CacheWriterAdapter{
 +        
 +        public void beforeDestroy(EntryEvent entryEvent) throws com.gemstone.gemfire.cache.CacheWriterException {
 +            Integer o1 = new Integer(1);
 +            remRegion.put(o1, "beforeDestroy");
 +        }
 +        
 +    }//end of RemoveCacheWriter
 +    
 +    
 +    static class RemoveCacheListener extends CacheListenerAdapter{
 +        
 +        public void afterDestroy(EntryEvent entryEvent) throws com.gemstone.gemfire.cache.CacheWriterException {
 +            Integer o1 = new Integer(3);
 +            remRegion.put(o1, "afterDestroy");
 +            
 +            afterDestroyObj = entryEvent.getKey();
 +            
 +            //to continue main thread where region.remove has actually occurred
 +            afterDestroy = true;
 +        }
 +        
 +    }//end of RemoveCacheListener
 +    
 +    
 +}//end of class

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5beaaedc/geode-core/src/test/java/com/gemstone/gemfire/cache30/DistributedNoAckRegionCCEDUnitTest.java
----------------------------------------------------------------------
diff --cc geode-core/src/test/java/com/gemstone/gemfire/cache30/DistributedNoAckRegionCCEDUnitTest.java
index a1cc2cd,0000000..f6836ae
mode 100644,000000..100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/DistributedNoAckRegionCCEDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/DistributedNoAckRegionCCEDUnitTest.java
@@@ -1,586 -1,0 +1,586 @@@
 +/*
 + * 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 com.gemstone.gemfire.cache30;
 +
 +import java.util.Map;
 +import java.util.Properties;
 +
 +import com.gemstone.gemfire.cache.AttributesFactory;
 +import com.gemstone.gemfire.cache.CacheException;
 +import com.gemstone.gemfire.cache.CacheListener;
 +import com.gemstone.gemfire.cache.DataPolicy;
 +import com.gemstone.gemfire.cache.EntryEvent;
 +import com.gemstone.gemfire.cache.EntryNotFoundException;
 +import com.gemstone.gemfire.cache.RegionAttributes;
 +import com.gemstone.gemfire.cache.RegionFactory;
 +import com.gemstone.gemfire.cache.RegionShortcut;
 +import com.gemstone.gemfire.cache.Scope;
 +import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
 +import com.gemstone.gemfire.distributed.internal.DistributionConfig;
 +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 +import com.gemstone.gemfire.internal.cache.LocalRegion;
 +import com.gemstone.gemfire.test.dunit.Assert;
 +import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 +import com.gemstone.gemfire.test.dunit.Host;
 +import com.gemstone.gemfire.test.dunit.LogWriterUtils;
 +import com.gemstone.gemfire.test.dunit.SerializableRunnable;
 +import com.gemstone.gemfire.test.dunit.VM;
 +import com.gemstone.gemfire.test.dunit.Wait;
 +
 +public class DistributedNoAckRegionCCEDUnitTest extends
 +    DistributedNoAckRegionDUnitTest {
 +  
 +  static volatile boolean ListenerBlocking;
 +
 +  public DistributedNoAckRegionCCEDUnitTest(String name) {
 +    super(name);
 +  }
 +
 +  @Override
 +  public Properties getDistributedSystemProperties() {
 +    Properties p = super.getDistributedSystemProperties();
 +    p.put(DistributionConfig.CONSERVE_SOCKETS_NAME, "false");
 +    if (distributedSystemID > 0) {
 +      p.put(DistributionConfig.DISTRIBUTED_SYSTEM_ID_NAME, ""+distributedSystemID);
 +    }
 +    p.put(DistributionConfig.SOCKET_BUFFER_SIZE_NAME, ""+2000000);
 +    return p;
 +  }
 +
 +
 +  /**
 +   * Returns region attributes for a <code>GLOBAL</code> region
 +   */
 +  protected RegionAttributes getRegionAttributes() {
 +    AttributesFactory factory = new AttributesFactory();
 +    factory.setScope(Scope.DISTRIBUTED_NO_ACK);
 +    factory.setDataPolicy(DataPolicy.REPLICATE);
 +    factory.setConcurrencyChecksEnabled(true);
 +    return factory.create();
 +  }
 +  protected RegionAttributes getRegionAttributes(String type) {
 +    RegionAttributes ra = getCache().getRegionAttributes(type);
 +    if (ra == null) {
 +      throw new IllegalStateException("The region shortcut " + type
 +                                      + " has been removed.");
 +    }
 +    AttributesFactory factory = new AttributesFactory(ra);
 +    factory.setScope(Scope.DISTRIBUTED_NO_ACK);
 +    factory.setConcurrencyChecksEnabled(true);
 +    return factory.create();
 +  }
 +  
 +  @Override
 +  public void sendSerialMessageToAll() {
 +    try {
 +      com.gemstone.gemfire.distributed.internal.SerialAckedMessage msg = new com.gemstone.gemfire.distributed.internal.SerialAckedMessage();
 +      msg.send(InternalDistributedSystem.getConnectedInstance().getDM().getNormalDistributionManagerIds(), false);
 +    }
 +    catch (Exception e) {
 +      throw new RuntimeException("Unable to send serial message due to exception", e);
 +    }
 +  }
 +
 +
 +  @Override
 +  public void testLocalDestroy() throws InterruptedException {
 +    // replicates don't allow local destroy
 +  }
 +
 +  @Override
 +  public void testEntryTtlLocalDestroy() throws InterruptedException {
 +    // replicates don't allow local destroy
 +  }
 +
 +  public void testClearWithManyEventsInFlight() throws Exception {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3);
 +    
 +    // create replicated regions in VM 0 and 1, then perform concurrent ops
 +    // on the same key while creating the region in VM2.  Afterward make
 +    // sure that all three regions are consistent
 +    
 +    final String name = this.getUniqueName() + "-CC";
 +    createRegionWithAttribute(vm0, name, false);
 +    createRegionWithAttribute(vm1, name, false);
 +    createRegionWithAttribute(vm2, name, false);
 +    createRegionWithAttribute(vm3, name, false);
-     vm0.invoke(DistributedNoAckRegionCCEDUnitTest.class, "addBlockingListener");
-     vm1.invoke(DistributedNoAckRegionCCEDUnitTest.class, "addBlockingListener");
-     vm2.invoke(DistributedNoAckRegionCCEDUnitTest.class, "addBlockingListener");
-     AsyncInvocation vm0Ops = vm0.invokeAsync(DistributedNoAckRegionCCEDUnitTest.class, "doManyOps");
-     AsyncInvocation vm1Ops = vm1.invokeAsync(DistributedNoAckRegionCCEDUnitTest.class, "doManyOps");
-     AsyncInvocation vm2Ops = vm2.invokeAsync(DistributedNoAckRegionCCEDUnitTest.class, "doManyOps");
++    vm0.invoke(() -> DistributedNoAckRegionCCEDUnitTest.addBlockingListener());
++    vm1.invoke(() -> DistributedNoAckRegionCCEDUnitTest.addBlockingListener());
++    vm2.invoke(() -> DistributedNoAckRegionCCEDUnitTest.addBlockingListener());
++    AsyncInvocation vm0Ops = vm0.invokeAsync(() -> DistributedNoAckRegionCCEDUnitTest.doManyOps());
++    AsyncInvocation vm1Ops = vm1.invokeAsync(() -> DistributedNoAckRegionCCEDUnitTest.doManyOps());
++    AsyncInvocation vm2Ops = vm2.invokeAsync(() -> DistributedNoAckRegionCCEDUnitTest.doManyOps());
 +    // pause to let a bunch of operations build up
 +    Wait.pause(5000);
-     AsyncInvocation a0 = vm3.invokeAsync(DistributedNoAckRegionCCEDUnitTest.class, "clearRegion");
-     vm0.invoke(DistributedNoAckRegionCCEDUnitTest.class, "unblockListener");
-     vm1.invoke(DistributedNoAckRegionCCEDUnitTest.class, "unblockListener");
-     vm2.invoke(DistributedNoAckRegionCCEDUnitTest.class, "unblockListener");
++    AsyncInvocation a0 = vm3.invokeAsync(() -> DistributedNoAckRegionCCEDUnitTest.clearRegion());
++    vm0.invoke(() -> DistributedNoAckRegionCCEDUnitTest.unblockListener());
++    vm1.invoke(() -> DistributedNoAckRegionCCEDUnitTest.unblockListener());
++    vm2.invoke(() -> DistributedNoAckRegionCCEDUnitTest.unblockListener());
 +    waitForAsyncProcessing(a0, "");
 +    waitForAsyncProcessing(vm0Ops, "");
 +    waitForAsyncProcessing(vm1Ops, "");
 +    waitForAsyncProcessing(vm2Ops, "");
 +
 +//    if (a0failed && a1failed) {
 +//      fail("neither member saw event conflation - check stats for " + name);
 +//    }
 +    Wait.pause(2000);//this test has with noack, thus we should wait before validating entries
 +    // check consistency of the regions
-     Map r0Contents = (Map)vm0.invoke(this.getClass(), "getCCRegionContents");
-     Map r1Contents = (Map)vm1.invoke(this.getClass(), "getCCRegionContents");
-     Map r2Contents = (Map)vm2.invoke(this.getClass(), "getCCRegionContents");
-     Map r3Contents = (Map)vm3.invoke(this.getClass(), "getCCRegionContents");
++    Map r0Contents = (Map)vm0.invoke(() -> this.getCCRegionContents());
++    Map r1Contents = (Map)vm1.invoke(() -> this.getCCRegionContents());
++    Map r2Contents = (Map)vm2.invoke(() -> this.getCCRegionContents());
++    Map r3Contents = (Map)vm3.invoke(() -> this.getCCRegionContents());
 +    
 +    for (int i=0; i<10; i++) {
 +      String key = "cckey" + i;
 +      assertEquals("region contents are not consistent", r0Contents.get(key), r1Contents.get(key));
 +      assertEquals("region contents are not consistent", r1Contents.get(key), r2Contents.get(key));
 +      assertEquals("region contents are not consistent", r2Contents.get(key), r3Contents.get(key));
 +      for (int subi=1; subi<3; subi++) {
 +        String subkey = key + "-" + subi;
 +        assertEquals("region contents are not consistent", r0Contents.get(subkey), r1Contents.get(subkey));
 +        assertEquals("region contents are not consistent", r1Contents.get(subkey), r2Contents.get(subkey));
 +        assertEquals("region contents are not consistent", r2Contents.get(subkey), r3Contents.get(subkey));
 +      }
 +    }
 +  }
 +  
 +  static void addBlockingListener() {
 +    ListenerBlocking = true;
 +    CCRegion.getAttributesMutator().addCacheListener(new CacheListenerAdapter(){
 +      public void afterCreate(EntryEvent event) {
 +        onEvent(event);
 +      }
 +      private void onEvent(EntryEvent event) {
 +        boolean blocked = false;
 +        if (event.isOriginRemote()) {
 +          synchronized(this) {
 +            while (ListenerBlocking) {
 +              LogWriterUtils.getLogWriter().info("blocking cache operations for " + event.getDistributedMember());
 +              blocked = true;
 +              try {
 +                wait();
 +              } catch (InterruptedException e) {
 +                Thread.currentThread().interrupt();
 +                LogWriterUtils.getLogWriter().info("blocking cache listener interrupted");
 +                return;
 +              }
 +            }
 +          }
 +          if (blocked) {
 +            LogWriterUtils.getLogWriter().info("allowing cache operations for " + event.getDistributedMember());
 +          }
 +        }
 +      }
 +      @Override
 +      public void close() {
 +        LogWriterUtils.getLogWriter().info("closing blocking listener");
 +        ListenerBlocking = false;
 +        synchronized(this) {
 +          notifyAll();
 +        }
 +      }
 +      @Override
 +      public void afterUpdate(EntryEvent event) {
 +        onEvent(event);
 +      }
 +      @Override
 +      public void afterInvalidate(EntryEvent event) {
 +        onEvent(event);
 +      }
 +      @Override
 +      public void afterDestroy(EntryEvent event) {
 +        onEvent(event);
 +      }
 +    });
 +  }
 +  
 +  static void doManyOps() {
 +    // do not include putAll, which requires an Ack to detect failures
 +    doOpsLoopNoFlush(5000, false, false);
 +  }
 +  
 +  static void unblockListener() {
 +    CacheListener listener = CCRegion.getCacheListener();
 +    ListenerBlocking = false;
 +    synchronized(listener) {
 +      listener.notifyAll();
 +    }
 +  }
 +  
 +  static void clearRegion() {
 +    CCRegion.clear();
 +  }
 +
 +  /**
 +   * This test creates a server cache in vm0 and a peer cache in vm1.
 +   * It then tests to see if GII transferred tombstones to vm1 like it's supposed to.
 +   * A client cache is created in vm2 and the same sort of check is performed
 +   * for register-interest.
 +   */
 +
 +  public void testGIISendsTombstones() throws Exception {
 +    versionTestGIISendsTombstones();
 +  }
 +
 +
 +  protected void do_version_recovery_if_necessary(final VM vm0, final VM vm1, final VM vm2, final Object[] params) {
 +    // do nothing here
 +  }
 +  
 +  /**
 +   * This tests the concurrency versioning system to ensure that event conflation
 +   * happens correctly and that the statistic is being updated properly
 +   */
 +  public void testConcurrentEvents() throws Exception {
 +    versionTestConcurrentEvents();
 +  }
 +  
 +  
 +  public void testClearWithConcurrentEvents() throws Exception {
 +    // need to figure out how to flush clear() ops for verification steps
 +  }
 +
 +  public void testClearWithConcurrentEventsAsync() throws Exception {
 +    // need to figure out how to flush clear() ops for verification steps
 +  }
 +
 +  public void testClearOnNonReplicateWithConcurrentEvents() throws Exception {
 +    // need to figure out how to flush clear() ops for verification steps
 +  }
 +  
 +  
 +  public void testTombstones() throws Exception {
 +//    for (int i=0; i<1000; i++) {
 +//      System.out.println("starting run #"+i);
 +      versionTestTombstones();
 +//      if (i < 999) {
 +//        tearDown();
 +//        setUp();
 +//      }
 +//    }
 +  }
 +  
 +
 +  
 +  
 +  
 +  
 +  
 +  public void testOneHopKnownIssues() {
 +    Host host = Host.getHost(0);
 +    VM vm0 = host.getVM(0);
 +    VM vm1 = host.getVM(1);
 +    VM vm2 = host.getVM(2);
 +    VM vm3 = host.getVM(3); // this VM, but treat as a remote for uniformity
 +    
 +    // create an empty region in vm0 and replicated regions in VM 1 and 3,
 +    // then perform concurrent ops
 +    // on the same key while creating the region in VM2.  Afterward make
 +    // sure that all three regions are consistent
 +    
 +    final String name = this.getUniqueName() + "-CC";
 +    SerializableRunnable createRegion = new SerializableRunnable("Create Region") {
 +        public void run() {
 +          try {
 +            final RegionFactory f;
 +            int vmNumber = VM.getCurrentVMNum();
 +            switch (vmNumber) {
 +            case 0:
 +              f = getCache().createRegionFactory(getRegionAttributes(RegionShortcut.REPLICATE_PROXY.toString()));
 +              break;
 +            case 1:
 +              f = getCache().createRegionFactory(getRegionAttributes(RegionShortcut.REPLICATE.toString()));
 +              f.setDataPolicy(DataPolicy.NORMAL);
 +              break;
 +            default:
 +              f = getCache().createRegionFactory(getRegionAttributes());
 +              break;
 +            }
 +            CCRegion = (LocalRegion)f.create(name);
 +          } catch (CacheException ex) {
 +            Assert.fail("While creating region", ex);
 +          }
 +        }
 +      };
 +      
 +    vm0.invoke(createRegion); // empty
 +    vm1.invoke(createRegion); // normal
 +    vm2.invoke(createRegion); // replicate
 +    
 +    // case 1: entry already invalid on vm2 (replicate) is invalidated by vm0 (empty)
 +    final String invalidationKey = "invalidationKey";
 +    final String destroyKey = "destroyKey";
 +    SerializableRunnable test = new SerializableRunnable("case 1: second invalidation not applied or distributed") {
 +      public void run() {
 +        CCRegion.put(invalidationKey, "initialValue");
 +        
 +        int invalidationCount = CCRegion.getCachePerfStats().getInvalidates(); 
 +        CCRegion.invalidate(invalidationKey);
 +        CCRegion.invalidate(invalidationKey);
 +        assertEquals(invalidationCount+1, CCRegion.getCachePerfStats().getInvalidates());
 +
 +        // also test destroy() while we're at it.  It should throw an exception
 +        int destroyCount = CCRegion.getCachePerfStats().getDestroys();
 +        CCRegion.destroy(invalidationKey);
 +        try {
 +          CCRegion.destroy(invalidationKey);
 +          fail("expected an EntryNotFoundException");
 +        } catch (EntryNotFoundException e) {
 +          // expected
 +        }
 +        assertEquals(destroyCount+1, CCRegion.getCachePerfStats().getDestroys());
 +      }
 +    };
 +    vm0.invoke(test);
 +
 +    // now do the same with the datapolicy=normal region
 +    test.setName("case 2: second invalidation not applied or distributed");
 +    vm1.invoke(test);
 +  }
 +
 +  /**
 +   * This tests the concurrency versioning system to ensure that event conflation
 +   * happens correctly and that the statistic is being updated properly
 +   */
 +  public void testConcurrentEventsOnEmptyRegion() {
 +    versionTestConcurrentEventsOnEmptyRegion();
 +  }
 +  
 +  
 +  
 +  
 +  /**
 +   * This tests the concurrency versioning system to ensure that event conflation
 +   * happens correctly and that the statistic is being updated properly
 +   */
 +  public void testConcurrentEventsOnNonReplicatedRegion() {
 +    versionTestConcurrentEventsOnNonReplicatedRegion();
 +  }
 +  
 +  
 +  public void testGetAllWithVersions() {
 +    versionTestGetAllWithVersions();
 +  }
 +
 +  
 +
 +  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 +  // these methods can be uncommented to inhibit test execution
 +  // when new tests are added
 +  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 +
 +//  @Override
 +//  public void testNonblockingGetInitialImage() throws Throwable {
 +//  }
 +//  @Override
 +//  public void testConcurrentOperations() throws Exception {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedUpdate() {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedGet() {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedPutNoUpdate() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testDefinedEntryUpdated() {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedDestroy() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedRegionDestroy() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testLocalRegionDestroy() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedInvalidate() {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedInvalidate4() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedRegionInvalidate() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteCacheListener() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteCacheListenerInSubregion() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteCacheLoader() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteCacheLoaderArg() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteCacheLoaderException() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testCacheLoaderWithNetSearch() throws CacheException {
 +//  }
 +//
 +//  @Override
 +//  public void testCacheLoaderWithNetLoad() throws CacheException {
 +//  }
 +//
 +//  @Override
 +//  public void testNoRemoteCacheLoader() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testNoLoaderWithInvalidEntry() {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteCacheWriter() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testLocalAndRemoteCacheWriters() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testCacheLoaderModifyingArgument() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testRemoteLoaderNetSearch() throws CacheException {
 +//  }
 +//
 +//  @Override
 +//  public void testLocalCacheLoader() {
 +//  }
 +//
 +//  @Override
 +//  public void testDistributedPut() throws Exception {
 +//  }
 +//
 +//  @Override
 +//  public void testReplicate() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testDeltaWithReplicate() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testGetInitialImage() {
 +//  }
 +//
 +//  @Override
 +//  public void testLargeGetInitialImage() {
 +//  }
 +//
 +//  @Override
 +//  public void testMirroredDataFromNonMirrored() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testNoMirroredDataToNonMirrored() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testMirroredLocalLoad() {
 +//  }
 +//
 +//  @Override
 +//  public void testMirroredNetLoad() {
 +//  }
 +//
 +//  @Override
 +//  public void testNoRegionKeepAlive() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testNetSearchObservesTtl() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testNetSearchObservesIdleTime() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testEntryTtlDestroyEvent() throws InterruptedException {
 +//  }
 +//
 +//  @Override
 +//  public void testUpdateResetsIdleTime() throws InterruptedException {
 +//  }
 +//  @Override
 +//  public void testTXNonblockingGetInitialImage() throws Throwable {
 +//  }
 +//
 +//  @Override
 +//  public void testNBRegionInvalidationDuringGetInitialImage() throws Throwable {
 +//  }
 +//
 +//  @Override
 +//  public void testNBRegionDestructionDuringGetInitialImage() throws Throwable {
 +//  }
 +//
 +//  @Override
 +//  public void testNoDataSerializer() {
 +//  }
 +//
 +//  @Override
 +//  public void testNoInstantiator() {
 +//  }
 +//
 +//  @Override
 +//  public void testTXSimpleOps() throws Exception {
 +//  }
 +//
 +//  @Override
 +//  public void testTXUpdateLoadNoConflict() throws Exception {
 +//  }
 +//
 +//  @Override
 +//  public void testTXMultiRegion() throws Exception {
 +//  }
 +//
 +//  @Override
 +//  public void testTXRmtMirror() throws Exception {
 +//  }
 +
 +
 +}